Submit EIP-712 signatures
curl --request POST \
--url https://transfer.layerzero-api.com/v1/submit-signature \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"quoteId": "quote_abc123",
"signatures": [
"0x..."
]
}
'import requests
url = "https://transfer.layerzero-api.com/v1/submit-signature"
payload = {
"quoteId": "quote_abc123",
"signatures": ["0x..."]
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({quoteId: 'quote_abc123', signatures: ['0x...']})
};
fetch('https://transfer.layerzero-api.com/v1/submit-signature', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://transfer.layerzero-api.com/v1/submit-signature",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'quoteId' => 'quote_abc123',
'signatures' => [
'0x...'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://transfer.layerzero-api.com/v1/submit-signature"
payload := strings.NewReader("{\n \"quoteId\": \"quote_abc123\",\n \"signatures\": [\n \"0x...\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://transfer.layerzero-api.com/v1/submit-signature")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"quoteId\": \"quote_abc123\",\n \"signatures\": [\n \"0x...\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://transfer.layerzero-api.com/v1/submit-signature")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"quoteId\": \"quote_abc123\",\n \"signatures\": [\n \"0x...\"\n ]\n}"
response = http.request(request)
puts response.read_body{}API Reference
Submit Signature
Submit EIP-712 signatures for intent-based transfer routes.
POST
/
submit-signature
Submit EIP-712 signatures
curl --request POST \
--url https://transfer.layerzero-api.com/v1/submit-signature \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"quoteId": "quote_abc123",
"signatures": [
"0x..."
]
}
'import requests
url = "https://transfer.layerzero-api.com/v1/submit-signature"
payload = {
"quoteId": "quote_abc123",
"signatures": ["0x..."]
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({quoteId: 'quote_abc123', signatures: ['0x...']})
};
fetch('https://transfer.layerzero-api.com/v1/submit-signature', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://transfer.layerzero-api.com/v1/submit-signature",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'quoteId' => 'quote_abc123',
'signatures' => [
'0x...'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://transfer.layerzero-api.com/v1/submit-signature"
payload := strings.NewReader("{\n \"quoteId\": \"quote_abc123\",\n \"signatures\": [\n \"0x...\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://transfer.layerzero-api.com/v1/submit-signature")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"quoteId\": \"quote_abc123\",\n \"signatures\": [\n \"0x...\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://transfer.layerzero-api.com/v1/submit-signature")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"quoteId\": \"quote_abc123\",\n \"signatures\": [\n \"0x...\"\n ]\n}"
response = http.request(request)
puts response.read_body{}Submits EIP-712 signatures for intent-based routes like Aori. Required when a quote includes
SIGNATURE user steps.
Reference
When to use
| Route type | When to call |
|---|---|
| AORI_V1 | Required. Intent-based routes need off-chain signature submission. |
| Other routes | Not applicable. Use on-chain transactions only. |
Request body
| Parameter | Type | Required | Description |
|---|---|---|---|
quoteId | string | Yes | Quote ID from the /quotes response |
signatures | string or array | Yes | EIP-712 signature(s) as hex string(s) |
Response
Returns an empty object on success.{}
Code examples
- cURL
- TypeScript
- Python
curl -X POST "https://transfer.layerzero-api.com/v1/submit-signature" \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"quoteId": "QUOTE_ID",
"signatures": ["0x1234567890abcdef..."]
}'
const response = await fetch('https://transfer.layerzero-api.com/v1/submit-signature', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': 'YOUR_API_KEY',
},
body: JSON.stringify({
quoteId: 'QUOTE_ID',
signatures: ['0x1234567890abcdef...'],
}),
});
if (!response.ok) {
throw new Error(`Signature submission failed: ${response.statusText}`);
}
console.log('Signature submitted successfully');
import requests
response = requests.post(
"https://transfer.layerzero-api.com/v1/submit-signature",
headers={"x-api-key": "YOUR_API_KEY"},
json={
"quoteId": "QUOTE_ID",
"signatures": ["0x1234567890abcdef..."],
},
)
if not response.ok:
raise Exception(f"Signature submission failed: {response.status_code}")
print("Signature submitted successfully")
Signing EIP-712 messages
When a quote includes aSIGNATURE 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
- viem
- ethers
import {type WalletClient} from 'viem';
const signature = await walletClient.signTypedData({
domain,
types,
primaryType: Object.keys(types).find((key) => key !== 'EIP712Domain'),
message: normalizedMessage,
});
import {ethers} from 'ethers';
const signature = await signer._signTypedData(domain, types, normalizedMessage);
Step 4: Submit signature
await fetch('https://transfer.layerzero-api.com/v1/submit-signature', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': 'YOUR_API_KEY',
},
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: {
'Content-Type': 'application/json',
'x-api-key': 'YOUR_API_KEY',
},
body: JSON.stringify({
quoteId: quote.id,
signatures: [signature],
}),
});
}
}
}
Errors
| HTTP Status | Description |
|---|---|
400 | Invalid signature or quote ID |
404 | Quote not found |
Related endpoints
- Quotes — Request transfer quotes (includes
SIGNATUREsteps for Aori routes) - Status — Track transfer progress after signature submission
Authorizations
API key for authenticating requests. Required for /quotes, /build-user-steps, /submit-signature, and /status endpoints.
Body
application/json
Response
200 - application/json
Signature submitted successfully
The response is of type object.
Was this page helpful?
⌘I