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

# Supported chains and tokens

> The chains Olympex supports, how to read the enabled chains and token lists at runtime, where limit orders and DCA run, and how to send chain IDs, token addresses and amounts.

Olympex supports single-chain swaps on eight EVM chains, and cross-chain transfers that start on six of them. [`GET /chains`](/api-reference/chains/list-chains) is the source of truth for which chains are enabled, and [`GET /tokens`](/api-reference/tokens/list-tokens) lists the tokens Olympex lists on each one. Limit orders and DCA run on a subset of the chains. This page also covers the conventions every request shares: chain ID types, token addresses and amounts.

## Chain support matrix

| Chain | Chain ID | Single-chain swaps | Cross-chain source | Limit orders and DCA |
| - | - | - | - | - |
| <img src="https://mintcdn.com/olympex/Hv2idqJvAaUqU38v/images/chains/ethereum.svg?fit=max&auto=format&n=Hv2idqJvAaUqU38v&q=85&s=293c0e1b97dc747a3955f204461beb6f" alt="" width="24" height="24" style={{background:"#fff",borderRadius:"6px",verticalAlign:"middle",marginRight:"8px",display:"inline-block"}} data-path="images/chains/ethereum.svg" /> Ethereum | `1` | Yes | Yes | Yes |
| <img src="https://mintcdn.com/olympex/Hv2idqJvAaUqU38v/images/chains/optimism.svg?fit=max&auto=format&n=Hv2idqJvAaUqU38v&q=85&s=cf6a4bcfad7bd05a78cf8faa7f216968" alt="" width="24" height="24" style={{background:"#fff",borderRadius:"6px",verticalAlign:"middle",marginRight:"8px",display:"inline-block"}} data-path="images/chains/optimism.svg" /> Optimism | `10` | Yes | Yes | Yes |
| <img src="https://mintcdn.com/olympex/Hv2idqJvAaUqU38v/images/chains/bnb.svg?fit=max&auto=format&n=Hv2idqJvAaUqU38v&q=85&s=17fb2131b216c51121697b697c161133" alt="" width="24" height="24" style={{background:"#fff",borderRadius:"6px",verticalAlign:"middle",marginRight:"8px",display:"inline-block"}} data-path="images/chains/bnb.svg" /> BNB Chain | `56` | Yes | Yes | Yes |
| <img src="https://mintcdn.com/olympex/Hv2idqJvAaUqU38v/images/chains/polygon.svg?fit=max&auto=format&n=Hv2idqJvAaUqU38v&q=85&s=f9ef4e672e0743e17ce9fe99d1506f4b" alt="" width="24" height="24" style={{background:"#fff",borderRadius:"6px",verticalAlign:"middle",marginRight:"8px",display:"inline-block"}} data-path="images/chains/polygon.svg" /> Polygon | `137` | Yes | Yes | Yes |
| <img src="https://mintcdn.com/olympex/Hv2idqJvAaUqU38v/images/chains/base.svg?fit=max&auto=format&n=Hv2idqJvAaUqU38v&q=85&s=f9a8742fcbf950055443d8581fa13f6d" alt="" width="24" height="24" style={{background:"#fff",borderRadius:"6px",verticalAlign:"middle",marginRight:"8px",display:"inline-block"}} data-path="images/chains/base.svg" /> Base | `8453` | Yes | No | Yes |
| <img src="https://mintcdn.com/olympex/Hv2idqJvAaUqU38v/images/chains/arbitrum.svg?fit=max&auto=format&n=Hv2idqJvAaUqU38v&q=85&s=70d855119ee63c451321c7db0e731eba" alt="" width="24" height="24" style={{background:"#fff",borderRadius:"6px",verticalAlign:"middle",marginRight:"8px",display:"inline-block"}} data-path="images/chains/arbitrum.svg" /> Arbitrum | `42161` | Yes | Yes | Yes |
| <img src="https://mintcdn.com/olympex/Hv2idqJvAaUqU38v/images/chains/avalanche.svg?fit=max&auto=format&n=Hv2idqJvAaUqU38v&q=85&s=5940c1ce2e4ea155ac4cc6400725f442" alt="" width="24" height="24" style={{background:"#fff",borderRadius:"6px",verticalAlign:"middle",marginRight:"8px",display:"inline-block"}} data-path="images/chains/avalanche.svg" /> Avalanche | `43114` | Yes | Yes | Yes |
| <img src="https://mintcdn.com/olympex/Hv2idqJvAaUqU38v/images/chains/linea.svg?fit=max&auto=format&n=Hv2idqJvAaUqU38v&q=85&s=0246b017a75e24be1d41ba6fde70c3c5" alt="" width="24" height="24" style={{background:"#fff",borderRadius:"6px",verticalAlign:"middle",marginRight:"8px",display:"inline-block"}} data-path="images/chains/linea.svg" /> Linea | `59144` | Yes | No | Yes |

A cross-chain transfer starts on a chain marked Yes in the cross-chain source column and ends on another chain in the table. Whether a specific pair has a route depends on the providers when you ask, so request a quote to confirm it.

Limit orders and DCA execute only on the chains marked Yes in the last column, through the Olympex order contract on each one. [Order signatures and allowances](/concepts/order-authorization#the-order-contract) lists the contract address on each chain.

`GET /chains` returns chain IDs only, without names, logos or capabilities. If your product needs them, keep this table's names and columns in your code, and use [`GET /chains`](/api-reference/chains/list-chains) to decide which of these chains to offer: offer a chain only while its ID is in the response. [`POST /support-chain`](/api-reference/chains/check-chain-support) checks one chain ID against the same list.

The API doesn't return chain names or the capabilities in this matrix, so keep them in your code. Read which chains are enabled from `GET /chains` at runtime, and offer a chain only while it appears there.

## Enabled chains at runtime

`GET /chains` is a signed endpoint with no request body. It takes no parameters and ignores any query parameters you send. It returns `data.chainIds`: the IDs of the enabled chains, as integers, in ascending order. Use it to decide which chains to offer before you request tokens, quotes or orders.

```ts theme={null}
import { olympexRequest } from "./sign-request.ts"; // /authentication/sign-requests

const { chainIds } = await olympexRequest<{ chainIds: number[] }>("GET", "/chains");
const enabled = new Set(chainIds);
console.log(enabled.has(137) ? "Polygon is enabled" : "Polygon is not enabled");
```

The response lists the eight chains in the matrix:

```json Response theme={null}
{
  "success": true,
  "data": {
    "chainIds": [
      1,
      10,
      56,
      137,
      8453,
      42161,
      43114,
      59144
    ]
  },
  "meta": {
    "requestId": "E7eeEiPDIAMEP7Q=",
    "version": "v1",
    "accountType": "integrator",
    "apiKeyId": "00000000-0000-4000-8000-000000000000"
  }
}
```

[`POST /support-chain`](/api-reference/chains/check-chain-support) checks one chain against the same list. It takes a chain ID as an integer and returns `data: true` when the chain is enabled:

<CodeGroup>
  ```json Request theme={null}
  {
    "chainId": 137
  }
  ```

  ```json Supported theme={null}
  {
    "success": true,
    "data": true,
    "meta": {
      "requestId": "ENUlxjCsIAMEMUA=",
      "version": "v1",
      "accountType": "integrator",
      "apiKeyId": "00000000-0000-4000-8000-000000000000"
    }
  }
  ```

  ```json Not supported theme={null}
  {
    "success": true,
    "data": false,
    "meta": {
      "requestId": "ENUmEhC2oAMEMtQ=",
      "version": "v1",
      "accountType": "integrator",
      "apiKeyId": "00000000-0000-4000-8000-000000000000"
    }
  }
  ```
</CodeGroup>

The second response is for chain `324`. A string such as `"137"` returns `400 VALIDATION_ERROR`, not `false`. Whether a specific pair has a route on an enabled chain is answered by a quote.

## Limit orders and DCA

Limit orders and DCA strategies execute only on chains where the Olympex order contract exists: Ethereum, Optimism, BNB Chain, Polygon, Base, Arbitrum One, Avalanche C-Chain and Linea. [Order signatures and allowances](/concepts/order-authorization#the-order-contract) lists the contract on each chain, which is the spender the maker approves. Create orders and strategies only on chains that are in that table and that `GET /chains` returns.

## Chain IDs are integers

Every endpoint takes and returns chain IDs as JSON integers:

| Endpoint | Fields | Type | Example |
| - | - | - | - |
| [`GET /chains`](/api-reference/chains/list-chains) | `data.chainIds[]` in the response | Integer | `137` |
| [`GET /tokens`](/api-reference/tokens/list-tokens) | The `chainId` query parameter, and `data.chainId` in the response | Integer | `137` |
| [`POST /quotes`](/api-reference/quotes/get-quote) | `params.chainId`, `params.fromChainId`, `params.toChainId` | Integer | `137` |
| [`POST /swap`](/api-reference/swap/build-swap) | `params.chainId`, `params.fromChainId`, `params.toChainId` | Integer | `137` |
| [`POST /support-chain`](/api-reference/chains/check-chain-support) | `chainId` | Integer | `137` |
| [`POST /tx-status`](/api-reference/transactions/get-transaction-status) | `chainId`, and `fromChainId` and `toChainId` in the response | Integer | `137` |
| [`GET /transactions/{hash}`](/api-reference/transactions/get-transaction) | The `chainId` query parameter, and `data.chainId` in the response | Integer | `137` |
| [Limit orders](/concepts/limit-orders) | `chainId` in requests and responses, and the `?chainId=` filter | Integer | `137` |
| [DCA strategies](/concepts/dca) | `chainIdFrom`, `chainIdTo` | Integer | `137` |

In a request body, the wrong type fails validation with `400`, and so does a non-numeric `chainId` query parameter on `GET /tokens` or `GET /transactions/{hash}`:

```json theme={null}
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid request body",
    "details": [
      {
        "field": "params.chainId",
        "message": "Invalid input: expected number, received string"
      },
      {
        "field": "params.inTokenAddress",
        "message": "Must be a valid EVM address"
      }
    ]
  },
  "meta": {
    "requestId": "ENUlmg3dIAMEMEw=",
    "version": "v1",
    "accountType": "integrator",
    "apiKeyId": "00000000-0000-4000-8000-000000000000"
  }
}
```

The `?chainId=` filter of `GET /limit-order` is the exception: it isn't validated, and a `chainId` that isn't a number returns an empty array, not an error.

## Token lists

`GET /tokens?chainId=<n>` returns the tokens Olympex lists on one chain:

* **Query.** `chainId` is required and must be a positive integer. Any other query parameter returns `400 VALIDATION_ERROR` `"Invalid query parameters"`, and a chain that isn't enabled returns `400` `"Chain N is not enabled"`.
* **Response.** `data.chainId` (a number) and `data.tokens[]`. Each token has `address`, `symbol`, `name`, `decimals`, `icon` and sometimes `logoURI`. `icon` is a logo URL, usually on the Olympex CDN, or an empty string when there is no logo; some URLs point to third-party hosts that may not serve the image, so show a fallback when a logo fails to load. Other fields can appear; ignore the ones you don't use.
* **Addresses.** Casing varies between entries, so compare addresses case-insensitively. The native token appears as `0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee`, in lowercase: the lowercase form of `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE`.
* **Size.** The list is large (hundreds of tokens per chain), unsorted and unpaginated, and it changes rarely. It carries no cache headers: cache it on your side, for example for 24 hours.
* **Identity.** Symbols aren't unique. Match tokens by address, never by symbol. When several listed tokens share a symbol, some carry a numeric suffix, such as `STRK_1`, and the number can change when the list is refreshed. A few symbols also differ from the contract's `symbol()` in case or spacing. Where you need a token's real symbol, as limit orders do, read `symbol()` from the contract, or trim the listed symbol and drop a trailing `_<number>`.
* **Empty lists.** An enabled chain can return an empty list.

<CodeGroup>
  ```ts TypeScript theme={null}
  import { olympexRequest } from "./sign-request.ts"; // /authentication/sign-requests

  type Token = { address: string; symbol: string; name: string; decimals: number; icon: string; logoURI?: string };

  const TTL_MS = 24 * 60 * 60 * 1000;
  const cache = new Map<number, { at: number; byAddress: Map<string, Token> }>();

  /** The chain's tokens keyed by lowercase address, cached for 24 hours. */
  export const tokensByAddress = async (chainId: number) => {
    const hit = cache.get(chainId);
    if (hit && Date.now() - hit.at < TTL_MS) return hit.byAddress;
    const { tokens } = await olympexRequest<{ chainId: number; tokens: Token[] }>("GET", `/tokens?chainId=${chainId}`);
    const byAddress = new Map(tokens.map((token) => [token.address.toLowerCase(), token]));
    cache.set(chainId, { at: Date.now(), byAddress });
    return byAddress;
  };

  const usdc = (await tokensByAddress(137)).get("0x3c499c542cef5e3811e1192ce70d8cc03d5c3359"); // USDC on Polygon
  console.log(usdc?.symbol, usdc?.decimals); // USDC 6
  ```

  ```python Python theme={null}
  import time

  from sign_request import olympex_request  # /authentication/sign-requests

  TTL_SECONDS = 24 * 60 * 60
  _cache = {}


  def tokens_by_address(chain_id):
      """The chain's tokens keyed by lowercase address, cached for 24 hours."""
      hit = _cache.get(chain_id)
      if hit and time.time() - hit[0] < TTL_SECONDS:
          return hit[1]
      data = olympex_request("GET", f"/tokens?chainId={chain_id}")
      by_address = {token["address"].lower(): token for token in data["tokens"]}
      _cache[chain_id] = (time.time(), by_address)
      return by_address


  usdc = tokens_by_address(137).get("0x3c499c542cef5e3811e1192ce70d8cc03d5c3359")  # USDC on Polygon
  print(usdc["symbol"], usdc["decimals"])  # USDC 6
  ```
</CodeGroup>

## Token addresses

Token fields accept any valid EVM address: `0x` and 40 hexadecimal digits, in lowercase or in EIP-55 checksum form. An invalid address, including a mixed-case address whose checksum is wrong, fails validation with `400 VALIDATION_ERROR` and `"Must be a valid EVM address"`. The checksum check catches most typos.

Each chain's native token (ETH on Ethereum, POL on Polygon, BNB on BNB Chain, AVAX on Avalanche, and so on) uses one pseudo-address on every chain:

```text theme={null}
0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE
```

The API accepts it in either casing, and `GET /tokens` lists it in lowercase, `0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee`, so compare it case-insensitively. Use it as `inTokenAddress` or `outTokenAddress` in a quote or a swap, single-chain or cross-chain. With native-token input, `/swap` returns the amount to send in `value`, in wei, and no approval is needed. The `uniswapV3Hermes` source doesn't support native-token input.

Limit orders and DCA strategies can't sell the native token: sell the wrapped token instead. These are the wrapped tokens on three chains, all listed in `GET /tokens`:

| Chain | Wrapped token | Address |
| - | - | - |
| Ethereum (`1`) | WETH | `0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2` |
| BNB Chain (`56`) | WBNB | `0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c` |
| Polygon (`137`) | WPOL | `0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270` |

For other chains, check the wrapped token's address on the chain's block explorer.

`GET /tokens` doesn't limit what you can trade. Quotes, swaps, limit orders and DCA strategies accept any valid token address, listed or not, although a limit order still needs a [reference price](/concepts/limit-orders#reference-price). Request a quote to find out whether a token has a route. The guides stop on unlisted tokens only to keep their examples short. The list has no ranking or verification flag, so `GET /tokens` tells you which tokens Olympex lists, and you still decide which tokens your product offers.

<Warning>
  Scam tokens often copy the name and symbol of well-known tokens. Identify tokens by address, check each address you offer on the chain's block explorer, and never let users paste an address without showing which token it is.
</Warning>

## Amounts and decimals

Olympex resolves token decimals server-side. Inputs are human-readable and outputs are base units:

| Direction | Fields | Format | Example |
| - | - | - | - |
| You send | `params.amount` on `/quotes` and `/swap` | Human-readable decimal string of the input token. Don't convert to base units. | `"10"` is 10 USDT. |
| You send | `amount` on a limit order | Human-readable decimal string of the token sold | `"0.5"` is 0.5 WETH. |
| You send | `totalAmount` on a DCA strategy | Human-readable JSON number of the token sold | `100` is 100 USDC. |
| You receive | `outAmount`, `minOutAmount`, `toTokenAmount`, `minimumReceived`, `market[].swapAmount` | Integer string in base units of the output token | `"10034668"` is 10.034668 USDC. |
| You receive | `swap.value` | Integer string in wei of the native token | `"0"` for ERC-20 input. |

To display an output amount, divide it by 10 to the power of the output token's decimals. Single-chain responses don't include decimals, so read them from `GET /tokens` or the token contract's `decimals()`. Cross-chain quotes include decimals only for the swap legs listed in `middlewareRoute`, which may not include the token you receive. Read the destination token's decimals from `GET /tokens` for the destination chain, or from its contract there: the same symbol can use different decimals on different chains.

<Tip>
  Keep amounts as strings end to end, and use integer or decimal arithmetic for base units: 18-decimal amounts exceed what a JavaScript `number` represents exactly. DCA strategies are the exception: they take `totalAmount` as a JSON number.
</Tip>

## Requesting a chain

To ask for a chain that isn't in the matrix, contact [partners@olympex.io](mailto:partners@olympex.io).

## What this means for your integration

* Read the enabled chains from `GET /chains` and each chain's tokens from `GET /tokens`, cache the token lists, and match tokens by address.
* Send chain IDs as integers to every endpoint.
* Create limit orders and DCA strategies only on chains that have an order contract.
* Send human-readable amounts, and convert outputs from base units with the token's decimals.

## Related

<CardGroup cols={2}>
  <Card title="List enabled chains" icon="code" href="/api-reference/chains/list-chains">
    The `GET /chains` reference.
  </Card>

  <Card title="List tokens" icon="code" href="/api-reference/tokens/list-tokens">
    The `GET /tokens` reference.
  </Card>

  <Card title="Order signatures and allowances" icon="signature" href="/concepts/order-authorization">
    The order contract on each chain.
  </Card>

  <Card title="Cross-chain mechanics" icon="link" href="/concepts/cross-chain-mechanics">
    How transfers between these chains work.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.