cURL
curl --request POST \
--url https://api.example.com/rpc/Trails/ExecuteIntentEdge \
--header 'Content-Type: application/json' \
--data '
{
"intentId": "<string>"
}
'import requests
url = "https://api.example.com/rpc/Trails/ExecuteIntentEdge"
payload = { "intentId": "<string>" }
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({intentId: '<string>'})
};
fetch('https://api.example.com/rpc/Trails/ExecuteIntentEdge', 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.example.com/rpc/Trails/ExecuteIntentEdge",
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([
'intentId' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);
$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.example.com/rpc/Trails/ExecuteIntentEdge"
payload := strings.NewReader("{\n \"intentId\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
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.example.com/rpc/Trails/ExecuteIntentEdge")
.header("Content-Type", "application/json")
.body("{\n \"intentId\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/rpc/Trails/ExecuteIntentEdge")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"intentId\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"intentId": "<string>",
"intentStatus": "QUOTED"
}{
"error": "WebrpcEndpoint",
"code": 0,
"msg": "endpoint error",
"status": 400,
"cause": "<string>"
}{
"error": "WebrpcBadResponse",
"code": -5,
"msg": "bad response",
"status": 500,
"cause": "<string>"
}Intents
ExecuteIntentEdge
POST
/
rpc
/
Trails
/
ExecuteIntentEdge
cURL
curl --request POST \
--url https://api.example.com/rpc/Trails/ExecuteIntentEdge \
--header 'Content-Type: application/json' \
--data '
{
"intentId": "<string>"
}
'import requests
url = "https://api.example.com/rpc/Trails/ExecuteIntentEdge"
payload = { "intentId": "<string>" }
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({intentId: '<string>'})
};
fetch('https://api.example.com/rpc/Trails/ExecuteIntentEdge', 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.example.com/rpc/Trails/ExecuteIntentEdge",
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([
'intentId' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);
$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.example.com/rpc/Trails/ExecuteIntentEdge"
payload := strings.NewReader("{\n \"intentId\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
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.example.com/rpc/Trails/ExecuteIntentEdge")
.header("Content-Type", "application/json")
.body("{\n \"intentId\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/rpc/Trails/ExecuteIntentEdge")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"intentId\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"intentId": "<string>",
"intentStatus": "QUOTED"
}{
"error": "WebrpcEndpoint",
"code": 0,
"msg": "endpoint error",
"status": 400,
"cause": "<string>"
}{
"error": "WebrpcBadResponse",
"code": -5,
"msg": "bad response",
"status": 500,
"cause": "<string>"
}Overview
TheExecuteIntentEdge endpoint arms an origin-mode edge intent — a cross-chain intent whose origin is a non-EVM chain (Solana or Tron) quoted through QuoteIntentEdge. Arming is the client’s “user is proceeding” signal and starts server-side monitoring of the external rail: once Trails observes the deposit fill, execution completes without any further client call.
Call ExecuteIntentEdge before the user pays on the edge chain. No deposit hash is attached — the fill is discovered server-side. Re-arming an already-armed intent is an idempotent success.
When to use it
- Origin-mode edge intents (Solana → EVM, Tron → EVM): call this after
QuoteIntentEdgeand before prompting the user to sign on the edge chain. - Destination-mode edge intents (EVM → Solana, EVM → Tron): do not call this. Destination-mode arming happens atomically inside
ExecuteIntentwhen the origin transaction is submitted. - Non-edge intents (EVM → EVM): call
ExecuteIntentdirectly.
Request Parameters
Required Fields
- intentId (string): The unique identifier returned from
QuoteIntentEdge. The edge quote is resolved and validated server-side from the intent; noedgeIdis required here.
Response
- intentId (string): The intent identifier.
- intentStatus (
IntentStatus): The current intent status. Arming does not itself transition the intent — the intent stays in a pre-execution status (typicallyQUOTED) until the edge monitor observes the fill and internally invokesExecuteIntent.
Example
import { TrailsApi } from '@0xtrails/api'
const trailsApi = new TrailsApi('YOUR_API_KEY')
// 1. Quote an edge intent (e.g. Solana → Base)
const { intent, edgeId } = await trailsApi.quoteIntentEdge({
intent: {
ownerAddress: '0x0709CF2d5D4f3D38f5948d697fE64d7FB3639Eb1',
originChainId: 0,
destinationChainId: 8453,
destinationTokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
destinationToAddress: '0x0709CF2d5D4f3D38f5948d697fE64d7FB3639Eb1',
destinationTokenAmount: 100000000n,
},
edge: {
rail: 'SOLANA',
mode: 'ORIGIN',
originChainId: 1399811149,
originAddress: 'AbC...',
originTokenAddress: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
},
})
// 2. Arm the intent before the user pays on Solana
await trailsApi.executeIntentEdge({ intentId: intent.id })
// 3. Prompt the user to sign the Solana deposit
// (the server watches for the fill and completes execution)
// 4. Track completion
const receipt = await trailsApi.waitIntentReceipt({ intentId: intent.id })
Errors
ErrInvalidArgument:intentIdis missing, the intent has no origin edge quote, or the edge quote is in a terminal state.ErrNotFound: The intent does not exist.ErrIntentStatus: The intent is no longer in a pre-execution status (already executing, aborted, or completed).ErrQuoteExpired: The quote’s validity window has elapsed. Request a fresh quote and arm again.ErrIntentsDisabled: Intents are disabled on this deployment.
Notes
ExecuteIntentEdge replaces the arming behavior of the deprecated CommitIntent call for edge intents in the SDK send flow.Next Steps
GetEdgeStatus
Track the external rail leg’s status
WaitIntentReceipt
Stream the inner intent’s receipt updates
Was this page helpful?