Initiate an intent with Permit2
curl --request POST \
--url https://api.eco.com/v1/intents/submit/permit2 \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"chainId": 8453,
"target": {
"quoteId": "quote:8a7cbdcd-2aed-40b0-ab08-c4c10af15f23"
},
"permit2": {
"details": {
"token": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"amount": "1000000",
"expiration": 1789526504,
"nonce": 0
},
"spender": "0xf6358b8f1d0Ec04EBc9Fe8FdEe5e6791640D1c2F",
"sigDeadline": "1789526504"
},
"signature": "0xedc90fdd27654dd49ac1087901450c9c5fdf444943f61faa8d787bee86304d821f06a5db4a67eddf5cf286014d6ec8bd33c64f9e072045a9f3c5e50cc28960fc1b"
}
'import requests
url = "https://api.eco.com/v1/intents/submit/permit2"
payload = {
"chainId": 8453,
"target": { "quoteId": "quote:8a7cbdcd-2aed-40b0-ab08-c4c10af15f23" },
"permit2": {
"details": {
"token": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"amount": "1000000",
"expiration": 1789526504,
"nonce": 0
},
"spender": "0xf6358b8f1d0Ec04EBc9Fe8FdEe5e6791640D1c2F",
"sigDeadline": "1789526504"
},
"signature": "0xedc90fdd27654dd49ac1087901450c9c5fdf444943f61faa8d787bee86304d821f06a5db4a67eddf5cf286014d6ec8bd33c64f9e072045a9f3c5e50cc28960fc1b"
}
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({
chainId: 8453,
target: {quoteId: 'quote:8a7cbdcd-2aed-40b0-ab08-c4c10af15f23'},
permit2: {
details: {
token: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
amount: '1000000',
expiration: 1789526504,
nonce: 0
},
spender: '0xf6358b8f1d0Ec04EBc9Fe8FdEe5e6791640D1c2F',
sigDeadline: '1789526504'
},
signature: '0xedc90fdd27654dd49ac1087901450c9c5fdf444943f61faa8d787bee86304d821f06a5db4a67eddf5cf286014d6ec8bd33c64f9e072045a9f3c5e50cc28960fc1b'
})
};
fetch('https://api.eco.com/v1/intents/submit/permit2', 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://api.eco.com/v1/intents/submit/permit2",
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([
'chainId' => 8453,
'target' => [
'quoteId' => 'quote:8a7cbdcd-2aed-40b0-ab08-c4c10af15f23'
],
'permit2' => [
'details' => [
'token' => '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
'amount' => '1000000',
'expiration' => 1789526504,
'nonce' => 0
],
'spender' => '0xf6358b8f1d0Ec04EBc9Fe8FdEe5e6791640D1c2F',
'sigDeadline' => '1789526504'
],
'signature' => '0xedc90fdd27654dd49ac1087901450c9c5fdf444943f61faa8d787bee86304d821f06a5db4a67eddf5cf286014d6ec8bd33c64f9e072045a9f3c5e50cc28960fc1b'
]),
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://api.eco.com/v1/intents/submit/permit2"
payload := strings.NewReader("{\n \"chainId\": 8453,\n \"target\": {\n \"quoteId\": \"quote:8a7cbdcd-2aed-40b0-ab08-c4c10af15f23\"\n },\n \"permit2\": {\n \"details\": {\n \"token\": \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n \"amount\": \"1000000\",\n \"expiration\": 1789526504,\n \"nonce\": 0\n },\n \"spender\": \"0xf6358b8f1d0Ec04EBc9Fe8FdEe5e6791640D1c2F\",\n \"sigDeadline\": \"1789526504\"\n },\n \"signature\": \"0xedc90fdd27654dd49ac1087901450c9c5fdf444943f61faa8d787bee86304d821f06a5db4a67eddf5cf286014d6ec8bd33c64f9e072045a9f3c5e50cc28960fc1b\"\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://api.eco.com/v1/intents/submit/permit2")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"chainId\": 8453,\n \"target\": {\n \"quoteId\": \"quote:8a7cbdcd-2aed-40b0-ab08-c4c10af15f23\"\n },\n \"permit2\": {\n \"details\": {\n \"token\": \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n \"amount\": \"1000000\",\n \"expiration\": 1789526504,\n \"nonce\": 0\n },\n \"spender\": \"0xf6358b8f1d0Ec04EBc9Fe8FdEe5e6791640D1c2F\",\n \"sigDeadline\": \"1789526504\"\n },\n \"signature\": \"0xedc90fdd27654dd49ac1087901450c9c5fdf444943f61faa8d787bee86304d821f06a5db4a67eddf5cf286014d6ec8bd33c64f9e072045a9f3c5e50cc28960fc1b\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.eco.com/v1/intents/submit/permit2")
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 \"chainId\": 8453,\n \"target\": {\n \"quoteId\": \"quote:8a7cbdcd-2aed-40b0-ab08-c4c10af15f23\"\n },\n \"permit2\": {\n \"details\": {\n \"token\": \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n \"amount\": \"1000000\",\n \"expiration\": 1789526504,\n \"nonce\": 0\n },\n \"spender\": \"0xf6358b8f1d0Ec04EBc9Fe8FdEe5e6791640D1c2F\",\n \"sigDeadline\": \"1789526504\"\n },\n \"signature\": \"0xedc90fdd27654dd49ac1087901450c9c5fdf444943f61faa8d787bee86304d821f06a5db4a67eddf5cf286014d6ec8bd33c64f9e072045a9f3c5e50cc28960fc1b\"\n}"
response = http.request(request)
puts response.read_body{
"id": "gasless:0f450218-1b2c-4d3e-8f9a-0b1c2d3e4f5a",
"status": "published",
"signatureHash": "0x94245dddfb2339e6e06fe251c90de895bf2995ff3c5a5fb185390f1850ed6726",
"subStatuses": [
{
"chainId": 8453,
"quoteIds": [
"quote:8a7cbdcd-2aed-40b0-ab08-c4c10af15f23"
],
"txHash": "0x3ef97346fd076aadb54c851f33ba9234feb34d27442b9bb0abc7a0d75827af13",
"intentHashes": [
"0x3f1886e7c3a4cab62b4a0661e393600f0917d5a514652e96623b0f17ce0d3749"
],
"state": "published"
}
],
"createdAt": 1789522604,
"updatedAt": 1789522654
}{
"id": "gasless:0f450218-1b2c-4d3e-8f9a-0b1c2d3e4f5a",
"status": "processing",
"signatureHash": "0x94245dddfb2339e6e06fe251c90de895bf2995ff3c5a5fb185390f1850ed6726",
"subStatuses": [
{
"chainId": 8453,
"quoteIds": [
"quote:8a7cbdcd-2aed-40b0-ab08-c4c10af15f23"
],
"txHash": null,
"intentHashes": [],
"state": "pending"
}
],
"createdAt": 1789522604,
"updatedAt": 1789522614
}{
"type": "https://api.eco.com/v1/errors/invalid-request",
"title": "Request failed validation",
"status": 400,
"code": "invalid-request",
"detail": "chainId: Invalid input: expected number, received undefined; permit2.sigDeadline: Invalid input: expected string, received number",
"errors": [
{
"field": "chainId",
"detail": "Invalid input: expected number, received undefined"
},
{
"field": "permit2.sigDeadline",
"detail": "Invalid input: expected string, received number"
}
],
"requestId": "f371e43e6fd4406b10e19487b3170edf"
}{
"type": "https://api.eco.com/v1/errors/invalid-api-key",
"title": "API key is missing, unknown, or revoked",
"status": 401,
"code": "invalid-api-key",
"requestId": "98e4c42f-9c70-4539-843e-8d31803001e6"
}{
"Message": "User is not authorized to access this resource with an explicit deny in an identity-based policy"
}{
"type": "https://api.eco.com/v1/errors/signature-already-bound",
"title": "This signature is already pinned to a different target",
"status": 409,
"code": "signature-already-bound",
"requestId": "3ff33e83251b3cdb7d3daf15d186b89b"
}{
"type": "https://api.eco.com/v1/errors/quote-expired",
"title": "The quote is unknown or expired at submit time",
"status": 410,
"code": "quote-expired",
"requestId": "19ff8aa0914e6fbe2fcb7fbe930bf0ea"
}{
"type": "https://api.eco.com/v1/errors/chain-not-supported",
"title": "Chain is not supported",
"status": 422,
"code": "chain-not-supported",
"requestId": "252dbcdeebe5465fdc089843e8643b37"
}{
"type": "https://api.eco.com/v1/errors/rate-limit-exceeded",
"title": "Rate limit exceeded",
"status": 429,
"code": "rate-limit-exceeded",
"requestId": "1eac3d6cc2aafa524b0c47a039576f8c"
}{
"type": "https://api.eco.com/v1/errors/internal-error",
"title": "Internal error",
"status": 500,
"code": "internal-error",
"requestId": "02dabcf0f4e3def9a6091526d3d21022"
}{
"type": "<string>",
"title": "<string>",
"status": 499,
"code": "<string>",
"detail": "<string>",
"instance": "<string>",
"legacyCode": "<string>",
"solverErrors": [
{
"solver": "<string>",
"message": "<string>",
"solverName": "<string>",
"code": "<string>"
}
],
"errors": [
{
"field": "<string>",
"detail": "<string>"
}
],
"requestId": "<string>"
}Quote funding and status
Initiate an intent with Permit2
Funds a quote gaslessly with a signed Permit2 PermitSingle. Requires an API key.
POST
/
v1
/
intents
/
submit
/
permit2
Initiate an intent with Permit2
curl --request POST \
--url https://api.eco.com/v1/intents/submit/permit2 \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"chainId": 8453,
"target": {
"quoteId": "quote:8a7cbdcd-2aed-40b0-ab08-c4c10af15f23"
},
"permit2": {
"details": {
"token": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"amount": "1000000",
"expiration": 1789526504,
"nonce": 0
},
"spender": "0xf6358b8f1d0Ec04EBc9Fe8FdEe5e6791640D1c2F",
"sigDeadline": "1789526504"
},
"signature": "0xedc90fdd27654dd49ac1087901450c9c5fdf444943f61faa8d787bee86304d821f06a5db4a67eddf5cf286014d6ec8bd33c64f9e072045a9f3c5e50cc28960fc1b"
}
'import requests
url = "https://api.eco.com/v1/intents/submit/permit2"
payload = {
"chainId": 8453,
"target": { "quoteId": "quote:8a7cbdcd-2aed-40b0-ab08-c4c10af15f23" },
"permit2": {
"details": {
"token": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"amount": "1000000",
"expiration": 1789526504,
"nonce": 0
},
"spender": "0xf6358b8f1d0Ec04EBc9Fe8FdEe5e6791640D1c2F",
"sigDeadline": "1789526504"
},
"signature": "0xedc90fdd27654dd49ac1087901450c9c5fdf444943f61faa8d787bee86304d821f06a5db4a67eddf5cf286014d6ec8bd33c64f9e072045a9f3c5e50cc28960fc1b"
}
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({
chainId: 8453,
target: {quoteId: 'quote:8a7cbdcd-2aed-40b0-ab08-c4c10af15f23'},
permit2: {
details: {
token: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
amount: '1000000',
expiration: 1789526504,
nonce: 0
},
spender: '0xf6358b8f1d0Ec04EBc9Fe8FdEe5e6791640D1c2F',
sigDeadline: '1789526504'
},
signature: '0xedc90fdd27654dd49ac1087901450c9c5fdf444943f61faa8d787bee86304d821f06a5db4a67eddf5cf286014d6ec8bd33c64f9e072045a9f3c5e50cc28960fc1b'
})
};
fetch('https://api.eco.com/v1/intents/submit/permit2', 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://api.eco.com/v1/intents/submit/permit2",
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([
'chainId' => 8453,
'target' => [
'quoteId' => 'quote:8a7cbdcd-2aed-40b0-ab08-c4c10af15f23'
],
'permit2' => [
'details' => [
'token' => '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
'amount' => '1000000',
'expiration' => 1789526504,
'nonce' => 0
],
'spender' => '0xf6358b8f1d0Ec04EBc9Fe8FdEe5e6791640D1c2F',
'sigDeadline' => '1789526504'
],
'signature' => '0xedc90fdd27654dd49ac1087901450c9c5fdf444943f61faa8d787bee86304d821f06a5db4a67eddf5cf286014d6ec8bd33c64f9e072045a9f3c5e50cc28960fc1b'
]),
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://api.eco.com/v1/intents/submit/permit2"
payload := strings.NewReader("{\n \"chainId\": 8453,\n \"target\": {\n \"quoteId\": \"quote:8a7cbdcd-2aed-40b0-ab08-c4c10af15f23\"\n },\n \"permit2\": {\n \"details\": {\n \"token\": \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n \"amount\": \"1000000\",\n \"expiration\": 1789526504,\n \"nonce\": 0\n },\n \"spender\": \"0xf6358b8f1d0Ec04EBc9Fe8FdEe5e6791640D1c2F\",\n \"sigDeadline\": \"1789526504\"\n },\n \"signature\": \"0xedc90fdd27654dd49ac1087901450c9c5fdf444943f61faa8d787bee86304d821f06a5db4a67eddf5cf286014d6ec8bd33c64f9e072045a9f3c5e50cc28960fc1b\"\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://api.eco.com/v1/intents/submit/permit2")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"chainId\": 8453,\n \"target\": {\n \"quoteId\": \"quote:8a7cbdcd-2aed-40b0-ab08-c4c10af15f23\"\n },\n \"permit2\": {\n \"details\": {\n \"token\": \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n \"amount\": \"1000000\",\n \"expiration\": 1789526504,\n \"nonce\": 0\n },\n \"spender\": \"0xf6358b8f1d0Ec04EBc9Fe8FdEe5e6791640D1c2F\",\n \"sigDeadline\": \"1789526504\"\n },\n \"signature\": \"0xedc90fdd27654dd49ac1087901450c9c5fdf444943f61faa8d787bee86304d821f06a5db4a67eddf5cf286014d6ec8bd33c64f9e072045a9f3c5e50cc28960fc1b\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.eco.com/v1/intents/submit/permit2")
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 \"chainId\": 8453,\n \"target\": {\n \"quoteId\": \"quote:8a7cbdcd-2aed-40b0-ab08-c4c10af15f23\"\n },\n \"permit2\": {\n \"details\": {\n \"token\": \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n \"amount\": \"1000000\",\n \"expiration\": 1789526504,\n \"nonce\": 0\n },\n \"spender\": \"0xf6358b8f1d0Ec04EBc9Fe8FdEe5e6791640D1c2F\",\n \"sigDeadline\": \"1789526504\"\n },\n \"signature\": \"0xedc90fdd27654dd49ac1087901450c9c5fdf444943f61faa8d787bee86304d821f06a5db4a67eddf5cf286014d6ec8bd33c64f9e072045a9f3c5e50cc28960fc1b\"\n}"
response = http.request(request)
puts response.read_body{
"id": "gasless:0f450218-1b2c-4d3e-8f9a-0b1c2d3e4f5a",
"status": "published",
"signatureHash": "0x94245dddfb2339e6e06fe251c90de895bf2995ff3c5a5fb185390f1850ed6726",
"subStatuses": [
{
"chainId": 8453,
"quoteIds": [
"quote:8a7cbdcd-2aed-40b0-ab08-c4c10af15f23"
],
"txHash": "0x3ef97346fd076aadb54c851f33ba9234feb34d27442b9bb0abc7a0d75827af13",
"intentHashes": [
"0x3f1886e7c3a4cab62b4a0661e393600f0917d5a514652e96623b0f17ce0d3749"
],
"state": "published"
}
],
"createdAt": 1789522604,
"updatedAt": 1789522654
}{
"id": "gasless:0f450218-1b2c-4d3e-8f9a-0b1c2d3e4f5a",
"status": "processing",
"signatureHash": "0x94245dddfb2339e6e06fe251c90de895bf2995ff3c5a5fb185390f1850ed6726",
"subStatuses": [
{
"chainId": 8453,
"quoteIds": [
"quote:8a7cbdcd-2aed-40b0-ab08-c4c10af15f23"
],
"txHash": null,
"intentHashes": [],
"state": "pending"
}
],
"createdAt": 1789522604,
"updatedAt": 1789522614
}{
"type": "https://api.eco.com/v1/errors/invalid-request",
"title": "Request failed validation",
"status": 400,
"code": "invalid-request",
"detail": "chainId: Invalid input: expected number, received undefined; permit2.sigDeadline: Invalid input: expected string, received number",
"errors": [
{
"field": "chainId",
"detail": "Invalid input: expected number, received undefined"
},
{
"field": "permit2.sigDeadline",
"detail": "Invalid input: expected string, received number"
}
],
"requestId": "f371e43e6fd4406b10e19487b3170edf"
}{
"type": "https://api.eco.com/v1/errors/invalid-api-key",
"title": "API key is missing, unknown, or revoked",
"status": 401,
"code": "invalid-api-key",
"requestId": "98e4c42f-9c70-4539-843e-8d31803001e6"
}{
"Message": "User is not authorized to access this resource with an explicit deny in an identity-based policy"
}{
"type": "https://api.eco.com/v1/errors/signature-already-bound",
"title": "This signature is already pinned to a different target",
"status": 409,
"code": "signature-already-bound",
"requestId": "3ff33e83251b3cdb7d3daf15d186b89b"
}{
"type": "https://api.eco.com/v1/errors/quote-expired",
"title": "The quote is unknown or expired at submit time",
"status": 410,
"code": "quote-expired",
"requestId": "19ff8aa0914e6fbe2fcb7fbe930bf0ea"
}{
"type": "https://api.eco.com/v1/errors/chain-not-supported",
"title": "Chain is not supported",
"status": 422,
"code": "chain-not-supported",
"requestId": "252dbcdeebe5465fdc089843e8643b37"
}{
"type": "https://api.eco.com/v1/errors/rate-limit-exceeded",
"title": "Rate limit exceeded",
"status": 429,
"code": "rate-limit-exceeded",
"requestId": "1eac3d6cc2aafa524b0c47a039576f8c"
}{
"type": "https://api.eco.com/v1/errors/internal-error",
"title": "Internal error",
"status": 500,
"code": "internal-error",
"requestId": "02dabcf0f4e3def9a6091526d3d21022"
}{
"type": "<string>",
"title": "<string>",
"status": 499,
"code": "<string>",
"detail": "<string>",
"instance": "<string>",
"legacyCode": "<string>",
"solverErrors": [
{
"solver": "<string>",
"message": "<string>",
"solverName": "<string>",
"code": "<string>"
}
],
"errors": [
{
"field": "<string>",
"detail": "<string>"
}
],
"requestId": "<string>"
}Funds a quote gaslessly with a signed Permit2
PermitSingle (AllowanceTransfer, not SignatureTransfer). chainId is the chain the permit was signed for, target.quoteId names the quote, permit2.spender is the quote’s execution.vault, and signature is the top-level EIP-712 signature. permit2.sigDeadline is a decimal string. The first submission answers 202 with a gasless job; resending the same signature returns the existing job with 200.
Requires x-api-key. Partner pricing, attribution, and enabled features are tied to the key. Without a key the gateway can answer 403 with a plain JSON body ({"Message": "User is not authorized ..."}); a key that is unknown, revoked, or not enabled for v1 answers 401 invalid-api-key. No requests-per-second quota is published. Handle 429 and honor Retry-After when present. See Errors and retries for common errors and retry handling.
Examples use mainnet token and contract addresses with placeholder wallets, hashes, signatures, and IDs. They are illustrative and must not be used to transfer funds.Authorizations
Body
application/json
Response
Existing job for the same signature and target.
