# Add Chord to your app

> The conventions that hold on every endpoint — chains, addresses, amounts, timestamps, coverage flags, caching and errors — so you read them once.

Source: https://getchord.xyz/docs/build/

Everything Chord shows is served by this API, and the app follows the same rules you will. Read this page once; nothing below is repeated per endpoint.

## Chains

Chord routes on eight EVM chains and indexes them, plus Solana (data and swaps). Pass the chain id where an endpoint takes one; the `/v1/arc/*`, `/v1/rh/*` and `/v1/chains/{chain}/*` families are chain-bound.

| Chain | id | Gas | Stable anchor | Data family | Notes |
| --- | --- | --- | --- | --- | --- |
| Arc | `5042` | USDC (native, 18 decimals) | USDC predeploy `0x3600…0000` (6 decimals) | `/v1/arc/*` | Chord's home chain. Trading, markets, portfolio, points and Ask read Arc. |
| Robinhood Chain | `4663` | ETH | USDG (6 decimals) | `/v1/rh/*` | Tokenized stocks and ETFs; the stocks page. |
| Monad | `143` | MON | USDC (6 decimals) | `/v1/tokens/*`, `/v1/markets/monad/hourly` | The default when `chain` is omitted. |
| Avalanche | `43114` | AVAX | USDC, USDt (6 decimals) | `/v1/chains/avalanche/*` | |
| Base | `8453` | ETH | USDC, USDT (6 decimals) | `/v1/chains/base/*` | |
| BNB Chain | `56` | BNB | USDT, USDC (**18 decimals**) | `/v1/chains/bnb/*` | Swaps under $100 are not indexed. |
| Arbitrum | `42161` | ETH | USDC, USDT0 (6 decimals) | `/v1/chains/arbitrum/*` | |
| Ethereum | `1` | ETH | USDC, USDT (6 decimals), DAI (18) | `/v1/chains/ethereum/*` | USDT: approve 0 first when an old allowance is left |
| Solana | none | SOL | USDC | `/v1/chains/solana/*`, `/v1/sol/trade/*` | Swaps through Chord's own router and Jupiter, best of both. |

`chain` is required in practice on `/quote`, `/swap`, `/tokens`, `/smart-money/top`, `/portfolio/*` and every `/lp/*` call: omitting it selects Monad. `GET /v1/chains` lists which route serves each capability on each chain. Details per chain, with contracts and venues, are under [Networks](/docs/networks/).

## Addresses and amounts

- Addresses are hex, case-insensitive. The zero address `0x0000…0000` is the chain's native unit wherever a token is accepted. On Arc it is an alias for the USDC predeploy: there is nothing to wrap, so a "native" leg is an ERC-20 leg.
- Amounts are **strings in the token's smallest unit**, never floats. USDC and USDG have 6 decimals, most tokens 18, cirBTC 8. Read `decimals` from `/v1/tokens?chain=` or from the token row; never assume.
- USD figures in read endpoints are numbers, already scaled.

## Timestamps

Unix seconds, UTC. Hourly buckets are named `hour`, daily ones `day`, and both are the bucket's start. The one exception is `updatedAt`, which is milliseconds and says when the server built the answer.

## Coverage, not the clock

Read endpoints say how fresh and how deep they are. The rollup families carry a `coverage` object (`recentAt`, `stale`, `floorHour`, `genesisHour`, `backfillComplete`); the holder ledger carries `tracked` and `complete`; the pools and positions families expose their cursors on `/v1/lp/status`. A quiet number with `stale: true` is a lane that stopped, not a market that stopped. See [Data freshness](/docs/concepts/data-freshness/).

## Honesty flags

Chord flags rather than hides. Token rows carry `flags: ["wash"]` when a day's volume came from one or two wallets and `["impostor"]` when an unlisted token wears a listed symbol; the boards sort those below clean rows. Pools carry `suspect` (wash or launch-farm printing) and `token0.impostor` / `token1.impostor`; the pool list hides suspect pools unless you ask with `flagged=1`. Trader counts are attributed wallets only: routers, executors and bots are not wallets. Build the same distinctions into your UI, or your users will see a $10M pool with three traders.

## Caching

Rolled-up reads are cheap and memoised server-side (30–60 s on the liquidity family, per-window on the boards). Poll the boards at 10–30 s, the token page at 5–10 s, and use the [streams](/docs/concepts/streaming/) for prices and candles instead of polling. Quotes are live venue reads: do not cache them beyond about 30 seconds.

Responses that are safe to cache say so with `Cache-Control: public, max-age=…`; the rest send none.

## Errors

Every non-2xx body is `{ "error": "CODE", "message": "for humans" }`. Codes are stable strings; branch on them, not on the message. A `503` is a lane that has not run or is not enabled on the deployment — retry later, never render it as "no data". The table is in [Errors and retries](/docs/concepts/errors/).

## Rate limit headers

Every response carries `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset`. Back off on a `429`. Reads without a key share a per-IP bucket; a key gives you your own. See [Rate limits](/docs/concepts/rate-limits/).

## CORS

Open to any origin on `/v1`, no credentials. A browser can call the API directly, including with `X-API-Key` — but a key in a public bundle is a key anyone can use, so proxy it from your server if the limit matters to you.

## Logos

Every Arc token row's `logoURI` points at Chord's logo proxy, `/v1/logo/5042/{address}`: a 128 px WebP cached on disk, a placeholder when there is none, never a 404. Use it as-is in an `<img>`. `logoUriRaw` is the upstream URL if you want the original.
