Skip to main content
Version: Endpoint V2

Submit signature

Submits EIP-712 signatures for intent-based routes like Aori. Required when a quote includes SIGNATURE user steps.

POST/submit-signature

Submit signed EIP-712 messages for intent-based transfers (for example, Aori routes). Required when a quote includes SIGNATURE user steps.
Header ParametersValue
x-api-key
string
required
Your API key
Body ParametersValue
quoteId
string
required
The quote ID from the /quotes response
signatures
string
required
Array of signature hex strings
Response
{}

Reference

Authentication

Required. Include your API key in the x-api-key header.

When to use

Route typeWhen to call
AORI_V1Required. Intent-based routes need off-chain signature submission.
Other routesNot applicable. Use on-chain transactions only.

Request body

ParameterTypeRequiredDescription
quoteIdstringYesQuote ID from the /quotes response
signaturesstring or arrayYesEIP-712 signature(s) as hex string(s)

Response

Returns an empty object on success.

{}

Code examples

curl -X POST "https://transfer.layerzero-api.com/v1/submit-signature" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"quoteId": "quote_abc123",
"signatures": ["0x1234567890abcdef..."]
}'

Signing EIP-712 messages

When a quote includes a SIGNATURE user step, sign the EIP-712 typed data and submit it:

Step 1: Extract typed data

const signatureStep = quote.userSteps.find((step) => step.type === 'SIGNATURE');
const {domain, types, message} = signatureStep.signature.typedData;

Step 2: Convert BigInt fields

BigInt conversion required

The API returns numeric message fields as strings for JSON compatibility. Convert these to BigInt before signing:

const normalizedMessage = {
...message,
inputAmount: BigInt(message.inputAmount),
outputAmount: BigInt(message.outputAmount),
startTime: BigInt(message.startTime),
endTime: BigInt(message.endTime),
};

Step 3: Sign typed data

import {type WalletClient} from 'viem';

const signature = await walletClient.signTypedData({
domain,
types,
primaryType: Object.keys(types).find((key) => key !== 'EIP712Domain'),
message: normalizedMessage,
});

Step 4: Submit signature

await fetch('https://transfer.layerzero-api.com/v1/submit-signature', {
method: 'POST',
headers: {
'x-api-key': process.env.VT_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
quoteId: quote.id,
signatures: [signature],
}),
});

Complete example

async function executeAoriRoute(quote: Quote, walletClient: WalletClient) {
for (const step of quote.userSteps) {
if (step.type === 'SIGNATURE') {
const {domain, types, message} = step.signature.typedData;

// Convert numeric fields to BigInt
const normalizedMessage = {
...message,
inputAmount: BigInt(message.inputAmount),
outputAmount: BigInt(message.outputAmount),
startTime: BigInt(message.startTime),
endTime: BigInt(message.endTime),
};

// Sign EIP-712 message
const signature = await walletClient.signTypedData({
domain,
types,
primaryType: Object.keys(types).find((k) => k !== 'EIP712Domain'),
message: normalizedMessage,
});

// Submit signature to API
await fetch('https://transfer.layerzero-api.com/v1/submit-signature', {
method: 'POST',
headers: {
'x-api-key': process.env.VT_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
quoteId: quote.id,
signatures: [signature],
}),
});
}
}
}

Errors

HTTP StatusDescription
400Invalid signature or quote ID
401Missing or invalid API key
404Quote not found
  • Quotes — Request transfer quotes (includes SIGNATURE steps for Aori routes)
  • Status — Track transfer progress after signature submission