> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.0x.org/llms.txt.
> For full documentation content, see https://docs.0x.org/llms-full.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.0x.org/_mcp/server.

# Get started

> Learn how to use the 0x Cross Chain API endpoint to get a quote, set allowance, and send a cross chain swap transaction.

Quick link with examples: [0x-examples](https://github.com/0xProject/0x-examples)

## About 0x Cross Chain API

The 0x Cross Chain API is a fast, flexible API that lets developers programmatically access tokens across various blockchains, enabling cross-chain swap functionality in any app or wallet.

Whether you're building a new application, or expanding the offering of your existing product, this API helps you integrate cross-chain token swaps with minimal overhead and maximum efficiency.

## Steps to Cross Chain Swap Tokens

This guide will walk you through using the `/quotes` and `/status` endpoints on 0x's Cross Chain API to:

1. Fetch a quote
2. Set allowance
3. Sign and send a transaction
4. Monitor the status of the cross chain swap

In our example, we will be swapping WETH on Base to USDC on Arbitrum.

### 0. Prerequisites

Make sure you have:

* A funded Base wallet
* [0x API key](https://dashboard.0x.org/apps)
* An RPC Connection (see details below)

Base provides a [default public RPC endpoint](https://docs.base.org/chain/network-information), but for production use, it's strongly recommended to run your own or use a third-party provider like [QuickNode](https://www.quicknode.com/) or [Alchemy](https://www.alchemy.com/).

To interact with that RPC, we will use a popular TS library, [viem](https://viem.sh/).

```typescript
import { createWalletClient, http } from "viem";
import { base } from "viem/chains";
import { privateKeyToAccount } from "viem/accounts";

const PRIVATE_KEY = 'your_private_key'

const account = privateKeyToAccount(PRIVATE_KEY as `0x${string}`);
const walletClient = createWalletClient(
  {
    account,
    chain: base,
    transport: http(configuration.rpcUrls.base),
  }
)
```

### 1. Fetch a Quote

Start by sending a GET request to the 0x `/quotes` endpoint to get a quote for a specific tokens and chains pair with selected amount.

```typescript
const quotesParams = new URLSearchParams({
    originChain: '8453', // Base mainnet
    destinationChain: '42161', // Arbitrum mainnet
    sellToken: '0x4200000000000000000000000000000000000006', // WETH on Base
    buyToken: '0xaf88d065e77c8cc2239327c5edb3a432268e5831', // USDC on Arbitrum
    sellAmount: '1000000000000000000', // Amount of sellToken in base units
    originAddress: '$USER_TAKER_ADDRESS', // Address that will make the trade
    sortQuotesBy: 'price', // Prefer the quote that will result in the best price / output
    maxNumQuotes: 1 // only the best quote
});

const headers = {
    '0x-api-key': '[api-key]', // Get your live API key from the 0x Dashboard (https://dashboard.0x.org/apps)
};

const quoteResponse = await fetch('https://api.0x.org/cross-chain/quotes?' + quotesParams.toString(), { headers });

console.log(await quoteResponse.json());
```

```json
{
    "liquidityAvailable": true,
    "allowanceTarget": "0x0000000000001ff3684f28c67538d4d072c22734",
    "originChainId": 8453,
    "originChain": "base",
    "destinationChainId": 42161,
    "destinationChain": "arbitrum",
    "sellToken": "0xcbb7c0000ab88b473b1f5afd9ef808440eed33bf",
    "buyToken": "0xaf88d065e77c8cc2239327c5edb3a432268e5831",
    "issues": {
        "allowance": {
            "actual": "0",
            "spender": "0x0000000000001ff3684f28c67538d4d072c22734"
        },
        "balance": {
            "token": "0xcbb7c0000ab88b473b1f5afd9ef808440eed33bf",
            "actual": "0",
            "expected": "2570"
        },
        "simulationIncomplete": false,
        "invalidSwapSourcesPassed": [],
        "invalidBridgesPassed": []
    },
    "zid": "0x0d2804bc7404160d778f0f7f",
    "quotes": [
        {
            "sellAmount": "2570",
            "buyAmount": "2016894",
            "minBuyAmount": "1996725",
            "fees": {
                "integratorFee": null,
                "integratorFees": null,
                "zeroExFee": {
                    "amount": "24",
                    "token": "0xcbb7c0000ab88b473b1f5afd9ef808440eed33bf",
                    "type": "volume"
                },
                "bridgeNativeFee": null
            },
            "gasCosts": {
                "chainType": "evm",
                "gasPrice": "7610802",
                "gasLimit": "151386",
                "totalNetworkFee": "1252356913486"
            },
            "steps": [
                {
                    "type": "bridge",
                    "originChainId": 8453,
                    "destinationChainId": 42161,
                    "sellToken": "0xcbb7c0000ab88b473b1f5afd9ef808440eed33bf",
                    "buyToken": "0xaf88d065e77c8cc2239327c5edb3a432268e5831",
                    "sellAmount": "2546",
                    "buyAmount": "2016894",
                    "minBuyAmount": "1996725",
                    "provider": "relay",
                    "estimatedTimeSeconds": 1
                }
            ],
            "transaction": {
                "chainType": "evm",
                "details": {
                    "to": "0x0000000000001ff3684f28c67538d4d072c22734",
                    "data": "0x2213bc0b...",
                    "gas": "151386",
                    "gasPrice": "7610802",
                    "value": "0"
                }
            },
            "estimatedTimeSeconds": 1,
            "issues": {
                "allowance": {
                    "actual": "0",
                    "spender": "0x0000000000001ff3684f28c67538d4d072c22734"
                },
                "balance": {
                    "token": "0xcbb7c0000ab88b473b1f5afd9ef808440eed33bf",
                    "actual": "0",
                    "expected": "2570"
                },
                "simulationIncomplete": false
            },
            "quoteId": "0x0d2804bc7404160d778f0f7f4ec037a2"
        }
    ]
}
```

### 2. Set a token allowance

It is possible, that you will need to set proper token allowance to 0x's [AllowanceHolder contract](/docs/0x-swap-api/additional-topics/how-to-set-your-token-allowances). In cases where allowance will be needed, it will be reported in `issues` in the response and will be the same as the allowance target for Swap API (when using AllowanceHolder flow). It may differ across chains, so always use the value from the response rather than hardcoding an address.

Below you can find an example on how to set proper token allowance for received quote.

```typescript
// Example assumes that you've set up your walletClient with viem

import { erc20Abi } from "viem";
...
// Code that fetches a valid quotesResponse
...
const approveTxHash = await walletClient.writeContract({
  address: quoteResponse.sellToken as `0x${string}`,
  abi: erc20Abi,
  functionName: "approve",
  args: [
      quotesResponse.quotes[0].issues.allowance.spender as `0x${string}`,
      BigInt(quoteResponse.sellAmount),
  ],
});

await walletClient.waitForTransactionReceipt({
  hash: approveTxHash,
  confirmations: 1,
});
```

**Important:** Only EVM chains require token allowances. Solana and Tron do not need an approval step and `allowanceTarget` will be `null` for those chains. Native tokens (ETH, BNB, etc.) also do not need approvals.

### 3. Sign and submit a transaction

Now that we have both the approval and the quote, we can construct, sign, and submit the transaction. Optionally, after the approval, you might want to re-fetch a fresh quote.

Code below will construct, sign, and submit the transaction based on the quote response.

```typescript
// Prepare a transaction request
const txRequest = {
    to: quoteResponse.quotes[0].transaction.details.to as `0x${string}`,
    data: quoteResponse.quotes[0].transaction.details.data as `0x${string}`,
    value: BigInt(quoteResponse.quotes[0].transaction.details.value),
    gas: quoteResponse.quotes[0].transaction.details.gas
        ? BigInt(quoteResponse.quotes[0].transaction.details.gas)
        : undefined,
};

// Sign and submit the transaction request
const txHash = await walletClient.sendTransaction(txRequest);

// Wait for confirmation on Base
const receipt = await walletClient.waitForTransactionReceipt({
    hash: txHash,
    confirmations: 2,
});
console.log(`Transaction confirmed in block: ${receipt.blockNumber}`);
console.log(`View on BaseScan: https://basescan.org/tx/${txHash}`);
```

### 4. Monitor the cross chain execution

The last step is to monitor the execution of the cross chain transaction, including the fill on the destination chain. For that, we will use the `/status` endpoint.

```typescript
const statusParams = new URLSearchParams({
    originChain: 8453, // origin chain
    originTxHash, // transaction hash of the origin chain transaction, submitted in previous step
    quoteId, // the quote ID of the submitted quote, equivalent to quoteResponse.quotes[0].quoteId
});

const headers = {
    '0x-api-key': '[api-key]', // Get your live API key from the 0x Dashboard (https://dashboard.0x.org/apps)
};

const statusResponse = await fetch('https://api.0x.org/cross-chain/status?' + statusParams.toString(), { headers });

console.log(await statusResponse.json());
```

In your application, you might need to monitor the status repeatedly, as bridging operation might take several seconds or minutes to complete.

It is a good practice to always pass `quoteId` when polling `/status`. Without it, bundled transactions (e.g. with ERC-4337) cannot be disambiguated, and the first status request will be slower.

For full status lifecycle details, polling intervals, and failure handling, see [Tracking Transaction Status](/docs/cross-chain-api/key-concepts/tracking-transaction-status) and [Handling Failures and Recovery](/docs/cross-chain-api/key-concepts/handling-failures-and-recovery).

```json
{
    "status": "bridge_filled",
    "bridge": "stargate",
    "steps": [
        {
            "bridge": "stargate",
            "originChainId": 8453,
            "destinationChainId": 42161,
            "sellToken": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
            "buyToken": "0xaf88d065e77c8cc2239327c5edb3a432268e5831",
            "sellAmount": "997500",
            "minBuyAmount": "987525",
            "quotedBuyAmount": "997059",
            "estimatedTimeSeconds": 20,
            "transactions": [
                {
                    "chainId": 8453,
                    "chain": "base",
                    "txHash": "0x53287620e5e527c6e11c70dfb1fc9e9f2675fcc27d7c98b2d0c7e82e9ac011d6",
                    "timestamp": 1762985805
                },
                {
                    "chainId": 42161,
                    "chain": "arbitrum",
                    "txHash": "0x390ca459f68cc5320d0c8904ba890cb5e4f25484a1a0def62c65852b48ddabd8",
                    "timestamp": 1762985833
                }
            ],
            "type": "bridge"
        }
    ],
    "failure": null,
    "transactions": [
        {
            "chainId": 8453,
            "chain": "base",
            "txHash": "0x53287620e5e527c6e11c70dfb1fc9e9f2675fcc27d7c98b2d0c7e82e9ac011d6",
            "timestamp": 1762985805
        },
        {
            "chainId": 42161,
            "chain": "arbitrum",
            "txHash": "0x390ca459f68cc5320d0c8904ba890cb5e4f25484a1a0def62c65852b48ddabd8",
            "timestamp": 1762985833
        }
    ],
    "zid": "0xeccee60cd76a5084fdff17d4"
}
```

**Want to collect fees?** See [Monetize Your App](/docs/cross-chain-api/guides/monetize-your-app) to learn how to add integrator fees to cross-chain swaps.