Skip to content

Cross-Chain Swaps

Cross-chain swaps (bridging) let you move tokens between different blockchain networks through a single API call. Suwappu handles the routing, bridging protocol selection, and settlement automatically.

How It Works

To perform a cross-chain swap, include both from_chain and to_chain parameters in your POST /quote request. When these differ, Suwappu routes the transaction through the optimal bridge.

POST /quote

{

class="hl-str">"from_token": class="hl-str">"USDC",

class="hl-str">"to_token": class="hl-str">"USDC",

class="hl-str">"amount": class="hl-str">"1000",

class="hl-str">"from_chain": class="hl-str">"ethereum",

class="hl-str">"to_chain": class="hl-str">"arbitrum"

}

The quote response includes the expected output amount after bridge fees and slippage. Execute the quote the same way as a single-chain swap -- via POST /swap/execute.

Important Considerations

  • Settlement time: Cross-chain swaps take longer than same-chain swaps. Ethereum to L2 bridges typically complete in 1-15 minutes. L2 to L1 withdrawals can take longer depending on the bridge used.
  • Bridge fees: The quoted output amount accounts for bridge fees. The expected_output field reflects what you will receive after all fees.
  • Status tracking: Use GET /swap/status/{swapId} to poll for completion. Cross-chain swaps may stay in "pending" status longer than same-chain swaps.
  • Token availability: Not all token pairs are available for cross-chain swaps. The quote endpoint will return an error if no route is found.

Full Example: Bridge USDC from Ethereum to Arbitrum

Step 1: Get a Cross-Chain Quote

-kw">curl -X POST https://api.suwappu.bot/v1/agent/quote \

-H -str">"Authorization: Bearer suwappu_sk_your_api_key" \

-H -str">"Content-Type: application/json" \

-d -str">'{

-str">"from_token": -str">"USDC",

-str">"to_token": -str">"USDC",

-str">"amount": -str">"1000",

-str">"from_chain": -str">"ethereum",

-str">"to_chain": -str">"arbitrum"

}'

#### Example Response

{

"hl-key">"success": true,

"hl-key">"quote_id": "qt_bridge_x1y2z3",

"hl-key">"from_token": "USDC",

"hl-key">"to_token": "USDC",

"hl-key">"amount": "1000",

"hl-key">"expected_output": "999.15",

"hl-key">"from_chain": "ethereum",

"hl-key">"to_chain": "arbitrum",

"hl-key">"expires_at": "2026-03-07T12:05:00Z"

}

Step 2: Execute the Swap

-kw">curl -X POST https://api.suwappu.bot/v1/agent/swap/execute \

-H -str">"Authorization: Bearer suwappu_sk_your_api_key" \

-H -str">"Content-Type: application/json" \

-d -str">'{-str">"quote_id": -str">"qt_bridge_x1y2z3"}'

#### Example Response

{

"hl-key">"success": true,

"hl-key">"swap_id": 5201,

"hl-key">"status": "submitted",

"hl-key">"tx_hash": "0x7b2a...e91f"

}

Step 3: Check Status Until Complete

-kw">curl https://api.suwappu.bot/v1/agent/swap/status/5201 \

-H -str">"Authorization: Bearer suwappu_sk_your_api_key"

#### Example Response (in progress)

{

"hl-key">"success": true,

"hl-key">"swap_id": 5201,

"hl-key">"status": "pending",

"hl-key">"tx_hash": "0x7b2a...e91f",

"hl-key">"from_token": "USDC",

"hl-key">"to_token": "USDC"

}

#### Example Response (completed)

{

"hl-key">"success": true,

"hl-key">"swap_id": 5201,

"hl-key">"status": "completed",

"hl-key">"tx_hash": "0x7b2a...e91f",

"hl-key">"from_token": "USDC",

"hl-key">"to_token": "USDC"

}

Python Example

import requests
import time

API_KEY = class="hl-str">"suwappu_sk_your_api_key"

BASE_URL = class="hl-str">"https:class="hl-commentclass="hl-str">">//api.suwappu.bot/v1/agent"

headers = {class="hl-str">"Authorization": fclass="hl-str">"Bearer {API_KEY}"}

class=class="hl-str">"hl-comment"># Step 1: Get a cross-chain quote

quote_response = requests.post(

fclass="hl-str">"{BASE_URL}/quote",

headers=headers,

json={

class="hl-str">"from_token": class="hl-str">"USDC",

class="hl-str">"to_token": class="hl-str">"USDC",

class="hl-str">"amount": class="hl-str">"1000",

class="hl-str">"from_chain": class="hl-str">"ethereum",

class="hl-str">"to_chain": class="hl-str">"arbitrum",

},

)

quote = quote_response.json()

print(fclass="hl-str">"Expected output: {quote[class="hl-str">'expected_output']} USDC on Arbitrum") class=class="hl-str">"hl-comment"># Step 2: Execute the swap

swap_response = requests.post(

fclass="hl-str">"{BASE_URL}/swap/execute",

headers=headers,

json={class="hl-str">"quote_id": quote[class="hl-str">"quote_id"]},

)

swap = swap_response.json()

swap_id = swap[class="hl-str">"swap_id"]

print(fclass="hl-str">"Swap submitted: {swap_id}") class=class="hl-str">"hl-comment"># Step 3: Poll for completion

while True:

status_response = requests.get(

fclass="hl-str">"{BASE_URL}/swap/status/{swap_id}",

headers=headers,

)

status = status_response.json()

print(fclass="hl-str">"Status: {status[class="hl-str">'status']}")

if status[class="hl-str">"status"] in (class="hl-str">"completed", class="hl-str">"failed"):

break

time.sleep(10) class=class="hl-str">"hl-comment"># Cross-chain swaps can take minutes

if status[class="hl-str">"status"] == class="hl-str">"completed":

print(fclass="hl-str">"Bridge complete! TX: {status[class="hl-str">'tx_hash']}")

else:

print(class="hl-str">"Bridge failed.")

TypeScript Example

const API_KEY = class="hl-str">"suwappu_sk_your_api_key";
const BASE_URL = class="hl-str">"https:class="hl-commentclass="hl-str">">//api.suwappu.bot/v1/agent";
const headers = {

Authorization: Bearer ${API_KEY},

class="hl-str">"Content-Type": class="hl-str">"application/json",

};

class=class="hl-str">"hl-comment">// Step 1: Get a cross-chain quote const quoteRes = await fetch(${BASE_URL}/quote, {

method: class="hl-str">"POST",

headers,

body: JSON.stringify({

from_token: class="hl-str">"USDC",

to_token: class="hl-str">"USDC",

amount: class="hl-str">"1000",

from_chain: class="hl-str">"ethereum",

to_chain: class="hl-str">"arbitrum",

}),

});

const quote = await quoteRes.json();

console.log(Expected output: ${quote.expected_output} USDC on Arbitrum);

class=class="hl-str">"hl-comment">// Step 2: Execute the swap const swapRes = await fetch(${BASE_URL}/swap/execute, {

method: class="hl-str">"POST",

headers,

body: JSON.stringify({ quote_id: quote.quote_id }),

});

const swap = await swapRes.json(); const swapId = swap.swap_id;

console.log(Swap submitted: ${swapId});

class=class="hl-str">"hl-comment">// Step 3: Poll for completion const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));

while (true) {

const statusRes = await fetch(${BASE_URL}/swap/status/${swapId}, {

headers: { Authorization: Bearer ${API_KEY} },

});

const status = await statusRes.json();

console.log(Status: ${status.status});

if (status.status === class="hl-str">"completed" || status.status === class="hl-str">"failed") {

if (status.status === class="hl-str">"completed") {

console.log(Bridge complete! TX: ${status.tx_hash});

} else {

console.log(class="hl-str">"Bridge failed.");

}

break;

}

await sleep(10_000); class=class="hl-str">"hl-comment">// Cross-chain swaps can take minutes

}

Supported Cross-Chain Routes

Cross-chain swaps are supported between all EVM chains. The most common routes include:

  • Ethereum to/from L2s (Arbitrum, Optimism, Base)
  • Between L2s (e.g., Arbitrum to Base)
  • Stablecoin bridges (USDC, USDT) across any EVM pair

Use the POST /quote endpoint to check if a specific route is available. If no bridge route exists, the API returns an error with a descriptive message.