API Reference
Source Code
The API is designed to be run serverlessly (without storing state) and is a wrapper on top of the SDK. See full implementation here.
Caching & Liveness
Users of the Across API are requested to cache results for no longer than 300 seconds.
The Across API serves data that is derived from the on-chain state of the Across contracts and relayer bots. The on-chain state is subject to change each block, and cached data can quickly become invalid as a result.
The exception is the /deposit/status endpoint which is implemented in this stateful repository because it relies on an indexing solution.
Note: Relayer settlement only happens on mainnet. Relayers on the testnet are funded manually by Risk Labs. Therefore we request developers to test with smaller amounts while bridging using the testnet.
You can retrieve current limits of the protocol on testnet using the /limits API on the testnet.
A complete testnet experience can be found at the Across Testnet Bridge.
API Endpoints
Returns data required to execute a crosschain swap.
If the input token requires approval, approvalTxns will be included in the response.
Type of trade. Use minOutput, exactInput or exactOutput.
exactInputPossible values: Required amount of output token in smallest unit.
1000000Address of the input token on the origin chain.
0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85Address of the output token on the destination chain.
0x82aF49447D8a07e3bd95BD0d56f35241523fBab1Chain ID of the origin chain.
10Chain ID of the destination chain.
42161Address of the depositor initiating the swap.
0xA4d353BBc130cbeF1811f27ac70989F9d568CeABAddress of the account receiving the output token.
0xA4d353BBc130cbeF1811f27ac70989F9d568CeAB2-byte hex-string that identifies the integrator. E.g., "0xdead".
0xdeadAddress to receive refunds. Defaults to depositor if not provided.
0xDEPOSITOR_ADDRESSSpecifies whether refund should be sent on the origin chain. Defaults to true.
trueSlippage tolerance percentage (e.g., 1 for 1%, 0.5 for 0.5%).
1Swap approval data returned successfully.
Bad request due to invalid input parameter.
GET /api/swap/approval?tradeType=exactInput&amount=1000000&inputToken=0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85&outputToken=0x82aF49447D8a07e3bd95BD0d56f35241523fBab1&originChainId=10&destinationChainId=42161&depositor=0xA4d353BBc130cbeF1811f27ac70989F9d568CeAB&recipient=0xA4d353BBc130cbeF1811f27ac70989F9d568CeAB HTTP/1.1
Host: app.across.to
Accept: */*
{
"checks": {
"allowance": {
"token": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
"spender": "0x5c7BCd6E7De5423a257D81B442095A1a6ced35C5",
"actual": "115792089237316195423570985008687907853269984665640564039457584007913129639935",
"expected": "1065159719994"
},
"balance": {
"token": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
"actual": "0",
"expected": "1065159719994"
}
},
"steps": {
"bridge": {
"inputAmount": "1065159719994",
"outputAmount": "940201830",
"tokenIn": {
"decimals": 18,
"symbol": "ETH",
"address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
"name": "Ether",
"chainId": 1
},
"tokenOut": {
"decimals": 18,
"symbol": "ETH",
"address": "0xE5ecd226b3032910CEaa43ba92EE8232f8237553",
"name": "Ether",
"chainId": 232
},
"fees": {
"totalRelay": {
"pct": "999117313760226216",
"total": "1064219518164"
},
"relayerCapital": {
"pct": "99999954936899",
"total": "106515923"
},
"relayerGas": {
"pct": "999017313805289317",
"total": "1064113002241"
},
"lp": {
"pct": "0",
"total": "0"
}
}
}
},
"refundToken": {
"decimals": 18,
"symbol": "WETH",
"address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
"name": "Ether",
"chainId": 1
},
"inputAmount": "1065159719994",
"expectedOutputAmount": "940201830",
"minOutputAmount": "940201830",
"expectedFillTime": 8,
"swapTx": {
"simulationSuccess": false,
"chainId": 1,
"to": "0x5c7BCd6E7De5423a257D81B442095A1a6ced35C5",
"data": "0x7b939232000000000000000000000000a4d353bbc130cbef1811f27ac70989f9d568ceab...",
"maxFeePerGas": "1213349849",
"maxPriorityFeePerGas": "500000000"
}
}The crosschain swap API is currently in beta. We are still adding changes and improving the developer experience here. In this period, we request you to provide valuable feedback on how we can improve the overall experience and ensure that we can make the API as seamless as possible.
We appreciate your participation and kindly request you to report any unexpected behaviors or API response anomalies.
Please note that getting routes using /available-routes API is not available on the crosschain swap endpoint. In addition to this, you donot need /suggested-fees API to build the intent.
Learn how to integrate the /swap/approval Endpoint
/swap/approval EndpointLet us now focus on conducting a crosschain swap with the following parameters:
tradeType: Defines the type of trade for eg -minOutput.amount: Specifies amount ofinputTokenin the smallest unit (wei for ETH or 6 decimals for USDC).inputToken: Address of the token being swapped.originChainId: Chain ID of the source/origin chain (232 for Lens Chain mainnet).outputToken: Address of the token to be received after the swap.destinationChainId: Chain ID of the destination chain where the output token will be delivered.depositor: The address of the sender (usually the wallet initiating the swap).
In this specific example, we will be swapping 1 USDC on Optimism with a related amount of ETH on Arbitrum.
Run the following script to conduct the crosschain swap:
import { createWalletClient, http, parseUnits } from 'viem'
import { privateKeyToAccount } from 'viem/accounts';
import { optimism, arbitrum } from 'viem/chains'
import axios from 'axios'
import dotenv from 'dotenv'
dotenv.config()
async function acrossSwapApproval() {
const PRIVATE_KEY = process.env.PRIVATE_KEY
const account = privateKeyToAccount(PRIVATE_KEY)
const client = createWalletClient({
account,
chain: optimism,
transport: http()
})
const { data } = await axios.get('https://app.across.to/api/swap/approval', {
params: {
tradeType: 'minOutput',
amount: parseUnits('1',6).toString(),
inputToken: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85', // USDC on Optimism
originChainId: 10,
outputToken: '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1', // ETH on Arbitrum
destinationChainId: 42161,
depositor: account.address,
}
})
// Handle token approvals if required
if (data.approvalTxns) {
for (const approvalTxn of data.approvalTxns) {
const tx = await client.sendTransaction({
to: approvalTxn.to,
data: approvalTxn.data,
})
console.log('Approval tx hash:', tx)
}
}
// Execute swap transaction
const tx = await client.sendTransaction({
to: data.swapTx.to,
data: data.swapTx.data,
value: data.swapTx.value ? BigInt(data.swapTx.value) : undefined,
})
console.log('Crosschain swap tx hash:', tx)
}
acrossSwapApproval()import { Wallet } from "ethers";
import { ethers } from "ethers";
import axios from "axios";
import dotenv from "dotenv";
dotenv.config();
const wallet = new Wallet(process.env.PRIVATE_KEY).connect(
new ethers.JsonRpcProvider("https://mainnet.optimism.io")
);
const { data } = await axios.get(
`https://preview.across.to/api/swap/approval`,
{
params: {
tradeType: "minOutput",
// required min. output amount of `outputToken` in smallest unit
amount: ethers.parseUnits("1", 6).toString(),
// Eth on Ethereum Mainnet
inputToken: "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",
// Ethereum Mainnet
originChainId: 10,
// WETH on Lens Chain
outputToken: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
// Lens Chain
destinationChainId: 42161,
depositor: wallet.address,
},
}
);
// If the depositor address has insufficient allowance, the response
// will contain the field `approvalTxns`. This field is a list of
// approve-transactions that are required before a cross-swap can be
// facilitated.
if (data.approvalTxns) {
// This field is a list because in rare cases (e.g. USDT), updating an
// already-set allowance requires 2 steps:
// 1. Set allowance to 0
// 2. Set allowance to new value
for (const approvalTxn of data.approvalTxns) {
const tx = await wallet.sendTransaction({
to: approvalTxn.to,
data: approvalTxn.data,
});
console.log(`Approval tx hash:`, tx.hash);
await tx.wait();
}
}
// Sign cross-swap tx
const tx = await wallet.sendTransaction({
to: data.swapTx.to,
data: data.swapTx.data,
value: data.swapTx.value,
});
console.log("Crosschain swap tx hash: ", tx.hash);
await tx.wait();Upon successful execution of the /swap/approval endpoint, the return data should be something like this:
{
"checks": {
"allowance": {
"token": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
"spender": "0x5c7BCd6E7De5423a257D81B442095A1a6ced35C5",
"actual": "115792089237316195423570985008687907853269984665640564039457584007913129639935",
"expected": "1065159719994"
},
"balance": {
"token": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
"actual": "0",
"expected": "1065159719994"
}
},
"steps": {
"bridge": {
"inputAmount": "1065159719994",
"outputAmount": "940201830",
"tokenIn": {
"decimals": 18,
"symbol": "ETH",
"address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
"name": "Ether",
"chainId": 1
},
"tokenOut": {
"decimals": 18,
"symbol": "ETH",
"address": "0xE5ecd226b3032910CEaa43ba92EE8232f8237553",
"name": "Ether",
"chainId": 232
},
"fees": {
"totalRelay": {
"pct": "999117313760226216",
"total": "1064219518164"
},
"relayerCapital": {
"pct": "99999954936899",
"total": "106515923"
},
"relayerGas": {
"pct": "999017313805289317",
"total": "1064113002241"
},
"lp": {
"pct": "0",
"total": "0"
}
}
}
},
"refundToken": {
"decimals": 18,
"symbol": "WETH",
"address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
"name": "Ether",
"chainId": 1
},
"inputAmount": "1065159719994",
"expectedOutputAmount": "940201830",
"minOutputAmount": "940201830",
"expectedFillTime": 8,
"swapTx": {
"simulationSuccess": false,
"chainId": 1,
"to": "0x5c7BCd6E7De5423a257D81B442095A1a6ced35C5",
"data": "0x7b939232000000000000000000000000a4d353bbc130cbef1811f27ac70989f9d568ceab000000000000000000000000c5939f59b3c9662377dda53a08d5085b2d52b719000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000e5ecd226b3032910ceaa43ba92ee8232f8237553000000000000000000000000000000000000000000000000000000f800777c3a00000000000000000000000000000000000000000000000000000000380a576600000000000000000000000000000000000000000000000000000000000000e800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000067f4f4530000000000000000000000000000000000000000000000000000000067f5494300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000c5939f59b3c9662377dda53a08d5085b2d52b719000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044ef8738d3000000000000000000000000e5ecd226b3032910ceaa43ba92ee8232f8237553000000000000000000000000a4d353bbc130cbef1811f27ac70989f9d568ceab00000000000000000000000000000000000000000000000000000000",
"maxFeePerGas": "1213349849",
"maxPriorityFeePerGas": "500000000"
}
}With the above response from the /swap/approval endpoint, you can proceed to sign transaction on the wallet client.
Planned Advancements
We're continuously enhancing the /swap endpoint to provide a more robust and flexible swapping experience. Here's a glimpse into upcoming improvements:
Advanced DEX Aggregation: Expect smarter routing across multiple DEXes, including 0x and LiFi, for optimal execution.
Customizable Application Fees: Integrate the ability to specify and manage application-specific fees directly within the swap.
Permit2 Integration: Streamlined token approvals through Permit2 for a smoother user experience.
Destination Chain Embedded Actions: Enable post-swap actions directly on the destination chain for more complex workflows.
Comprehensive Native Token Support: Seamlessly swap to and from native chain tokens (e.g., ETH).
Detailed API Documentation: Comprehensive API docs for all
/swaprelated endpoints, including clear error responses and usage guides.
Returns transfer limits for inputToken+outputToken, originChainId, and destinationChainId.
Address of token to bridge on the origin chain. Must be used together with parameter outputToken. For ETH, use the wrapped address, like WETH.
Note that the address provided must exist on the specified originChainId.
0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2Address of token to bridge on the destination chain. Must be used together with parameter inputToken. For ETH, use the wrapped address, like WETH.
Note that the address provided must match the token address on the specified destinationChainId below.
0x4200000000000000000000000000000000000006Chain ID where the specified token or inputToken exists.
1The intended destination chain ID of the bridge transfer.
10Transfer limits
Invalid input
Unexpected error within the API
curl -L \
'https://app.across.to/api/limits?inputToken=0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2&outputToken=0x4200000000000000000000000000000000000006&originChainId=1&destinationChainId=10'
{
"minDeposit": "7799819",
"maxDeposit": "22287428516241",
"maxDepositInstant": "201958902363",
"maxDepositShortDelay": "2045367713809",
"recommendedDepositInstant": "201958902363"
}Returns the fill status of a deposit along with a corresponding fill transaction hash if filled.
This endpoint loads data queried by an indexing service that polls relevant events on a 10-second cadence. Users should therefore expect an average latency of 1 to 15 seconds after submitting a deposit to see the status changed in this endpoint. This delay comes from the time it takes for the internal indexing to include the deposit transaction.
Chain Id where the deposit originated from.
137The deposit id that is emitted from the DepositV3 function call as a V3FundsDeposited event.
1349975Lifecycle of a transaction
GET /api/deposit/status?originChainId=137&depositId=1349975 HTTP/1.1
Host: app.across.to
Accept: */*
Lifecycle of a transaction
{
"fillStatus": "filled",
"fillTxHash": "0x123abc<...>",
"destinationChainId": 42161
}Returns all deposits for a given depositor.
This endpoint loads data queried by an indexing service that polls relevant events on a 10-second cadence. Users should therefore expect an average latency of 1 to 15 seconds after submitting a deposit to see the status changed in this endpoint. This delay comes from the time it takes for the internal indexing to include the deposit transaction.
Maximum number of deposits to return in a single request; used for pagination.
50Number of deposits to skip from the beginning of the result set; used for pagination.
100Wallet address of the depositor; filters results to deposits made by this address.
0x89f423567c2648BB828c3997f60c47b54f57Fa6eList of deposits for a given depositor
GET /api/deposits HTTP/1.1
Host: app.across.to
Accept: */*
List of deposits for a given depositor
{
"[\n {\n \"id\": 12108048,\n \"relayHash\": \"0x1496b885808d5c0c03db1287841408be6d9968b70ebba8ef9f771d8f5ab82c3f\",\n \"depositId\": \"3346250\",\n \"originChainId\": 42161,\n \"destinationChainId\": 232,\n \"depositor\": \"0xA4d353BBc130cbeF1811f27ac70989F9d568CeAB\",\n \"recipient\": \"0xA4d353BBc130cbeF1811f27ac70989F9d568CeAB\",\n \"inputToken\": \"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1\",\n \"inputAmount\": \"10000000000000000\",\n \"outputToken\": \"0xE5ecd226b3032910CEaa43ba92EE8232f8237553\",\n \"outputAmount\": \"9997963572235392\",\n \"message\": \"0x\",\n \"messageHash\": \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n \"exclusiveRelayer\": \"0x0000000000000000000000000000000000000000\",\n \"exclusivityDeadline\": null,\n \"fillDeadline\": \"2025-05-06T19:19:35.000Z\",\n \"quoteTimestamp\": \"2025-05-06T16:00:59.000Z\",\n \"depositTxHash\": \"0xfa8e7ff5ba8d31ea16fd5b21a0b59874fde02f5a6cb0c3b4f5e6487c4c146a3f\",\n \"depositBlockNumber\": 333897296,\n \"depositBlockTimestamp\": \"2025-05-06T16:06:58.000Z\",\n \"status\": \"filled\",\n \"depositRefundTxHash\": null,\n \"swapTokenPriceUsd\": null,\n \"swapFeeUsd\": null,\n \"bridgeFeeUsd\": \"0.003682179272249265\",\n \"inputPriceUsd\": \"1808.156093844096\",\n \"outputPriceUsd\": \"1808.156093844096\",\n \"fillGasFee\": \"292908896918512\",\n \"fillGasFeeUsd\": \"0.000292749850110516\",\n \"fillGasTokenPriceUsd\": \"0.9994570092965116\",\n \"swapTransactionHash\": null,\n \"swapToken\": null,\n \"swapTokenAmount\": null,\n \"relayer\": \"0x41ee28EE05341E7fdDdc8d433BA66054Cd302cA1\",\n \"fillBlockTimestamp\": \"2025-05-06T16:06:58.000Z\",\n \"fillTx\": \"0x11463a294431144fcbf1cfbc2faeaddfbdcf5e7248460cee10ff934bb6b8c32b\",\n \"speedups\": []\n }\n]": null
}Last updated