> ## Documentation Index
> Fetch the complete documentation index at: https://docs.socket.tech/llms.txt
> Use this file to discover all available pages before exploring further.

# Guide to Integrate Socket API

> Step-by-step guide to integrating the Socket Swap V3 API for same-chain swaps and cross-chain bridging.

This guide covers the Socket Swap V3 endpoints:

* `GET /v3/swap/quote` — fetch executable transaction routes, deposit-address routes, and CEX withdraw routes
* `GET /v3/swap/status` — poll the status of a submitted route
* `GET /v3/swap/supported-chains` — list supported chains
* `GET /v3/swap/tokens/list` — list supported tokens
* `GET /v3/swap/tokens/search` — search tokens by address, name, or symbol

Use the production base URL:

```txt theme={null}
https://dedicated-backend.socket.tech
```

The examples below use the dedicated endpoint with `x-api-key` and `affiliate` headers. For testing without credentials, use `https://public-backend.socket.tech`. See [Get API Access](/integrate/get-api-access) for the full breakdown.

## Endpoint Selection

Use `/v3/swap/quote` with `userOps=tx` for OpenRouter direct routes, which support:

* **Same-chain swaps** when `originChainId === destinationChainId`
* **Cross-chain bridge routes** when `originChainId !== destinationChainId`

For deposit-address flows, use `userOps=deposit`. See the [Deposit Addresses Guide](/integrate/integration-guides/deposit-addresses).

## Common Token and Amount Rules

* `inputAmount` is a string in the smallest token unit for EVM-style chains.
* The native token address is `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE`.
* EVM addresses are normalized to lowercase by the API.
* `receiverAddress` must be valid for the destination chain.
* `userAddress` is required for OpenRouter transaction routes.
* Same-chain quotes reject identical `inputToken` and `outputToken`.

## Step 1: Get a Quote

### Request

```http theme={null}
GET /v3/swap/quote
```

**Required query parameters:**

| Parameter            | Type   | Description                                                                                                          |
| -------------------- | ------ | -------------------------------------------------------------------------------------------------------------------- |
| `userOps`            | string | Comma-separated route types. Use `tx` for OpenRouter transaction routes. Also supports `deposit` and `cex-withdraw`. |
| `originChainId`      | string | Required for `tx` and `deposit`. Source chain ID.                                                                    |
| `destinationChainId` | string | Destination chain ID.                                                                                                |
| `inputToken`         | string | Source token address.                                                                                                |
| `inputAmount`        | string | Source amount in smallest units.                                                                                     |
| `outputToken`        | string | Destination token address.                                                                                           |
| `receiverAddress`    | string | Destination receiver address.                                                                                        |
| `userAddress`        | string | Required for `tx`. Source wallet that will sign the transaction.                                                     |

**Optional query parameters:**

| Parameter             | Type              | Description                                                                     |
| --------------------- | ----------------- | ------------------------------------------------------------------------------- |
| `slippage`            | number string     | Slippage percent, for example `0.5`.                                            |
| `feeBps`              | number string     | Integrator fee in basis points. Supports decimals. Requires `feeTakerAddress`.  |
| `feeTakerAddress`     | string            | Fee recipient. Required when `feeBps` is set.                                   |
| `includeProvider`     | string            | Comma-separated provider IDs to include.                                        |
| `excludeProvider`     | string            | Comma-separated provider IDs to exclude. Cannot overlap with `includeProvider`. |
| `refuel`              | `true` or `false` | Optional refuel request. Defaults to `false`.                                   |
| `destinationPayload`  | hex string        | Destination payload. Requires `destinationGasLimit`.                            |
| `destinationGasLimit` | string            | Gas limit for `destinationPayload`. Requires `destinationPayload`.              |
| `refundAddress`       | string            | Required for `deposit` and `cex-withdraw`.                                      |
| `exchange`            | string            | Required for `cex-withdraw`, for example `coinbase` or `binance`.               |

### Same-chain DEX provider IDs

| Provider ID       | Display name     |
| ----------------- | ---------------- |
| `zeroxv2`         | 0x v2            |
| `openocean`       | OpenOcean        |
| `kyberswap`       | KyberSwap        |
| `magpie`          | Magpie           |
| `bebopPmm`        | Bebop PMM        |
| `tempoStablecoin` | Tempo Stablecoin |
| `ondoGm`          | Ondo GM          |

### Cross-chain bridge provider IDs

| Provider ID            | Display name               |
| ---------------------- | -------------------------- |
| `across`               | Across                     |
| `arbitrum-native`      | Arbitrum Native Bridge     |
| `bob-gateway`          | BOB Gateway                |
| `celer`                | Celer                      |
| `cctp-v2`              | CCTP v2 (fast)             |
| `cctp-v2-slow`         | CCTP v2 (slow / canonical) |
| `gaszip`               | GasZip                     |
| `gnosis-native`        | Gnosis Native Bridge       |
| `hypercore`            | Hypercore Deposit          |
| `kyo-ag`               | Kyo AG                     |
| `mayan`                | Mayan                      |
| `native-op-stack`      | Native OP Stack Bridge     |
| `near-intents`         | Near Intents               |
| `oft`                  | OFT (LayerZero)            |
| `polygon-native`       | Polygon Native Bridge      |
| `relay`                | Relay                      |
| `rhinofi`              | RhinoFi                    |
| `scroll-native`        | Scroll Native Bridge       |
| `tempo-stablecoin-dex` | Tempo Stablecoin DEX       |

### Example: Same-chain swap

```bash theme={null}
curl -sS -G "https://dedicated-backend.socket.tech/v3/swap/quote" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "affiliate: YOUR_AFFILIATE_ID" \
  --data-urlencode "userOps=tx" \
  --data-urlencode "originChainId=42161" \
  --data-urlencode "destinationChainId=42161" \
  --data-urlencode "inputToken=0xaf88d065e77c8cC2239327C5EDb3A432268e5831" \
  --data-urlencode "outputToken=0x912ce59144191c1204e64559fe8253a0e49e6548" \
  --data-urlencode "inputAmount=10000000" \
  --data-urlencode "userAddress=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" \
  --data-urlencode "receiverAddress=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" \
  --data-urlencode "slippage=0.5" \
  --data-urlencode "includeProvider=zeroxv2,kyberswap"
```

### Example: Cross-chain bridge

```bash theme={null}
curl -sS -G "https://dedicated-backend.socket.tech/v3/swap/quote" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "affiliate: YOUR_AFFILIATE_ID" \
  --data-urlencode "userOps=tx" \
  --data-urlencode "originChainId=8453" \
  --data-urlencode "destinationChainId=42161" \
  --data-urlencode "inputToken=0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" \
  --data-urlencode "outputToken=0xaf88d065e77c8cC2239327C5EDb3A432268e5831" \
  --data-urlencode "inputAmount=1000000" \
  --data-urlencode "userAddress=0x1111111111111111111111111111111111111111" \
  --data-urlencode "receiverAddress=0x1111111111111111111111111111111111111111" \
  --data-urlencode "slippage=1"
```

### Quote response

```json theme={null}
{
  "success": true,
  "statusCode": 200,
  "result": {
    "originChainId": 42161,
    "destinationChainId": 10,
    "userAddress": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266",
    "receiverAddress": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266",
    "input": {
      "token": {
        "chainId": 42161,
        "address": "0xaf88d065e77c8cc2239327c5edb3a432268e5831",
        "name": "USDC",
        "symbol": "USDC",
        "decimals": 6,
        "logoURI": "https://...",
        "icon": "https://..."
      },
      "amount": "10000000",
      "priceInUsd": 1,
      "valueInUsd": 10
    },
    "routes": [
      {
        "userOp": "tx",
        "quoteId": "0x...",
        "expiresAt": 1760000000,
        "output": {
          "token": {
            "chainId": 10,
            "address": "0x...",
            "name": "USDC",
            "symbol": "USDC",
            "decimals": 6,
            "logoURI": "https://...",
            "icon": "https://..."
          },
          "amount": "9855420",
          "minAmountOut": "9806142",
          "priceInUsd": 1,
          "valueInUsd": 9.85542
        },
        "estimatedTime": 60,
        "slippage": 0.5,
        "suggestedSlippage": 0.5,
        "routeTags": ["SUGGESTED", "MAX_OUTPUT"],
        "routeDetails": {
          "dexDetails": null,
          "bridgeDetails": {
            "protocol": {
              "name": "across",
              "displayName": "Across",
              "icon": "https://media.socket.tech/bridges/across.png"
            },
            "inputTokenAddress": "0xaf88d065e77c8cc2239327c5edb3a432268e5831",
            "outputTokenAddress": "0x0b2c639c533813f4aa9d7837caf62653d097ff85",
            "amountIn": "10000000",
            "amountOut": "9855420",
            "minAmountOut": "9806142",
            "slippage": 0.5
          },
          "feeDetails": null
        },
        "approval": {
          "spenderAddress": "0x...",
          "amount": "10000000",
          "tokenAddress": "0xaf88d065e77c8cc2239327c5edb3a432268e5831",
          "userAddress": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266"
        },
        "txData": {
          "kind": "evm_tx",
          "object": {
            "chainId": 42161,
            "to": "0x...",
            "data": "0x...",
            "value": "0"
          }
        },
        "gasFee": {
          "gasToken": {
            "chainId": 42161,
            "address": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
            "name": "Ether",
            "symbol": "ETH",
            "decimals": 18,
            "logoURI": "https://...",
            "icon": "https://..."
          },
          "gasLimit": "650000",
          "gasPrice": "100000000",
          "estimatedFee": "65000000000000",
          "feeInUsd": 0.01
        },
        "statusCheck": {
          "endpoint": "https://public-backend.socket.tech/v3/swap/status?quoteId=0x...",
          "method": "GET",
          "intervalSec": 5,
          "maxDurationSec": 600
        }
      }
    ]
  },
  "message": null
}
```

**Important route fields:**

| Field                        | Description                                                                                             |
| ---------------------------- | ------------------------------------------------------------------------------------------------------- |
| `quoteId`                    | Stable route ID. Use it for status polling. For OpenRouter tx routes this is the on-chain request hash. |
| `expiresAt`                  | Unix timestamp after which the quote should be discarded.                                               |
| `output.amount`              | Expected destination output amount after applicable fees.                                               |
| `output.minAmountOut`        | Minimum acceptable destination output amount.                                                           |
| `suggestedSlippage`          | Suggested slippage percent returned by the API.                                                         |
| `routeTags`                  | Ranking labels: `SUGGESTED`, `FASTEST`, `MAX_OUTPUT`.                                                   |
| `routeDetails.bridgeDetails` | Bridge leg metadata, including provider ID, token addresses, amounts, and slippage.                     |
| `routeDetails.dexDetails`    | Same-chain or origin-swap DEX leg metadata when present.                                                |
| `routeDetails.feeDetails`    | Integrator fee metadata when a fee applies. Otherwise `null`.                                           |
| `approval`                   | Present for ERC20 inputs. Approve this spender before sending `txData`.                                 |
| `txData.kind`                | Transaction type. OpenRouter EVM routes use `evm_tx`.                                                   |
| `txData.object`              | Transaction payload to send from `userAddress`.                                                         |
| `gasFee.gasToken`            | Native gas token metadata for the source chain.                                                         |
| `statusCheck`                | Suggested polling endpoint and cadence.                                                                 |

## Step 2: Check Approval

If the `approval` field is present in the route response, approve the `approval.spenderAddress` for `approval.amount` of `approval.tokenAddress` before submitting the transaction.

<Note>
  OpenRouter EVM routes usually ask the user to approve the AllowanceHolder contract, not the final bridge or DEX. The `to` address in `txData` is typically the AllowanceHolder.
</Note>

## Step 3: Submit the Transaction

Submit `txData.object` as a transaction from `userAddress`.

```javascript theme={null}
// Example using ethers.js / viem
const tx = await signer.sendTransaction({
  to: route.txData.object.to,
  data: route.txData.object.data,
  value: BigInt(route.txData.object.value),
});
```

<Warning>
  Do not rebuild calldata client-side. Always use the returned `txData.object` exactly as provided.
</Warning>

## Step 4: Poll Status

### Request

```http theme={null}
GET /v3/swap/status?quoteId=<quoteId>
```

| Parameter             | Required | Description                                                        |
| --------------------- | -------- | ------------------------------------------------------------------ |
| `quoteId`             | Yes      | Quote ID returned by `/v3/swap/quote`.                             |
| `includeQuoteDetails` | No       | Set to `true` to include stored quote row details in the response. |

The v3 status endpoint looks up execution state by `quoteId`.

### Status response

```json theme={null}
{
  "quoteId": "0x...",
  "userOp": "tx",
  "status": "IN_PROGRESS",
  "statusCode": "PENDING",
  "origin": {
    "chainId": 42161,
    "status": "COMPLETED",
    "txHash": "0x...",
    "userAddress": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266"
  },
  "destination": {
    "chainId": 10,
    "status": "PENDING",
    "txHash": null,
    "receiverAddress": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266"
  },
  "routeDetails": {
    "name": "Across",
    "logoURI": "https://media.socket.tech/bridges/across.png"
  },
  "refund": null
}
```

**Status values:**

| Status        | Meaning                                                         |
| ------------- | --------------------------------------------------------------- |
| `PENDING`     | Quote or route has not started.                                 |
| `IN_PROGRESS` | Source transaction is known, destination completion is pending. |
| `COMPLETED`   | Route is complete.                                              |
| `FAILED`      | Route failed.                                                   |
| `EXPIRED`     | Quote or execution window expired.                              |
| `REFUNDED`    | Funds were refunded.                                            |

## Full Execution Flow

1. Request quotes from `/v3/swap/quote` with `userOps=tx`.
2. Select a route. Prefer `routeTags` or compare `output.valueInUsd`, `estimatedTime`, and `gasFee`.
3. Check quote freshness with `expiresAt` — do not send expired quotes.
4. If `approval` is present, approve `approval.spenderAddress` for `approval.amount`.
5. Submit the route transaction from `userAddress` using `txData.object`.
6. Poll status with the returned `quoteId`.
7. Poll until the route reaches a terminal status.

## Fees

Integrator fees are set with `feeBps` and `feeTakerAddress`.

Rules:

* `feeBps` and `feeTakerAddress` must be provided together.
* `feeBps` must be greater than `0` and at most `10000`.
* For direct DEX routes, fees can be taken from input or output depending on the OpenRouter fee resolution.
* For direct bridge no-swap routes, fees are forced to the input side.
* The client-facing output amount is already net of applicable fees.

See the [Charging Fees Guide](/integrate/integration-guides/additional-guides/charging-fees) for detailed implementation steps.

## Validation and Error Notes

Common `400` errors:

* Missing `userOps` for `/v3/swap/quote`.
* Missing `originChainId` for `userOps=tx`.
* Missing `userAddress` for `userOps=tx`.
* Missing `refundAddress` for `userOps=deposit` or `userOps=cex-withdraw`.
* Missing `exchange` for `userOps=cex-withdraw`.
* Invalid `slippage`.
* Invalid or unsupported chain ID.
* `destinationPayload` without `destinationGasLimit`, or the reverse.
* `feeBps` without `feeTakerAddress`, or the reverse.
* Provider listed in both include and exclude filters.

Quote responses can return an empty route list when providers fail to quote, the route is unsupported, or filters exclude all providers.

## Implementation Notes

* OpenRouter EVM routes usually ask the user to approve the AllowanceHolder contract, not the final bridge or DEX.
* Use `quoteId` exactly as returned — it is used for status lookup and source transaction recording.
* Do not rebuild calldata client-side. Use the returned `txData`.
* For same-chain swaps, `routeDetails.dexDetails` is populated when route metadata is available.
* For cross-chain routes, `routeDetails.bridgeDetails` describes the bridge leg. If there is an origin swap leg, `routeDetails.dexDetails` may also be present.

<CardGroup cols={2}>
  <Card title="Charging Fees" icon="coins" href="/integrate/integration-guides/additional-guides/charging-fees">
    Add integrator fees to your quotes
  </Card>

  <Card title="Deposit Addresses" icon="wallet" href="/integrate/integration-guides/deposit-addresses">
    Accept deposits from any chain
  </Card>

  <Card title="Destination Payload" icon="code" href="/integrate/integration-guides/additional-guides/destination-payload">
    Execute calldata on the destination chain
  </Card>

  <Card title="Chain Support" icon="link" href="/about/chain-support">
    See all supported networks
  </Card>
</CardGroup>
