Examples
Runnable snippets — curl, TypeScript, an x402 agent handshake, and an MCP session.
Four examples against the live Testnet API. All amounts are USDC; rates are indicative (the sandbox FX source is simulated StableFX).
1. Quote, send, and track with curl
# Quote USD → EUR
curl -s -X POST https://transvia.xyz/api/quote \
-H "content-type: application/json" \
-d '{"corridor":"USD-EUR","amountUsdc":100}'
# Lock the quote into a transfer (use the quote id from the response)
curl -s -X POST https://transvia.xyz/api/send \
-H "content-type: application/json" \
-d '{"quoteId":"qt_…","recipientLabel":"Alice","recipientAddr":"0x…"}'
# Poll the status — simulated-rail settlement completes in seconds
curl -s https://transvia.xyz/api/intents/int_…
# Release the payout to the recipient
curl -s -X POST https://transvia.xyz/api/claim \
-H "content-type: application/json" \
-d '{"intentId":"int_…"}'2. Create a transfer in TypeScript
const API = "https://transvia.xyz";
async function send100UsdcToEur(recipientLabel: string) {
const { quote } = await fetch(`${API}/api/quote`, {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ corridor: "USD-EUR", amountUsdc: 100 }),
}).then((r) => r.json());
const { intent } = await fetch(`${API}/api/send`, {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ quoteId: quote.id, recipientLabel }),
}).then((r) => r.json());
// Poll until the transfer reaches a terminal state
let status = intent.status;
while (!["claimable", "claimed", "refunded"].includes(status)) {
await new Promise((r) => setTimeout(r, 2000));
const { intent: fresh } = await fetch(`${API}/api/intents/${intent.id}`)
.then((r) => r.json());
status = fresh.status;
}
return status;
}3. An x402 agent handshake
An agent pays 0.01 USDC per quote: request → 402 with terms → sign an
EIP-3009 authorization → retry with x-payment.
const first = await fetch("https://transvia.xyz/api/quote", {
method: "POST",
headers: {
"content-type": "application/json",
"x-corridor-client": "external-agent",
},
body: JSON.stringify({ corridor: "USD-EUR", amountUsdc: 100 }),
});
// first.status === 402 — payment terms in (await first.json()).accepts[0]
// Build the payment: an EIP-3009 TransferWithAuthorization signed by the
// agent's wallet (viem signTypedData), then base64-encode the payload.
const payment = {
x402Version: 1,
scheme: "exact",
network: "arc-testnet",
payer: account.address,
asset: "USDC",
amount: "10000", // 0.01 USDC in 6-decimal units
authorization: { from, to: payTo, value: "10000", validAfter, validBefore, nonce },
signature,
};
const second = await fetch("https://transvia.xyz/api/quote", {
method: "POST",
headers: {
"content-type": "application/json",
"x-corridor-client": "external-agent",
"x-payment": btoa(JSON.stringify(payment)),
},
body: JSON.stringify({ corridor: "USD-EUR", amountUsdc: 100 }),
});
// second.status === 200 — the verifier recovered the signer, matched the payerPrefer not to sign anything? POST https://transvia.xyz/api/x402/demo
replays the full 402 → pay → 200 handshake against the live API. See
x402.
4. An MCP session with Claude Code
claude mcp add --transport http transvia https://transvia.xyz/api/mcpThen just ask:
Quote 500 USDC to INR and send it to "Alice" — then show me the status.Claude discovers the tools (rail_overview, corridor_quote,
corridor_send, corridor_status, …), calls them, and narrates the
lifecycle. Every send is policy-gated and logged like any other transfer.
See MCP for the tool reference.
Prefer raw JSON-RPC? The same session over curl:
curl -s -X POST https://transvia.xyz/api/mcp \
-H "content-type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'More endpoints in API; the full sending flow in Sending USDC.