{"generatedAt":"2026-10-17T14:23:22.560Z","site":"https://getchord.xyz/docs","openapiUrl":"https://getchord.xyz/docs/openapi.json","pages":[{"kind":"page","path":"/docs/","url":"https://getchord.xyz/docs/","title":"Chord Docs","description":"Chord routes trades on eight EVM chains, indexes their swaps and Solana's, and keeps prices current around the clock. The developer reference for the API, the streams and the agent tools.","markdown":"**Trade**\n\n    `GET /v1/quote` finds the best route across every venue on the chain, splitting the order when that improves the output. `POST /v1/swap` turns it into a transaction you sign yourself. Chord never holds funds or keys.\n  \n\n  \n**Read**\n\n    Swaps on nine chains from Chord's own index: chain totals, every token traded and wallet PnL on all of them; launches, holders, top wallets, liquidity pools and positions where the chain has them (`GET /v1/chains` says which). Answers carry their own coverage flags.\n  \n\n  \n**Stream**\n\n    A public WebSocket for live candles, trade tapes and Arc prices, and a server-sent events feed for Robinhood Chain prices. No key, automatic reconnect.\n  \n\n  \n**Agents**\n\n    The same API as an MCP server and a function-calling manifest, plus the analyst: ask a question in plain language and get a researched answer over the index, with a route card when the question implies a trade.\n  \n\n## Where to start\n\n  \n**Get started** — An API key (optional), your first request, and the three-call swap.\n\n  \n**Add Chord to your app** — Patterns that hold across every endpoint: chains, amounts, coverage, caching, errors.\n\n  \n**Recipes** — A token page, a markets board, a swap, charts, a trader dashboard, an LP dashboard, a launch feed, a bridge.\n\n  \n**Networks** — Ethereum, Arbitrum, Base, BNB Chain, Avalanche, Monad, Arc, Robinhood Chain and Solana: ids, anchors, contracts, venues.\n\n  \n**Agents** — MCP server, function-calling manifest, the Ask agent API and llms.txt.\n\n  \n**API reference** — Every endpoint with parameters, response schemas and real examples, generated from the OpenAPI document.\n\n## The base URL\n\n```\nhttps://api.getchord.xyz/v1\n```\n\nReads need no key at 60 requests a minute per IP. A key from [getchord.xyz/developer](https://getchord.xyz/developer) raises that to your plan and meters usage per key. The whole contract is one file: [openapi.json](/docs/openapi.json).","sections":[{"heading":"","anchor":"","text":"**Trade**\n\n    `GET /v1/quote` finds the best route across every venue on the chain, splitting the order when that improves the output. `POST /v1/swap` turns it into a transaction you sign yourself. Chord never holds funds or keys.\n  \n\n  \n**Read**\n\n    Swaps on nine chains from Chord's own index: chain totals, every token traded and wallet PnL on all of them; launches, holders, top wallets, liquidity pools and positions where the chain has them (`GET /v1/chains` says which). Answers carry their own coverage flags.\n  \n\n  \n**Stream**\n\n    A public WebSocket for live candles, trade tapes and Arc prices, and a server-sent events feed for Robinhood Chain prices. No key, automatic reconnect.\n  \n\n  \n**Agents**\n\n    The same API as an MCP server and a function-calling manifest, plus the analyst: ask a question in plain language and get a researched answer over the index, with a route card when the question implies a trade."},{"heading":"Where to start","anchor":"where-to-start","text":"**Get started** — An API key (optional), your first request, and the three-call swap.\n\n  \n**Add Chord to your app** — Patterns that hold across every endpoint: chains, amounts, coverage, caching, errors.\n\n  \n**Recipes** — A token page, a markets board, a swap, charts, a trader dashboard, an LP dashboard, a launch feed, a bridge.\n\n  \n**Networks** — Ethereum, Arbitrum, Base, BNB Chain, Avalanche, Monad, Arc, Robinhood Chain and Solana: ids, anchors, contracts, venues.\n\n  \n**Agents** — MCP server, function-calling manifest, the Ask agent API and llms.txt.\n\n  \n**API reference** — Every endpoint with parameters, response schemas and real examples, generated from the OpenAPI document."},{"heading":"The base URL","anchor":"the-base-url","text":"```\nhttps://api.getchord.xyz/v1\n```\n\nReads need no key at 60 requests a minute per IP. A key from [getchord.xyz/developer](https://getchord.xyz/developer) raises that to your plan and meters usage per key. The whole contract is one file: [openapi.json](/docs/openapi.json)."}]},{"kind":"page","path":"/docs/agents/","url":"https://getchord.xyz/docs/agents/","title":"Agents on Chord","description":"The same API as tools for models — an MCP server, a function-calling manifest, the Ask agent API, and llms.txt for retrieval.","markdown":"Chord is built for agents first: every number the app shows is one GET away, amounts are strings, errors are stable codes, and nothing needs a browser. The ways in:\n\n| Path | What it is | Best for |\n| --- | --- | --- |\n| [Docs MCP](/docs/agents/docs-mcp/) | this documentation as tools — search, read a page, look up an endpoint with a real example; hosted at `getchord.xyz/docs/mcp` | any agent writing code against the API; no key, no install |\n| [Agent skill](/docs/agents/skill/) | `SKILL.md`, references and a dependency-free Python client in the Agent Skills format; one `curl` loop installs it, no repository access | Claude Code, Codex, OpenClaw, Hermes: read prices and boards on every chain, quote, prepare an unsigned swap |\n| [MCP server](/docs/agents/mcp/) | hosted at `api.getchord.xyz/v1/mcp`: 17 tools, every chain as a parameter, one URL per chain with `?chain=` | Claude Code, Claude Desktop, Cursor, any MCP client; no install, key optional |\n| [Function calling](/docs/agents/function-calling/) | the same tools as OpenAI-style JSON Schema, public at `api.getchord.xyz/v1/mcp/tools.json` | OpenAI, LangChain, anything that takes a manifest |\n| [Ask agent API](/docs/agents/ask-api/) | `POST /v1/ask` — Chord's own analyst over the index, 40+ tools, one JSON answer | judgement questions: is this launch real, where is support, who is buying |\n| [llms.txt](/docs/agents/llms-txt/) | this documentation as plain text, every page as Markdown, the OpenAPI document, and the discovery files (`/.well-known/api-catalog`, `ai-catalog.json`, `agent-skills/index.json`) | retrieval, system prompts, codegen by a model, finding Chord's tools from the domain alone |\n\n## Prepare, then sign\n\nThe API is non-custodial. A tool that trades returns an **unsigned transaction**; the agent's own wallet signs it and broadcasts it to the chain it names. Chord never sees a private key, never holds funds, never broadcasts. Read `otherAmountThreshold` before signing — it is the minimum the transaction enforces — and simulate with `POST /v1/swap/simulate` when the wallet cannot.\n\n## Which tool for which question\n\n- Raw numbers — prices, a token's tape, who launched what, a wallet's PnL: the data tools (MCP / manifest) or the REST endpoints directly. Fast, deterministic, free.\n- Judgement — \"is ARGUS still being bought by real wallets\", \"give me an entry ladder\", \"compare these three launches\": the Ask agent. 5–40 s, metered, needs a key.\n- Trading: `chord_quote` then `chord_swap_tx`, or the REST pair `/quote` → `/swap`, on any EVM chain Chord routes; Solana swaps go through `/v1/sol/trade/*`.\n\n## Keys\n\nRead tools work without a key at the anonymous limit. Set `CHORD_API_KEY` (MCP) or send `X-API-Key` (manifest, REST) to run at your plan's limit; the Ask agent requires one. Keys come from [getchord.xyz/developer](https://getchord.xyz/developer).","sections":[{"heading":"","anchor":"","text":"Chord is built for agents first: every number the app shows is one GET away, amounts are strings, errors are stable codes, and nothing needs a browser. The ways in:\n\n| Path | What it is | Best for |\n| --- | --- | --- |\n| [Docs MCP](/docs/agents/docs-mcp/) | this documentation as tools — search, read a page, look up an endpoint with a real example; hosted at `getchord.xyz/docs/mcp` | any agent writing code against the API; no key, no install |\n| [Agent skill](/docs/agents/skill/) | `SKILL.md`, references and a dependency-free Python client in the Agent Skills format; one `curl` loop installs it, no repository access | Claude Code, Codex, OpenClaw, Hermes: read prices and boards on every chain, quote, prepare an unsigned swap |\n| [MCP server](/docs/agents/mcp/) | hosted at `api.getchord.xyz/v1/mcp`: 17 tools, every chain as a parameter, one URL per chain with `?chain=` | Claude Code, Claude Desktop, Cursor, any MCP client; no install, key optional |\n| [Function calling](/docs/agents/function-calling/) | the same tools as OpenAI-style JSON Schema, public at `api.getchord.xyz/v1/mcp/tools.json` | OpenAI, LangChain, anything that takes a manifest |\n| [Ask agent API](/docs/agents/ask-api/) | `POST /v1/ask` — Chord's own analyst over the index, 40+ tools, one JSON answer | judgement questions: is this launch real, where is support, who is buying |\n| [llms.txt](/docs/agents/llms-txt/) | this documentation as plain text, every page as Markdown, the OpenAPI document, and the discovery files (`/.well-known/api-catalog`, `ai-catalog.json`, `agent-skills/index.json`) | retrieval, system prompts, codegen by a model, finding Chord's tools from the domain alone |"},{"heading":"Prepare, then sign","anchor":"prepare-then-sign","text":"The API is non-custodial. A tool that trades returns an **unsigned transaction**; the agent's own wallet signs it and broadcasts it to the chain it names. Chord never sees a private key, never holds funds, never broadcasts. Read `otherAmountThreshold` before signing — it is the minimum the transaction enforces — and simulate with `POST /v1/swap/simulate` when the wallet cannot."},{"heading":"Which tool for which question","anchor":"which-tool-for-which-question","text":"- Raw numbers — prices, a token's tape, who launched what, a wallet's PnL: the data tools (MCP / manifest) or the REST endpoints directly. Fast, deterministic, free.\n- Judgement — \"is ARGUS still being bought by real wallets\", \"give me an entry ladder\", \"compare these three launches\": the Ask agent. 5–40 s, metered, needs a key.\n- Trading: `chord_quote` then `chord_swap_tx`, or the REST pair `/quote` → `/swap`, on any EVM chain Chord routes; Solana swaps go through `/v1/sol/trade/*`."},{"heading":"Keys","anchor":"keys","text":"Read tools work without a key at the anonymous limit. Set `CHORD_API_KEY` (MCP) or send `X-API-Key` (manifest, REST) to run at your plan's limit; the Ask agent requires one. Keys come from [getchord.xyz/developer](https://getchord.xyz/developer)."}]},{"kind":"page","path":"/docs/agents/ask-api/","url":"https://getchord.xyz/docs/agents/ask-api/","title":"Ask agent API","description":"POST /v1/ask — Chord's analyst over the Arc index and the router, as an API for other agents. One JSON answer, sources, a route card, tables.","markdown":"Ask is the analyst behind the chat on getchord.xyz. It has 40+ tools over the Arc index and the router — trending, a token's flow, holders and risk, support and resistance, top traders on a token, a wallet's PnL and trades, largest prints, launches and launchers, depth, a bridge quote, read-only SQL over the index — and answers in plain language with the sources it read. The same agent is available to your agent.\n\n## Call it\n\n```bash\ncurl -X POST https://api.getchord.xyz/v1/ask \\\n  -H \"X-API-Key: YOUR_KEY\" -H \"Content-Type: application/json\" \\\n  -d '{ \"question\": \"Is ARGUS still being bought by real wallets, and where is support?\", \"stream\": false }'\n```\n\n- **Auth**: an API key (`X-API-Key`). The browser uses a Google session instead; agents use a key.\n- **`stream: false`** returns one JSON answer in 5–40 s. Without it the response is `text/event-stream` (below).\n- **`history`**: up to 12 prior turns `{ role, content }` for a conversation.\n- **`wallet`**: the agent's wallet, so \"my PnL\" and \"my positions\" resolve.\n- **`mode`**: `\"quick\"` or `\"deep\"`, the chat's answer switch. Quick returns the shortest form of the answer (the verdict, its claim, at most three rows of evidence, 120 words at most) and runs faster. Deep returns a judgement or an explanation as a full research note (`shape: \"report\"`), and any other answer with a longer `details`. Leave it out for the length the question calls for; any other value is ignored.\n- **Limits**: 8 questions a minute per key, metered per key per day against the deployment's token budget (`GET /v1/ask/status`).\n\n## The answer\n\n```json\n{\n  \"text\": \"**ARGUS is still being bought by real wallets: 59.8% of the last hour's buying is not bots or routers.** Confidence: medium (…)\\n\\n| Level | Price | vs now % | Why |\\n| --- | --- | --- | --- |\\n| Support | 0.0181 | … | … |\\n\\n**Against:** …\\n\\n*… UTC. Chord's Arc index.*\",\n  \"shape\": \"brief\",\n  \"parts\": [\n    { \"t\": \"md\", \"text\": \"**ARGUS is still being bought by real wallets: 59.8% of the last hour's buying is not bots or routers.** Confidence: medium (…)\" },\n    { \"t\": \"viz\", \"i\": 0 },\n    { \"t\": \"md\", \"text\": \"**Against:** …\\n\\n*… UTC. Chord's Arc index.*\" }\n  ],\n  \"details\": null,\n  \"viz\": [ { \"kind\": \"table\", \"title\": \"ARGUS · key levels on the tape\", \"columns\": [ \"Level\", \"Price\", \"vs now %\", \"Why\" ], \"rows\": [ … ] } ],\n  \"followUps\": [ \"Who are the top buyers of $ARGUS this hour?\", \"…\", \"Alert me if ARGUS closes below 0.0176\" ],\n  \"followUpKinds\": [ \"deeper\", \"ask\", \"alert\" ],\n  \"assets\": [ { \"symbol\": \"ARGUS\", \"label\": \"…\", \"price\": …, \"change24hPct\": 12.7 } ],\n  \"focus\": 0,\n  \"citations\": [ { \"label\": \"ARGUS on Arc\", \"href\": \"/arc/token/0xece5…\" } ],\n  \"quote\": null,\n  \"artifact\": { \"kind\": \"token\", \"token\": { \"address\": \"0xece5…\", \"symbol\": \"ARGUS\" }, \"stats\": { … }, \"analysis\": { … }, \"report\": null },\n  \"toolsUsed\": [\"arc_token\", \"arc_price_analysis\", \"arc_token_traders\"],\n  \"tokens\": 9120\n}\n```\n\n| Field | Meaning |\n| --- | --- |\n| `text` | The answer, Markdown, complete on its own. A table the answer placed is written out here as a Markdown table (its first 8 rows and 6 columns), so a client that reads only `text` shows the whole answer. |\n| `shape` | The kind of answer the question got: `fact` · `explain` · `brief` (a call with its evidence) · `board` (a ranked list) · `why` · `overview` · `compare` · `post` (something to paste or a chart) · `do` (steps on Chord) · `report` · `auto`. |\n| `parts` | The same answer in order, for a client that draws blocks: `{ \"t\": \"md\", \"text\" }` is text, `{ \"t\": \"viz\", \"i\" }` is the table or chart `viz[i]` placed at that point. |\n| `details` | `{ text, parts }` or `null`: further depth (a per-venue breakdown, a longer history) that the chat folds under \"Show full analysis\". It is not repeated in `text`. |\n| `viz` | Tables and charts from real numbers (`kind`: `table` · `bar` · `line` · `donut`), at most 6. The ones `parts` and `details` place come first, in that order; the rest were not placed in the text. A client that draws `text` and then `viz` should skip the tables `parts` points at: `text` already holds them. |\n| `followUps` · `followUpKinds` | Up to three next questions, and for each whether it is `deeper` (into this answer), an `alert` to set, or another `ask`. |\n| `assets` · `focus` | Price chips for the assets the answer names; `focus` is the index of the one asset the answer is about, or `null`. A chip of a token Chord checked in this answer carries `risk`: `{ verdict, reasons }`, the verdict `avoid`, `caution` or `ok` of Chord's safety check (the same report as `GET /v1/security/token/{chain}/{address}`) and its reasons, worst first. |\n| `citations` | Where to check the numbers: `{ label, href }` per source. `href` is a Chord page as a path under `https://getchord.xyz` (`/arc/token/0x…`), or the source's own URL. A deep answer (`mode: \"deep\"`, or a question that asks for deep research) numbers its sources: `[n]` in `text` is `citations[n-1]`, and each source also carries `tier` (1 primary data, 2 major media, 3 blog or other site, 4 social) and `kind` (`index`, `data`, `official`, `media`, `blog`, `social`, `other`). |\n| `revokes` | Only when the answer read a wallet's approvals: one row per risky approval with the transaction that revokes it, `{ chainId, kind, token, spender, to, data, value, label }` (`kind` `erc20` = `approve(spender, 0)`, `nft` = `setApprovalForAll(spender, false)`, sent `to` the token). Unsigned: the wallet's owner signs it, Chord never does. At most 20. |\n| `quote` | A route card when the question implied a trade: the two tokens, the amounts in whole tokens, the venues, price impact, fee and a link to the trade on Chord. It is a preview, not a `/v1/quote` response: `/v1/swap` needs a fresh `/v1/quote`. |\n| `artifact` | The token the answer is about: its stats, where volume traded (support, resistance, VWAP) and a report link when one was built. No entry ladder, stop or targets: levels are a reading of the tape, not orders. |\n| `toolsUsed` · `tokens` | What ran and what it cost. |\n\n`shape`, `parts`, `details`, `followUpKinds` and `focus` are optional (and so are `revokes`, a chip's `risk` and a source's `tier` and `kind`): an answer that asks you something back leaves `shape`, `parts` and `followUpKinds` out, with `details` and `focus` at `null`. Ignore all five and `text` plus `viz` is still the whole answer, without the folded `details`.\n\nErrors: `401 UNAUTHORIZED` (no key), `429 RATE_LIMITED`, `503 DISABLED` (the analyst is off), `503 EMPTY` (no answer produced — ask again, more specifically).\n\n## Streaming\n\nWithout `stream: false`, the response is server-sent events: `status` frames name the tool running (`{ \"tool\": \"arc_price_analysis\", \"label\": \"Reading the tape\" }`), one `answer` frame carries the object above, `error` carries `{ code, message }`, and `done` closes. Use it for a UI that shows progress; agents want the JSON.\n\n## Picks and reports\n\n- `GET /v1/ask/picks` — the analyst's current board (rebuilt every four hours over tokens with real activity): side, score, confidence, reasons for and against, and the seven-day track record (picks graded, the share that moved their way, average move). No targets or stops. Public.\n- `POST /v1/ask/report { token }` — a three-page research note for a token (HTML for print-to-PDF, and Markdown), links good for seven days. Session-gated today.\n\n## What to ask\n\nIt answers like a trader's analyst: from the index first, and from outside market data, news headlines and posts on X where the question needs them. Good questions: \"what is moving on Arc and why\", \"launch forensics on 0x…\", \"top PnL wallets on Minara and how they traded it\", \"is TOLLY a buy here, and what would change that\", \"which pools pay real fees on USDC pairs\". It takes a position and shows the evidence for it, and it says when the data is thin. A plan (zones, tranches, an exit, the level where the idea is wrong) is written only when you ask for one, as illustrative scenarios with their assumptions stated, never as advice.","sections":[{"heading":"","anchor":"","text":"Ask is the analyst behind the chat on getchord.xyz. It has 40+ tools over the Arc index and the router — trending, a token's flow, holders and risk, support and resistance, top traders on a token, a wallet's PnL and trades, largest prints, launches and launchers, depth, a bridge quote, read-only SQL over the index — and answers in plain language with the sources it read. The same agent is available to your agent."},{"heading":"Call it","anchor":"call-it","text":"```bash\ncurl -X POST https://api.getchord.xyz/v1/ask \\\n  -H \"X-API-Key: YOUR_KEY\" -H \"Content-Type: application/json\" \\\n  -d '{ \"question\": \"Is ARGUS still being bought by real wallets, and where is support?\", \"stream\": false }'\n```\n\n- **Auth**: an API key (`X-API-Key`). The browser uses a Google session instead; agents use a key.\n- **`stream: false`** returns one JSON answer in 5–40 s. Without it the response is `text/event-stream` (below).\n- **`history`**: up to 12 prior turns `{ role, content }` for a conversation.\n- **`wallet`**: the agent's wallet, so \"my PnL\" and \"my positions\" resolve.\n- **`mode`**: `\"quick\"` or `\"deep\"`, the chat's answer switch. Quick returns the shortest form of the answer (the verdict, its claim, at most three rows of evidence, 120 words at most) and runs faster. Deep returns a judgement or an explanation as a full research note (`shape: \"report\"`), and any other answer with a longer `details`. Leave it out for the length the question calls for; any other value is ignored.\n- **Limits**: 8 questions a minute per key, metered per key per day against the deployment's token budget (`GET /v1/ask/status`)."},{"heading":"The answer","anchor":"the-answer","text":"```json\n{\n  \"text\": \"**ARGUS is still being bought by real wallets: 59.8% of the last hour's buying is not bots or routers.** Confidence: medium (…)\\n\\n| Level | Price | vs now % | Why |\\n| --- | --- | --- | --- |\\n| Support | 0.0181 | … | … |\\n\\n**Against:** …\\n\\n*… UTC. Chord's Arc index.*\",\n  \"shape\": \"brief\",\n  \"parts\": [\n    { \"t\": \"md\", \"text\": \"**ARGUS is still being bought by real wallets: 59.8% of the last hour's buying is not bots or routers.** Confidence: medium (…)\" },\n    { \"t\": \"viz\", \"i\": 0 },\n    { \"t\": \"md\", \"text\": \"**Against:** …\\n\\n*… UTC. Chord's Arc index.*\" }\n  ],\n  \"details\": null,\n  \"viz\": [ { \"kind\": \"table\", \"title\": \"ARGUS · key levels on the tape\", \"columns\": [ \"Level\", \"Price\", \"vs now %\", \"Why\" ], \"rows\": [ … ] } ],\n  \"followUps\": [ \"Who are the top buyers of $ARGUS this hour?\", \"…\", \"Alert me if ARGUS closes below 0.0176\" ],\n  \"followUpKinds\": [ \"deeper\", \"ask\", \"alert\" ],\n  \"assets\": [ { \"symbol\": \"ARGUS\", \"label\": \"…\", \"price\": …, \"change24hPct\": 12.7 } ],\n  \"focus\": 0,\n  \"citations\": [ { \"label\": \"ARGUS on Arc\", \"href\": \"/arc/token/0xece5…\" } ],\n  \"quote\": null,\n  \"artifact\": { \"kind\": \"token\", \"token\": { \"address\": \"0xece5…\", \"symbol\": \"ARGUS\" }, \"stats\": { … }, \"analysis\": { … }, \"report\": null },\n  \"toolsUsed\": [\"arc_token\", \"arc_price_analysis\", \"arc_token_traders\"],\n  \"tokens\": 9120\n}\n```\n\n| Field | Meaning |\n| --- | --- |\n| `text` | The answer, Markdown, complete on its own. A table the answer placed is written out here as a Markdown table (its first 8 rows and 6 columns), so a client that reads only `text` shows the whole answer. |\n| `shape` | The kind of answer the question got: `fact` · `explain` · `brief` (a call with its evidence) · `board` (a ranked list) · `why` · `overview` · `compare` · `post` (something to paste or a chart) · `do` (steps on Chord) · `report` · `auto`. |\n| `parts` | The same answer in order, for a client that draws blocks: `{ \"t\": \"md\", \"text\" }` is text, `{ \"t\": \"viz\", \"i\" }` is the table or chart `viz[i]` placed at that point. |\n| `details` | `{ text, parts }` or `null`: further depth (a per-venue breakdown, a longer history) that the chat folds under \"Show full analysis\". It is not repeated in `text`. |\n| `viz` | Tables and charts from real numbers (`kind`: `table` · `bar` · `line` · `donut`), at most 6. The ones `parts` and `details` place come first, in that order; the rest were not placed in the text. A client that draws `text` and then `viz` should skip the tables `parts` points at: `text` already holds them. |\n| `followUps` · `followUpKinds` | Up to three next questions, and for each whether it is `deeper` (into this answer), an `alert` to set, or another `ask`. |\n| `assets` · `focus` | Price chips for the assets the answer names; `focus` is the index of the one asset the answer is about, or `null`. A chip of a token Chord checked in this answer carries `risk`: `{ verdict, reasons }`, the verdict `avoid`, `caution` or `ok` of Chord's safety check (the same report as `GET /v1/security/token/{chain}/{address}`) and its reasons, worst first. |\n| `citations` | Where to check the numbers: `{ label, href }` per source. `href` is a Chord page as a path under `https://getchord.xyz` (`/arc/token/0x…`), or the source's own URL. A deep answer (`mode: \"deep\"`, or a question that asks for deep research) numbers its sources: `[n]` in `text` is `citations[n-1]`, and each source also carries `tier` (1 primary data, 2 major media, 3 blog or other site, 4 social) and `kind` (`index`, `data`, `official`, `media`, `blog`, `social`, `other`). |\n| `revokes` | Only when the answer read a wallet's approvals: one row per risky approval with the transaction that revokes it, `{ chainId, kind, token, spender, to, data, value, label }` (`kind` `erc20` = `approve(spender, 0)`, `nft` = `setApprovalForAll(spender, false)`, sent `to` the token). Unsigned: the wallet's owner signs it, Chord never does. At most 20. |\n| `quote` | A route card when the question implied a trade: the two tokens, the amounts in whole tokens, the venues, price impact, fee and a link to the trade on Chord. It is a preview, not a `/v1/quote` response: `/v1/swap` needs a fresh `/v1/quote`. |\n| `artifact` | The token the answer is about: its stats, where volume traded (support, resistance, VWAP) and a report link when one was built. No entry ladder, stop or targets: levels are a reading of the tape, not orders. |\n| `toolsUsed` · `tokens` | What ran and what it cost. |\n\n`shape`, `parts`, `details`, `followUpKinds` and `focus` are optional (and so are `revokes`, a chip's `risk` and a source's `tier` and `kind`): an answer that asks you something back leaves `shape`, `parts` and `followUpKinds` out, with `details` and `focus` at `null`. Ignore all five and `text` plus `viz` is still the whole answer, without the folded `details`.\n\nErrors: `401 UNAUTHORIZED` (no key), `429 RATE_LIMITED`, `503 DISABLED` (the analyst is off), `503 EMPTY` (no answer produced — ask again, more specifically)."},{"heading":"Streaming","anchor":"streaming","text":"Without `stream: false`, the response is server-sent events: `status` frames name the tool running (`{ \"tool\": \"arc_price_analysis\", \"label\": \"Reading the tape\" }`), one `answer` frame carries the object above, `error` carries `{ code, message }`, and `done` closes. Use it for a UI that shows progress; agents want the JSON."},{"heading":"Picks and reports","anchor":"picks-and-reports","text":"- `GET /v1/ask/picks` — the analyst's current board (rebuilt every four hours over tokens with real activity): side, score, confidence, reasons for and against, and the seven-day track record (picks graded, the share that moved their way, average move). No targets or stops. Public.\n- `POST /v1/ask/report { token }` — a three-page research note for a token (HTML for print-to-PDF, and Markdown), links good for seven days. Session-gated today."},{"heading":"What to ask","anchor":"what-to-ask","text":"It answers like a trader's analyst: from the index first, and from outside market data, news headlines and posts on X where the question needs them. Good questions: \"what is moving on Arc and why\", \"launch forensics on 0x…\", \"top PnL wallets on Minara and how they traded it\", \"is TOLLY a buy here, and what would change that\", \"which pools pay real fees on USDC pairs\". It takes a position and shows the evidence for it, and it says when the data is thin. A plan (zones, tranches, an exit, the level where the idea is wrong) is written only when you ask for one, as illustrative scenarios with their assumptions stated, never as advice."}]},{"kind":"page","path":"/docs/agents/docs-mcp/","url":"https://getchord.xyz/docs/agents/docs-mcp/","title":"Docs MCP","description":"Give your agent the Chord documentation as tools — search, read a page, look up an endpoint with its real example — hosted at getchord.xyz/docs/mcp or run locally over stdio.","markdown":"The Chord Docs MCP is this documentation as a Model Context Protocol server: an agent searches the docs, reads a page, or pulls an endpoint's exact parameters, response shape and a real example — instead of guessing from training data. It is read-only and never calls the Chord API; when the agent also needs live numbers, pair it with the hosted [MCP server](/docs/agents/mcp/), the [Agent skill](/docs/agents/skill/) or direct API calls.\n\n## Hosted\n\nOne URL, no install, Streamable HTTP:\n\n```\nhttps://getchord.xyz/docs/mcp\n```\n\n**Claude Code**\n\n```bash\nclaude mcp add --transport http chord-docs https://getchord.xyz/docs/mcp\n```\n\n**Claude Desktop, Cursor, Windsurf, any client with an `mcpServers` config**\n\n```json\n{ \"mcpServers\": { \"chord-docs\": { \"type\": \"http\", \"url\": \"https://getchord.xyz/docs/mcp\" } } }\n```\n\n**Codex, OpenAI Agents SDK and other clients that take a URL**: point them at the same address. The server is stateless (no session ids), answers JSON to a `POST`, and allows any origin.\n\nIts server card ([MCP SEP-2127](https://modelcontextprotocol.io/seps/2127-mcp-server-cards)) is at [`https://getchord.xyz/docs/mcp/server-card`](https://getchord.xyz/docs/mcp/server-card), and the site's AI catalog ([`/.well-known/ai-catalog.json`](https://getchord.xyz/.well-known/ai-catalog.json)) lists it.\n\n## Local (stdio)\n\nThe same server also runs over stdio, for an offline client or one that only speaks stdio, but only from a checkout of the Chord repository (`packages/docs-mcp`), which is not public yet. Outside it, use the hosted URL above: same server, same index.\n\n```bash\n# from a checkout of the Chord repository\npnpm install --filter @nullterminal/docs-mcp\nclaude mcp add chord-docs -- node $PWD/packages/docs-mcp/stdio.mjs\n```\n\nIt fetches the docs index from getchord.xyz on start and refreshes it every 30 minutes. `DOCS_INDEX_URL` points it elsewhere; `DOCS_INDEX_FILE` uses a local build of the docs.\n\n## Tools\n\n| Tool | What it does |\n| --- | --- |\n| `search_chord_docs` | Full-text search over every page and every endpoint; returns matching sections and operations with a snippet and URL. `kind` narrows to pages or operations. |\n| `read_chord_docs_page` | The full Markdown of one page (or one section with `#anchor`) by path, e.g. `/docs/concepts/streaming/`. |\n| `chord_api_reference` | An endpoint's method, path, every parameter with type / enum / default, the request body, the response shape and a real example captured from the live API. Look up by operationId (`getQuote`), path (`/v1/arc/tokens`) or words. |\n| `list_chord_docs_pages` | Every page with its description, grouped by section, plus the API tags — for orientation. |\n\nThe server also sends `instructions` on connect (base URL, the amounts rule, the Arc USDC alias), so a model that only calls one tool still gets the facts it most often gets wrong.\n\n## What the index is\n\nA JSON built with the site — every page's Markdown split into sections, every OpenAPI operation with its parameters, response outline and example — published at [`/docs/docs-index.json`](/docs/docs-index.json) and rebuilt on every deploy. Search is a small in-memory scorer; a query answers in a few milliseconds.\n\n## Tested with Claude\n\nBoth transports were verified with Claude Code in headless mode: the model was told to answer only from the MCP, and it called `search_chord_docs` then `read_chord_docs_page` / `chord_api_reference` and returned the exact WebSocket subscribe frame and the holders endpoint with the doc URLs. Run the same check yourself:\n\n```bash\nclaude -p \"Using only the chord-docs MCP, how do I subscribe to live Arc prices over WebSocket?\" \\\n  --allowedTools \"mcp__chord-docs__*\"\n```","sections":[{"heading":"","anchor":"","text":"The Chord Docs MCP is this documentation as a Model Context Protocol server: an agent searches the docs, reads a page, or pulls an endpoint's exact parameters, response shape and a real example — instead of guessing from training data. It is read-only and never calls the Chord API; when the agent also needs live numbers, pair it with the hosted [MCP server](/docs/agents/mcp/), the [Agent skill](/docs/agents/skill/) or direct API calls."},{"heading":"Hosted","anchor":"hosted","text":"One URL, no install, Streamable HTTP:\n\n```\nhttps://getchord.xyz/docs/mcp\n```\n\n**Claude Code**\n\n```bash\nclaude mcp add --transport http chord-docs https://getchord.xyz/docs/mcp\n```\n\n**Claude Desktop, Cursor, Windsurf, any client with an `mcpServers` config**\n\n```json\n{ \"mcpServers\": { \"chord-docs\": { \"type\": \"http\", \"url\": \"https://getchord.xyz/docs/mcp\" } } }\n```\n\n**Codex, OpenAI Agents SDK and other clients that take a URL**: point them at the same address. The server is stateless (no session ids), answers JSON to a `POST`, and allows any origin.\n\nIts server card ([MCP SEP-2127](https://modelcontextprotocol.io/seps/2127-mcp-server-cards)) is at [`https://getchord.xyz/docs/mcp/server-card`](https://getchord.xyz/docs/mcp/server-card), and the site's AI catalog ([`/.well-known/ai-catalog.json`](https://getchord.xyz/.well-known/ai-catalog.json)) lists it."},{"heading":"Local (stdio)","anchor":"local-stdio","text":"The same server also runs over stdio, for an offline client or one that only speaks stdio, but only from a checkout of the Chord repository (`packages/docs-mcp`), which is not public yet. Outside it, use the hosted URL above: same server, same index.\n\n```bash\n# from a checkout of the Chord repository\npnpm install --filter @nullterminal/docs-mcp\nclaude mcp add chord-docs -- node $PWD/packages/docs-mcp/stdio.mjs\n```\n\nIt fetches the docs index from getchord.xyz on start and refreshes it every 30 minutes. `DOCS_INDEX_URL` points it elsewhere; `DOCS_INDEX_FILE` uses a local build of the docs."},{"heading":"Tools","anchor":"tools","text":"| Tool | What it does |\n| --- | --- |\n| `search_chord_docs` | Full-text search over every page and every endpoint; returns matching sections and operations with a snippet and URL. `kind` narrows to pages or operations. |\n| `read_chord_docs_page` | The full Markdown of one page (or one section with `#anchor`) by path, e.g. `/docs/concepts/streaming/`. |\n| `chord_api_reference` | An endpoint's method, path, every parameter with type / enum / default, the request body, the response shape and a real example captured from the live API. Look up by operationId (`getQuote`), path (`/v1/arc/tokens`) or words. |\n| `list_chord_docs_pages` | Every page with its description, grouped by section, plus the API tags — for orientation. |\n\nThe server also sends `instructions` on connect (base URL, the amounts rule, the Arc USDC alias), so a model that only calls one tool still gets the facts it most often gets wrong."},{"heading":"What the index is","anchor":"what-the-index-is","text":"A JSON built with the site — every page's Markdown split into sections, every OpenAPI operation with its parameters, response outline and example — published at [`/docs/docs-index.json`](/docs/docs-index.json) and rebuilt on every deploy. Search is a small in-memory scorer; a query answers in a few milliseconds."},{"heading":"Tested with Claude","anchor":"tested-with-claude","text":"Both transports were verified with Claude Code in headless mode: the model was told to answer only from the MCP, and it called `search_chord_docs` then `read_chord_docs_page` / `chord_api_reference` and returned the exact WebSocket subscribe frame and the holders endpoint with the doc URLs. Run the same check yourself:\n\n```bash\nclaude -p \"Using only the chord-docs MCP, how do I subscribe to live Arc prices over WebSocket?\" \\\n  --allowedTools \"mcp__chord-docs__*\"\n```"}]},{"kind":"page","path":"/docs/agents/function-calling/","url":"https://getchord.xyz/docs/agents/function-calling/","title":"Function calling","description":"The Chord agent tools as an OpenAI-style JSON Schema manifest, always current, for any framework that takes a tool list.","markdown":"`https://api.getchord.xyz/v1/mcp/tools.json` is the tool set as JSON Schema: a `tools` array in the OpenAI function format, the `base_url`, the MCP endpoint and the `auth` header. It is public, needs no install, and is printed from the same list the [hosted MCP server](/docs/agents/mcp/) serves, so it never lags behind it. A copy also lives at `https://getchord.xyz/agent/tools.json`.\n\n```bash\ncurl -s https://api.getchord.xyz/v1/mcp/tools.json | jq '{base_url, mcp, auth, tools: [.tools[].function.name]}'\n```\n\n```json\n{\n  \"base_url\": \"https://api.getchord.xyz\",\n  \"mcp\": \"https://api.getchord.xyz/v1/mcp\",\n  \"auth\": { \"header\": \"X-API-Key\", \"required\": false },\n  \"tools\": [\"chord_chains\", \"chord_status\", \"chord_overview\", \"chord_tokens\", \"chord_search\", \"chord_token\", \"chord_trades\", \"chord_candles\", \"chord_wallet\", \"chord_wallet_trades\", \"chord_smart_money\", \"chord_holders\", \"chord_lp_pools\", \"chord_lp_positions\", \"chord_quote\", \"chord_swap_tx\", \"chord_ask\"]\n}\n```\n\n## A minimal loop\n\nHand `tools` to the model. When it returns a tool call, send that call to the MCP endpoint as one JSON-RPC message and give the text back to the model. No MCP library is needed: it is one POST.\n\n```ts\nconst manifest = await fetch(\"https://api.getchord.xyz/v1/mcp/tools.json\").then((r) => r.json());\nconst tools = manifest.tools; // OpenAI format: { type: \"function\", function: { name, description, parameters } }\n\nasync function runChordTool(name: string, args: object) {\n  const res = await fetch(manifest.mcp, {\n    method: \"POST\",\n    headers: { \"content-type\": \"application/json\", ...(process.env.CHORD_API_KEY ? { \"X-API-Key\": process.env.CHORD_API_KEY } : {}) },\n    body: JSON.stringify({ jsonrpc: \"2.0\", id: 1, method: \"tools/call\", params: { name, arguments: args } }),\n  }).then((r) => r.json());\n  return res.result.content[0].text; // JSON text: { chain, route, data }; res.result.isError marks a tool-level error\n}\n\n// 1. ask the model with the tools attached\n// 2. for each tool_call the model returns:\nfor (const call of message.tool_calls) {\n  const result = await runChordTool(call.function.name, JSON.parse(call.function.arguments));\n  messages.push({ role: \"tool\", tool_call_id: call.id, content: result });\n}\n// 3. ask the model again with the tool results\n```\n\nEvery data tool takes a `chain` (`monad`, `robinhood`, `arc`, `avalanche`, `base`, `bnb`, `arbitrum`, `ethereum`, `solana`). To default one, POST to `https://api.getchord.xyz/v1/mcp?chain=arc` instead. Tools take addresses and integer amounts in the token's smallest unit; `chord_search` turns a symbol into an address, and the token's `decimals` come back with it.\n\nEach answer names the REST `route` that produced it. If you would rather call REST yourself, [`GET /v1/chains`](/docs/api-reference/) lists the route of every capability on every chain.\n\n## The trading pair\n\n`chord_quote` returns the route, the expected output and a `quoteId`; `chord_swap_tx` returns the unsigned transaction for that `quoteId` and a taker, with the approval it needs and a simulation. Both work on the eight EVM chains; Solana swaps are REST only (`/v1/sol/trade/*`). The model proposes; your code signs, or shows the user what would be signed. Never let a model hold a key.\n\n## Direct REST as tools\n\nFor a framework that generates tools from an OpenAPI document (LangChain's OpenAPI toolkit, an OpenAI Actions schema, a Gemini extension), point it at [openapi.json](/docs/openapi.json). Every operation has an `operationId`, a summary a model can read, and examples.","sections":[{"heading":"","anchor":"","text":"`https://api.getchord.xyz/v1/mcp/tools.json` is the tool set as JSON Schema: a `tools` array in the OpenAI function format, the `base_url`, the MCP endpoint and the `auth` header. It is public, needs no install, and is printed from the same list the [hosted MCP server](/docs/agents/mcp/) serves, so it never lags behind it. A copy also lives at `https://getchord.xyz/agent/tools.json`.\n\n```bash\ncurl -s https://api.getchord.xyz/v1/mcp/tools.json | jq '{base_url, mcp, auth, tools: [.tools[].function.name]}'\n```\n\n```json\n{\n  \"base_url\": \"https://api.getchord.xyz\",\n  \"mcp\": \"https://api.getchord.xyz/v1/mcp\",\n  \"auth\": { \"header\": \"X-API-Key\", \"required\": false },\n  \"tools\": [\"chord_chains\", \"chord_status\", \"chord_overview\", \"chord_tokens\", \"chord_search\", \"chord_token\", \"chord_trades\", \"chord_candles\", \"chord_wallet\", \"chord_wallet_trades\", \"chord_smart_money\", \"chord_holders\", \"chord_lp_pools\", \"chord_lp_positions\", \"chord_quote\", \"chord_swap_tx\", \"chord_ask\"]\n}\n```"},{"heading":"A minimal loop","anchor":"a-minimal-loop","text":"Hand `tools` to the model. When it returns a tool call, send that call to the MCP endpoint as one JSON-RPC message and give the text back to the model. No MCP library is needed: it is one POST.\n\n```ts\nconst manifest = await fetch(\"https://api.getchord.xyz/v1/mcp/tools.json\").then((r) => r.json());\nconst tools = manifest.tools; // OpenAI format: { type: \"function\", function: { name, description, parameters } }\n\nasync function runChordTool(name: string, args: object) {\n  const res = await fetch(manifest.mcp, {\n    method: \"POST\",\n    headers: { \"content-type\": \"application/json\", ...(process.env.CHORD_API_KEY ? { \"X-API-Key\": process.env.CHORD_API_KEY } : {}) },\n    body: JSON.stringify({ jsonrpc: \"2.0\", id: 1, method: \"tools/call\", params: { name, arguments: args } }),\n  }).then((r) => r.json());\n  return res.result.content[0].text; // JSON text: { chain, route, data }; res.result.isError marks a tool-level error\n}\n\n// 1. ask the model with the tools attached\n// 2. for each tool_call the model returns:\nfor (const call of message.tool_calls) {\n  const result = await runChordTool(call.function.name, JSON.parse(call.function.arguments));\n  messages.push({ role: \"tool\", tool_call_id: call.id, content: result });\n}\n// 3. ask the model again with the tool results\n```\n\nEvery data tool takes a `chain` (`monad`, `robinhood`, `arc`, `avalanche`, `base`, `bnb`, `arbitrum`, `ethereum`, `solana`). To default one, POST to `https://api.getchord.xyz/v1/mcp?chain=arc` instead. Tools take addresses and integer amounts in the token's smallest unit; `chord_search` turns a symbol into an address, and the token's `decimals` come back with it.\n\nEach answer names the REST `route` that produced it. If you would rather call REST yourself, [`GET /v1/chains`](/docs/api-reference/) lists the route of every capability on every chain."},{"heading":"The trading pair","anchor":"the-trading-pair","text":"`chord_quote` returns the route, the expected output and a `quoteId`; `chord_swap_tx` returns the unsigned transaction for that `quoteId` and a taker, with the approval it needs and a simulation. Both work on the eight EVM chains; Solana swaps are REST only (`/v1/sol/trade/*`). The model proposes; your code signs, or shows the user what would be signed. Never let a model hold a key."},{"heading":"Direct REST as tools","anchor":"direct-rest-as-tools","text":"For a framework that generates tools from an OpenAPI document (LangChain's OpenAPI toolkit, an OpenAI Actions schema, a Gemini extension), point it at [openapi.json](/docs/openapi.json). Every operation has an `operationId`, a summary a model can read, and examples."}]},{"kind":"page","path":"/docs/agents/llms-txt/","url":"https://getchord.xyz/docs/agents/llms-txt/","title":"llms.txt, Markdown and discovery files","description":"This documentation as plain text and as Markdown pages for retrieval and system prompts, the machine-readable API contract, and the files that let an agent find Chord's tools from the domain alone.","markdown":"| File | What | Size |\n| --- | --- | --- |\n| [`/llms.txt`](/llms.txt) (also [`/docs/llms.txt`](/docs/llms.txt)) | What Chord is, then every page of this documentation with a one-line description, the API, the agent integrations and the app ([llmstxt.org](https://llmstxt.org) format) | small |\n| `/docs/<page>.md` | Any page as Markdown: add `.md` to the page's path (`/docs/agents/mcp/` → [`/docs/agents/mcp.md`](/docs/agents/mcp.md)), or ask for the page with `Accept: text/markdown`. API operations too ([`/docs/api-reference.md`](/docs/api-reference.md) lists them) | per page |\n| [`/llms-full.txt`](/llms-full.txt) (also `/docs/llms-full.txt`) | Every page of this documentation, concatenated | large |\n| [`/docs/llms-small.txt`](/docs/llms-small.txt) | The same, minified — for a context window that needs the whole thing | medium |\n| [`/openapi.json`](/openapi.json) (also `/docs/openapi.json`) | The OpenAPI 3.1 contract: every endpoint, parameter, schema and example | large |\n\n## Discovery files\n\nAn agent that only knows `getchord.xyz` finds everything else from these:\n\n| File | Standard | Points to |\n| --- | --- | --- |\n| [`/.well-known/api-catalog`](/.well-known/api-catalog) | RFC 9727 (linkset) | the REST API with its OpenAPI document, docs and status; both MCP servers; the skill index |\n| [`/.well-known/ai-catalog.json`](/.well-known/ai-catalog.json) | AI Catalog ([MCP SEP-2127](https://modelcontextprotocol.io/seps/2127-mcp-server-cards)) | the server cards of the [MCP server](/docs/agents/mcp/) and the [Docs MCP](/docs/agents/docs-mcp/) |\n| [`/.well-known/agent-skills/index.json`](/.well-known/agent-skills/index.json) | [Agent Skills discovery](https://github.com/cloudflare/agent-skills-discovery-rfc) | the [Chord skill](/docs/agents/skill/) archive and its SHA-256 digest |\n| [`/robots.txt`](/robots.txt) | robots + Content Signals | crawlers, assistants and agents allowed (`search`, `ai-input`, `ai-train` = yes); both sitemaps |\n\n`api.getchord.xyz` answers `/.well-known/api-catalog`, `/.well-known/ai-catalog.json` and `/robots.txt` too, and `GET https://api.getchord.xyz/` returns the same links as JSON.\n\n## In a system prompt\n\nPaste `llms.txt` and let the model fetch the `.md` pages it needs, or paste `llms-small.txt` when the model must answer without fetching. Add the two facts models get wrong most:\n\n```\nChord API base: https://api.getchord.xyz/v1. Amounts are decimal strings in the token's smallest unit.\nOn Arc (chain 5042) USDC is the gas token; send the ERC-20 predeploy 0x3600000000000000000000000000000000000000 (6 decimals); the zero address is an alias for it and transactions always have value 0.\n```\n\n## For codegen by a model\n\nGive it `openapi.json`. Every operation has an `operationId`, constraints on parameters (enums, ranges, patterns), a response schema, and a real example captured from the live API.\n\n## For a retrieval index\n\nFetch `llms-full.txt` and split on the page separators; each page starts with its title and URL. Refresh daily — the file is rebuilt with every deploy of the docs.","sections":[{"heading":"","anchor":"","text":"| File | What | Size |\n| --- | --- | --- |\n| [`/llms.txt`](/llms.txt) (also [`/docs/llms.txt`](/docs/llms.txt)) | What Chord is, then every page of this documentation with a one-line description, the API, the agent integrations and the app ([llmstxt.org](https://llmstxt.org) format) | small |\n| `/docs/<page>.md` | Any page as Markdown: add `.md` to the page's path (`/docs/agents/mcp/` → [`/docs/agents/mcp.md`](/docs/agents/mcp.md)), or ask for the page with `Accept: text/markdown`. API operations too ([`/docs/api-reference.md`](/docs/api-reference.md) lists them) | per page |\n| [`/llms-full.txt`](/llms-full.txt) (also `/docs/llms-full.txt`) | Every page of this documentation, concatenated | large |\n| [`/docs/llms-small.txt`](/docs/llms-small.txt) | The same, minified — for a context window that needs the whole thing | medium |\n| [`/openapi.json`](/openapi.json) (also `/docs/openapi.json`) | The OpenAPI 3.1 contract: every endpoint, parameter, schema and example | large |"},{"heading":"Discovery files","anchor":"discovery-files","text":"An agent that only knows `getchord.xyz` finds everything else from these:\n\n| File | Standard | Points to |\n| --- | --- | --- |\n| [`/.well-known/api-catalog`](/.well-known/api-catalog) | RFC 9727 (linkset) | the REST API with its OpenAPI document, docs and status; both MCP servers; the skill index |\n| [`/.well-known/ai-catalog.json`](/.well-known/ai-catalog.json) | AI Catalog ([MCP SEP-2127](https://modelcontextprotocol.io/seps/2127-mcp-server-cards)) | the server cards of the [MCP server](/docs/agents/mcp/) and the [Docs MCP](/docs/agents/docs-mcp/) |\n| [`/.well-known/agent-skills/index.json`](/.well-known/agent-skills/index.json) | [Agent Skills discovery](https://github.com/cloudflare/agent-skills-discovery-rfc) | the [Chord skill](/docs/agents/skill/) archive and its SHA-256 digest |\n| [`/robots.txt`](/robots.txt) | robots + Content Signals | crawlers, assistants and agents allowed (`search`, `ai-input`, `ai-train` = yes); both sitemaps |\n\n`api.getchord.xyz` answers `/.well-known/api-catalog`, `/.well-known/ai-catalog.json` and `/robots.txt` too, and `GET https://api.getchord.xyz/` returns the same links as JSON."},{"heading":"In a system prompt","anchor":"in-a-system-prompt","text":"Paste `llms.txt` and let the model fetch the `.md` pages it needs, or paste `llms-small.txt` when the model must answer without fetching. Add the two facts models get wrong most:\n\n```\nChord API base: https://api.getchord.xyz/v1. Amounts are decimal strings in the token's smallest unit.\nOn Arc (chain 5042) USDC is the gas token; send the ERC-20 predeploy 0x3600000000000000000000000000000000000000 (6 decimals); the zero address is an alias for it and transactions always have value 0.\n```"},{"heading":"For codegen by a model","anchor":"for-codegen-by-a-model","text":"Give it `openapi.json`. Every operation has an `operationId`, constraints on parameters (enums, ranges, patterns), a response schema, and a real example captured from the live API."},{"heading":"For a retrieval index","anchor":"for-a-retrieval-index","text":"Fetch `llms-full.txt` and split on the page separators; each page starts with its title and URL. Refresh daily — the file is rebuilt with every deploy of the docs."}]},{"kind":"page","path":"/docs/agents/mcp/","url":"https://getchord.xyz/docs/agents/mcp/","title":"MCP server","description":"The hosted Chord MCP server. One URL, 17 tools, every chain Chord serves as a tool parameter. Market data, quotes and unsigned swap transactions for any MCP client, no install.","markdown":"Chord runs an MCP server at `https://api.getchord.xyz/v1/mcp`. Add the URL to an MCP client and 17 tools appear: boards, tokens, trades, candles, wallets, smart money, holders and liquidity pools on Ethereum, Arbitrum One, Base, BNB Chain, Avalanche, Monad, Arc, Robinhood Chain and Solana, plus quotes and unsigned swap transactions on the eight EVM chains.\n\nEvery data tool takes a `chain`. Nothing signs or sends: `chord_swap_tx` returns a transaction for the taker's own wallet.\n\n## Add it\n\n**Claude Code**\n\n```bash\nclaude mcp add --transport http chord https://api.getchord.xyz/v1/mcp\n```\n\n**Any client that takes a config**\n\n```json\n{\n  \"mcpServers\": {\n    \"chord\": {\n      \"type\": \"http\",\n      \"url\": \"https://api.getchord.xyz/v1/mcp\",\n      \"headers\": { \"X-API-Key\": \"optional: raises the rate limit; chord_ask needs it\" }\n    }\n  }\n}\n```\n\nThe server is stateless Streamable HTTP with JSON answers. It needs no session and no OAuth: the handshake and the tool list work without credentials.\n\n## One URL per chain\n\nAdd `?chain=` and the endpoint defaults to that chain. `chain` stops being a required argument and the server names itself after the chain.\n\n```\nhttps://api.getchord.xyz/v1/mcp?chain=arc\nhttps://api.getchord.xyz/v1/mcp?chain=monad\nhttps://api.getchord.xyz/v1/mcp?chain=solana\n```\n\nKeys: `monad`, `robinhood`, `arc`, `avalanche`, `base`, `bnb`, `arbitrum`, `ethereum`, `solana`. A call may still pass another `chain`.\n\n## Discovery\n\nClients and registries can find the server without being given the URL:\n\n- **Server card** ([MCP SEP-2127](https://modelcontextprotocol.io/seps/2127-mcp-server-cards)): [`https://api.getchord.xyz/v1/mcp/server-card`](https://api.getchord.xyz/v1/mcp/server-card) gives the name, version, transport, protocol versions and the optional key header. It has no tool list: read that live with `tools/list`.\n- **AI catalog**: [`https://getchord.xyz/.well-known/ai-catalog.json`](https://getchord.xyz/.well-known/ai-catalog.json) lists this server and the [Docs MCP](/docs/agents/docs-mcp/), each with its card.\n- **API catalog** (RFC 9727): [`https://getchord.xyz/.well-known/api-catalog`](https://getchord.xyz/.well-known/api-catalog) links the REST API, both MCP servers, their docs and status.\n- **MCP Registry**: `io.github.getchordlabs/chord`.\n\n## Keys and limits\n\nA tool call is an ordinary API request made as you. Without a key it runs at the anonymous limit of the address you call from. With `X-API-Key` (or `Authorization: Bearer <key>`, or `?apiKey=` for connectors that cannot set a header) it is metered and limited as that key. The handshake and the tool list are free. Keys come from the [developer page](https://getchord.xyz/developer).\n\n## Tools\n\n| Tool | Arguments | Returns |\n| --- | --- | --- |\n| `chord_chains` | none | every chain with its native asset, anchors, and which capabilities it has |\n| `chord_status` | none | per chain: routing engine state and how far the newest indexed trade is behind the chain |\n| `chord_overview` | `chain` | last 24 hours: volume, swaps, venue share, hourly buckets |\n| `chord_tokens` | `chain`, `sort`, `limit` | the 24h token board |\n| `chord_search` | `chain`, `query` | tokens matching a symbol, name or address |\n| `chord_token` | `chain`, `address` | one token: price, volume, trades, pools or venues |\n| `chord_trades` | `chain`, `address`, `limit` | the newest swaps of a token |\n| `chord_candles` | `chain`, `address`, `tf`, `limit` | OHLCV candles from Chord's index |\n| `chord_wallet` | `chain`, `wallet` | realised and open PnL per token |\n| `chord_wallet_trades` | `chain`, `wallet` | a wallet's recent swaps |\n| `chord_smart_money` | `chain`, `days`, `limit` | wallets ranked by profit, bots removed |\n| `chord_holders` | `chain`, `address`, `limit` | balances by address |\n| `chord_lp_pools` | `chain`, `limit` | pools ranked for a liquidity provider |\n| `chord_lp_positions` | `chain`, `wallet` | a wallet's liquidity positions |\n| `chord_quote` | `chain`, `tokenIn`, `tokenOut`, `amount`, `slippageBps`, `taker` | the best quote; Chord's router first, another aggregator only when Chord cannot route |\n| `chord_swap_tx` | `quoteId` or the pair and amount, `taker` | the unsigned transaction, its approval and a simulation |\n| `chord_ask` | `question`, `wallet` | the analyst's researched answer (needs a key) |\n\nAmounts are integer strings in the token's smallest unit. The zero address is the native asset on EVM chains. Solana addresses are base58 and case-sensitive.\n\n## Not every chain has everything\n\n`chord_chains` returns the live list. A tool called for a chain that lacks the capability answers with the chains that have it, for example: `base has no holders data. Chains with it: robinhood, arc.`\n\n| Capability | Monad | Robinhood | Arc | Avalanche | Base | BNB | Arbitrum | Ethereum | Solana |\n| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |\n| Overview, tokens, search, token, trades, candles, wallet | yes | yes | yes | yes | yes | yes | yes | yes | yes |\n| Wallet trades | yes | yes | yes | yes | yes | yes | yes | yes | yes |\n| Smart money | yes | yes | yes | no | no | no | no | no | yes |\n| Holders | no | yes | yes | no | no | no | no | no | no |\n| LP pools and positions | yes | yes | yes | no | no | no | no | no | yes |\n| Quote and swap transaction | yes | yes | yes | yes | yes | yes | yes | yes | no |\n\nSolana swaps are open on REST, not yet in the MCP tools: [`GET /v1/sol/trade/quote`](/docs/networks/solana/) answers with the unsigned transaction, the wallet signs it unchanged and `POST /v1/sol/trade/send` relays it. `chord_quote` called for Solana answers with those steps, and `chord_chains` lists Solana's `quote` and `swap` as those two routes.\n\nThe same table as data: [`GET /v1/chains`](/docs/api-reference/).\n\n## What an answer looks like\n\nEach tool returns one JSON text block: the chain, the REST route that produced it, and that route's body.\n\n```json\n{ \"chain\": \"arc\", \"route\": \"GET /v1/arc/overview\", \"data\": { \"chain\": 5042, \"last24h\": { \"volUsd\": 15625106.36, \"swaps\": 133764 } } }\n```\n\nThe `route` is the endpoint to call if you want the same data without MCP. Large answers are shortened by dropping rows from the end of long lists, with a count of what was dropped; the JSON is always valid.\n\n## Clients that only speak stdio\n\n`chord-agent` in the Chord repository is a stdio bridge to the same hosted server: it lists and calls the tools above over HTTP, so it never goes out of date. It is not on npm yet. From a checkout:\n\n```bash\ncd packages/agent && pnpm install && pnpm build\nclaude mcp add chord -- node /absolute/path/to/packages/agent/dist/mcp.js\n```\n\nEnvironment: `CHORD_API_KEY` (optional), `CHORD_CHAIN` (optional default chain), `CHORD_API_URL` (default `https://api.getchord.xyz`).\n\n## Related\n\n- [Function calling](/docs/agents/function-calling/): the same tools as an OpenAI-style manifest.\n- [Docs MCP](/docs/agents/docs-mcp/): a second hosted server that answers questions about this documentation.\n- [Status](https://getchord.xyz/status): uptime of the API on every chain, measured every minute from outside Chord's servers.","sections":[{"heading":"","anchor":"","text":"Chord runs an MCP server at `https://api.getchord.xyz/v1/mcp`. Add the URL to an MCP client and 17 tools appear: boards, tokens, trades, candles, wallets, smart money, holders and liquidity pools on Ethereum, Arbitrum One, Base, BNB Chain, Avalanche, Monad, Arc, Robinhood Chain and Solana, plus quotes and unsigned swap transactions on the eight EVM chains.\n\nEvery data tool takes a `chain`. Nothing signs or sends: `chord_swap_tx` returns a transaction for the taker's own wallet."},{"heading":"Add it","anchor":"add-it","text":"**Claude Code**\n\n```bash\nclaude mcp add --transport http chord https://api.getchord.xyz/v1/mcp\n```\n\n**Any client that takes a config**\n\n```json\n{\n  \"mcpServers\": {\n    \"chord\": {\n      \"type\": \"http\",\n      \"url\": \"https://api.getchord.xyz/v1/mcp\",\n      \"headers\": { \"X-API-Key\": \"optional: raises the rate limit; chord_ask needs it\" }\n    }\n  }\n}\n```\n\nThe server is stateless Streamable HTTP with JSON answers. It needs no session and no OAuth: the handshake and the tool list work without credentials."},{"heading":"One URL per chain","anchor":"one-url-per-chain","text":"Add `?chain=` and the endpoint defaults to that chain. `chain` stops being a required argument and the server names itself after the chain.\n\n```\nhttps://api.getchord.xyz/v1/mcp?chain=arc\nhttps://api.getchord.xyz/v1/mcp?chain=monad\nhttps://api.getchord.xyz/v1/mcp?chain=solana\n```\n\nKeys: `monad`, `robinhood`, `arc`, `avalanche`, `base`, `bnb`, `arbitrum`, `ethereum`, `solana`. A call may still pass another `chain`."},{"heading":"Discovery","anchor":"discovery","text":"Clients and registries can find the server without being given the URL:\n\n- **Server card** ([MCP SEP-2127](https://modelcontextprotocol.io/seps/2127-mcp-server-cards)): [`https://api.getchord.xyz/v1/mcp/server-card`](https://api.getchord.xyz/v1/mcp/server-card) gives the name, version, transport, protocol versions and the optional key header. It has no tool list: read that live with `tools/list`.\n- **AI catalog**: [`https://getchord.xyz/.well-known/ai-catalog.json`](https://getchord.xyz/.well-known/ai-catalog.json) lists this server and the [Docs MCP](/docs/agents/docs-mcp/), each with its card.\n- **API catalog** (RFC 9727): [`https://getchord.xyz/.well-known/api-catalog`](https://getchord.xyz/.well-known/api-catalog) links the REST API, both MCP servers, their docs and status.\n- **MCP Registry**: `io.github.getchordlabs/chord`."},{"heading":"Keys and limits","anchor":"keys-and-limits","text":"A tool call is an ordinary API request made as you. Without a key it runs at the anonymous limit of the address you call from. With `X-API-Key` (or `Authorization: Bearer <key>`, or `?apiKey=` for connectors that cannot set a header) it is metered and limited as that key. The handshake and the tool list are free. Keys come from the [developer page](https://getchord.xyz/developer)."},{"heading":"Tools","anchor":"tools","text":"| Tool | Arguments | Returns |\n| --- | --- | --- |\n| `chord_chains` | none | every chain with its native asset, anchors, and which capabilities it has |\n| `chord_status` | none | per chain: routing engine state and how far the newest indexed trade is behind the chain |\n| `chord_overview` | `chain` | last 24 hours: volume, swaps, venue share, hourly buckets |\n| `chord_tokens` | `chain`, `sort`, `limit` | the 24h token board |\n| `chord_search` | `chain`, `query` | tokens matching a symbol, name or address |\n| `chord_token` | `chain`, `address` | one token: price, volume, trades, pools or venues |\n| `chord_trades` | `chain`, `address`, `limit` | the newest swaps of a token |\n| `chord_candles` | `chain`, `address`, `tf`, `limit` | OHLCV candles from Chord's index |\n| `chord_wallet` | `chain`, `wallet` | realised and open PnL per token |\n| `chord_wallet_trades` | `chain`, `wallet` | a wallet's recent swaps |\n| `chord_smart_money` | `chain`, `days`, `limit` | wallets ranked by profit, bots removed |\n| `chord_holders` | `chain`, `address`, `limit` | balances by address |\n| `chord_lp_pools` | `chain`, `limit` | pools ranked for a liquidity provider |\n| `chord_lp_positions` | `chain`, `wallet` | a wallet's liquidity positions |\n| `chord_quote` | `chain`, `tokenIn`, `tokenOut`, `amount`, `slippageBps`, `taker` | the best quote; Chord's router first, another aggregator only when Chord cannot route |\n| `chord_swap_tx` | `quoteId` or the pair and amount, `taker` | the unsigned transaction, its approval and a simulation |\n| `chord_ask` | `question`, `wallet` | the analyst's researched answer (needs a key) |\n\nAmounts are integer strings in the token's smallest unit. The zero address is the native asset on EVM chains. Solana addresses are base58 and case-sensitive."},{"heading":"Not every chain has everything","anchor":"not-every-chain-has-everything","text":"`chord_chains` returns the live list. A tool called for a chain that lacks the capability answers with the chains that have it, for example: `base has no holders data. Chains with it: robinhood, arc.`\n\n| Capability | Monad | Robinhood | Arc | Avalanche | Base | BNB | Arbitrum | Ethereum | Solana |\n| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |\n| Overview, tokens, search, token, trades, candles, wallet | yes | yes | yes | yes | yes | yes | yes | yes | yes |\n| Wallet trades | yes | yes | yes | yes | yes | yes | yes | yes | yes |\n| Smart money | yes | yes | yes | no | no | no | no | no | yes |\n| Holders | no | yes | yes | no | no | no | no | no | no |\n| LP pools and positions | yes | yes | yes | no | no | no | no | no | yes |\n| Quote and swap transaction | yes | yes | yes | yes | yes | yes | yes | yes | no |\n\nSolana swaps are open on REST, not yet in the MCP tools: [`GET /v1/sol/trade/quote`](/docs/networks/solana/) answers with the unsigned transaction, the wallet signs it unchanged and `POST /v1/sol/trade/send` relays it. `chord_quote` called for Solana answers with those steps, and `chord_chains` lists Solana's `quote` and `swap` as those two routes.\n\nThe same table as data: [`GET /v1/chains`](/docs/api-reference/)."},{"heading":"What an answer looks like","anchor":"what-an-answer-looks-like","text":"Each tool returns one JSON text block: the chain, the REST route that produced it, and that route's body.\n\n```json\n{ \"chain\": \"arc\", \"route\": \"GET /v1/arc/overview\", \"data\": { \"chain\": 5042, \"last24h\": { \"volUsd\": 15625106.36, \"swaps\": 133764 } } }\n```\n\nThe `route` is the endpoint to call if you want the same data without MCP. Large answers are shortened by dropping rows from the end of long lists, with a count of what was dropped; the JSON is always valid."},{"heading":"Clients that only speak stdio","anchor":"clients-that-only-speak-stdio","text":"`chord-agent` in the Chord repository is a stdio bridge to the same hosted server: it lists and calls the tools above over HTTP, so it never goes out of date. It is not on npm yet. From a checkout:\n\n```bash\ncd packages/agent && pnpm install && pnpm build\nclaude mcp add chord -- node /absolute/path/to/packages/agent/dist/mcp.js\n```\n\nEnvironment: `CHORD_API_KEY` (optional), `CHORD_CHAIN` (optional default chain), `CHORD_API_URL` (default `https://api.getchord.xyz`)."},{"heading":"Related","anchor":"related","text":"- [Function calling](/docs/agents/function-calling/): the same tools as an OpenAI-style manifest.\n- [Docs MCP](/docs/agents/docs-mcp/): a second hosted server that answers questions about this documentation.\n- [Status](https://getchord.xyz/status): uptime of the API on every chain, measured every minute from outside Chord's servers."}]},{"kind":"page","path":"/docs/agents/skill/","url":"https://getchord.xyz/docs/agents/skill/","title":"Agent skill","description":"The Chord Agent Skill (SKILL.md + references + a small client) for Claude Code, Codex, OpenClaw, Hermes and any agent that reads the Agent Skills format.","markdown":"The Chord skill teaches an agent to use Chord the way a careful trader's assistant would: read prices, boards, candles, holders and wallet PnL on all eight EVM chains, quote a swap across every venue, and prepare an unsigned transaction, without ever signing anything itself. It follows the open [Agent Skills](https://agentskills.io) format, so Claude Code, Codex, OpenClaw, Hermes and other agents load it the same way.\n\n## Install\n\nOne command, no repository access needed. It unpacks the whole skill (SKILL.md, references, the client) into the folder your agent reads:\n\n```bash\nmkdir -p ~/.claude/skills/chord && curl -fsSL https://getchord.xyz/.well-known/agent-skills/chord.tar.gz | tar -xz -C ~/.claude/skills/chord\n```\n\nOr with the [`skills`](https://www.npmjs.com/package/skills) CLI, which reads the site's discovery index (`-a` picks the agent; `-g` installs for your user instead of the project):\n\n```bash\nnpx skills add https://getchord.xyz -s chord -a claude-code\n```\n\nTools that follow [Agent Skills discovery](https://github.com/cloudflare/agent-skills-discovery-rfc) find it from the domain alone: [`https://getchord.xyz/.well-known/agent-skills/index.json`](https://getchord.xyz/.well-known/agent-skills/index.json) lists the archive with its SHA-256 digest, so a client can check the bytes before loading them. `SKILL.md` by itself is at [`https://getchord.xyz/skill.md`](https://getchord.xyz/skill.md), and every file is also under `/docs/skills/chord/` (table below).\n\nThen, from that folder, `bash scripts/install.sh` copies it to `~/.agents/skills/chord` as well and prints the paths for OpenClaw (`~/.openclaw/skills/chord`) and Hermes (`~/.hermes/skills/chord`). For one project only: `bash scripts/install.sh --project /path/to/project` (writes `.claude/skills/chord` there). The installer is idempotent and only replaces a folder that already holds this skill.\n\nOptional: `export CHORD_API_KEY=...` raises the rate limit and unlocks [Chord Ask](/docs/agents/ask-api/). Data calls work without a key at 60 requests a minute. Create a key at [getchord.xyz/developer](https://getchord.xyz/developer), or in Ask at [getchord.xyz/ask](https://getchord.xyz/ask) (sign in, Settings, API Key). Both are the same kind of key and work for data and Ask.\n\n## What it covers\n\n| Ask your agent | What the skill does |\n| --- | --- |\n| \"Price of NVDA's stock token and its gap to the real stock\" | reads the Robinhood Chain stock screener: last on-chain price, reference price and its source, gap, off-hours share |\n| \"Quote 50 USDC to AERO on Base\" | resolves both tokens on the chain, converts the amount exactly, quotes every venue, shows fee, minimum received, impact and route |\n| \"Which tokens on Arc traded the most in the last 24h?\" | reads the chain board, flags wash and impostor rows and look-alike tickers |\n| \"What's moving on pump.fun? Who bought this Solana token?\" | reads Chord's Solana tape (read-only): board, token stats, traders, wallet PnL, with base58 mints kept exactly as given and the tape's gaps (no prop AMMs or order books) stated |\n| \"Who is buying ARGUS, where is support?\" | asks Chord Ask (needs a key) and relays the answer with its sources |\n| \"Swap it\" | shows a full confirmation summary, waits for an explicit yes in a new message, then builds the unsigned transaction for the user's own wallet |\n\nChains: Ethereum (1), Arbitrum One (42161), Base (8453), BNB Chain (56), Avalanche (43114), Monad (143), Robinhood Chain (4663), Arc (5042), plus Solana: data, and swaps through `/v1/sol/trade/*` (the user's wallet signs).\n\n## The safety model\n\n- **Read and prepare, never sign.** The skill never signs, broadcasts or asks for a private key. The swap transaction is unsigned and goes to the user's own wallet.\n- **Two-step confirmation.** The quote and summary come in one message; the transaction is built only after the user says yes in the next one. Any change to amount, token, chain, slippage or wallet voids the confirmation. The bundled client refuses to build without an explicit `--user-confirmed` flag and refuses quotes older than 60 seconds.\n- **Numbers only from the API**, with the chain, the source and the time named in every answer.\n- **Token safety.** Canonical addresses from the curated list (and CoinGecko on Avalanche, Base, BNB Chain, Arbitrum and Ethereum), bridged versus native tokens (USDC vs USDC.e or USDbC), look-alike tickers, airdrop and approval scams, address poisoning, stock token versus share.\n- **Analysis is not advice**: no buy calls, no promised returns, no stop-loss or take-profit recommendations.\n\n## Files\n\n| File | Contents |\n| --- | --- |\n| [`SKILL.md`](/docs/skills/chord/SKILL.md) | when to use it, chain table, intent routing, confirmation flow, answer and safety rules, errors |\n| [`references/data.md`](/docs/skills/chord/references/data.md) | market-data endpoints by chain |\n| [`references/quote-and-swap.md`](/docs/skills/chord/references/quote-and-swap.md) | quotes, the unsigned transaction, approvals, simulation |\n| [`references/stocks.md`](/docs/skills/chord/references/stocks.md) | Robinhood Chain stock tokens |\n| [`references/solana.md`](/docs/skills/chord/references/solana.md) | Solana: data and swaps |\n| [`references/ask.md`](/docs/skills/chord/references/ask.md) | Chord Ask over the API |\n| [`references/safety.md`](/docs/skills/chord/references/safety.md) | token and address safety |\n| [`references/examples.md`](/docs/skills/chord/references/examples.md) | real responses from the live API |\n| [`scripts/chord.py`](/docs/skills/chord/scripts/chord.py) | a dependency-free Python client (`token`, `price`, `board` — these three also on Solana — `stock`, `quote`, `swap-tx`, `simulate`, `ask`) |\n| [`scripts/install.sh`](/docs/skills/chord/scripts/install.sh) | the installer |\n\n## Other ways in\n\nThe skill sits on the same public API as the [MCP server](/docs/agents/mcp/), the [function-calling manifest](/docs/agents/function-calling/) and the [Docs MCP](/docs/agents/docs-mcp/). If your agent already has the `chord_*` tools, the skill's rules apply to them too: `chord_swap_tx` is the signing boundary.","sections":[{"heading":"","anchor":"","text":"The Chord skill teaches an agent to use Chord the way a careful trader's assistant would: read prices, boards, candles, holders and wallet PnL on all eight EVM chains, quote a swap across every venue, and prepare an unsigned transaction, without ever signing anything itself. It follows the open [Agent Skills](https://agentskills.io) format, so Claude Code, Codex, OpenClaw, Hermes and other agents load it the same way."},{"heading":"Install","anchor":"install","text":"One command, no repository access needed. It unpacks the whole skill (SKILL.md, references, the client) into the folder your agent reads:\n\n```bash\nmkdir -p ~/.claude/skills/chord && curl -fsSL https://getchord.xyz/.well-known/agent-skills/chord.tar.gz | tar -xz -C ~/.claude/skills/chord\n```\n\nOr with the [`skills`](https://www.npmjs.com/package/skills) CLI, which reads the site's discovery index (`-a` picks the agent; `-g` installs for your user instead of the project):\n\n```bash\nnpx skills add https://getchord.xyz -s chord -a claude-code\n```\n\nTools that follow [Agent Skills discovery](https://github.com/cloudflare/agent-skills-discovery-rfc) find it from the domain alone: [`https://getchord.xyz/.well-known/agent-skills/index.json`](https://getchord.xyz/.well-known/agent-skills/index.json) lists the archive with its SHA-256 digest, so a client can check the bytes before loading them. `SKILL.md` by itself is at [`https://getchord.xyz/skill.md`](https://getchord.xyz/skill.md), and every file is also under `/docs/skills/chord/` (table below).\n\nThen, from that folder, `bash scripts/install.sh` copies it to `~/.agents/skills/chord` as well and prints the paths for OpenClaw (`~/.openclaw/skills/chord`) and Hermes (`~/.hermes/skills/chord`). For one project only: `bash scripts/install.sh --project /path/to/project` (writes `.claude/skills/chord` there). The installer is idempotent and only replaces a folder that already holds this skill.\n\nOptional: `export CHORD_API_KEY=...` raises the rate limit and unlocks [Chord Ask](/docs/agents/ask-api/). Data calls work without a key at 60 requests a minute. Create a key at [getchord.xyz/developer](https://getchord.xyz/developer), or in Ask at [getchord.xyz/ask](https://getchord.xyz/ask) (sign in, Settings, API Key). Both are the same kind of key and work for data and Ask."},{"heading":"What it covers","anchor":"what-it-covers","text":"| Ask your agent | What the skill does |\n| --- | --- |\n| \"Price of NVDA's stock token and its gap to the real stock\" | reads the Robinhood Chain stock screener: last on-chain price, reference price and its source, gap, off-hours share |\n| \"Quote 50 USDC to AERO on Base\" | resolves both tokens on the chain, converts the amount exactly, quotes every venue, shows fee, minimum received, impact and route |\n| \"Which tokens on Arc traded the most in the last 24h?\" | reads the chain board, flags wash and impostor rows and look-alike tickers |\n| \"What's moving on pump.fun? Who bought this Solana token?\" | reads Chord's Solana tape (read-only): board, token stats, traders, wallet PnL, with base58 mints kept exactly as given and the tape's gaps (no prop AMMs or order books) stated |\n| \"Who is buying ARGUS, where is support?\" | asks Chord Ask (needs a key) and relays the answer with its sources |\n| \"Swap it\" | shows a full confirmation summary, waits for an explicit yes in a new message, then builds the unsigned transaction for the user's own wallet |\n\nChains: Ethereum (1), Arbitrum One (42161), Base (8453), BNB Chain (56), Avalanche (43114), Monad (143), Robinhood Chain (4663), Arc (5042), plus Solana: data, and swaps through `/v1/sol/trade/*` (the user's wallet signs)."},{"heading":"The safety model","anchor":"the-safety-model","text":"- **Read and prepare, never sign.** The skill never signs, broadcasts or asks for a private key. The swap transaction is unsigned and goes to the user's own wallet.\n- **Two-step confirmation.** The quote and summary come in one message; the transaction is built only after the user says yes in the next one. Any change to amount, token, chain, slippage or wallet voids the confirmation. The bundled client refuses to build without an explicit `--user-confirmed` flag and refuses quotes older than 60 seconds.\n- **Numbers only from the API**, with the chain, the source and the time named in every answer.\n- **Token safety.** Canonical addresses from the curated list (and CoinGecko on Avalanche, Base, BNB Chain, Arbitrum and Ethereum), bridged versus native tokens (USDC vs USDC.e or USDbC), look-alike tickers, airdrop and approval scams, address poisoning, stock token versus share.\n- **Analysis is not advice**: no buy calls, no promised returns, no stop-loss or take-profit recommendations."},{"heading":"Files","anchor":"files","text":"| File | Contents |\n| --- | --- |\n| [`SKILL.md`](/docs/skills/chord/SKILL.md) | when to use it, chain table, intent routing, confirmation flow, answer and safety rules, errors |\n| [`references/data.md`](/docs/skills/chord/references/data.md) | market-data endpoints by chain |\n| [`references/quote-and-swap.md`](/docs/skills/chord/references/quote-and-swap.md) | quotes, the unsigned transaction, approvals, simulation |\n| [`references/stocks.md`](/docs/skills/chord/references/stocks.md) | Robinhood Chain stock tokens |\n| [`references/solana.md`](/docs/skills/chord/references/solana.md) | Solana: data and swaps |\n| [`references/ask.md`](/docs/skills/chord/references/ask.md) | Chord Ask over the API |\n| [`references/safety.md`](/docs/skills/chord/references/safety.md) | token and address safety |\n| [`references/examples.md`](/docs/skills/chord/references/examples.md) | real responses from the live API |\n| [`scripts/chord.py`](/docs/skills/chord/scripts/chord.py) | a dependency-free Python client (`token`, `price`, `board` — these three also on Solana — `stock`, `quote`, `swap-tx`, `simulate`, `ask`) |\n| [`scripts/install.sh`](/docs/skills/chord/scripts/install.sh) | the installer |"},{"heading":"Other ways in","anchor":"other-ways-in","text":"The skill sits on the same public API as the [MCP server](/docs/agents/mcp/), the [function-calling manifest](/docs/agents/function-calling/) and the [Docs MCP](/docs/agents/docs-mcp/). If your agent already has the `chord_*` tools, the skill's rules apply to them too: `chord_swap_tx` is the signing boundary."}]},{"kind":"page","path":"/docs/build/","url":"https://getchord.xyz/docs/build/","title":"Add Chord to your app","description":"The conventions that hold on every endpoint — chains, addresses, amounts, timestamps, coverage flags, caching and errors — so you read them once.","markdown":"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.\n\n## Chains\n\nChord 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.\n\n| Chain | id | Gas | Stable anchor | Data family | Notes |\n| --- | --- | --- | --- | --- | --- |\n| 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. |\n| Robinhood Chain | `4663` | ETH | USDG (6 decimals) | `/v1/rh/*` | Tokenized stocks and ETFs; the stocks page. |\n| Monad | `143` | MON | USDC (6 decimals) | `/v1/tokens/*`, `/v1/markets/monad/hourly` | The default when `chain` is omitted. |\n| Avalanche | `43114` | AVAX | USDC, USDt (6 decimals) | `/v1/chains/avalanche/*` | |\n| Base | `8453` | ETH | USDC, USDT (6 decimals) | `/v1/chains/base/*` | |\n| BNB Chain | `56` | BNB | USDT, USDC (**18 decimals**) | `/v1/chains/bnb/*` | Swaps under $100 are not indexed. |\n| Arbitrum | `42161` | ETH | USDC, USDT0 (6 decimals) | `/v1/chains/arbitrum/*` | |\n| Ethereum | `1` | ETH | USDC, USDT (6 decimals), DAI (18) | `/v1/chains/ethereum/*` | USDT: approve 0 first when an old allowance is left |\n| Solana | none | SOL | USDC | `/v1/chains/solana/*`, `/v1/sol/trade/*` | Swaps through Chord's own router and Jupiter, best of both. |\n\n`chain` is required in practice on `/quote`, `/swap`, `/tokens`, `/smart-money/top`, `/portfolio/{wallet}/trades`, `/portfolio/{wallet}/pnl-calendar` and every `/lp/*` call: omitting it selects Monad (on `/portfolio/{wallet}/pnl` it merges Monad and Robinhood Chain). `GET /portfolio/{wallet}` and `/portfolio/{wallet}/activity` take `chains` instead and ignore `chain`: a comma list of chain ids and `solana` (which needs `sol`, the wallet's Solana address); omitted, every EVM chain, plus Solana when `sol` is given. `GET /v1/chains` lists which route serves each capability on each chain. Details per chain, with contracts and venues, are under [Networks](/docs/networks/).\n\n## Addresses and amounts\n\n- 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.\n- 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. `amount` in `GET /portfolio/{wallet}` and `/portfolio/{wallet}/activity` is in whole tokens instead, as a decimal string.\n- USD figures in read endpoints are numbers, already scaled.\n\n## Timestamps\n\nUnix seconds, UTC. Hourly buckets are named `hour`, daily ones `day`, and both are the bucket's start. `updatedAt` is milliseconds and says when the server built the answer, and so is every time in `GET /portfolio/{wallet}` and `/portfolio/{wallet}/activity` (`asOf`, `fromTs`, `tapeFromTs`, `ts`).\n\n## Coverage, not the clock\n\nRead 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/).\n\n## Honesty flags\n\nChord 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.\n\n## Caching\n\nRolled-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.\n\nResponses that are safe to cache say so with `Cache-Control: public, max-age=…`; the rest send none.\n\n## Errors\n\nEvery 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/).\n\n## Rate limit headers\n\nEvery 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/).\n\n## CORS\n\nOpen 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.\n\n## Logos\n\nEvery 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.","sections":[{"heading":"","anchor":"","text":"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."},{"heading":"Chains","anchor":"chains","text":"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.\n\n| Chain | id | Gas | Stable anchor | Data family | Notes |\n| --- | --- | --- | --- | --- | --- |\n| 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. |\n| Robinhood Chain | `4663` | ETH | USDG (6 decimals) | `/v1/rh/*` | Tokenized stocks and ETFs; the stocks page. |\n| Monad | `143` | MON | USDC (6 decimals) | `/v1/tokens/*`, `/v1/markets/monad/hourly` | The default when `chain` is omitted. |\n| Avalanche | `43114` | AVAX | USDC, USDt (6 decimals) | `/v1/chains/avalanche/*` | |\n| Base | `8453` | ETH | USDC, USDT (6 decimals) | `/v1/chains/base/*` | |\n| BNB Chain | `56` | BNB | USDT, USDC (**18 decimals**) | `/v1/chains/bnb/*` | Swaps under $100 are not indexed. |\n| Arbitrum | `42161` | ETH | USDC, USDT0 (6 decimals) | `/v1/chains/arbitrum/*` | |\n| Ethereum | `1` | ETH | USDC, USDT (6 decimals), DAI (18) | `/v1/chains/ethereum/*` | USDT: approve 0 first when an old allowance is left |\n| Solana | none | SOL | USDC | `/v1/chains/solana/*`, `/v1/sol/trade/*` | Swaps through Chord's own router and Jupiter, best of both. |\n\n`chain` is required in practice on `/quote`, `/swap`, `/tokens`, `/smart-money/top`, `/portfolio/{wallet}/trades`, `/portfolio/{wallet}/pnl-calendar` and every `/lp/*` call: omitting it selects Monad (on `/portfolio/{wallet}/pnl` it merges Monad and Robinhood Chain). `GET /portfolio/{wallet}` and `/portfolio/{wallet}/activity` take `chains` instead and ignore `chain`: a comma list of chain ids and `solana` (which needs `sol`, the wallet's Solana address); omitted, every EVM chain, plus Solana when `sol` is given. `GET /v1/chains` lists which route serves each capability on each chain. Details per chain, with contracts and venues, are under [Networks](/docs/networks/)."},{"heading":"Addresses and amounts","anchor":"addresses-and-amounts","text":"- 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.\n- 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. `amount` in `GET /portfolio/{wallet}` and `/portfolio/{wallet}/activity` is in whole tokens instead, as a decimal string.\n- USD figures in read endpoints are numbers, already scaled."},{"heading":"Timestamps","anchor":"timestamps","text":"Unix seconds, UTC. Hourly buckets are named `hour`, daily ones `day`, and both are the bucket's start. `updatedAt` is milliseconds and says when the server built the answer, and so is every time in `GET /portfolio/{wallet}` and `/portfolio/{wallet}/activity` (`asOf`, `fromTs`, `tapeFromTs`, `ts`)."},{"heading":"Coverage, not the clock","anchor":"coverage-not-the-clock","text":"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/)."},{"heading":"Honesty flags","anchor":"honesty-flags","text":"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."},{"heading":"Caching","anchor":"caching","text":"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.\n\nResponses that are safe to cache say so with `Cache-Control: public, max-age=…`; the rest send none."},{"heading":"Errors","anchor":"errors","text":"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/)."},{"heading":"Rate limit headers","anchor":"rate-limit-headers","text":"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/)."},{"heading":"CORS","anchor":"cors","text":"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."},{"heading":"Logos","anchor":"logos","text":"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."}]},{"kind":"page","path":"/docs/clients/","url":"https://getchord.xyz/docs/clients/","title":"Clients and codegen","description":"Generate a typed client from the OpenAPI document, or call the API with fetch. There is no SDK to install.","markdown":"The whole API is one OpenAPI 3.1 document, kept in step with the routes:\n\n```\nhttps://getchord.xyz/docs/openapi.json\n```\n\nIt has every endpoint in this reference, with parameter constraints, response schemas and the same real examples. Feed it to a generator or to a model.\n\n## TypeScript with openapi-typescript\n\n```bash\nnpx openapi-typescript https://getchord.xyz/docs/openapi.json -o chord.d.ts\n```\n\n```ts\n\nconst chord = createClient<paths>({ baseUrl: \"https://api.getchord.xyz/v1\", headers: { \"X-API-Key\": process.env.CHORD_API_KEY ?? \"\" } });\n\nconst { data } = await chord.GET(\"/arc/tokens\", { params: { query: { limit: 20, sort: \"volume\" } } });\nfor (const t of data?.tokens ?? []) console.log(t.symbol, t.priceUsd, t.volume24h, t.flags ?? []);\n```\n\n## Plain fetch\n\nNothing in the API needs more than `fetch`. Amounts are strings, so use `BigInt` for arithmetic.\n\n```ts\nconst A = \"https://api.getchord.xyz/v1\";\nconst quote = await fetch(`${A}/quote?chain=5042&inputMint=0x3600000000000000000000000000000000000000&outputMint=0x171a4217b86a807a64eb94757db6849fb4bdbaa0&amount=5000000&slippageBps=100`).then((r) => r.json());\nif (quote.routePlan.length === 0) throw new Error(quote.noRouteReason);\nconst { transaction } = await fetch(`${A}/swap`, { method: \"POST\", headers: { \"Content-Type\": \"application/json\" }, body: JSON.stringify({ quoteResponse: quote, userPublicKey: wallet, chain: 5042 }) }).then((r) => r.json());\n```\n\n## Python\n\n```python\n\nA = \"https://api.getchord.xyz/v1\"\nr = requests.get(f\"{A}/arc/trending\", params={\"limit\": 10}, headers={\"X-API-Key\": KEY}, timeout=20)\nr.raise_for_status()\nfor t in r.json()[\"tokens\"]:\n    print(t[\"symbol\"], t[\"score\"], t[\"change1hPct\"])\n```\n\n## Other generators\n\nAny OpenAPI 3.1 generator works: `openapi-generator-cli` for Go, Java, Rust or Swift, `orval` or `oazapfts` for TypeScript, `datamodel-codegen` for Pydantic models. The document uses `oneOf`, `allOf` and nullable type arrays (`[\"number\", \"null\"]`), so pick a generator that understands 3.1.\n\n## Agents\n\nIf the caller is a model, hand it the document or [llms.txt](/docs/agents/llms-txt/), or use the [MCP server](/docs/agents/mcp/) and the [function-calling manifest](/docs/agents/function-calling/), which wrap the API as tools.","sections":[{"heading":"","anchor":"","text":"The whole API is one OpenAPI 3.1 document, kept in step with the routes:\n\n```\nhttps://getchord.xyz/docs/openapi.json\n```\n\nIt has every endpoint in this reference, with parameter constraints, response schemas and the same real examples. Feed it to a generator or to a model."},{"heading":"TypeScript with openapi-typescript","anchor":"typescript-with-openapi-typescript","text":"```bash\nnpx openapi-typescript https://getchord.xyz/docs/openapi.json -o chord.d.ts\n```\n\n```ts\n\nconst chord = createClient<paths>({ baseUrl: \"https://api.getchord.xyz/v1\", headers: { \"X-API-Key\": process.env.CHORD_API_KEY ?? \"\" } });\n\nconst { data } = await chord.GET(\"/arc/tokens\", { params: { query: { limit: 20, sort: \"volume\" } } });\nfor (const t of data?.tokens ?? []) console.log(t.symbol, t.priceUsd, t.volume24h, t.flags ?? []);\n```"},{"heading":"Plain fetch","anchor":"plain-fetch","text":"Nothing in the API needs more than `fetch`. Amounts are strings, so use `BigInt` for arithmetic.\n\n```ts\nconst A = \"https://api.getchord.xyz/v1\";\nconst quote = await fetch(`${A}/quote?chain=5042&inputMint=0x3600000000000000000000000000000000000000&outputMint=0x171a4217b86a807a64eb94757db6849fb4bdbaa0&amount=5000000&slippageBps=100`).then((r) => r.json());\nif (quote.routePlan.length === 0) throw new Error(quote.noRouteReason);\nconst { transaction } = await fetch(`${A}/swap`, { method: \"POST\", headers: { \"Content-Type\": \"application/json\" }, body: JSON.stringify({ quoteResponse: quote, userPublicKey: wallet, chain: 5042 }) }).then((r) => r.json());\n```"},{"heading":"Python","anchor":"python","text":"```python\n\nA = \"https://api.getchord.xyz/v1\"\nr = requests.get(f\"{A}/arc/trending\", params={\"limit\": 10}, headers={\"X-API-Key\": KEY}, timeout=20)\nr.raise_for_status()\nfor t in r.json()[\"tokens\"]:\n    print(t[\"symbol\"], t[\"score\"], t[\"change1hPct\"])\n```"},{"heading":"Other generators","anchor":"other-generators","text":"Any OpenAPI 3.1 generator works: `openapi-generator-cli` for Go, Java, Rust or Swift, `orval` or `oazapfts` for TypeScript, `datamodel-codegen` for Pydantic models. The document uses `oneOf`, `allOf` and nullable type arrays (`[\"number\", \"null\"]`), so pick a generator that understands 3.1."},{"heading":"Agents","anchor":"agents","text":"If the caller is a model, hand it the document or [llms.txt](/docs/agents/llms-txt/), or use the [MCP server](/docs/agents/mcp/) and the [function-calling manifest](/docs/agents/function-calling/), which wrap the API as tools."}]},{"kind":"page","path":"/docs/concepts/authentication/","url":"https://getchord.xyz/docs/concepts/authentication/","title":"Authentication","description":"Reads need no key. A key raises your rate limit, meters usage, and unlocks the Ask agent API.","markdown":"Chord's API is open to read. Authentication exists to give you a limit of your own and to meter what you use.\n\n## The key\n\nCreate a key on [getchord.xyz/developer](https://getchord.xyz/developer) after a Google sign-in, or in Ask (sign in at [getchord.xyz/ask](https://getchord.xyz/ask), Settings, API Key). Both pages issue the same kind of key, valid for the data API and for Ask. It is shown once. Send it on every request as a header:\n\n```bash\ncurl -H \"X-API-Key: YOUR_KEY\" https://api.getchord.xyz/v1/arc/trending\n```\n\nA missing or unknown key is **not rejected** on read endpoints: the request simply gets the anonymous per-IP limit. Only two things require a key:\n\n- `POST /v1/ask` — the [Ask agent API](/docs/agents/ask-api/) (a Google session bearer also works; that is what the browser uses).\n- `?only=` on `/v1/quote` — a single-venue debug lever that bypasses the routing safety gates.\n\nCheck what a key can do with `GET /v1/me`:\n\n```json\n{ \"email\": \"you@example.com\", \"tier\": \"build\", \"limits\": { \"rpm\": 100, \"monthly\": 16000, \"priceUsd\": 99, \"label\": \"Build\" }, \"usage\": { \"today\": 812, \"month\": 9210 } }\n```\n\n## Keys in browsers\n\nCORS is open, so a browser can send `X-API-Key` directly. A key in a public bundle is a key anyone can copy; if the limit matters to you, call the API from your server or a small proxy and keep the key there. Reads that need no limit can go straight from the browser without a key.\n\n## Sessions\n\nThe Chord app signs users in with Google and mints a short bearer (`nts_…`) for its own surfaces: the developer page, the Ask chat, reports and LP alerts. Agents and integrations do not use sessions; use a key.\n\n## Plans\n\n| Plan | Requests a minute | Calls in any 30 days | Price |\n| --- | --- | --- | --- |\n| Free | 60 | 300 | $0 |\n| Build | 100 | 16,000 | $99 a month |\n| Grow | 150 | 144,000 | $696 a month |\n| Enterprise | custom | custom | talk to us |\n\nEvery key starts on Free. A plan covers all keys on an account together: their calls are counted as one, over the trailing 30 days, and a call past the package answers `429 QUOTA_EXCEEDED` until the window has room again. No endpoint is paywalled; plans change how much you can call.\n\nBuild and Grow are bought in the app, under Settings, API Key: one transfer of USDC (on Arc, Base, Monad, Avalanche, BNB Chain, Arbitrum or Ethereum) or of USDG (on Robinhood Chain) from your Chord wallet or from any other wallet. A plan runs 30 days, or a year at 20% less, and does not renew by itself. See the [pricing page](https://getchord.xyz/pricing).","sections":[{"heading":"","anchor":"","text":"Chord's API is open to read. Authentication exists to give you a limit of your own and to meter what you use."},{"heading":"The key","anchor":"the-key","text":"Create a key on [getchord.xyz/developer](https://getchord.xyz/developer) after a Google sign-in, or in Ask (sign in at [getchord.xyz/ask](https://getchord.xyz/ask), Settings, API Key). Both pages issue the same kind of key, valid for the data API and for Ask. It is shown once. Send it on every request as a header:\n\n```bash\ncurl -H \"X-API-Key: YOUR_KEY\" https://api.getchord.xyz/v1/arc/trending\n```\n\nA missing or unknown key is **not rejected** on read endpoints: the request simply gets the anonymous per-IP limit. Only two things require a key:\n\n- `POST /v1/ask` — the [Ask agent API](/docs/agents/ask-api/) (a Google session bearer also works; that is what the browser uses).\n- `?only=` on `/v1/quote` — a single-venue debug lever that bypasses the routing safety gates.\n\nCheck what a key can do with `GET /v1/me`:\n\n```json\n{ \"email\": \"you@example.com\", \"tier\": \"build\", \"limits\": { \"rpm\": 100, \"monthly\": 16000, \"priceUsd\": 99, \"label\": \"Build\" }, \"usage\": { \"today\": 812, \"month\": 9210 } }\n```"},{"heading":"Keys in browsers","anchor":"keys-in-browsers","text":"CORS is open, so a browser can send `X-API-Key` directly. A key in a public bundle is a key anyone can copy; if the limit matters to you, call the API from your server or a small proxy and keep the key there. Reads that need no limit can go straight from the browser without a key."},{"heading":"Sessions","anchor":"sessions","text":"The Chord app signs users in with Google and mints a short bearer (`nts_…`) for its own surfaces: the developer page, the Ask chat, reports and LP alerts. Agents and integrations do not use sessions; use a key."},{"heading":"Plans","anchor":"plans","text":"| Plan | Requests a minute | Calls in any 30 days | Price |\n| --- | --- | --- | --- |\n| Free | 60 | 300 | $0 |\n| Build | 100 | 16,000 | $99 a month |\n| Grow | 150 | 144,000 | $696 a month |\n| Enterprise | custom | custom | talk to us |\n\nEvery key starts on Free. A plan covers all keys on an account together: their calls are counted as one, over the trailing 30 days, and a call past the package answers `429 QUOTA_EXCEEDED` until the window has room again. No endpoint is paywalled; plans change how much you can call.\n\nBuild and Grow are bought in the app, under Settings, API Key: one transfer of USDC (on Arc, Base, Monad, Avalanche, BNB Chain, Arbitrum or Ethereum) or of USDG (on Robinhood Chain) from your Chord wallet or from any other wallet. A plan runs 30 days, or a year at 20% less, and does not renew by itself. See the [pricing page](https://getchord.xyz/pricing)."}]},{"kind":"page","path":"/docs/concepts/chains-and-amounts/","url":"https://getchord.xyz/docs/concepts/chains-and-amounts/","title":"Chains, addresses and amounts","description":"How Arc's native USDC, the zero address and decimals work across the API, and what differs on Robinhood Chain.","markdown":"## Arc (chain 5042)\n\nArc is Circle's stablecoin-native chain: **the gas token is USDC**. It has two faces, and the API takes one of them.\n\n| Face | Address | Decimals | Where you see it |\n| --- | --- | --- | --- |\n| Native USDC | — (balance via `eth_getBalance`) | 18 | wallet balances, `value` on transactions, Uniswap V4 `currency0 = address(0)` pools |\n| USDC predeploy | `0x3600000000000000000000000000000000000000` | 6 | the ERC-20 interface of the same balance; every V2 / V3 pool; the API |\n\nThey are one balance: `balanceOf(predeploy) == nativeBalance / 1e12`. There is no wrapped-native contract and nothing to wrap. The API therefore treats the zero address as an **alias for the predeploy** on Arc: send either, get the same route, and the transaction always has `value: \"0\"` because the router pulls the predeploy by `transferFrom`. Approve the router on the predeploy like any ERC-20.\n\nOther anchors: EURC `0xbef5f6d51cb62b58e6a8f77868681825c6fe21c1` (6 decimals, tagged `fx`) and VIRTUAL `0x8c4252c87081c88c6ad57d6dd97e1cafebf842b7` (the quote asset of the Virtuals launcher pools, priced from its own USDC prints). Protocol fee on USDC and EURC is 0 bps.\n\n## Robinhood Chain (chain 4663)\n\nAn ordinary EVM chain: native ETH is the zero address, WETH `0x0Bd7D308f8E1639FAb988df18A8011f41EAcAD73` wraps it, and the stable anchor is USDG `0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168` (6 decimals). Tokenized stocks are 18-decimal tokens tagged `stock` (NVDA `0xd0601CE157Db5bdC3162BbaC2a2C8aF5320D9EEC`, AAPL `0xaF3D76f1834A1d425780943C99Ea8A608f8a93f9`, …). WETH, USDG and every stock are 0 bps.\n\n## Monad, Avalanche, Base, BNB Chain, Arbitrum and Ethereum (143, 43114, 8453, 56, 42161, 1)\n\nOrdinary EVM chains: the zero address is the native coin (MON, AVAX, ETH or BNB), sent as `value`; WMON, WAVAX, WETH and WBNB wrap it, and the router wraps and unwraps for you. The dollar anchors are USDC (and USDT where the chain has it), 6 decimals on Monad, Avalanche, Base, Arbitrum and Ethereum, **18 decimals on BNB Chain**. Ethereum's USDT refuses a new approval while an old one is left: approve 0 first (`approval.resetFirst` on `/v1/meta`). Anchors and contracts per chain: [Networks](/docs/networks/).\n\n## Amounts\n\nEvery amount the API takes or returns for a token is a **decimal string in the token's smallest unit**. Never a float, never scientific notation.\n\n```\n5 USDC on Arc        → \"5000000\"            (6 decimals)\n0.01 ETH on 4663     → \"10000000000000000\"  (18 decimals)\n0.005 cirBTC         → \"500000\"             (8 decimals)\n```\n\nRead decimals from the token list or the token row. Chord never defaults to 18, and neither should you.\n\n```ts\nconst { tokens } = await fetch(\"https://api.getchord.xyz/v1/tokens?chain=5042\").then((r) => r.json());\nconst usdc = tokens.find((t) => t.symbol === \"USDC\");\nconst amount = (5n * 10n ** BigInt(usdc.decimals)).toString(); // \"5000000\"\n```\n\nUSD figures in read endpoints (`volume24h`, `priceUsd`, `usd`) are plain numbers.\n\n## Addresses\n\nHex, case-insensitive on input; the API returns Arc addresses lower-cased and Robinhood Chain list addresses checksummed. Compare lower-cased. Pool identities are 20-byte addresses for V2 / V3 pools and **32-byte pool ids** for Uniswap V4 — any `pool` parameter accepts both, and any `pool` field may hold either. Treat a pool as an opaque string; only an explorer link needs to know which it is.\n\n## The `chain` parameter\n\n| Endpoint family | `chain` |\n| --- | --- |\n| `/quote`, `/swap`, `/swap/calldata`, `/swap/simulate` | `5042`, `4663`, `143`, `43114`, `8453`, `56`, `42161` or `1`. The default is `143`: always pass it. |\n| `/tokens` | `5042` or `4663`; omitted, the Monad list. |\n| `/tokens/market` | `4663` or `5042`. Omitted, it answers for Monad. |\n| `/tokens/board` | `143`. |\n| `/tokens/search` | `4663`, `5042`, `43114`, `8453`, `56`, `42161` or `1`. Omitted (or `143`), it is Monad off-list discovery. Arc also has `/arc/tokens/search` with full board rows. |\n| `/candles` | `5042`, `4663`, `143`, `43114`, `8453`, `56`, `42161` or `1`. The default is `143`: always pass it. |\n| `/chains/{chain}/*` | in the path: `avalanche` or `43114`, `base` or `8453`, `bnb` or `56`, `arbitrum` or `42161`, `ethereum` or `1` (and `solana`). |\n| `/tokens/chart`, `/tokens/trades`, `/tokens/stats`, `/logo` | none (address-keyed) — `/logo` takes the chain in the path. |\n| `/smart-money/top`, `/portfolio/{wallet}/pnl`, `/portfolio/{wallet}/trades`, `/portfolio/{wallet}/pnl-calendar`, `/lp/*` | `5042`, `4663` or `143`. `/portfolio/{wallet}/pnl` also takes `all`, its default: Monad and Robinhood Chain merged. |\n| `/portfolio/{wallet}`, `/portfolio/{wallet}/activity` | none: `chain` is ignored. They take `chains`, a comma list of `143`, `4663`, `5042`, `43114`, `8453`, `56`, `42161`, `1` and `solana` (which needs `sol`, the wallet's Solana address). Omitted or `all`, every EVM chain, plus Solana when `sol` is given. |\n| `/arc/*` | none; always 5042. |\n| `/rh/*` | none; always 4663. |\n| `/points/*`, `/ask/*` | none; always 5042. |","sections":[{"heading":"Arc (chain 5042)","anchor":"arc-chain-5042","text":"Arc is Circle's stablecoin-native chain: **the gas token is USDC**. It has two faces, and the API takes one of them.\n\n| Face | Address | Decimals | Where you see it |\n| --- | --- | --- | --- |\n| Native USDC | — (balance via `eth_getBalance`) | 18 | wallet balances, `value` on transactions, Uniswap V4 `currency0 = address(0)` pools |\n| USDC predeploy | `0x3600000000000000000000000000000000000000` | 6 | the ERC-20 interface of the same balance; every V2 / V3 pool; the API |\n\nThey are one balance: `balanceOf(predeploy) == nativeBalance / 1e12`. There is no wrapped-native contract and nothing to wrap. The API therefore treats the zero address as an **alias for the predeploy** on Arc: send either, get the same route, and the transaction always has `value: \"0\"` because the router pulls the predeploy by `transferFrom`. Approve the router on the predeploy like any ERC-20.\n\nOther anchors: EURC `0xbef5f6d51cb62b58e6a8f77868681825c6fe21c1` (6 decimals, tagged `fx`) and VIRTUAL `0x8c4252c87081c88c6ad57d6dd97e1cafebf842b7` (the quote asset of the Virtuals launcher pools, priced from its own USDC prints). Protocol fee on USDC and EURC is 0 bps."},{"heading":"Robinhood Chain (chain 4663)","anchor":"robinhood-chain-chain-4663","text":"An ordinary EVM chain: native ETH is the zero address, WETH `0x0Bd7D308f8E1639FAb988df18A8011f41EAcAD73` wraps it, and the stable anchor is USDG `0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168` (6 decimals). Tokenized stocks are 18-decimal tokens tagged `stock` (NVDA `0xd0601CE157Db5bdC3162BbaC2a2C8aF5320D9EEC`, AAPL `0xaF3D76f1834A1d425780943C99Ea8A608f8a93f9`, …). WETH, USDG and every stock are 0 bps."},{"heading":"Monad, Avalanche, Base, BNB Chain, Arbitrum and Ethereum (143, 43114, 8453, 56, 42161, 1)","anchor":"monad-avalanche-base-bnb-chain-arbitrum-and-ethereum-143-43114-8453-56-42161-1","text":"Ordinary EVM chains: the zero address is the native coin (MON, AVAX, ETH or BNB), sent as `value`; WMON, WAVAX, WETH and WBNB wrap it, and the router wraps and unwraps for you. The dollar anchors are USDC (and USDT where the chain has it), 6 decimals on Monad, Avalanche, Base, Arbitrum and Ethereum, **18 decimals on BNB Chain**. Ethereum's USDT refuses a new approval while an old one is left: approve 0 first (`approval.resetFirst` on `/v1/meta`). Anchors and contracts per chain: [Networks](/docs/networks/)."},{"heading":"Amounts","anchor":"amounts","text":"Every amount the API takes or returns for a token is a **decimal string in the token's smallest unit**. Never a float, never scientific notation.\n\n```\n5 USDC on Arc        → \"5000000\"            (6 decimals)\n0.01 ETH on 4663     → \"10000000000000000\"  (18 decimals)\n0.005 cirBTC         → \"500000\"             (8 decimals)\n```\n\nRead decimals from the token list or the token row. Chord never defaults to 18, and neither should you.\n\n```ts\nconst { tokens } = await fetch(\"https://api.getchord.xyz/v1/tokens?chain=5042\").then((r) => r.json());\nconst usdc = tokens.find((t) => t.symbol === \"USDC\");\nconst amount = (5n * 10n ** BigInt(usdc.decimals)).toString(); // \"5000000\"\n```\n\nUSD figures in read endpoints (`volume24h`, `priceUsd`, `usd`) are plain numbers."},{"heading":"Addresses","anchor":"addresses","text":"Hex, case-insensitive on input; the API returns Arc addresses lower-cased and Robinhood Chain list addresses checksummed. Compare lower-cased. Pool identities are 20-byte addresses for V2 / V3 pools and **32-byte pool ids** for Uniswap V4 — any `pool` parameter accepts both, and any `pool` field may hold either. Treat a pool as an opaque string; only an explorer link needs to know which it is."},{"heading":"The chain parameter","anchor":"the-chain-parameter","text":"| Endpoint family | `chain` |\n| --- | --- |\n| `/quote`, `/swap`, `/swap/calldata`, `/swap/simulate` | `5042`, `4663`, `143`, `43114`, `8453`, `56`, `42161` or `1`. The default is `143`: always pass it. |\n| `/tokens` | `5042` or `4663`; omitted, the Monad list. |\n| `/tokens/market` | `4663` or `5042`. Omitted, it answers for Monad. |\n| `/tokens/board` | `143`. |\n| `/tokens/search` | `4663`, `5042`, `43114`, `8453`, `56`, `42161` or `1`. Omitted (or `143`), it is Monad off-list discovery. Arc also has `/arc/tokens/search` with full board rows. |\n| `/candles` | `5042`, `4663`, `143`, `43114`, `8453`, `56`, `42161` or `1`. The default is `143`: always pass it. |\n| `/chains/{chain}/*` | in the path: `avalanche` or `43114`, `base` or `8453`, `bnb` or `56`, `arbitrum` or `42161`, `ethereum` or `1` (and `solana`). |\n| `/tokens/chart`, `/tokens/trades`, `/tokens/stats`, `/logo` | none (address-keyed) — `/logo` takes the chain in the path. |\n| `/smart-money/top`, `/portfolio/{wallet}/pnl`, `/portfolio/{wallet}/trades`, `/portfolio/{wallet}/pnl-calendar`, `/lp/*` | `5042`, `4663` or `143`. `/portfolio/{wallet}/pnl` also takes `all`, its default: Monad and Robinhood Chain merged. |\n| `/portfolio/{wallet}`, `/portfolio/{wallet}/activity` | none: `chain` is ignored. They take `chains`, a comma list of `143`, `4663`, `5042`, `43114`, `8453`, `56`, `42161`, `1` and `solana` (which needs `sol`, the wallet's Solana address). Omitted or `all`, every EVM chain, plus Solana when `sol` is given. |\n| `/arc/*` | none; always 5042. |\n| `/rh/*` | none; always 4663. |\n| `/points/*`, `/ask/*` | none; always 5042. |"}]},{"kind":"page","path":"/docs/concepts/data-freshness/","url":"https://getchord.xyz/docs/concepts/data-freshness/","title":"Data freshness and honesty","description":"Rollups versus the tape, coverage flags, attribution, and the flags that mark wash volume, impostors and suspect pools.","markdown":"Every number in a read endpoint comes from Chord's own index of the chain: every swap event on every venue, decoded and priced at index time, stored as a tape, and rolled up by hour, token and venue. Nothing is fetched from a third-party price API on the request path.\n\n## Tape and rollups\n\n- The **tape** is one row per swap: block, transaction, venue, pool, token, side, size, USD, price and the attributed wallet. Trade tapes, wallet PnL and positions read it.\n- The **rollups** sum the tape by hour per token and venue, and by day per chain. `/arc/*`, `/rh/*`, boards and overviews read only rollups, so they answer in milliseconds and never scan the tape.\n- **Live layers** sit on top where seconds matter: Arc prices are pushed from the chain head over WebSocket, and the Arc top-wallets board keeps the last minutes of trades in memory between rebuilds (`live` in the response).\n\n## Coverage flags\n\nRollup answers carry a `coverage` object. Read it before you trust a quiet number.\n\n| Field | Meaning |\n| --- | --- |\n| `recentAt` | The most recent hour the rollup has processed. |\n| `stale` | True when `recentAt` is older than the lane's freshness bar. A quiet chart with `stale: true` is a lane that stopped, not a market that stopped. |\n| `floorHour` | The oldest hour rolled up so far. Windows reaching further back undercount. |\n| `genesisHour` | The chain's first indexed hour. |\n| `backfillComplete` | True once `floorHour` reached genesis. |\n\nOther families expose the same idea in their own words: the holder ledger says `tracked` and `complete`; `/lp/status` shows each lane's cursor against the chain head; `/arc/status` shows the pool index cursor and whether discovery reached genesis. `updatedAt` on any answer is when the server built it.\n\n## Attribution\n\nA swap's wallet is the account that initiated the transaction, resolved through routers, aggregators and account-abstraction executors. On Robinhood Chain, routers and executors were 71 % of transactions in a day before attribution landed; publishing a \"top wallets\" board of routers would have been a lie. So: `wallets`, `traders`, `providers` count attributed wallets only, and bots are removed from rankings by cadence, nonce rate and behaviour (`botsRemoved` on the board says how many).\n\n## Honesty flags\n\nChord flags rather than hides, and sorts flagged rows below clean ones.\n\n| Flag | Where | Rule |\n| --- | --- | --- |\n| `flags: [\"wash\"]` | token rows | ≥ $5k of volume from ≤ 2 wallets, or ≥ $50k from fewer than 5. A fake ARGUS once printed \"$9.97M\" from ten $500k self-trades in one second. |\n| `flags: [\"impostor\"]` | token rows | An unlisted token wearing a listed or trusted symbol. |\n| `suspect` | pool rows | Turnover no honest pool reaches (24h volume ÷ TVL above 300×, or above 50× with under 25 traders), dust TVL under real volume, or fewer than five wallets printing over $10k. Hidden from `/lp/pools` unless `flagged=1`. |\n| `token0.impostor` / `token1.impostor` | pool rows | A symbol that copies the chain's anchor (a \"USDC\" that is not the predeploy). |\n| `screened` | `/arc/graduated` | Launches removed by each screen: impostor symbols, launch farms (one creator, many pools), no sells, too few traders, no trades. |\n| `jit` · `unreconciled` | positions | Opened and closed within seconds (a swap trick); dollars out far above dollars in (the tape missed an add). Shown, never scored. |\n\nForged pools — forks emitting Swap events with no USDC actually moving — are dropped from the tape entirely when detected.\n\n## Prices\n\n`priceUsd` on a token row is the last trade on the token's **dominant venue** for the day, not a blend; a thin fork cannot move it. Market cap is `totalSupply × price` and is fully diluted, because nothing on-chain says what is locked. Candles are built from the tape (`source: \"db\"`); a token with too few trades for a bucket has no candle rather than a fake one.","sections":[{"heading":"","anchor":"","text":"Every number in a read endpoint comes from Chord's own index of the chain: every swap event on every venue, decoded and priced at index time, stored as a tape, and rolled up by hour, token and venue. Nothing is fetched from a third-party price API on the request path."},{"heading":"Tape and rollups","anchor":"tape-and-rollups","text":"- The **tape** is one row per swap: block, transaction, venue, pool, token, side, size, USD, price and the attributed wallet. Trade tapes, wallet PnL and positions read it.\n- The **rollups** sum the tape by hour per token and venue, and by day per chain. `/arc/*`, `/rh/*`, boards and overviews read only rollups, so they answer in milliseconds and never scan the tape.\n- **Live layers** sit on top where seconds matter: Arc prices are pushed from the chain head over WebSocket, and the Arc top-wallets board keeps the last minutes of trades in memory between rebuilds (`live` in the response)."},{"heading":"Coverage flags","anchor":"coverage-flags","text":"Rollup answers carry a `coverage` object. Read it before you trust a quiet number.\n\n| Field | Meaning |\n| --- | --- |\n| `recentAt` | The most recent hour the rollup has processed. |\n| `stale` | True when `recentAt` is older than the lane's freshness bar. A quiet chart with `stale: true` is a lane that stopped, not a market that stopped. |\n| `floorHour` | The oldest hour rolled up so far. Windows reaching further back undercount. |\n| `genesisHour` | The chain's first indexed hour. |\n| `backfillComplete` | True once `floorHour` reached genesis. |\n\nOther families expose the same idea in their own words: the holder ledger says `tracked` and `complete`; `/lp/status` shows each lane's cursor against the chain head; `/arc/status` shows the pool index cursor and whether discovery reached genesis. `updatedAt` on any answer is when the server built it."},{"heading":"Attribution","anchor":"attribution","text":"A swap's wallet is the account that initiated the transaction, resolved through routers, aggregators and account-abstraction executors. On Robinhood Chain, routers and executors were 71 % of transactions in a day before attribution landed; publishing a \"top wallets\" board of routers would have been a lie. So: `wallets`, `traders`, `providers` count attributed wallets only, and bots are removed from rankings by cadence, nonce rate and behaviour (`botsRemoved` on the board says how many)."},{"heading":"Honesty flags","anchor":"honesty-flags","text":"Chord flags rather than hides, and sorts flagged rows below clean ones.\n\n| Flag | Where | Rule |\n| --- | --- | --- |\n| `flags: [\"wash\"]` | token rows | ≥ $5k of volume from ≤ 2 wallets, or ≥ $50k from fewer than 5. A fake ARGUS once printed \"$9.97M\" from ten $500k self-trades in one second. |\n| `flags: [\"impostor\"]` | token rows | An unlisted token wearing a listed or trusted symbol. |\n| `suspect` | pool rows | Turnover no honest pool reaches (24h volume ÷ TVL above 300×, or above 50× with under 25 traders), dust TVL under real volume, or fewer than five wallets printing over $10k. Hidden from `/lp/pools` unless `flagged=1`. |\n| `token0.impostor` / `token1.impostor` | pool rows | A symbol that copies the chain's anchor (a \"USDC\" that is not the predeploy). |\n| `screened` | `/arc/graduated` | Launches removed by each screen: impostor symbols, launch farms (one creator, many pools), no sells, too few traders, no trades. |\n| `jit` · `unreconciled` | positions | Opened and closed within seconds (a swap trick); dollars out far above dollars in (the tape missed an add). Shown, never scored. |\n\nForged pools — forks emitting Swap events with no USDC actually moving — are dropped from the tape entirely when detected."},{"heading":"Prices","anchor":"prices","text":"`priceUsd` on a token row is the last trade on the token's **dominant venue** for the day, not a blend; a thin fork cannot move it. Market cap is `totalSupply × price` and is fully diluted, because nothing on-chain says what is locked. Candles are built from the tape (`source: \"db\"`); a token with too few trades for a bucket has no candle rather than a fake one."}]},{"kind":"page","path":"/docs/concepts/errors/","url":"https://getchord.xyz/docs/concepts/errors/","title":"Errors and retries","description":"The error body, the codes you will branch on, and which ones to retry.","markdown":"Every non-2xx response is JSON with a stable machine code and a human message:\n\n```json\n{ \"error\": \"INSUFFICIENT_LIQUIDITY\", \"message\": \"no route at this size — try a smaller amount\" }\n```\n\nBranch on `error`, never on `message`. Some older routes add `statusCode`; ignore it.\n\n## Codes\n\n| Status | `error` | Where | Meaning and what to do |\n| --- | --- | --- | --- |\n| 400 | `INVALID_PARAMS` | everywhere | A parameter is missing or malformed. The message names it. |\n| 400 | `BAD_ADDRESS` · `BAD_LIMIT` · `BAD_HOURS` · `BAD_DAYS` · `BAD_SORT` · `BAD_QUERY` · `BAD_POOL` | reads | The named check failed. |\n| 400 | `UNSUPPORTED_CHAIN` · `BAD_CHAIN` | quote, swap, boards | The chain id is not one the API serves. |\n| 400 | `BAD_SOURCE` | smart money | `source=onchain` is required on 5042 / 4663. |\n| 400 | `SLIPPAGE_MISMATCH` | swap | The `slippageBps` you sent differs from the quote's. Re-quote at the slippage you want. |\n| 400 | `ROUTE_MISMATCH` | swap | The quote body was edited. Send it back unmodified. |\n| 400 | `ONLY_REQUIRES_KEY` | quote | `?only=` needs an API key. |\n| 401 | `UNAUTHORIZED` | ask, me | No key or session, or an unknown one. |\n| 404 | `UNKNOWN_TOKEN` | charts, trades, stats | Not on a curated list and not a side of an indexed pool. |\n| 404 | `NOT_FOUND` | pool, position, report | Nothing at this identity. |\n| 404 | `NO_ROUTE` | swap calldata | No route for this pair and size. |\n| 404 | `NOT_ENOUGH_HISTORY` | LP plan, simulate | Fewer than 24 hourly candles or no anchored pool. |\n| 409 | `ROUTE_STALE_GRADUATED` | quote | A bonding-curve token graduated mid-route (Monad). Re-quote. |\n| 409 | `NOT_ATTESTED` · `IN_FLIGHT` | bridge relay | Circle has not attested the burn yet, or a relay is already running. Poll `/bridge2/status`. |\n| 429 | `RATE_LIMIT_EXCEEDED` | everywhere | Read `X-RateLimit-Reset` and back off. |\n| 429 | `RATE_LIMITED` | ask | Over 8 questions a minute. |\n| 502 | `ENGINE_ERROR` · `ROUTE_ERROR` | quote, swap | The routing engine did not answer. Retry once after a second. |\n| 503 | `NOT_READY` | arc, rh, launchers | The rollup or index has not run on this deployment yet. |\n| 503 | `CHAIN_NOT_ENABLED` | quote, smart money | The chain's routing or board is not published here. |\n| 503 | `HOLDERS_PENDING` | holders | The token was just pinned for tracking. Retry in a few minutes. |\n| 503 | `NOT_ENABLED` | points | The points program is off on the deployment. |\n| 503 | `ARC_DATA_UNAVAILABLE` · `RH_DATA_UNAVAILABLE` · `SIMULATION_UNAVAILABLE` · `IRIS_UNAVAILABLE` · `SESSION_STORE_UNAVAILABLE` · `DISABLED` | various | A dependency did not answer. Retry with backoff. |\n\n## Empty is not an error\n\nSome answers are honest empties, not failures:\n\n- A quote with `routePlan: []` and `outputAmount: \"0\"` — no route at this size. Read `noRouteReason` (`INSUFFICIENT_LIQUIDITY` or `NO_POOLS`).\n- A token on `/arc/token/{address}` that comes back as `{ address, listed: false }` — no trades in the last 24 hours.\n- Portfolio routes answer an empty 200 shape (`tokens: []`) when the tape read fails, never a 5xx. Treat it as \"nothing yet\" and retry later.\n- A holder ledger with `complete: false` — the backfill has not reached the token's creation block; balances are partial and say so.\n\n## Retrying\n\nRetry `502` and `503` with exponential backoff starting at one second, at most three times. Do not retry `400`, `401`, `404` or `409` — the request will not become valid on its own (a `409 NOT_ATTESTED` is a poll, not a retry). Retry `429` after `X-RateLimit-Reset`.\n\nQuotes are live and expire: a `502` on `/swap` after a successful quote usually means the route changed. Quote again rather than resubmitting the old body.","sections":[{"heading":"","anchor":"","text":"Every non-2xx response is JSON with a stable machine code and a human message:\n\n```json\n{ \"error\": \"INSUFFICIENT_LIQUIDITY\", \"message\": \"no route at this size — try a smaller amount\" }\n```\n\nBranch on `error`, never on `message`. Some older routes add `statusCode`; ignore it."},{"heading":"Codes","anchor":"codes","text":"| Status | `error` | Where | Meaning and what to do |\n| --- | --- | --- | --- |\n| 400 | `INVALID_PARAMS` | everywhere | A parameter is missing or malformed. The message names it. |\n| 400 | `BAD_ADDRESS` · `BAD_LIMIT` · `BAD_HOURS` · `BAD_DAYS` · `BAD_SORT` · `BAD_QUERY` · `BAD_POOL` | reads | The named check failed. |\n| 400 | `UNSUPPORTED_CHAIN` · `BAD_CHAIN` | quote, swap, boards | The chain id is not one the API serves. |\n| 400 | `BAD_SOURCE` | smart money | `source=onchain` is required on 5042 / 4663. |\n| 400 | `SLIPPAGE_MISMATCH` | swap | The `slippageBps` you sent differs from the quote's. Re-quote at the slippage you want. |\n| 400 | `ROUTE_MISMATCH` | swap | The quote body was edited. Send it back unmodified. |\n| 400 | `ONLY_REQUIRES_KEY` | quote | `?only=` needs an API key. |\n| 401 | `UNAUTHORIZED` | ask, me | No key or session, or an unknown one. |\n| 404 | `UNKNOWN_TOKEN` | charts, trades, stats | Not on a curated list and not a side of an indexed pool. |\n| 404 | `NOT_FOUND` | pool, position, report | Nothing at this identity. |\n| 404 | `NO_ROUTE` | swap calldata | No route for this pair and size. |\n| 404 | `NOT_ENOUGH_HISTORY` | LP plan, simulate | Fewer than 24 hourly candles or no anchored pool. |\n| 409 | `ROUTE_STALE_GRADUATED` | quote | A bonding-curve token graduated mid-route (Monad). Re-quote. |\n| 409 | `NOT_ATTESTED` · `IN_FLIGHT` | bridge relay | Circle has not attested the burn yet, or a relay is already running. Poll `/bridge2/status`. |\n| 429 | `RATE_LIMIT_EXCEEDED` | everywhere | Read `X-RateLimit-Reset` and back off. |\n| 429 | `RATE_LIMITED` | ask | Over 8 questions a minute. |\n| 502 | `ENGINE_ERROR` · `ROUTE_ERROR` | quote, swap | The routing engine did not answer. Retry once after a second. |\n| 503 | `NOT_READY` | arc, rh, launchers | The rollup or index has not run on this deployment yet. |\n| 503 | `CHAIN_NOT_ENABLED` | quote, smart money | The chain's routing or board is not published here. |\n| 503 | `HOLDERS_PENDING` | holders | The token was just pinned for tracking. Retry in a few minutes. |\n| 503 | `NOT_ENABLED` | points | The points program is off on the deployment. |\n| 503 | `ARC_DATA_UNAVAILABLE` · `RH_DATA_UNAVAILABLE` · `SIMULATION_UNAVAILABLE` · `IRIS_UNAVAILABLE` · `SESSION_STORE_UNAVAILABLE` · `DISABLED` | various | A dependency did not answer. Retry with backoff. |"},{"heading":"Empty is not an error","anchor":"empty-is-not-an-error","text":"Some answers are honest empties, not failures:\n\n- A quote with `routePlan: []` and `outputAmount: \"0\"` — no route at this size. Read `noRouteReason` (`INSUFFICIENT_LIQUIDITY` or `NO_POOLS`).\n- A token on `/arc/token/{address}` that comes back as `{ address, listed: false }` — no trades in the last 24 hours.\n- Portfolio routes answer an empty 200 shape (`tokens: []`) when the tape read fails, never a 5xx. Treat it as \"nothing yet\" and retry later.\n- A holder ledger with `complete: false` — the backfill has not reached the token's creation block; balances are partial and say so."},{"heading":"Retrying","anchor":"retrying","text":"Retry `502` and `503` with exponential backoff starting at one second, at most three times. Do not retry `400`, `401`, `404` or `409` — the request will not become valid on its own (a `409 NOT_ATTESTED` is a poll, not a retry). Retry `429` after `X-RateLimit-Reset`.\n\nQuotes are live and expire: a `502` on `/swap` after a successful quote usually means the route changed. Quote again rather than resubmitting the old body."}]},{"kind":"page","path":"/docs/concepts/liquidity/","url":"https://getchord.xyz/docs/concepts/liquidity/","title":"Liquidity and positions","description":"What the liquidity family indexes — events, pools, positions, the health score, range planning — and how the numbers are made.","markdown":"The `/v1/lp/*` family is Chord's LP agent: the data a liquidity provider needs before, during and after a position, on Arc, Robinhood Chain and Monad.\n\n## What is indexed\n\n- **Events** — every `Mint` / `Burn` / `Collect` on V2 pairs, V3 pools and V4 pools (`ModifyLiquidity`), with the sender resolved through position managers to the wallet, and the dollars that entered or left the pool where the pool has an anchor side (USDC, EURC on Arc; WETH, USDG on 4663). V4 amounts are computed from `liquidityDelta` and the pool's price at that block, because the log does not carry them.\n- **Pools** — hourly volume, trades and price per pool from the swap tape, TVL from the chain (or a market-data fallback, named in `tvlSrc`), and the pool's fee tier. Fees are `volume × fee tier`; `feeTvlPct` is fees ÷ TVL for the window; `aprPct` is the 24-hour figure × 365, a full-range yardstick and not a promise.\n- **Positions** — every position NFT from the Uniswap V3 position manager and the V4 PositionManager on each chain: dollars in and out, fees collected, and for open positions the live value, uncollected fees (V3), whether it is in range, the distance to the nearest edge, and PnL on the liquidity leg.\n- **Providers** — the leaderboard: win rate on closed positions, fees, expected value per position, average age, invested and monthly profit, and the last seven days.\n\n## The health score\n\nEvery pool has a 0–100 score from six parts: traders (real wallets, not printing), TVL, yield sanity (fee/TVL a pool can honestly sustain), LP flow (net adds versus removes), age, and penalties. `reasons` names what cost points — \"the launcher holds 100 % of the liquidity added\", \"fee/TVL over 10 %/day: volume is being printed\". `/lp/token/{address}/pools` ranks a token's pools by it.\n\n## Suspect pools\n\nA pool is `suspect` when its numbers cannot be honest: 24-hour turnover above 300× TVL, above 50× with fewer than 25 traders, dust TVL under six-figure volume, fewer than five wallets printing over $10k, or a hooked V4 pool with dust TVL (a launchpad curve where the hook holds the real reserves). Suspect pools are hidden from `/lp/pools` unless `flagged=1`, and never chosen as \"best yield\". The rule was measured against a launch fleet printing $100k a day through $2.5k pools with three wallets, and against a real market-maker pool turning 48× a day with thousands of traders — turnover alone cannot split them; traders can.\n\n## Launch facts\n\nOn Arc most tokens are born through a launcher. `/lp/pools/{pool}` and `/lp/token/{address}/pools` say who launched the pool, how much of the liquidity ever added the launcher supplied (`launcherSharePct`), and when it last pulled and how much. A pool whose launcher holds all the liquidity and has started removing it is a different risk from one with fifty providers.\n\n## Planning a range\n\n`/lp/plan` derives three ranges from the token's own hourly and daily volatility (tight, balanced, wide), reports the share of the last seven days the price stayed inside each, and backtests each on Chord's candles against holding: fees at the pool's real tier and the position's share of liquidity, impermanent loss, how many times the price left the range, and the net versus hold. `/lp/simulate` runs one explicit range. Under two days of candles the answer says `young: true` — the bands are a launch's noise, not a distribution.\n\n## Minting\n\n`/lp/pools/{pool}` returns `mint`: the position manager to call, the pool key (tokens, fee, tick spacing, hooks), Permit2, and whether `currency0` is native. It is what the Chord app uses to add liquidity from the browser (V3 through the NPM, V4 through PositionManager + Permit2). Chord does not build the mint calldata for you; the pool key is the input to the Uniswap SDK.\n\n## Alerts\n\n`POST /lp/watch` turns on alerts for a wallet's positions — out of range, fees past a bar, a watched pool draining — in the app and, through a one-hour Telegram deep link, in a chat. `GET /lp/watch` is the inbox.","sections":[{"heading":"","anchor":"","text":"The `/v1/lp/*` family is Chord's LP agent: the data a liquidity provider needs before, during and after a position, on Arc, Robinhood Chain and Monad."},{"heading":"What is indexed","anchor":"what-is-indexed","text":"- **Events** — every `Mint` / `Burn` / `Collect` on V2 pairs, V3 pools and V4 pools (`ModifyLiquidity`), with the sender resolved through position managers to the wallet, and the dollars that entered or left the pool where the pool has an anchor side (USDC, EURC on Arc; WETH, USDG on 4663). V4 amounts are computed from `liquidityDelta` and the pool's price at that block, because the log does not carry them.\n- **Pools** — hourly volume, trades and price per pool from the swap tape, TVL from the chain (or a market-data fallback, named in `tvlSrc`), and the pool's fee tier. Fees are `volume × fee tier`; `feeTvlPct` is fees ÷ TVL for the window; `aprPct` is the 24-hour figure × 365, a full-range yardstick and not a promise.\n- **Positions** — every position NFT from the Uniswap V3 position manager and the V4 PositionManager on each chain: dollars in and out, fees collected, and for open positions the live value, uncollected fees (V3), whether it is in range, the distance to the nearest edge, and PnL on the liquidity leg.\n- **Providers** — the leaderboard: win rate on closed positions, fees, expected value per position, average age, invested and monthly profit, and the last seven days."},{"heading":"The health score","anchor":"the-health-score","text":"Every pool has a 0–100 score from six parts: traders (real wallets, not printing), TVL, yield sanity (fee/TVL a pool can honestly sustain), LP flow (net adds versus removes), age, and penalties. `reasons` names what cost points — \"the launcher holds 100 % of the liquidity added\", \"fee/TVL over 10 %/day: volume is being printed\". `/lp/token/{address}/pools` ranks a token's pools by it."},{"heading":"Suspect pools","anchor":"suspect-pools","text":"A pool is `suspect` when its numbers cannot be honest: 24-hour turnover above 300× TVL, above 50× with fewer than 25 traders, dust TVL under six-figure volume, fewer than five wallets printing over $10k, or a hooked V4 pool with dust TVL (a launchpad curve where the hook holds the real reserves). Suspect pools are hidden from `/lp/pools` unless `flagged=1`, and never chosen as \"best yield\". The rule was measured against a launch fleet printing $100k a day through $2.5k pools with three wallets, and against a real market-maker pool turning 48× a day with thousands of traders — turnover alone cannot split them; traders can."},{"heading":"Launch facts","anchor":"launch-facts","text":"On Arc most tokens are born through a launcher. `/lp/pools/{pool}` and `/lp/token/{address}/pools` say who launched the pool, how much of the liquidity ever added the launcher supplied (`launcherSharePct`), and when it last pulled and how much. A pool whose launcher holds all the liquidity and has started removing it is a different risk from one with fifty providers."},{"heading":"Planning a range","anchor":"planning-a-range","text":"`/lp/plan` derives three ranges from the token's own hourly and daily volatility (tight, balanced, wide), reports the share of the last seven days the price stayed inside each, and backtests each on Chord's candles against holding: fees at the pool's real tier and the position's share of liquidity, impermanent loss, how many times the price left the range, and the net versus hold. `/lp/simulate` runs one explicit range. Under two days of candles the answer says `young: true` — the bands are a launch's noise, not a distribution."},{"heading":"Minting","anchor":"minting","text":"`/lp/pools/{pool}` returns `mint`: the position manager to call, the pool key (tokens, fee, tick spacing, hooks), Permit2, and whether `currency0` is native. It is what the Chord app uses to add liquidity from the browser (V3 through the NPM, V4 through PositionManager + Permit2). Chord does not build the mint calldata for you; the pool key is the input to the Uniswap SDK."},{"heading":"Alerts","anchor":"alerts","text":"`POST /lp/watch` turns on alerts for a wallet's positions — out of range, fees past a bar, a watched pool draining — in the app and, through a one-hour Telegram deep link, in a chat. `GET /lp/watch` is the inbox."}]},{"kind":"page","path":"/docs/concepts/meta-aggregator/","url":"https://getchord.xyz/docs/concepts/meta-aggregator/","title":"Meta aggregator","description":"One quote and one unsigned transaction on any Chord chain. Chord's own router answers first; a third-party aggregator only when it fails, and the answer says who quoted it.","markdown":"`GET /v1/meta/quote` and `POST /v1/meta/swap` are the swap endpoints built for agents: one call on any of the eight EVM chains that ends in a route you can sign, or an honest \"no route anywhere\".\n\nChord's own router always answers first. A third-party aggregator answers only when Chord fails, and every answer names the provider and the reason.\n\n| Chain | First | Fallbacks, in order |\n| --- | --- | --- |\n| Monad `143` | Chord router | KyberSwap, Monorail, Relay |\n| Robinhood Chain `4663` | Chord router | KyberSwap, LI.FI, Relay |\n| Arc `5042` | Chord router | KyberSwap, LI.FI, Relay |\n| Avalanche `43114` | Chord router | KyberSwap, LI.FI, Relay |\n| Base `8453` | Chord router | KyberSwap, LI.FI, Relay |\n| BNB Chain `56` | Chord router | KyberSwap, LI.FI, Relay |\n| Arbitrum One `42161` | Chord router | KyberSwap, LI.FI, Relay |\n| Ethereum `1` | Chord router | KyberSwap, LI.FI, Relay |\n\nThe live order and each provider's breaker state: `GET /v1/meta/providers`.\n\n## When a fallback is used\n\nOnly on a Chord failure:\n\n- the routing engine timed out, returned an error, or is down (a cold start, a deploy);\n- Chord has no route for the pair or the size;\n- Chord refuses the route itself: the [value guard](/docs/concepts/quotes-and-routing/), a taxed token, a stale bonding-curve route;\n- the Chord router is not live on that chain;\n- the transaction Chord built fails simulation.\n\nNever because another aggregator shows a better price. Never on a user error: an address that is not a token, a bad amount or an unknown chain is answered with HTTP 400 and no other provider is asked.\n\n## What you get back\n\nThe same shape whichever provider answered.\n\n| Field | Meaning |\n| --- | --- |\n| `provider` | `chord`, `kyberswap`, `monorail`, `lifi`, `relay`. `null` = no provider has a route. |\n| `fallbackReason` | `null` when Chord answered, otherwise why it did not (`no_route`, `engine_timeout`, `value_guard`, `simulation_failed`, …). |\n| `attempts` | Every provider asked, in order, with `status`, `ms` and a short `error`. |\n| `amountOut` | What the taker receives after every fee, smallest unit. |\n| `minAmountOut` | The minimum the transaction enforces, from the slippage you asked for. |\n| `priceImpactPct` · `valueLossPct` | Impact when the provider states one; value lost at Chord's own prices (`null` when a side has no reliable price). |\n| `feeBps` · `feeRecipient` | Chord path: Chord's protocol fee. Fallback: the integrator fee Chord added (0 today); the provider's own fees are inside `amountOut`. |\n| `route.venues` | Venue names. |\n| `tx` | `{to, data, value, gas, chainId}`, unsigned. `null` without `taker`. |\n| `approval` | `{token, spender, amount}` to send first, or `null`. |\n| `simulation` | The transaction run as the taker: `{ok, amountOut, gasUsed}`. |\n| `safety` | A security scan of the unknown token, when the value check could not run. |\n| `warnings` | `INSUFFICIENT_BALANCE`, `UNPRICED`, `OUTPUT_WRAPPED`, `NO_ROUTE`. |\n| `quoteId` · `expiresAt` | Rebuild with `POST /v1/meta/swap {quoteId, taker}` within 2 minutes; quote again after `expiresAt`. |\n\nNote the one difference from `/v1/quote`: its `outputAmount` is before Chord's fee, `amountOut` here is after every fee, so answers from different providers compare directly.\n\n## The checks on a fallback answer\n\nA third-party answer is untrusted data until it passes all of these. One failure and the next provider is asked.\n\n1. **Allowlist.** The transaction target and the approval spender must be that provider's known router on that chain, and have code there. Anything else is refused, never returned.\n2. **Calldata.** For KyberSwap the calldata is decoded: receiver, tokens and amount must be what you asked.\n3. **Minimum.** `minAmountOut` comes from your slippage. A provider minimum below it is refused.\n4. **Value guard.** An output worth 30 % less than the input at Chord's own prices is refused, exactly as on `/v1/swap`. When Chord has no price for a side, the token is scanned (`safety`) and a honeypot is refused.\n5. **Simulation.** With a `taker`, the transaction is run as that wallet and must deliver at least `minAmountOut` to it. A fallback transaction that cannot be simulated is never returned.\n\nThe simulation runs the swap from the taker's own address and measures the taker's balance of the output token before and after, so it means the same thing for every aggregator. When the taker does not hold the input yet, the input is supplied for the simulation and the answer carries `INSUFFICIENT_BALANCE`.\n\n## Quote, then sign\n\n```bash\n# 1. Price (read-only)\ncurl -s \"https://api.getchord.xyz/v1/meta/quote?chain=base&tokenIn=0x833589fcd6edb6e08f4c7c32d4f71b54bda02913&tokenOut=0x4200000000000000000000000000000000000006&amount=10000000&slippageBps=50\"\n\n# 2. The unsigned transaction for a wallet (simulated as that wallet)\ncurl -s -X POST https://api.getchord.xyz/v1/meta/swap -H 'Content-Type: application/json' \\\n  -d '{\"chain\":\"base\",\"tokenIn\":\"0x833589fcd6edb6e08f4c7c32d4f71b54bda02913\",\"tokenOut\":\"0x4200000000000000000000000000000000000006\",\"amount\":\"10000000\",\"slippageBps\":50,\"taker\":\"0xYourWallet\"}'\n```\n\nThen, in your own wallet:\n\n1. If `approval` is not `null`, send `token.approve(spender, amount)` and wait for it.\n2. Sign and send `tx` on `tx.chainId`.\n\nChord never signs and never holds funds.\n\n## Reading the status codes\n\n| Answer | Meaning |\n| --- | --- |\n| `200`, `provider` set | A route. Read `provider` and `fallbackReason` first. |\n| `200`, `provider: null` | Every provider looked and none has a route. |\n| `400` | Your request: `INVALID_PARAMS`, `UNSUPPORTED_CHAIN`, `UNKNOWN_TOKEN`. |\n| `404` on `/meta/swap` | `NO_ROUTE`, with `attempts`. |\n| `410` on `/meta/swap` | `QUOTE_EXPIRED`: send the full params. |\n| `503 UNAVAILABLE` | Nobody could answer right now (timeouts, an open breaker). Retry in a few seconds; this is not \"no route\". |\n\n## For agents\n\n- MCP and function calling: `chord_quote` and `chord_swap_tx` call this endpoint on every EVM chain ([MCP server](/docs/agents/mcp/), [tools manifest](/docs/agents/function-calling/)).\n- The [Agent Skill](/docs/agents/skill/) quotes through the meta aggregator first and checks the router of every answer against its own pinned list.\n- Solana is not on this endpoint: Solana swaps are `/v1/sol/trade/*`, where every quote builds Chord's own Solana route and Jupiter's for the wallet and keeps the better one. See [Solana](/docs/networks/solana/#swaps).","sections":[{"heading":"","anchor":"","text":"`GET /v1/meta/quote` and `POST /v1/meta/swap` are the swap endpoints built for agents: one call on any of the eight EVM chains that ends in a route you can sign, or an honest \"no route anywhere\".\n\nChord's own router always answers first. A third-party aggregator answers only when Chord fails, and every answer names the provider and the reason.\n\n| Chain | First | Fallbacks, in order |\n| --- | --- | --- |\n| Monad `143` | Chord router | KyberSwap, Monorail, Relay |\n| Robinhood Chain `4663` | Chord router | KyberSwap, LI.FI, Relay |\n| Arc `5042` | Chord router | KyberSwap, LI.FI, Relay |\n| Avalanche `43114` | Chord router | KyberSwap, LI.FI, Relay |\n| Base `8453` | Chord router | KyberSwap, LI.FI, Relay |\n| BNB Chain `56` | Chord router | KyberSwap, LI.FI, Relay |\n| Arbitrum One `42161` | Chord router | KyberSwap, LI.FI, Relay |\n| Ethereum `1` | Chord router | KyberSwap, LI.FI, Relay |\n\nThe live order and each provider's breaker state: `GET /v1/meta/providers`."},{"heading":"When a fallback is used","anchor":"when-a-fallback-is-used","text":"Only on a Chord failure:\n\n- the routing engine timed out, returned an error, or is down (a cold start, a deploy);\n- Chord has no route for the pair or the size;\n- Chord refuses the route itself: the [value guard](/docs/concepts/quotes-and-routing/), a taxed token, a stale bonding-curve route;\n- the Chord router is not live on that chain;\n- the transaction Chord built fails simulation.\n\nNever because another aggregator shows a better price. Never on a user error: an address that is not a token, a bad amount or an unknown chain is answered with HTTP 400 and no other provider is asked."},{"heading":"What you get back","anchor":"what-you-get-back","text":"The same shape whichever provider answered.\n\n| Field | Meaning |\n| --- | --- |\n| `provider` | `chord`, `kyberswap`, `monorail`, `lifi`, `relay`. `null` = no provider has a route. |\n| `fallbackReason` | `null` when Chord answered, otherwise why it did not (`no_route`, `engine_timeout`, `value_guard`, `simulation_failed`, …). |\n| `attempts` | Every provider asked, in order, with `status`, `ms` and a short `error`. |\n| `amountOut` | What the taker receives after every fee, smallest unit. |\n| `minAmountOut` | The minimum the transaction enforces, from the slippage you asked for. |\n| `priceImpactPct` · `valueLossPct` | Impact when the provider states one; value lost at Chord's own prices (`null` when a side has no reliable price). |\n| `feeBps` · `feeRecipient` | Chord path: Chord's protocol fee. Fallback: the integrator fee Chord added (0 today); the provider's own fees are inside `amountOut`. |\n| `route.venues` | Venue names. |\n| `tx` | `{to, data, value, gas, chainId}`, unsigned. `null` without `taker`. |\n| `approval` | `{token, spender, amount}` to send first, or `null`. |\n| `simulation` | The transaction run as the taker: `{ok, amountOut, gasUsed}`. |\n| `safety` | A security scan of the unknown token, when the value check could not run. |\n| `warnings` | `INSUFFICIENT_BALANCE`, `UNPRICED`, `OUTPUT_WRAPPED`, `NO_ROUTE`. |\n| `quoteId` · `expiresAt` | Rebuild with `POST /v1/meta/swap {quoteId, taker}` within 2 minutes; quote again after `expiresAt`. |\n\nNote the one difference from `/v1/quote`: its `outputAmount` is before Chord's fee, `amountOut` here is after every fee, so answers from different providers compare directly."},{"heading":"The checks on a fallback answer","anchor":"the-checks-on-a-fallback-answer","text":"A third-party answer is untrusted data until it passes all of these. One failure and the next provider is asked.\n\n1. **Allowlist.** The transaction target and the approval spender must be that provider's known router on that chain, and have code there. Anything else is refused, never returned.\n2. **Calldata.** For KyberSwap the calldata is decoded: receiver, tokens and amount must be what you asked.\n3. **Minimum.** `minAmountOut` comes from your slippage. A provider minimum below it is refused.\n4. **Value guard.** An output worth 30 % less than the input at Chord's own prices is refused, exactly as on `/v1/swap`. When Chord has no price for a side, the token is scanned (`safety`) and a honeypot is refused.\n5. **Simulation.** With a `taker`, the transaction is run as that wallet and must deliver at least `minAmountOut` to it. A fallback transaction that cannot be simulated is never returned.\n\nThe simulation runs the swap from the taker's own address and measures the taker's balance of the output token before and after, so it means the same thing for every aggregator. When the taker does not hold the input yet, the input is supplied for the simulation and the answer carries `INSUFFICIENT_BALANCE`."},{"heading":"Quote, then sign","anchor":"quote-then-sign","text":"```bash\n# 1. Price (read-only)\ncurl -s \"https://api.getchord.xyz/v1/meta/quote?chain=base&tokenIn=0x833589fcd6edb6e08f4c7c32d4f71b54bda02913&tokenOut=0x4200000000000000000000000000000000000006&amount=10000000&slippageBps=50\"\n\n# 2. The unsigned transaction for a wallet (simulated as that wallet)\ncurl -s -X POST https://api.getchord.xyz/v1/meta/swap -H 'Content-Type: application/json' \\\n  -d '{\"chain\":\"base\",\"tokenIn\":\"0x833589fcd6edb6e08f4c7c32d4f71b54bda02913\",\"tokenOut\":\"0x4200000000000000000000000000000000000006\",\"amount\":\"10000000\",\"slippageBps\":50,\"taker\":\"0xYourWallet\"}'\n```\n\nThen, in your own wallet:\n\n1. If `approval` is not `null`, send `token.approve(spender, amount)` and wait for it.\n2. Sign and send `tx` on `tx.chainId`.\n\nChord never signs and never holds funds."},{"heading":"Reading the status codes","anchor":"reading-the-status-codes","text":"| Answer | Meaning |\n| --- | --- |\n| `200`, `provider` set | A route. Read `provider` and `fallbackReason` first. |\n| `200`, `provider: null` | Every provider looked and none has a route. |\n| `400` | Your request: `INVALID_PARAMS`, `UNSUPPORTED_CHAIN`, `UNKNOWN_TOKEN`. |\n| `404` on `/meta/swap` | `NO_ROUTE`, with `attempts`. |\n| `410` on `/meta/swap` | `QUOTE_EXPIRED`: send the full params. |\n| `503 UNAVAILABLE` | Nobody could answer right now (timeouts, an open breaker). Retry in a few seconds; this is not \"no route\". |"},{"heading":"For agents","anchor":"for-agents","text":"- MCP and function calling: `chord_quote` and `chord_swap_tx` call this endpoint on every EVM chain ([MCP server](/docs/agents/mcp/), [tools manifest](/docs/agents/function-calling/)).\n- The [Agent Skill](/docs/agents/skill/) quotes through the meta aggregator first and checks the router of every answer against its own pinned list.\n- Solana is not on this endpoint: Solana swaps are `/v1/sol/trade/*`, where every quote builds Chord's own Solana route and Jupiter's for the wallet and keeps the better one. See [Solana](/docs/networks/solana/#swaps)."}]},{"kind":"page","path":"/docs/concepts/quotes-and-routing/","url":"https://getchord.xyz/docs/concepts/quotes-and-routing/","title":"Quotes and routing","description":"What a quote is, how the route is found, what the numbers mean, fees, slippage, the fast frame, and the honest no-route answer.","markdown":"`GET /v1/quote` is a live read of every venue on the chain for one pair and size. It is not a price feed: the answer is what you would get right now, on the route the engine would execute.\n\n## How a route is found\n\n1. **Every single-hop venue is quoted in parallel** — Uniswap V3 and V4 pools (including hooked launchpad pools on Arc), V2 pairs, and the forks the engine knows.\n2. **Splits.** Within a hop the order can be split across venues (say 90 % in one pool and 10 % in another) when that improves the output beyond a small threshold, and only across distinct pools.\n3. **Composed hops.** When no direct pool wins, the engine composes the best `A → anchor` leg with the best `anchor → B` leg through the chain's anchors (USDC and EURC on Arc; WETH and USDG on Robinhood Chain).\n4. **Safety gates.** Routes over 50 % impact are dropped, hooks the engine has not verified are not routed, and a paused venue is muted.\n\nThe winner is returned with one `routePlan` entry per leg, each carrying the venue id, the pool, the amounts, and the adapter and calldata the router will use. Do not construct venue logic from these fields — pass the whole body to `/swap`.\n\n## Reading the numbers\n\n| Field | Meaning |\n| --- | --- |\n| `outputAmount` | What the route returns before the protocol fee, smallest unit. |\n| `feeBps` · `feeAmount` · `feeTier` | The protocol fee on the **output** token, per token, from the on-chain fee collector: 5 bps by default on every chain, 0 on USDC / EURC (Arc) and WETH / USDG / stocks (4663), capped at 100. `feeAmount` is deducted on-chain from `outputAmount`. |\n| `otherAmountThreshold` | The minimum output after fee and slippage — **the number the transaction enforces**. Positive slippage goes to the user. |\n| `priceImpactPct` | Percent, against the spot rate of the same route. Display only. |\n| `gasEstimate` | From the venue quoter or an RPC estimate. |\n| `blockNumber` | The block the venues were read at. |\n\nA quote is good for about 30 seconds. If the user waited longer, quote again before building.\n\n## No route\n\nAn empty `routePlan` with `outputAmount: \"0\"` is a real answer: nothing on the chain fills this size. `noRouteReason` says `INSUFFICIENT_LIQUIDITY` (the pair routes at a smaller size — try one) or `NO_POOLS` (no venue holds the pair). The engine never fabricates a price.\n\n## Slippage\n\n`slippageBps` on the quote sets `otherAmountThreshold`. On `/swap` it is a consistency check only: the signed minimum is the quote's threshold, which already folds in venue-specific widening the swap builder cannot re-derive. Sending a different value returns `400 SLIPPAGE_MISMATCH`. Want tighter or looser? Quote again.\n\n## The fast frame\n\n`fast=1` returns a single-hop quote in about 400 ms with `preliminary: true`. Use it to paint a first number, run the full quote alongside, and replace. Never build a transaction from a preliminary quote.\n\n## Debug: one venue\n\n`only=<venue id>` restricts routing to one venue and returns its raw quote **before** the safety gates. It needs an API key, because a shared link with `?only=` would hand a user exactly the route the gate refuses.\n\n## Simulate before you sign\n\n`POST /v1/swap/simulate` with the built transaction runs `eth_call` from the user's address and estimates gas. A revert comes back decoded (`NotRouter`, a paused market, allowance or balance) so the wallet never opens on a doomed transaction. An allowance revert is advisory: approve, then swap.\n\n## Where fees go\n\nThe fee is read per output token from the on-chain fee collector: 5 bps by default on every chain since 2026-10-02, 0 on the stablecoins and majors each chain exempts, capped at 100. It does not change with a token's age. A referrer passed as `feeAccount` on `POST /v1/swap` earns 50 % of the fee on that swap; `/v1/meta/*` and the MCP tools take no referrer. Quotes and API usage are free.","sections":[{"heading":"","anchor":"","text":"`GET /v1/quote` is a live read of every venue on the chain for one pair and size. It is not a price feed: the answer is what you would get right now, on the route the engine would execute."},{"heading":"How a route is found","anchor":"how-a-route-is-found","text":"1. **Every single-hop venue is quoted in parallel** — Uniswap V3 and V4 pools (including hooked launchpad pools on Arc), V2 pairs, and the forks the engine knows.\n2. **Splits.** Within a hop the order can be split across venues (say 90 % in one pool and 10 % in another) when that improves the output beyond a small threshold, and only across distinct pools.\n3. **Composed hops.** When no direct pool wins, the engine composes the best `A → anchor` leg with the best `anchor → B` leg through the chain's anchors (USDC and EURC on Arc; WETH and USDG on Robinhood Chain).\n4. **Safety gates.** Routes over 50 % impact are dropped, hooks the engine has not verified are not routed, and a paused venue is muted.\n\nThe winner is returned with one `routePlan` entry per leg, each carrying the venue id, the pool, the amounts, and the adapter and calldata the router will use. Do not construct venue logic from these fields — pass the whole body to `/swap`."},{"heading":"Reading the numbers","anchor":"reading-the-numbers","text":"| Field | Meaning |\n| --- | --- |\n| `outputAmount` | What the route returns before the protocol fee, smallest unit. |\n| `feeBps` · `feeAmount` · `feeTier` | The protocol fee on the **output** token, per token, from the on-chain fee collector: 5 bps by default on every chain, 0 on USDC / EURC (Arc) and WETH / USDG / stocks (4663), capped at 100. `feeAmount` is deducted on-chain from `outputAmount`. |\n| `otherAmountThreshold` | The minimum output after fee and slippage — **the number the transaction enforces**. Positive slippage goes to the user. |\n| `priceImpactPct` | Percent, against the spot rate of the same route. Display only. |\n| `gasEstimate` | From the venue quoter or an RPC estimate. |\n| `blockNumber` | The block the venues were read at. |\n\nA quote is good for about 30 seconds. If the user waited longer, quote again before building."},{"heading":"No route","anchor":"no-route","text":"An empty `routePlan` with `outputAmount: \"0\"` is a real answer: nothing on the chain fills this size. `noRouteReason` says `INSUFFICIENT_LIQUIDITY` (the pair routes at a smaller size — try one) or `NO_POOLS` (no venue holds the pair). The engine never fabricates a price."},{"heading":"Slippage","anchor":"slippage","text":"`slippageBps` on the quote sets `otherAmountThreshold`. On `/swap` it is a consistency check only: the signed minimum is the quote's threshold, which already folds in venue-specific widening the swap builder cannot re-derive. Sending a different value returns `400 SLIPPAGE_MISMATCH`. Want tighter or looser? Quote again."},{"heading":"The fast frame","anchor":"the-fast-frame","text":"`fast=1` returns a single-hop quote in about 400 ms with `preliminary: true`. Use it to paint a first number, run the full quote alongside, and replace. Never build a transaction from a preliminary quote."},{"heading":"Debug: one venue","anchor":"debug-one-venue","text":"`only=<venue id>` restricts routing to one venue and returns its raw quote **before** the safety gates. It needs an API key, because a shared link with `?only=` would hand a user exactly the route the gate refuses."},{"heading":"Simulate before you sign","anchor":"simulate-before-you-sign","text":"`POST /v1/swap/simulate` with the built transaction runs `eth_call` from the user's address and estimates gas. A revert comes back decoded (`NotRouter`, a paused market, allowance or balance) so the wallet never opens on a doomed transaction. An allowance revert is advisory: approve, then swap."},{"heading":"Where fees go","anchor":"where-fees-go","text":"The fee is read per output token from the on-chain fee collector: 5 bps by default on every chain since 2026-10-02, 0 on the stablecoins and majors each chain exempts, capped at 100. It does not change with a token's age. A referrer passed as `feeAccount` on `POST /v1/swap` earns 50 % of the fee on that swap; `/v1/meta/*` and the MCP tools take no referrer. Quotes and API usage are free."}]},{"kind":"page","path":"/docs/concepts/rate-limits/","url":"https://getchord.xyz/docs/concepts/rate-limits/","title":"Rate limits","description":"Per-minute buckets, what shares them, the headers to read, and how to stay under.","markdown":"Limits are per minute and enforced in Redis. Every response carries three headers:\n\n```\nX-RateLimit-Limit: 60\nX-RateLimit-Remaining: 42\nX-RateLimit-Reset: 1789891900\n```\n\nOver the limit you get `429` with `{ \"error\": \"RATE_LIMIT_EXCEEDED\" }`. Wait for `X-RateLimit-Reset` (Unix seconds), then continue. The limiter fails open if the store is unreachable: a store outage never turns into a client outage.\n\n## Buckets\n\nAnonymous traffic is keyed by IP. A key is keyed by the key and gets the plan's limit. Some families are read-heavy by nature and have their own, larger per-IP buckets, so a page that fans out on load cannot starve a swap from the same address.\n\n| Bucket | Applies to | Anonymous limit |\n| --- | --- | --- |\n| Default | `/quote`, `/swap`, `/arc/*`, `/rh/*`, `/lp/*`, `/smart-money/*`, `/points/*`, `/ask/*`, `/bridge2/*` and everything not below | 60 a minute per IP, or your plan with a key |\n| Data reads | `GET /tokens*`, `/portfolio/*`, `/market*`, `/stream/*` | 300 a minute per IP |\n| Logos | `GET /logo/*` | 3,000 a minute per IP |\n| Bridge polling | `GET /crosschain/status` | 240 a minute per IP |\n| Exempt | `/ws/live` upgrades | own connection and channel caps |\n\nThe Ask agent adds its own guard: 8 questions a minute per caller, and a daily token budget for the deployment (`GET /v1/ask/status` shows it).\n\n## Staying under\n\n- Poll boards at 10–30 s and token pages at 5–10 s; the answers are memoised server-side, and polling faster returns the same bytes.\n- Use `/v1/ws/live` for candles, trades and Arc prices instead of polling `/tokens/chart` and `/tokens/trades`.\n- One `/arc/tokens?limit=500` beats 500 token calls; one `/tokens/stats/{address}` beats four windowed calls.\n- Cache `/tokens?chain=` (the curated list) for an hour.\n- Quotes are the expensive call. Quote on user intent, not on every keystroke; the `fast=1` frame exists for the first paint.\n\n## Capacity, not rate\n\nTwo endpoints cap concurrency instead: `/v1/stream/market` at 500 clients and `/v1/ws/live` at 500 connections with 8 channels each. Both answer `503` when full. Reconnect with backoff.","sections":[{"heading":"","anchor":"","text":"Limits are per minute and enforced in Redis. Every response carries three headers:\n\n```\nX-RateLimit-Limit: 60\nX-RateLimit-Remaining: 42\nX-RateLimit-Reset: 1789891900\n```\n\nOver the limit you get `429` with `{ \"error\": \"RATE_LIMIT_EXCEEDED\" }`. Wait for `X-RateLimit-Reset` (Unix seconds), then continue. The limiter fails open if the store is unreachable: a store outage never turns into a client outage."},{"heading":"Buckets","anchor":"buckets","text":"Anonymous traffic is keyed by IP. A key is keyed by the key and gets the plan's limit. Some families are read-heavy by nature and have their own, larger per-IP buckets, so a page that fans out on load cannot starve a swap from the same address.\n\n| Bucket | Applies to | Anonymous limit |\n| --- | --- | --- |\n| Default | `/quote`, `/swap`, `/arc/*`, `/rh/*`, `/lp/*`, `/smart-money/*`, `/points/*`, `/ask/*`, `/bridge2/*` and everything not below | 60 a minute per IP, or your plan with a key |\n| Data reads | `GET /tokens*`, `/portfolio/*`, `/market*`, `/stream/*` | 300 a minute per IP |\n| Logos | `GET /logo/*` | 3,000 a minute per IP |\n| Bridge polling | `GET /crosschain/status` | 240 a minute per IP |\n| Exempt | `/ws/live` upgrades | own connection and channel caps |\n\nThe Ask agent adds its own guard: 8 questions a minute per caller, and a daily token budget for the deployment (`GET /v1/ask/status` shows it)."},{"heading":"Staying under","anchor":"staying-under","text":"- Poll boards at 10–30 s and token pages at 5–10 s; the answers are memoised server-side, and polling faster returns the same bytes.\n- Use `/v1/ws/live` for candles, trades and Arc prices instead of polling `/tokens/chart` and `/tokens/trades`.\n- One `/arc/tokens?limit=500` beats 500 token calls; one `/tokens/stats/{address}` beats four windowed calls.\n- Cache `/tokens?chain=` (the curated list) for an hour.\n- Quotes are the expensive call. Quote on user intent, not on every keystroke; the `fast=1` frame exists for the first paint."},{"heading":"Capacity, not rate","anchor":"capacity-not-rate","text":"Two endpoints cap concurrency instead: `/v1/stream/market` at 500 clients and `/v1/ws/live` at 500 connections with 8 channels each. Both answer `503` when full. Reconnect with backoff."}]},{"kind":"page","path":"/docs/concepts/streaming/","url":"https://getchord.xyz/docs/concepts/streaming/","title":"Streaming","description":"The public WebSocket (candles, trades, and the board-wide feed for Arc and Robinhood Chain — prices, 24h counters, first-time tokens) and the server-sent events feed, with the full protocol.","markdown":"Two push channels replace polling. Neither needs a key.\n\n| Channel | URL | Carries | Use it for |\n| --- | --- | --- | --- |\n| WebSocket | `wss://api.getchord.xyz/v1/ws/live` | live candles per token and timeframe, trade tapes per token, and the board-wide feed per chain (every print, 24h volume and trade counts, tokens trading for the first time) | token pages, charts, boards and tickers on Arc and Robinhood Chain |\n| Server-sent events | `https://api.getchord.xyz/v1/stream/market` | Robinhood Chain prices every ~8 s (`rh-ticker`) | a fallback where WebSockets are blocked |\n\n## WebSocket: `/v1/ws/live`\n\nOpen a socket, send JSON frames to subscribe, receive JSON frames. Up to **8 channels per connection**, 500 connections in total. The server pings every 25 seconds; reply is not required, but a proxy that idles at 100 s will not cut you.\n\n### Subscribe\n\n```json\n{ \"op\": \"sub\", \"channel\": \"candles\", \"token\": \"0x171a4217b86a807a64eb94757db6849fb4bdbaa0\", \"tf\": \"1m\" }\n{ \"op\": \"sub\", \"channel\": \"trades\",  \"token\": \"0x171a4217b86a807a64eb94757db6849fb4bdbaa0\" }\n{ \"op\": \"sub\", \"channel\": \"prices\",  \"chain\": 5042 }\n{ \"op\": \"sub\", \"channel\": \"prices\",  \"chain\": 4663 }\n```\n\n`tf` is one of `1m` · `1h` · `4h` · `1d` · `1w` (candles only). `prices` is keyed by chain, not token: `5042` (Arc), `4663` (Robinhood Chain) or `143` (Monad, prices only). A re-subscribe of a held channel re-acknowledges and re-sends the snapshot without counting twice.\n\n### Frames from the server\n\n```json\n{ \"op\": \"subbed\",  \"channel\": \"candles\", \"token\": \"0x171a…\", \"tf\": \"1m\" }\n{ \"op\": \"candle\",  \"token\": \"0x171a…\", \"tf\": \"1m\", \"candle\": { \"t\": 1789891800, \"o\": 80410.1, \"h\": 80425.0, \"l\": 80398.7, \"c\": 80418.3, \"v\": 1412.5 }, \"closed\": false }\n{ \"op\": \"trades\",  \"token\": \"0x171a…\", \"items\": [ { \"tx\": \"0x…\", \"logIndex\": 41, \"dex\": \"uniswap_v3\", \"side\": \"buy\", \"tokenAmt\": 0.0058, \"usd\": 472.37, \"priceUsd\": 80418.25, \"ts\": 1789891817, \"wallet\": \"0x0e17…\" } ] }\n{ \"op\": \"prices\",  \"chain\": 5042, \"snapshot\": true, \"at\": 1789891400120, \"items\": [ { \"address\": \"0xece5…\", \"priceUsd\": 0.01923, \"ts\": 1789891399, \"block\": 21808201, \"side\": \"buy\", \"usd\": 212.4, \"volume24h\": 48210.5, \"buyVolume24h\": 26011.2, \"sellVolume24h\": 22199.3, \"trades24h\": 1180, \"buys24h\": 640, \"sells24h\": 540 } ] }\n{ \"op\": \"new\",     \"chain\": 5042, \"items\": [ { \"address\": \"0x9f2c…\", \"symbol\": \"TKN\", \"name\": \"Token\", \"decimals\": 18, \"logoURI\": \"https://api.getchord.xyz/v1/logo/5042/0x9f2c…\", \"totalSupply\": 1000000000, \"firstTs\": 1789891402, \"priceUsd\": 0.0000412 } ] }\n{ \"op\": \"ping\", \"t\": 1789891855000 }\n{ \"op\": \"error\", \"code\": \"bad_tf\", \"message\": \"tf must be one of 1m|1h|4h|1d|1w\" }\n```\n\n- `candle` frames repeat the open candle as it updates; `closed: true` marks the last frame for a bucket. Seed the chart from `/v1/tokens/chart` first, then apply frames by `t`.\n- `trades` items have the same shape as `/v1/tokens/trades`.\n- `prices` sends a snapshot of recent prints on subscribe (the last 15 minutes), then one frame every ~400 ms carrying only the tokens that traded. Apply by `address`; later `block` wins.\n- On Arc and Robinhood Chain each item also carries the token's 24h counters **as the board should show them now**: the hourly rollup plus every trade since. Robinhood Chain has no buy/sell split, so only `volume24h` and `trades24h` appear there. `at` is the server time of the frame in milliseconds — REST boards carry `updatedAt` on the same clock, and the later of the two is the current number (the API adds the same not-yet-rolled trades to both, so switching between them never double counts).\n- `new` (Arc and Robinhood Chain) announces a token trading for the first time — neither the 24h board nor the feed had seen it — with its on-chain name and `totalSupply` in whole tokens (market cap = `totalSupply × priceUsd`). A snapshot of up to 100 recent ones follows the `prices` snapshot when there are any; a `prices` snapshot means start the list over. Unscreened: for the screened list use `GET /v1/arc/graduated`.\n- Error codes: `bad_op` · `bad_token` · `bad_tf` · `bad_chain` · `channel_cap`.\n\n### Unsubscribe\n\n```json\n{ \"op\": \"unsub\", \"channel\": \"candles\", \"token\": \"0x171a…\", \"tf\": \"1m\" }\n{ \"op\": \"unsub\", \"channel\": \"prices\", \"chain\": 5042 }\n```\n\n### Browser example\n\n```ts\nconst ws = new WebSocket(\"wss://api.getchord.xyz/v1/ws/live\");\nws.onopen = () => {\n  ws.send(JSON.stringify({ op: \"sub\", channel: \"prices\", chain: 5042 }));\n  ws.send(JSON.stringify({ op: \"sub\", channel: \"candles\", token, tf: \"1m\" }));\n};\nws.onmessage = (e) => {\n  const m = JSON.parse(e.data);\n  if (m.op === \"prices\") for (const it of m.items) prices.set(it.address, it); // price + 24h counters\n  if (m.op === \"new\") for (const t of m.items) newest.unshift(t);\n  if (m.op === \"candle\") chart.update(m.candle, m.closed);\n};\nws.onclose = () => setTimeout(reconnect, 1000 + Math.random() * 2000);\n```\n\nReconnect with jittered backoff and re-subscribe; the server keeps no state for a closed socket.\n\n## Server-sent events: `/v1/stream/market`\n\nAn `EventSource` feed with automatic reconnect built into the browser. Exactly these events:\n\n| `event:` | Cadence | Data |\n| --- | --- | --- |\n| `rh-ticker` | about every 10 s, only when a price moved | `{ \"items\": [ { \"address\", \"priceUsd\", \"change24h\" } ] }` for chain 4663 |\n| `ticker` · `whales` · `defi` | 15–60 s | Monad boards — ignore on Chord |\n| `ping` | 5 s | a timestamp |\n\n```ts\nconst es = new EventSource(\"https://api.getchord.xyz/v1/stream/market\");\nes.addEventListener(\"rh-ticker\", (e) => {\n  for (const it of JSON.parse(e.data).items) prices.set(it.address, it.priceUsd);\n});\n```\n\nCapacity is 500 concurrent clients; `503` beyond that. A closed feed reconnects on its own.\n\n## Which to use\n\n- The whole Arc or Robinhood Chain board — prices, volume, trade counts, new tokens: WebSocket `prices`.\n- Where WebSockets are blocked: SSE `rh-ticker` (Robinhood Chain prices only).\n- One token's chart or tape, either chain: WebSocket `candles` / `trades`.\n- Anything else: poll the REST endpoint at the cadence in [Rate limits](/docs/concepts/rate-limits/).","sections":[{"heading":"","anchor":"","text":"Two push channels replace polling. Neither needs a key.\n\n| Channel | URL | Carries | Use it for |\n| --- | --- | --- | --- |\n| WebSocket | `wss://api.getchord.xyz/v1/ws/live` | live candles per token and timeframe, trade tapes per token, and the board-wide feed per chain (every print, 24h volume and trade counts, tokens trading for the first time) | token pages, charts, boards and tickers on Arc and Robinhood Chain |\n| Server-sent events | `https://api.getchord.xyz/v1/stream/market` | Robinhood Chain prices every ~8 s (`rh-ticker`) | a fallback where WebSockets are blocked |"},{"heading":"WebSocket: /v1/ws/live","anchor":"websocket-v1-ws-live","text":"Open a socket, send JSON frames to subscribe, receive JSON frames. Up to **8 channels per connection**, 500 connections in total. The server pings every 25 seconds; reply is not required, but a proxy that idles at 100 s will not cut you."},{"heading":"Subscribe","anchor":"subscribe","text":"```json\n{ \"op\": \"sub\", \"channel\": \"candles\", \"token\": \"0x171a4217b86a807a64eb94757db6849fb4bdbaa0\", \"tf\": \"1m\" }\n{ \"op\": \"sub\", \"channel\": \"trades\",  \"token\": \"0x171a4217b86a807a64eb94757db6849fb4bdbaa0\" }\n{ \"op\": \"sub\", \"channel\": \"prices\",  \"chain\": 5042 }\n{ \"op\": \"sub\", \"channel\": \"prices\",  \"chain\": 4663 }\n```\n\n`tf` is one of `1m` · `1h` · `4h` · `1d` · `1w` (candles only). `prices` is keyed by chain, not token: `5042` (Arc), `4663` (Robinhood Chain) or `143` (Monad, prices only). A re-subscribe of a held channel re-acknowledges and re-sends the snapshot without counting twice."},{"heading":"Frames from the server","anchor":"frames-from-the-server","text":"```json\n{ \"op\": \"subbed\",  \"channel\": \"candles\", \"token\": \"0x171a…\", \"tf\": \"1m\" }\n{ \"op\": \"candle\",  \"token\": \"0x171a…\", \"tf\": \"1m\", \"candle\": { \"t\": 1789891800, \"o\": 80410.1, \"h\": 80425.0, \"l\": 80398.7, \"c\": 80418.3, \"v\": 1412.5 }, \"closed\": false }\n{ \"op\": \"trades\",  \"token\": \"0x171a…\", \"items\": [ { \"tx\": \"0x…\", \"logIndex\": 41, \"dex\": \"uniswap_v3\", \"side\": \"buy\", \"tokenAmt\": 0.0058, \"usd\": 472.37, \"priceUsd\": 80418.25, \"ts\": 1789891817, \"wallet\": \"0x0e17…\" } ] }\n{ \"op\": \"prices\",  \"chain\": 5042, \"snapshot\": true, \"at\": 1789891400120, \"items\": [ { \"address\": \"0xece5…\", \"priceUsd\": 0.01923, \"ts\": 1789891399, \"block\": 21808201, \"side\": \"buy\", \"usd\": 212.4, \"volume24h\": 48210.5, \"buyVolume24h\": 26011.2, \"sellVolume24h\": 22199.3, \"trades24h\": 1180, \"buys24h\": 640, \"sells24h\": 540 } ] }\n{ \"op\": \"new\",     \"chain\": 5042, \"items\": [ { \"address\": \"0x9f2c…\", \"symbol\": \"TKN\", \"name\": \"Token\", \"decimals\": 18, \"logoURI\": \"https://api.getchord.xyz/v1/logo/5042/0x9f2c…\", \"totalSupply\": 1000000000, \"firstTs\": 1789891402, \"priceUsd\": 0.0000412 } ] }\n{ \"op\": \"ping\", \"t\": 1789891855000 }\n{ \"op\": \"error\", \"code\": \"bad_tf\", \"message\": \"tf must be one of 1m|1h|4h|1d|1w\" }\n```\n\n- `candle` frames repeat the open candle as it updates; `closed: true` marks the last frame for a bucket. Seed the chart from `/v1/tokens/chart` first, then apply frames by `t`.\n- `trades` items have the same shape as `/v1/tokens/trades`.\n- `prices` sends a snapshot of recent prints on subscribe (the last 15 minutes), then one frame every ~400 ms carrying only the tokens that traded. Apply by `address`; later `block` wins.\n- On Arc and Robinhood Chain each item also carries the token's 24h counters **as the board should show them now**: the hourly rollup plus every trade since. Robinhood Chain has no buy/sell split, so only `volume24h` and `trades24h` appear there. `at` is the server time of the frame in milliseconds — REST boards carry `updatedAt` on the same clock, and the later of the two is the current number (the API adds the same not-yet-rolled trades to both, so switching between them never double counts).\n- `new` (Arc and Robinhood Chain) announces a token trading for the first time — neither the 24h board nor the feed had seen it — with its on-chain name and `totalSupply` in whole tokens (market cap = `totalSupply × priceUsd`). A snapshot of up to 100 recent ones follows the `prices` snapshot when there are any; a `prices` snapshot means start the list over. Unscreened: for the screened list use `GET /v1/arc/graduated`.\n- Error codes: `bad_op` · `bad_token` · `bad_tf` · `bad_chain` · `channel_cap`."},{"heading":"Unsubscribe","anchor":"unsubscribe","text":"```json\n{ \"op\": \"unsub\", \"channel\": \"candles\", \"token\": \"0x171a…\", \"tf\": \"1m\" }\n{ \"op\": \"unsub\", \"channel\": \"prices\", \"chain\": 5042 }\n```"},{"heading":"Browser example","anchor":"browser-example","text":"```ts\nconst ws = new WebSocket(\"wss://api.getchord.xyz/v1/ws/live\");\nws.onopen = () => {\n  ws.send(JSON.stringify({ op: \"sub\", channel: \"prices\", chain: 5042 }));\n  ws.send(JSON.stringify({ op: \"sub\", channel: \"candles\", token, tf: \"1m\" }));\n};\nws.onmessage = (e) => {\n  const m = JSON.parse(e.data);\n  if (m.op === \"prices\") for (const it of m.items) prices.set(it.address, it); // price + 24h counters\n  if (m.op === \"new\") for (const t of m.items) newest.unshift(t);\n  if (m.op === \"candle\") chart.update(m.candle, m.closed);\n};\nws.onclose = () => setTimeout(reconnect, 1000 + Math.random() * 2000);\n```\n\nReconnect with jittered backoff and re-subscribe; the server keeps no state for a closed socket."},{"heading":"Server-sent events: /v1/stream/market","anchor":"server-sent-events-v1-stream-market","text":"An `EventSource` feed with automatic reconnect built into the browser. Exactly these events:\n\n| `event:` | Cadence | Data |\n| --- | --- | --- |\n| `rh-ticker` | about every 10 s, only when a price moved | `{ \"items\": [ { \"address\", \"priceUsd\", \"change24h\" } ] }` for chain 4663 |\n| `ticker` · `whales` · `defi` | 15–60 s | Monad boards — ignore on Chord |\n| `ping` | 5 s | a timestamp |\n\n```ts\nconst es = new EventSource(\"https://api.getchord.xyz/v1/stream/market\");\nes.addEventListener(\"rh-ticker\", (e) => {\n  for (const it of JSON.parse(e.data).items) prices.set(it.address, it.priceUsd);\n});\n```\n\nCapacity is 500 concurrent clients; `503` beyond that. A closed feed reconnects on its own."},{"heading":"Which to use","anchor":"which-to-use","text":"- The whole Arc or Robinhood Chain board — prices, volume, trade counts, new tokens: WebSocket `prices`.\n- Where WebSockets are blocked: SSE `rh-ticker` (Robinhood Chain prices only).\n- One token's chart or tape, either chain: WebSocket `candles` / `trades`.\n- Anything else: poll the REST endpoint at the cadence in [Rate limits](/docs/concepts/rate-limits/)."}]},{"kind":"page","path":"/docs/concepts/wallet-pnl/","url":"https://getchord.xyz/docs/concepts/wallet-pnl/","title":"Wallet PnL and Smart Score","description":"How portfolio PnL is computed from the tape, what is excluded, and how the top-wallets board ranks.","markdown":"## Average-cost PnL\n\n`/v1/portfolio/{wallet}/pnl` replays the wallet's swaps from the tape, in order, with an average-cost basis per token:\n\n- A **buy** adds to the position and raises or lowers the average cost.\n- A **sell** realizes `(price − average cost) × amount` against that average and reduces the position.\n- What is still held is marked at the current price (`priceUsd` on the token's dominant venue) as **unrealized**.\n\n`realized`, `unrealized` and `total` are the sums; per token you also get `avgCost`, `curAmount`, `curValue`, `costRemaining` and `roiPct`. The calendar (`/pnl-calendar`) sums the same realized events by UTC day, so it reconciles with `realized` by construction.\n\n### What is excluded\n\n- **Transfers.** A balance that arrived by transfer has no cost basis. It is reported as `untrackedAmount` / `untrackedValue` and left out of PnL. Airdrops, bridged funds and CEX withdrawals fall here.\n- **Liquidity.** Adding to or removing from a pool is not a swap. LP results live in `/v1/lp/positions`.\n- **Gas.** Not deducted.\n\n### Freshness\n\nThe compute walks the wallet's whole tape and is cached with stale-while-revalidate: a fresh answer for a minute, a stale one served for up to a day while a refresh runs behind it. An empty result is never cached over a real one. If the tape read fails you get an empty 200 shape, not a 5xx.\n\n## Smart Score\n\n`/v1/smart-money/top` ranks wallets on the tape by a **Smart Score**, not raw profit:\n\n- **Realized-weighted.** Money taken off the table counts more than paper gains.\n- **Luck-corrected.** Win rate is shrunk toward the mean for wallets with few trades (`winRateAdj`), so one lucky launch does not top the board.\n- **Recency-decayed.** Recent skill counts more than old.\n\nBefore ranking, routers, executors and bots are removed — by cadence (hundreds of transactions a day from a wallet's first trade), by nonce rate and deny lists, and by behaviour (bursts, sub-minute round trips, sniping dozens of launches). `botsRemoved` counts each pass; `totalWallets` is what qualified. Each row carries its archetype (`degen`, `allrounder`, …), meme share, and top token.\n\nThe board is rebuilt per window (15 minutes for 24h, hourly for 7d and 30d, three hours for all) and served from cache between rebuilds. On Arc a live delta of the last minutes' trades sits on top, so the board moves between polls; `live` in the response shows its state.","sections":[{"heading":"Average-cost PnL","anchor":"average-cost-pnl","text":"`/v1/portfolio/{wallet}/pnl` replays the wallet's swaps from the tape, in order, with an average-cost basis per token:\n\n- A **buy** adds to the position and raises or lowers the average cost.\n- A **sell** realizes `(price − average cost) × amount` against that average and reduces the position.\n- What is still held is marked at the current price (`priceUsd` on the token's dominant venue) as **unrealized**.\n\n`realized`, `unrealized` and `total` are the sums; per token you also get `avgCost`, `curAmount`, `curValue`, `costRemaining` and `roiPct`. The calendar (`/pnl-calendar`) sums the same realized events by UTC day, so it reconciles with `realized` by construction."},{"heading":"What is excluded","anchor":"what-is-excluded","text":"- **Transfers.** A balance that arrived by transfer has no cost basis. It is reported as `untrackedAmount` / `untrackedValue` and left out of PnL. Airdrops, bridged funds and CEX withdrawals fall here.\n- **Liquidity.** Adding to or removing from a pool is not a swap. LP results live in `/v1/lp/positions`.\n- **Gas.** Not deducted."},{"heading":"Freshness","anchor":"freshness","text":"The compute walks the wallet's whole tape and is cached with stale-while-revalidate: a fresh answer for a minute, a stale one served for up to a day while a refresh runs behind it. An empty result is never cached over a real one. If the tape read fails you get an empty 200 shape, not a 5xx."},{"heading":"Smart Score","anchor":"smart-score","text":"`/v1/smart-money/top` ranks wallets on the tape by a **Smart Score**, not raw profit:\n\n- **Realized-weighted.** Money taken off the table counts more than paper gains.\n- **Luck-corrected.** Win rate is shrunk toward the mean for wallets with few trades (`winRateAdj`), so one lucky launch does not top the board.\n- **Recency-decayed.** Recent skill counts more than old.\n\nBefore ranking, routers, executors and bots are removed — by cadence (hundreds of transactions a day from a wallet's first trade), by nonce rate and deny lists, and by behaviour (bursts, sub-minute round trips, sniping dozens of launches). `botsRemoved` counts each pass; `totalWallets` is what qualified. Each row carries its archetype (`degen`, `allrounder`, …), meme share, and top token.\n\nThe board is rebuilt per window (15 minutes for 24h, hourly for 7d and 30d, three hours for all) and served from cache between rebuilds. On Arc a live delta of the last minutes' trades sits on top, so the board moves between polls; `live` in the response shows its state."}]},{"kind":"page","path":"/docs/get-started/","url":"https://getchord.xyz/docs/get-started/","title":"Get started","description":"An API key (optional), your first request, and the three calls that take you from nothing to a signed swap on Arc.","markdown":"Chord's API is REST over HTTPS, JSON in and out. The base URL is `https://api.getchord.xyz` and every path starts with `/v1`. Nothing below needs an account.\n\n## 1. Make a request\n\nThe chain overview is the cheapest useful call: the last 24 hours on Arc, venue share, hourly buckets and daily rows, with the coverage flags every read carries.\n\n```bash\ncurl https://api.getchord.xyz/v1/arc/overview\n```\n\n```json\n{\n  \"chain\": 5042,\n  \"last24h\": { \"volUsd\": 70377594.23, \"swaps\": 788926, \"tokens\": 6288, \"sinceHour\": 1789808400 },\n  \"venues24h\": [ { \"dex\": \"uniswap_v4\", \"volUsd\": 55014882.20, \"trades\": 683313, \"tokens\": 4059, \"sharePct\": 78.17 } ],\n  \"hourly24\": [ { \"hour\": 1789808400, \"volUsd\": 3234644.52, \"swaps\": 50225 } ],\n  \"daily\": [ { \"day\": 1787356800, \"swaps\": 5712, \"volUsd\": 609934.64, \"tokens\": 292, \"wallets\": 768, \"venues\": 4 } ],\n  \"coverage\": { \"recentAt\": 1789891429, \"stale\": false, \"backfillComplete\": true },\n  \"updatedAt\": 1789891764243\n}\n```\n\nRead `coverage` before you trust a quiet number. `stale: true` means the most recent rolled-up hour is older than the lane's freshness bar; `backfillComplete: false` means long windows undercount. See [Data freshness](/docs/concepts/data-freshness/).\n\n## 2. Get a key (optional)\n\nAnonymous reads answer at 60 requests a minute per IP. A key raises that to your plan and meters usage per key; it is required for the [Ask agent API](/docs/agents/ask-api/) and for the `only=` debug lever on quotes.\n\n1. Open [getchord.xyz/developer](https://getchord.xyz/developer) and sign in with Google.\n2. Create a key. It is shown once; store it.\n3. Send it as a header on every request.\n\n```bash\ncurl -H \"X-API-Key: YOUR_KEY\" https://api.getchord.xyz/v1/me\n```\n\n```json\n{ \"email\": \"you@example.com\", \"tier\": \"free\", \"limits\": { \"rpm\": 60, \"monthly\": 100000, \"priceUsd\": 0, \"label\": \"Free\" }, \"usage\": { \"today\": 41, \"month\": 1209 } }\n```\n\nPlans are on [getchord.xyz/pricing](https://getchord.xyz/pricing): Free (60 a minute, 300 calls in any 30 days), Build (100 a minute, 16,000 calls) and Grow (150 a minute, 144,000 calls). A plan covers all keys on an account together. See [Rate limits](/docs/concepts/rate-limits/).\n\n## 3. Swap in three calls\n\nThis buys cirBTC with 5 USDC on Arc. Amounts are strings in the token's smallest unit: the USDC predeploy has 6 decimals, so 5 USDC is `5000000`.\n\n### Quote\n\n```bash\ncurl \"https://api.getchord.xyz/v1/quote?chain=5042\\\n&inputMint=0x3600000000000000000000000000000000000000\\\n&outputMint=0x171a4217b86a807a64eb94757db6849fb4bdbaa0\\\n&amount=5000000&slippageBps=100\"\n```\n\nThe answer is the best route: `outputAmount`, `otherAmountThreshold` (the minimum the transaction enforces), `priceImpactPct`, the `routePlan` with one leg per venue, the protocol `feeBps` on the output token, and a gas estimate. An empty `routePlan` with `outputAmount: \"0\"` means no route at this size, and `noRouteReason` says why.\n\n### Build\n\nSend the quote body back unmodified with the wallet that signs.\n\n```bash\ncurl -X POST https://api.getchord.xyz/v1/swap \\\n  -H \"Content-Type: application/json\" \\\n  -d '{ \"quoteResponse\": <the quote body>, \"userPublicKey\": \"0xYourWallet\", \"chain\": 5042 }'\n```\n\n```json\n{ \"transaction\": { \"to\": \"0x1b1fee89a381e595fe6536b99ba91f3e16e9601a\", \"data\": \"0xdc72a437…\", \"value\": \"0\", \"gasLimit\": \"1500000\", \"chainId\": 5042 } }\n```\n\nFor an ERC-20 input, approve `transaction.to` (the Chord router) for at least the input amount first. On Arc the gas token's ERC-20 face is the USDC predeploy, so even a \"native\" input is pulled by `transferFrom` and `value` is always `0`.\n\n### Sign and send\n\n```ts\nconst { transaction } = await res.json();\nawait wallet.sendTransaction({\n  to: transaction.to,\n  data: transaction.data,\n  value: BigInt(transaction.value),\n  gas: BigInt(transaction.gasLimit),\n  chainId: 5042,\n});\n```\n\nBefore the wallet opens you can `POST /v1/swap/simulate` with the same fields: it `eth_call`s the calldata from your address, decodes a revert if there is one, and estimates gas. The full flow, with approvals and simulation, is in the [Swap recipe](/docs/recipes/swap/).\n\n## Next\n\n- [Add Chord to your app](/docs/build/) — the conventions that hold on every endpoint.\n- [Clients and codegen](/docs/clients/) — generate a typed client from the OpenAPI document.\n- [Recipes](/docs/recipes/token-page/) — a token page, a markets board, an LP dashboard, a launch feed.\n- [API reference](/docs/api-reference/) — every endpoint, with real examples.","sections":[{"heading":"","anchor":"","text":"Chord's API is REST over HTTPS, JSON in and out. The base URL is `https://api.getchord.xyz` and every path starts with `/v1`. Nothing below needs an account."},{"heading":"1. Make a request","anchor":"1-make-a-request","text":"The chain overview is the cheapest useful call: the last 24 hours on Arc, venue share, hourly buckets and daily rows, with the coverage flags every read carries.\n\n```bash\ncurl https://api.getchord.xyz/v1/arc/overview\n```\n\n```json\n{\n  \"chain\": 5042,\n  \"last24h\": { \"volUsd\": 70377594.23, \"swaps\": 788926, \"tokens\": 6288, \"sinceHour\": 1789808400 },\n  \"venues24h\": [ { \"dex\": \"uniswap_v4\", \"volUsd\": 55014882.20, \"trades\": 683313, \"tokens\": 4059, \"sharePct\": 78.17 } ],\n  \"hourly24\": [ { \"hour\": 1789808400, \"volUsd\": 3234644.52, \"swaps\": 50225 } ],\n  \"daily\": [ { \"day\": 1787356800, \"swaps\": 5712, \"volUsd\": 609934.64, \"tokens\": 292, \"wallets\": 768, \"venues\": 4 } ],\n  \"coverage\": { \"recentAt\": 1789891429, \"stale\": false, \"backfillComplete\": true },\n  \"updatedAt\": 1789891764243\n}\n```\n\nRead `coverage` before you trust a quiet number. `stale: true` means the most recent rolled-up hour is older than the lane's freshness bar; `backfillComplete: false` means long windows undercount. See [Data freshness](/docs/concepts/data-freshness/)."},{"heading":"2. Get a key (optional)","anchor":"2-get-a-key-optional","text":"Anonymous reads answer at 60 requests a minute per IP. A key raises that to your plan and meters usage per key; it is required for the [Ask agent API](/docs/agents/ask-api/) and for the `only=` debug lever on quotes.\n\n1. Open [getchord.xyz/developer](https://getchord.xyz/developer) and sign in with Google.\n2. Create a key. It is shown once; store it.\n3. Send it as a header on every request.\n\n```bash\ncurl -H \"X-API-Key: YOUR_KEY\" https://api.getchord.xyz/v1/me\n```\n\n```json\n{ \"email\": \"you@example.com\", \"tier\": \"free\", \"limits\": { \"rpm\": 60, \"monthly\": 100000, \"priceUsd\": 0, \"label\": \"Free\" }, \"usage\": { \"today\": 41, \"month\": 1209 } }\n```\n\nPlans are on [getchord.xyz/pricing](https://getchord.xyz/pricing): Free (60 a minute, 300 calls in any 30 days), Build (100 a minute, 16,000 calls) and Grow (150 a minute, 144,000 calls). A plan covers all keys on an account together. See [Rate limits](/docs/concepts/rate-limits/)."},{"heading":"3. Swap in three calls","anchor":"3-swap-in-three-calls","text":"This buys cirBTC with 5 USDC on Arc. Amounts are strings in the token's smallest unit: the USDC predeploy has 6 decimals, so 5 USDC is `5000000`."},{"heading":"Quote","anchor":"quote","text":"```bash\ncurl \"https://api.getchord.xyz/v1/quote?chain=5042\\\n&inputMint=0x3600000000000000000000000000000000000000\\\n&outputMint=0x171a4217b86a807a64eb94757db6849fb4bdbaa0\\\n&amount=5000000&slippageBps=100\"\n```\n\nThe answer is the best route: `outputAmount`, `otherAmountThreshold` (the minimum the transaction enforces), `priceImpactPct`, the `routePlan` with one leg per venue, the protocol `feeBps` on the output token, and a gas estimate. An empty `routePlan` with `outputAmount: \"0\"` means no route at this size, and `noRouteReason` says why."},{"heading":"Build","anchor":"build","text":"Send the quote body back unmodified with the wallet that signs.\n\n```bash\ncurl -X POST https://api.getchord.xyz/v1/swap \\\n  -H \"Content-Type: application/json\" \\\n  -d '{ \"quoteResponse\": <the quote body>, \"userPublicKey\": \"0xYourWallet\", \"chain\": 5042 }'\n```\n\n```json\n{ \"transaction\": { \"to\": \"0x1b1fee89a381e595fe6536b99ba91f3e16e9601a\", \"data\": \"0xdc72a437…\", \"value\": \"0\", \"gasLimit\": \"1500000\", \"chainId\": 5042 } }\n```\n\nFor an ERC-20 input, approve `transaction.to` (the Chord router) for at least the input amount first. On Arc the gas token's ERC-20 face is the USDC predeploy, so even a \"native\" input is pulled by `transferFrom` and `value` is always `0`."},{"heading":"Sign and send","anchor":"sign-and-send","text":"```ts\nconst { transaction } = await res.json();\nawait wallet.sendTransaction({\n  to: transaction.to,\n  data: transaction.data,\n  value: BigInt(transaction.value),\n  gas: BigInt(transaction.gasLimit),\n  chainId: 5042,\n});\n```\n\nBefore the wallet opens you can `POST /v1/swap/simulate` with the same fields: it `eth_call`s the calldata from your address, decodes a revert if there is one, and estimates gas. The full flow, with approvals and simulation, is in the [Swap recipe](/docs/recipes/swap/)."},{"heading":"Next","anchor":"next","text":"- [Add Chord to your app](/docs/build/) — the conventions that hold on every endpoint.\n- [Clients and codegen](/docs/clients/) — generate a typed client from the OpenAPI document.\n- [Recipes](/docs/recipes/token-page/) — a token page, a markets board, an LP dashboard, a launch feed.\n- [API reference](/docs/api-reference/) — every endpoint, with real examples."}]},{"kind":"page","path":"/docs/launchpads/","url":"https://getchord.xyz/docs/launchpads/","title":"Supported launchpads","description":"The launcher contracts Chord names on Arc, what they create, and how to follow their launches through the API.","markdown":"Most tokens on Arc are created through a launcher contract that deploys the token and initialises its first pool — a Uniswap V4 pool with a hook that runs a bonding curve, or a V3 / V2 pool with seeded liquidity. Chord's launch radar watches every pool creation on the chain, attributes it to the contract that made it, and names the ones it knows. `GET /v1/arc/launchers` returns the live activity of every launcher, named or not, with the addresses.\n\n| Launcher | Site | Pools it creates |\n| --- | --- | --- |\n| Uniswap Liquidity Launcher | github.com/Uniswap/sdks | V4 |\n| Uniswap V4 PoolManager (direct) | app.uniswap.org | V4 |\n| Pools.trade | pools.trade | V4 (fee 2500, tick spacing 25) |\n| aka.fun | aka.fun | V4 |\n| Argus | argus.world | V4 |\n| Minara.fun | minara.fun | V4 |\n| Rapid Launch | rapidlaunch.io | V4 |\n| Sharc.fun | sharc.fun | V4 |\n| Bozo | bozo.fun | V4 |\n| o1 Launchpad | launch.o1.exchange | V4 |\n| Enso | enso.trade | V4 |\n| Triplfun | tripl.fun | V4 |\n| BullCheese | bullcheese.fun | V4 |\n| par.family | par.family | V4 |\n| lift.fun | lift.fun | V3, V4 |\n| Long.supply | long.supply | V3, V4 |\n| Synthra | synthra.org | V3 |\n| TOLLY | tollylabs.com | V3 |\n| circlearc.fun | circlearc.fun | V3 |\n| ArcPad | arcpad.meme | V3 |\n| Curving | curving.fun | V3 |\n| DEPLOY | deploydollars.com | V3 |\n| ARClove | arclove.fun | V3 |\n| ARK | ark-ai.xyz | V3 |\n| PEGD | pegd.fun | V3 |\n| BigShort | bigshort.xyz | V2 |\n| Niorfun | niorfun.com | V2 |\n| Tollan | tollan.io | V2 |\n\n## Routing hooked pools\n\nA V4 launchpad pool carries a hook, and a hook can do anything to a swap — including quoting one amount and delivering another. Chord routes a hook only after a real swap has been verified in both directions on it; an unverified hook is not routed, and its tokens show `routable: false` until it is. The engine has verified the launchpad hooks in the table above plus two per-token hook templates; a token on a hook it has not seen quotes `NO_POOLS`.\n\n## Following launches\n\n- Feed: `GET /v1/arc/graduated?hours=48` — screened launches, newest first, with `launcher` and `launcherName`.\n- Activity per launcher: `GET /v1/arc/launchers?hours=24` — pool shapes, pools per hour, creators, 24-hour swaps and volume over its pools.\n- Forensics per token: holders, pools with launch facts, windowed stats — the [Launch lifecycle](/docs/recipes/launchpad-lifecycle/) recipe.\n- Token art: launchers publish metadata off-chain in different places; Chord resolves logos from the token contract, the launcher's events, and public sources, and serves them at `/v1/logo/5042/{address}` with a placeholder until found.\n\nA launcher you use that is missing here: the address still appears in `/v1/arc/launchers` and on every launch row; naming it is a one-line registry change on Chord's side.","sections":[{"heading":"","anchor":"","text":"Most tokens on Arc are created through a launcher contract that deploys the token and initialises its first pool — a Uniswap V4 pool with a hook that runs a bonding curve, or a V3 / V2 pool with seeded liquidity. Chord's launch radar watches every pool creation on the chain, attributes it to the contract that made it, and names the ones it knows. `GET /v1/arc/launchers` returns the live activity of every launcher, named or not, with the addresses.\n\n| Launcher | Site | Pools it creates |\n| --- | --- | --- |\n| Uniswap Liquidity Launcher | github.com/Uniswap/sdks | V4 |\n| Uniswap V4 PoolManager (direct) | app.uniswap.org | V4 |\n| Pools.trade | pools.trade | V4 (fee 2500, tick spacing 25) |\n| aka.fun | aka.fun | V4 |\n| Argus | argus.world | V4 |\n| Minara.fun | minara.fun | V4 |\n| Rapid Launch | rapidlaunch.io | V4 |\n| Sharc.fun | sharc.fun | V4 |\n| Bozo | bozo.fun | V4 |\n| o1 Launchpad | launch.o1.exchange | V4 |\n| Enso | enso.trade | V4 |\n| Triplfun | tripl.fun | V4 |\n| BullCheese | bullcheese.fun | V4 |\n| par.family | par.family | V4 |\n| lift.fun | lift.fun | V3, V4 |\n| Long.supply | long.supply | V3, V4 |\n| Synthra | synthra.org | V3 |\n| TOLLY | tollylabs.com | V3 |\n| circlearc.fun | circlearc.fun | V3 |\n| ArcPad | arcpad.meme | V3 |\n| Curving | curving.fun | V3 |\n| DEPLOY | deploydollars.com | V3 |\n| ARClove | arclove.fun | V3 |\n| ARK | ark-ai.xyz | V3 |\n| PEGD | pegd.fun | V3 |\n| BigShort | bigshort.xyz | V2 |\n| Niorfun | niorfun.com | V2 |\n| Tollan | tollan.io | V2 |"},{"heading":"Routing hooked pools","anchor":"routing-hooked-pools","text":"A V4 launchpad pool carries a hook, and a hook can do anything to a swap — including quoting one amount and delivering another. Chord routes a hook only after a real swap has been verified in both directions on it; an unverified hook is not routed, and its tokens show `routable: false` until it is. The engine has verified the launchpad hooks in the table above plus two per-token hook templates; a token on a hook it has not seen quotes `NO_POOLS`."},{"heading":"Following launches","anchor":"following-launches","text":"- Feed: `GET /v1/arc/graduated?hours=48` — screened launches, newest first, with `launcher` and `launcherName`.\n- Activity per launcher: `GET /v1/arc/launchers?hours=24` — pool shapes, pools per hour, creators, 24-hour swaps and volume over its pools.\n- Forensics per token: holders, pools with launch facts, windowed stats — the [Launch lifecycle](/docs/recipes/launchpad-lifecycle/) recipe.\n- Token art: launchers publish metadata off-chain in different places; Chord resolves logos from the token contract, the launcher's events, and public sources, and serves them at `/v1/logo/5042/{address}` with a placeholder until found.\n\nA launcher you use that is missing here: the address still appears in `/v1/arc/launchers` and on every launch row; naming it is a one-line registry change on Chord's side."}]},{"kind":"page","path":"/docs/networks/","url":"https://getchord.xyz/docs/networks/","title":"Supported networks","description":"The chains Chord indexes and routes on, with ids, gas, anchors and the data families that serve them.","markdown":"| Network | Chain id | Gas | Stable anchor | Trading | Data | Streams |\n| --- | --- | --- | --- | --- | --- | --- |\n| [Arc](/docs/networks/arc/) | `5042` | USDC (native) | USDC predeploy `0x3600…0000`, EURC | Uniswap V3 / V4 / V2, launchpad hooks, the forks | `/v1/arc/*`, `/v1/lp/*`, portfolio, top wallets, holders, points, Ask | WebSocket `prices`, `candles`, `trades` |\n| [Robinhood Chain](/docs/networks/robinhood-chain/) | `4663` | ETH | USDG | Uniswap V3 / V4, GIGA, SwapHood, PancakeSwap, up, Metric OMM | `/v1/rh/*`, `/v1/lp/*`, portfolio, top wallets, holders | SSE `rh-ticker`, WebSocket `prices`, `candles`, `trades` |\n| [Monad](/docs/networks/monad/) | `143` | MON | USDC | Uniswap V3 / V4, PancakeSwap, Capricorn, Atlantis, LFJ, Kuru, Hanji, Metric, WOOFi, Balancer, Curve, Mento, nad.fun | `/v1/tokens/*`, `/v1/markets/monad/hourly`, `/v1/lp/*`, portfolio, top wallets | WebSocket `prices` |\n| [Avalanche](/docs/networks/avalanche/) | `43114` | AVAX | USDC, USDt | Uniswap V3 / V4, Pharaoh, LFJ, Pangolin, Blackhole, Metric, WOOFi | `/v1/chains/avalanche/*`, candles, search | none |\n| [Base](/docs/networks/base/) | `8453` | ETH | USDC, USDT | Uniswap V2 / V3 / V4, PancakeSwap, Aerodrome, Hydrex, QuickSwap, Metric | `/v1/chains/base/*`, candles, search | none |\n| [BNB Chain](/docs/networks/bnb-chain/) | `56` | BNB | USDT, USDC (18 decimals) | PancakeSwap V2 / V3 / Infinity, Uniswap V3 / V4, Topaz, THENA | `/v1/chains/bnb/*` (swaps ≥ $100), candles, search | none |\n| [Arbitrum](/docs/networks/arbitrum/) | `42161` | ETH | USDC, USDT0 | Uniswap V2 / V3 / V4, PancakeSwap, SushiSwap, Camelot, Metric, WOOFi | `/v1/chains/arbitrum/*`, candles, search | none |\n| [Ethereum](/docs/networks/ethereum/) | `1` | ETH | USDC, USDT, DAI | Uniswap V2 / V3 / V4, PancakeSwap, SushiSwap | `/v1/chains/ethereum/*`, candles, search | none |\n| [Solana](/docs/networks/solana/) | none (`solana` in the path) | SOL | USDC, USDT, wSOL | swaps (`/v1/sol/trade/*`): Chord's own router on Raydium, Orca, Meteora, pump.fun and PumpSwap, against Jupiter, best of both | `/v1/chains/solana/*` (11 venues) | none |\n\nEvery EVM chain above shares the router, fee and registry contracts at the same addresses, and one API: `/v1/quote` and `/v1/swap` take any of the eight chain ids. Pass `chain=` where an endpoint takes it; the `/arc/*`, `/rh/*` and `/chains/{chain}/*` families are bound to their chain. `GET /v1/chains` lists the chains with the route that serves each capability, and is the place to check before calling a route on a chain.\n\nThe data on Arc, Robinhood Chain and Monad is the deepest (top wallets, wallet PnL, liquidity positions); on Avalanche, Base, BNB Chain, Arbitrum and Ethereum it is the tape, token and wallet routes of `/v1/chains/{chain}/*`. Robinhood Chain data (tokenized stocks and ETFs, 24/7) is on the stocks page of the Chord app.\n\nSolana has its own API: swaps under `/v1/sol/trade/*`, where every quote builds Chord's own route and Jupiter's for your wallet and keeps whichever leaves it with more, and data from Chord's own tape of the swap events of 11 Solana venues (pump.fun, PumpSwap, Meteora, Raydium, Orca), with base58, case-sensitive addresses. It does not read prop AMMs or order books, so major pairs are understated. See [Solana](/docs/networks/solana/).","sections":[{"heading":"","anchor":"","text":"| Network | Chain id | Gas | Stable anchor | Trading | Data | Streams |\n| --- | --- | --- | --- | --- | --- | --- |\n| [Arc](/docs/networks/arc/) | `5042` | USDC (native) | USDC predeploy `0x3600…0000`, EURC | Uniswap V3 / V4 / V2, launchpad hooks, the forks | `/v1/arc/*`, `/v1/lp/*`, portfolio, top wallets, holders, points, Ask | WebSocket `prices`, `candles`, `trades` |\n| [Robinhood Chain](/docs/networks/robinhood-chain/) | `4663` | ETH | USDG | Uniswap V3 / V4, GIGA, SwapHood, PancakeSwap, up, Metric OMM | `/v1/rh/*`, `/v1/lp/*`, portfolio, top wallets, holders | SSE `rh-ticker`, WebSocket `prices`, `candles`, `trades` |\n| [Monad](/docs/networks/monad/) | `143` | MON | USDC | Uniswap V3 / V4, PancakeSwap, Capricorn, Atlantis, LFJ, Kuru, Hanji, Metric, WOOFi, Balancer, Curve, Mento, nad.fun | `/v1/tokens/*`, `/v1/markets/monad/hourly`, `/v1/lp/*`, portfolio, top wallets | WebSocket `prices` |\n| [Avalanche](/docs/networks/avalanche/) | `43114` | AVAX | USDC, USDt | Uniswap V3 / V4, Pharaoh, LFJ, Pangolin, Blackhole, Metric, WOOFi | `/v1/chains/avalanche/*`, candles, search | none |\n| [Base](/docs/networks/base/) | `8453` | ETH | USDC, USDT | Uniswap V2 / V3 / V4, PancakeSwap, Aerodrome, Hydrex, QuickSwap, Metric | `/v1/chains/base/*`, candles, search | none |\n| [BNB Chain](/docs/networks/bnb-chain/) | `56` | BNB | USDT, USDC (18 decimals) | PancakeSwap V2 / V3 / Infinity, Uniswap V3 / V4, Topaz, THENA | `/v1/chains/bnb/*` (swaps ≥ $100), candles, search | none |\n| [Arbitrum](/docs/networks/arbitrum/) | `42161` | ETH | USDC, USDT0 | Uniswap V2 / V3 / V4, PancakeSwap, SushiSwap, Camelot, Metric, WOOFi | `/v1/chains/arbitrum/*`, candles, search | none |\n| [Ethereum](/docs/networks/ethereum/) | `1` | ETH | USDC, USDT, DAI | Uniswap V2 / V3 / V4, PancakeSwap, SushiSwap | `/v1/chains/ethereum/*`, candles, search | none |\n| [Solana](/docs/networks/solana/) | none (`solana` in the path) | SOL | USDC, USDT, wSOL | swaps (`/v1/sol/trade/*`): Chord's own router on Raydium, Orca, Meteora, pump.fun and PumpSwap, against Jupiter, best of both | `/v1/chains/solana/*` (11 venues) | none |\n\nEvery EVM chain above shares the router, fee and registry contracts at the same addresses, and one API: `/v1/quote` and `/v1/swap` take any of the eight chain ids. Pass `chain=` where an endpoint takes it; the `/arc/*`, `/rh/*` and `/chains/{chain}/*` families are bound to their chain. `GET /v1/chains` lists the chains with the route that serves each capability, and is the place to check before calling a route on a chain.\n\nThe data on Arc, Robinhood Chain and Monad is the deepest (top wallets, wallet PnL, liquidity positions); on Avalanche, Base, BNB Chain, Arbitrum and Ethereum it is the tape, token and wallet routes of `/v1/chains/{chain}/*`. Robinhood Chain data (tokenized stocks and ETFs, 24/7) is on the stocks page of the Chord app.\n\nSolana has its own API: swaps under `/v1/sol/trade/*`, where every quote builds Chord's own route and Jupiter's for your wallet and keeps whichever leaves it with more, and data from Chord's own tape of the swap events of 11 Solana venues (pump.fun, PumpSwap, Meteora, Raydium, Orca), with base58, case-sensitive addresses. It does not read prop AMMs or order books, so major pairs are understated. See [Solana](/docs/networks/solana/)."}]},{"kind":"page","path":"/docs/networks/arbitrum/","url":"https://getchord.xyz/docs/networks/arbitrum/","title":"Arbitrum","description":"Arbitrum One (42161). Ids, anchors, contracts, venues and the /v1/chains/arbitrum/* data family.","markdown":"| | |\n| --- | --- |\n| Chain id | `42161` (key `arbitrum` in `/v1/chains/{chain}/*`) |\n| Gas | ETH (zero address in the API; WETH `0x82aF49447D8a07e3bd95BD0d56f35241523fBab1`) |\n| Blocks | ~250 ms |\n| Stable anchors | USDC `0xaf88d065e77c8cC2239327C5EDb3A432268e5831` and USDT0 `0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9` (6 decimals); the bridged USDC.e counts as a dollar too |\n| Explorer | [arbiscan.io](https://arbiscan.io) |\n| Chord index since | 2026-10-06 20:00 UTC |\n\n## Chord contracts\n\nThe same proxies as every EVM chain Chord routes on: router `0x1b1fee89a381e595fe6536b99ba91f3e16e9601a`, fee collector `0x6c66229675fd9ceda9a9b2ea2bd983b3d8255834`, adapter registry `0x6cf25d2af1a58d7094b0ac253ae616a8e1f2ea3f`. Adapters come with every quote. Protocol fee: 5 bps by default, 0 on the dollar stables and WETH.\n\n## Venues\n\nRouting covers Uniswap V2, V3 and V4, PancakeSwap V3, SushiSwap V2 and V3, Camelot V3, Metric and WOOFi. The data index covers every venue on the chain; `GET /v1/chains/arbitrum/venues` is the live list with share. Common ids: `uniswap_v3` · `uniswap_v4` · `pancake_v3` · `camelot_v3` · `sushi_v3` · `sushi_v2` · `camelot_v2` · `uniswap_v2` · `ramses_v2` · `pancake_v2`.\n\n## Endpoints\n\n| Need | Call |\n| --- | --- |\n| Freshness and coverage | `GET /v1/chains/arbitrum/status` |\n| Chain totals, venue share, hourly and daily | `GET /v1/chains/arbitrum/overview` |\n| Every token traded in 24h | `GET /v1/chains/arbitrum/tokens` |\n| One token's hourly tape and venue split, its swaps | `GET /v1/chains/arbitrum/token/{address}`, `…/token/{address}/trades` |\n| Search | `GET /v1/tokens/search?q=&chain=42161` |\n| Candles | `GET /v1/candles?chain=42161&token=` |\n| A wallet's swaps and PnL | `GET /v1/chains/arbitrum/wallet/{address}`, `…/wallet/{address}/trades` |\n| Quote and swap | `GET /v1/quote?chain=42161…`, `POST /v1/swap { chain: 42161 }`, native ETH goes in `value` |\n\nThere are no top-wallet, holder or liquidity boards for Arbitrum yet.","sections":[{"heading":"","anchor":"","text":"| | |\n| --- | --- |\n| Chain id | `42161` (key `arbitrum` in `/v1/chains/{chain}/*`) |\n| Gas | ETH (zero address in the API; WETH `0x82aF49447D8a07e3bd95BD0d56f35241523fBab1`) |\n| Blocks | ~250 ms |\n| Stable anchors | USDC `0xaf88d065e77c8cC2239327C5EDb3A432268e5831` and USDT0 `0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9` (6 decimals); the bridged USDC.e counts as a dollar too |\n| Explorer | [arbiscan.io](https://arbiscan.io) |\n| Chord index since | 2026-10-06 20:00 UTC |"},{"heading":"Chord contracts","anchor":"chord-contracts","text":"The same proxies as every EVM chain Chord routes on: router `0x1b1fee89a381e595fe6536b99ba91f3e16e9601a`, fee collector `0x6c66229675fd9ceda9a9b2ea2bd983b3d8255834`, adapter registry `0x6cf25d2af1a58d7094b0ac253ae616a8e1f2ea3f`. Adapters come with every quote. Protocol fee: 5 bps by default, 0 on the dollar stables and WETH."},{"heading":"Venues","anchor":"venues","text":"Routing covers Uniswap V2, V3 and V4, PancakeSwap V3, SushiSwap V2 and V3, Camelot V3, Metric and WOOFi. The data index covers every venue on the chain; `GET /v1/chains/arbitrum/venues` is the live list with share. Common ids: `uniswap_v3` · `uniswap_v4` · `pancake_v3` · `camelot_v3` · `sushi_v3` · `sushi_v2` · `camelot_v2` · `uniswap_v2` · `ramses_v2` · `pancake_v2`."},{"heading":"Endpoints","anchor":"endpoints","text":"| Need | Call |\n| --- | --- |\n| Freshness and coverage | `GET /v1/chains/arbitrum/status` |\n| Chain totals, venue share, hourly and daily | `GET /v1/chains/arbitrum/overview` |\n| Every token traded in 24h | `GET /v1/chains/arbitrum/tokens` |\n| One token's hourly tape and venue split, its swaps | `GET /v1/chains/arbitrum/token/{address}`, `…/token/{address}/trades` |\n| Search | `GET /v1/tokens/search?q=&chain=42161` |\n| Candles | `GET /v1/candles?chain=42161&token=` |\n| A wallet's swaps and PnL | `GET /v1/chains/arbitrum/wallet/{address}`, `…/wallet/{address}/trades` |\n| Quote and swap | `GET /v1/quote?chain=42161…`, `POST /v1/swap { chain: 42161 }`, native ETH goes in `value` |\n\nThere are no top-wallet, holder or liquidity boards for Arbitrum yet."}]},{"kind":"page","path":"/docs/networks/arc/","url":"https://getchord.xyz/docs/networks/arc/","title":"Arc","description":"Chain 5042 — Circle's USDC-native L1. Ids, RPC, the two faces of USDC, contracts, venues and launchers as Chord indexes them.","markdown":"| | |\n| --- | --- |\n| Chain id | `5042` |\n| Gas | USDC — native (18 decimals) with an ERC-20 face at the predeploy `0x3600000000000000000000000000000000000000` (6 decimals) |\n| Finality | sub-second |\n| Explorer | [explorer.arc.io](https://explorer.arc.io) |\n| Public RPC | `https://rpc.mainnet.arc.io` (rate-limited; Chord lists alternatives at [getchord.xyz/rpc](https://getchord.xyz/rpc)) |\n| Chord index since | genesis (rollups reach `genesisHour`; pool discovery reached genesis) |\n\n## USDC, twice\n\nNative USDC pays gas and appears as `currency0 = address(0)` in Uniswap V4 pools with 18 decimals; the predeploy is the same balance seen as an ERC-20 with 6 decimals (`balanceOf == native / 1e12`). There is no wrapped-native contract. The API takes the predeploy, treats the zero address as its alias, and always builds transactions with `value: \"0\"`. Details in [Chains, addresses and amounts](/docs/concepts/chains-and-amounts/).\n\nOther anchors: EURC `0xbef5f6d51cb62b58e6a8f77868681825c6fe21c1` (6 decimals, tagged `fx`), VIRTUAL `0x8c4252c87081c88c6ad57d6dd97e1cafebf842b7` (Virtuals launcher quote asset, priced from its USDC prints). Beware tokens named USDC that are not the predeploy — the API flags them `impostor`.\n\n## Chord contracts\n\n| Contract | Address |\n| --- | --- |\n| Router (UUPS proxy) — `transaction.to` in every `/swap` answer | `0x1b1fee89a381e595fe6536b99ba91f3e16e9601a` |\n| Fee collector (UUPS proxy) — `feeBpsFor(token)` is the on-chain fee authority | `0x6c66229675fd9ceda9a9b2ea2bd983b3d8255834` |\n| Adapter registry (UUPS proxy) — the approved venue adapters | `0x6cf25d2af1a58d7094b0ac253ae616a8e1f2ea3f` |\n\nAdapters (one per venue family: Uniswap V3 and forks, Uniswap V4 with native currency, V2 with tax detection) are returned inside every quote's `routePlan`; never hardcode them. The fee schedule: USDC and EURC 0 bps, every other token 5 bps.\n\n## Protocol contracts Chord reads\n\n| | Address |\n| --- | --- |\n| Uniswap V3 factory | `0xf0db7b58379503491d857db50ac9ece64c653918` |\n| Uniswap V3 QuoterV2 | `0x7dfd4f31be6814d2906bde155c3e1b146eac1468` |\n| Uniswap V3 NonfungiblePositionManager | `0x39654a85a4c05127f5fd6ed22caec077a0fb1377` |\n| Uniswap V2 factory | `0x89e5db8b5aa49aa85ac63f691524311aeb649eba` |\n| Uniswap V4 PoolManager | `0x8366a39cc670b4001a1121b8f6a443a643e40951` |\n| Uniswap V4 PositionManager | `0x6049c9a0e26405c0985f9e3685c87d0ae917f82b` |\n| Uniswap V4 StateView | `0xf3334192d15450cdd385c8b70e03f9a6bd9e673b` |\n| Uniswap V4 Quoter | `0x8dc178efb8111bb0973dd9d722ebeff267c98f94` |\n| SwapRouter02 | `0x53bf6b0684ec7ef91e1387da3d1a1769bc5a6f77` |\n| Permit2 | `0x000000000022d473030f116ddee9f6b43ac78ba3` |\n| Multicall3 | `0xca11bde05977b3631167028862be2a173976ca11` |\n\n## Venues\n\nEvery pool from every factory and the V4 PoolManager is indexed for data; routing covers the Uniswap trio plus verified launchpad hooks and the named forks. Venue ids as they appear in `dex` fields:\n\n| id | Venue |\n| --- | --- |\n| `uniswap_v4` | Uniswap V4 (most launches live here; hooked pools are per-launcher curves) |\n| `uniswap_v3` · `uniswap_v2` | Uniswap V3 / V2 |\n| `pools_trade` | Pools.trade — V4 pools (fee 2500, tick spacing 25) through its launcher |\n| `synthra_v3` | Synthra |\n| `sushi_v2` · `sushi_v3` | SushiSwap V2 / V3 |\n| `dyorswap` | DYORSwap |\n| `slipstream_fork` | an Aerodrome Slipstream fork (\"Aero\") |\n| `v3fork_<8hex>` · `v2fork_<8hex>` | unnamed forks, keyed by the first 8 hex of the factory |\n\n`GET /v1/arc/venues` is the live list with volume and share. Names for display are in [Venue ids](/docs/resources/venue-ids/).\n\n## Launchers\n\nArc's tokens are mostly born through launcher contracts. Chord names 27 of them and indexes the rest by address; the [Launchpads](/docs/launchpads/) page lists them and `GET /v1/arc/launchers` reports their activity.\n\n## Data lanes\n\n| Lane | Freshness | Endpoint to check |\n| --- | --- | --- |\n| Trade tape (every swap, priced) | seconds behind the head (WebSocket head trigger + a forward crawler) | `/v1/arc/status` → `recentAt`, `staleSec` |\n| Hourly / daily rollups | rolled every few minutes | `/v1/arc/status` → `coverage` |\n| Pool index (V2 / V3 / V4 discovery) | minutes | `/v1/arc/status` → `index` |\n| Holder ledger (Transfer logs for tracked tokens) | forward lane near the head; backfill per token | `/v1/arc/status` → `holders`; per token `complete` |\n| Liquidity events, pools, positions | minutes | `/v1/lp/status` |\n| Live prices | per print, over WebSocket | subscribe `prices` |","sections":[{"heading":"","anchor":"","text":"| | |\n| --- | --- |\n| Chain id | `5042` |\n| Gas | USDC — native (18 decimals) with an ERC-20 face at the predeploy `0x3600000000000000000000000000000000000000` (6 decimals) |\n| Finality | sub-second |\n| Explorer | [explorer.arc.io](https://explorer.arc.io) |\n| Public RPC | `https://rpc.mainnet.arc.io` (rate-limited; Chord lists alternatives at [getchord.xyz/rpc](https://getchord.xyz/rpc)) |\n| Chord index since | genesis (rollups reach `genesisHour`; pool discovery reached genesis) |"},{"heading":"USDC, twice","anchor":"usdc-twice","text":"Native USDC pays gas and appears as `currency0 = address(0)` in Uniswap V4 pools with 18 decimals; the predeploy is the same balance seen as an ERC-20 with 6 decimals (`balanceOf == native / 1e12`). There is no wrapped-native contract. The API takes the predeploy, treats the zero address as its alias, and always builds transactions with `value: \"0\"`. Details in [Chains, addresses and amounts](/docs/concepts/chains-and-amounts/).\n\nOther anchors: EURC `0xbef5f6d51cb62b58e6a8f77868681825c6fe21c1` (6 decimals, tagged `fx`), VIRTUAL `0x8c4252c87081c88c6ad57d6dd97e1cafebf842b7` (Virtuals launcher quote asset, priced from its USDC prints). Beware tokens named USDC that are not the predeploy — the API flags them `impostor`."},{"heading":"Chord contracts","anchor":"chord-contracts","text":"| Contract | Address |\n| --- | --- |\n| Router (UUPS proxy) — `transaction.to` in every `/swap` answer | `0x1b1fee89a381e595fe6536b99ba91f3e16e9601a` |\n| Fee collector (UUPS proxy) — `feeBpsFor(token)` is the on-chain fee authority | `0x6c66229675fd9ceda9a9b2ea2bd983b3d8255834` |\n| Adapter registry (UUPS proxy) — the approved venue adapters | `0x6cf25d2af1a58d7094b0ac253ae616a8e1f2ea3f` |\n\nAdapters (one per venue family: Uniswap V3 and forks, Uniswap V4 with native currency, V2 with tax detection) are returned inside every quote's `routePlan`; never hardcode them. The fee schedule: USDC and EURC 0 bps, every other token 5 bps."},{"heading":"Protocol contracts Chord reads","anchor":"protocol-contracts-chord-reads","text":"| | Address |\n| --- | --- |\n| Uniswap V3 factory | `0xf0db7b58379503491d857db50ac9ece64c653918` |\n| Uniswap V3 QuoterV2 | `0x7dfd4f31be6814d2906bde155c3e1b146eac1468` |\n| Uniswap V3 NonfungiblePositionManager | `0x39654a85a4c05127f5fd6ed22caec077a0fb1377` |\n| Uniswap V2 factory | `0x89e5db8b5aa49aa85ac63f691524311aeb649eba` |\n| Uniswap V4 PoolManager | `0x8366a39cc670b4001a1121b8f6a443a643e40951` |\n| Uniswap V4 PositionManager | `0x6049c9a0e26405c0985f9e3685c87d0ae917f82b` |\n| Uniswap V4 StateView | `0xf3334192d15450cdd385c8b70e03f9a6bd9e673b` |\n| Uniswap V4 Quoter | `0x8dc178efb8111bb0973dd9d722ebeff267c98f94` |\n| SwapRouter02 | `0x53bf6b0684ec7ef91e1387da3d1a1769bc5a6f77` |\n| Permit2 | `0x000000000022d473030f116ddee9f6b43ac78ba3` |\n| Multicall3 | `0xca11bde05977b3631167028862be2a173976ca11` |"},{"heading":"Venues","anchor":"venues","text":"Every pool from every factory and the V4 PoolManager is indexed for data; routing covers the Uniswap trio plus verified launchpad hooks and the named forks. Venue ids as they appear in `dex` fields:\n\n| id | Venue |\n| --- | --- |\n| `uniswap_v4` | Uniswap V4 (most launches live here; hooked pools are per-launcher curves) |\n| `uniswap_v3` · `uniswap_v2` | Uniswap V3 / V2 |\n| `pools_trade` | Pools.trade — V4 pools (fee 2500, tick spacing 25) through its launcher |\n| `synthra_v3` | Synthra |\n| `sushi_v2` · `sushi_v3` | SushiSwap V2 / V3 |\n| `dyorswap` | DYORSwap |\n| `slipstream_fork` | an Aerodrome Slipstream fork (\"Aero\") |\n| `v3fork_<8hex>` · `v2fork_<8hex>` | unnamed forks, keyed by the first 8 hex of the factory |\n\n`GET /v1/arc/venues` is the live list with volume and share. Names for display are in [Venue ids](/docs/resources/venue-ids/)."},{"heading":"Launchers","anchor":"launchers","text":"Arc's tokens are mostly born through launcher contracts. Chord names 27 of them and indexes the rest by address; the [Launchpads](/docs/launchpads/) page lists them and `GET /v1/arc/launchers` reports their activity."},{"heading":"Data lanes","anchor":"data-lanes","text":"| Lane | Freshness | Endpoint to check |\n| --- | --- | --- |\n| Trade tape (every swap, priced) | seconds behind the head (WebSocket head trigger + a forward crawler) | `/v1/arc/status` → `recentAt`, `staleSec` |\n| Hourly / daily rollups | rolled every few minutes | `/v1/arc/status` → `coverage` |\n| Pool index (V2 / V3 / V4 discovery) | minutes | `/v1/arc/status` → `index` |\n| Holder ledger (Transfer logs for tracked tokens) | forward lane near the head; backfill per token | `/v1/arc/status` → `holders`; per token `complete` |\n| Liquidity events, pools, positions | minutes | `/v1/lp/status` |\n| Live prices | per print, over WebSocket | subscribe `prices` |"}]},{"kind":"page","path":"/docs/networks/avalanche/","url":"https://getchord.xyz/docs/networks/avalanche/","title":"Avalanche","description":"Avalanche C-Chain (43114). Ids, anchors, contracts, venues and the /v1/chains/avalanche/* data family.","markdown":"| | |\n| --- | --- |\n| Chain id | `43114` (key `avalanche` in `/v1/chains/{chain}/*`) |\n| Gas | AVAX (zero address in the API; WAVAX `0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7`) |\n| Blocks | ~1.3 s |\n| Stable anchors | USDC `0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E` and USDt `0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7` (6 decimals); the bridged USDC.e and USDT.e count as dollars too |\n| Explorer | [snowtrace.io](https://snowtrace.io) |\n| Chord index since | 2026-09-23 16:00 UTC |\n\n## Chord contracts\n\nThe same proxies as every EVM chain Chord routes on: router `0x1b1fee89a381e595fe6536b99ba91f3e16e9601a`, fee collector `0x6c66229675fd9ceda9a9b2ea2bd983b3d8255834`, adapter registry `0x6cf25d2af1a58d7094b0ac253ae616a8e1f2ea3f`. Adapters come with every quote. Protocol fee: 5 bps by default, 0 on the dollar stables and WAVAX.\n\n## Venues\n\nRouting covers Uniswap V3 and V4, Pharaoh (V3 and DLMM), LFJ (V1 and Liquidity Book), Pangolin V2 and V3, Blackhole (V2 and CL), Metric and WOOFi. The data index covers every venue on the chain; `GET /v1/chains/avalanche/venues` is the live list with share. Common ids: `pharaoh_v3` · `pharaoh_dlmm` · `uniswap_v3` · `blackhole_v3` · `lfj_lb_v22` · `lfj_lb_v21` · `uniswap_v4` · `lfj_v1` · `pangolin_v2` · `pangolin_v3` · `blackhole_v2`.\n\n## Endpoints\n\n| Need | Call |\n| --- | --- |\n| Freshness and coverage | `GET /v1/chains/avalanche/status` |\n| Chain totals, venue share, hourly and daily | `GET /v1/chains/avalanche/overview` |\n| Every token traded in 24h | `GET /v1/chains/avalanche/tokens` |\n| One token's hourly tape and venue split, its swaps | `GET /v1/chains/avalanche/token/{address}`, `…/token/{address}/trades` |\n| Search | `GET /v1/tokens/search?q=&chain=43114` |\n| Candles | `GET /v1/candles?chain=43114&token=` |\n| A wallet's swaps and PnL | `GET /v1/chains/avalanche/wallet/{address}`, `…/wallet/{address}/trades` |\n| Quote and swap | `GET /v1/quote?chain=43114…`, `POST /v1/swap { chain: 43114 }`, native AVAX goes in `value` |\n\nThe database keeps the raw tape for about 7 days on this chain; a wallet's older days come from Chord's data lake, and the answer's `window` and `history` say which. There are no top-wallet, holder or liquidity boards for Avalanche yet.","sections":[{"heading":"","anchor":"","text":"| | |\n| --- | --- |\n| Chain id | `43114` (key `avalanche` in `/v1/chains/{chain}/*`) |\n| Gas | AVAX (zero address in the API; WAVAX `0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7`) |\n| Blocks | ~1.3 s |\n| Stable anchors | USDC `0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E` and USDt `0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7` (6 decimals); the bridged USDC.e and USDT.e count as dollars too |\n| Explorer | [snowtrace.io](https://snowtrace.io) |\n| Chord index since | 2026-09-23 16:00 UTC |"},{"heading":"Chord contracts","anchor":"chord-contracts","text":"The same proxies as every EVM chain Chord routes on: router `0x1b1fee89a381e595fe6536b99ba91f3e16e9601a`, fee collector `0x6c66229675fd9ceda9a9b2ea2bd983b3d8255834`, adapter registry `0x6cf25d2af1a58d7094b0ac253ae616a8e1f2ea3f`. Adapters come with every quote. Protocol fee: 5 bps by default, 0 on the dollar stables and WAVAX."},{"heading":"Venues","anchor":"venues","text":"Routing covers Uniswap V3 and V4, Pharaoh (V3 and DLMM), LFJ (V1 and Liquidity Book), Pangolin V2 and V3, Blackhole (V2 and CL), Metric and WOOFi. The data index covers every venue on the chain; `GET /v1/chains/avalanche/venues` is the live list with share. Common ids: `pharaoh_v3` · `pharaoh_dlmm` · `uniswap_v3` · `blackhole_v3` · `lfj_lb_v22` · `lfj_lb_v21` · `uniswap_v4` · `lfj_v1` · `pangolin_v2` · `pangolin_v3` · `blackhole_v2`."},{"heading":"Endpoints","anchor":"endpoints","text":"| Need | Call |\n| --- | --- |\n| Freshness and coverage | `GET /v1/chains/avalanche/status` |\n| Chain totals, venue share, hourly and daily | `GET /v1/chains/avalanche/overview` |\n| Every token traded in 24h | `GET /v1/chains/avalanche/tokens` |\n| One token's hourly tape and venue split, its swaps | `GET /v1/chains/avalanche/token/{address}`, `…/token/{address}/trades` |\n| Search | `GET /v1/tokens/search?q=&chain=43114` |\n| Candles | `GET /v1/candles?chain=43114&token=` |\n| A wallet's swaps and PnL | `GET /v1/chains/avalanche/wallet/{address}`, `…/wallet/{address}/trades` |\n| Quote and swap | `GET /v1/quote?chain=43114…`, `POST /v1/swap { chain: 43114 }`, native AVAX goes in `value` |\n\nThe database keeps the raw tape for about 7 days on this chain; a wallet's older days come from Chord's data lake, and the answer's `window` and `history` say which. There are no top-wallet, holder or liquidity boards for Avalanche yet."}]},{"kind":"page","path":"/docs/networks/base/","url":"https://getchord.xyz/docs/networks/base/","title":"Base","description":"Base (8453). Ids, anchors, contracts, venues and the /v1/chains/base/* data family.","markdown":"| | |\n| --- | --- |\n| Chain id | `8453` (key `base` in `/v1/chains/{chain}/*`) |\n| Gas | ETH (zero address in the API; WETH `0x4200000000000000000000000000000000000006`) |\n| Blocks | ~2 s |\n| Stable anchors | USDC `0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913` and USDT `0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2` (6 decimals); the bridged USDbC counts as a dollar too |\n| Explorer | [basescan.org](https://basescan.org) |\n| Chord index since | 2026-09-23 15:00 UTC |\n\n## Chord contracts\n\nThe same proxies as every EVM chain Chord routes on: router `0x1b1fee89a381e595fe6536b99ba91f3e16e9601a`, fee collector `0x6c66229675fd9ceda9a9b2ea2bd983b3d8255834`, adapter registry `0x6cf25d2af1a58d7094b0ac253ae616a8e1f2ea3f`. Adapters come with every quote. Protocol fee: 5 bps by default, 0 on the dollar stables and WETH.\n\n## Venues\n\nRouting covers Uniswap V2, V3 and V4, PancakeSwap V3, Aerodrome (Slipstream and V2), Hydrex, QuickSwap V4 and Metric. The data index covers every venue on the chain; `GET /v1/chains/base/venues` is the live list with share. Common ids: `aerodrome_slipstream_3` · `uniswap_v3` · `aerodrome_slipstream` · `pancake_v3` · `uniswap_v4` · `aerodrome_v2` · `aerodrome_slipstream_2` · `uniswap_v2` · `hydrex_integral` · `quickswap_v4` · `sushi_v3`.\n\n## Endpoints\n\n| Need | Call |\n| --- | --- |\n| Freshness and coverage | `GET /v1/chains/base/status` |\n| Chain totals, venue share, hourly and daily | `GET /v1/chains/base/overview` |\n| Every token traded in 24h | `GET /v1/chains/base/tokens` |\n| One token's hourly tape and venue split, its swaps | `GET /v1/chains/base/token/{address}`, `…/token/{address}/trades` |\n| Search | `GET /v1/tokens/search?q=&chain=8453` |\n| Candles | `GET /v1/candles?chain=8453&token=` |\n| A wallet's swaps and PnL | `GET /v1/chains/base/wallet/{address}`, `…/wallet/{address}/trades` |\n| Quote and swap | `GET /v1/quote?chain=8453…`, `POST /v1/swap { chain: 8453 }`, native ETH goes in `value` |\n\nThe database keeps the raw tape for about 3 days on this chain; a wallet's older days come from Chord's data lake, and the answer's `window` and `history` say which. There are no top-wallet, holder or liquidity boards for Base yet.","sections":[{"heading":"","anchor":"","text":"| | |\n| --- | --- |\n| Chain id | `8453` (key `base` in `/v1/chains/{chain}/*`) |\n| Gas | ETH (zero address in the API; WETH `0x4200000000000000000000000000000000000006`) |\n| Blocks | ~2 s |\n| Stable anchors | USDC `0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913` and USDT `0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2` (6 decimals); the bridged USDbC counts as a dollar too |\n| Explorer | [basescan.org](https://basescan.org) |\n| Chord index since | 2026-09-23 15:00 UTC |"},{"heading":"Chord contracts","anchor":"chord-contracts","text":"The same proxies as every EVM chain Chord routes on: router `0x1b1fee89a381e595fe6536b99ba91f3e16e9601a`, fee collector `0x6c66229675fd9ceda9a9b2ea2bd983b3d8255834`, adapter registry `0x6cf25d2af1a58d7094b0ac253ae616a8e1f2ea3f`. Adapters come with every quote. Protocol fee: 5 bps by default, 0 on the dollar stables and WETH."},{"heading":"Venues","anchor":"venues","text":"Routing covers Uniswap V2, V3 and V4, PancakeSwap V3, Aerodrome (Slipstream and V2), Hydrex, QuickSwap V4 and Metric. The data index covers every venue on the chain; `GET /v1/chains/base/venues` is the live list with share. Common ids: `aerodrome_slipstream_3` · `uniswap_v3` · `aerodrome_slipstream` · `pancake_v3` · `uniswap_v4` · `aerodrome_v2` · `aerodrome_slipstream_2` · `uniswap_v2` · `hydrex_integral` · `quickswap_v4` · `sushi_v3`."},{"heading":"Endpoints","anchor":"endpoints","text":"| Need | Call |\n| --- | --- |\n| Freshness and coverage | `GET /v1/chains/base/status` |\n| Chain totals, venue share, hourly and daily | `GET /v1/chains/base/overview` |\n| Every token traded in 24h | `GET /v1/chains/base/tokens` |\n| One token's hourly tape and venue split, its swaps | `GET /v1/chains/base/token/{address}`, `…/token/{address}/trades` |\n| Search | `GET /v1/tokens/search?q=&chain=8453` |\n| Candles | `GET /v1/candles?chain=8453&token=` |\n| A wallet's swaps and PnL | `GET /v1/chains/base/wallet/{address}`, `…/wallet/{address}/trades` |\n| Quote and swap | `GET /v1/quote?chain=8453…`, `POST /v1/swap { chain: 8453 }`, native ETH goes in `value` |\n\nThe database keeps the raw tape for about 3 days on this chain; a wallet's older days come from Chord's data lake, and the answer's `window` and `history` say which. There are no top-wallet, holder or liquidity boards for Base yet."}]},{"kind":"page","path":"/docs/networks/bnb-chain/","url":"https://getchord.xyz/docs/networks/bnb-chain/","title":"BNB Chain","description":"BNB Chain (56). Ids, anchors with 18 decimals, contracts, venues, the $100 ingest floor and the /v1/chains/bnb/* data family.","markdown":"| | |\n| --- | --- |\n| Chain id | `56` (key `bnb` in `/v1/chains/{chain}/*`) |\n| Gas | BNB (zero address in the API; WBNB `0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c`) |\n| Blocks | ~450 ms |\n| Stable anchors | USDT `0x55d398326f99059fF775485246999027B3197955`, USDC `0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d`, USD1, FDUSD, BUSD: all **18 decimals** |\n| Explorer | [bscscan.com](https://bscscan.com) |\n| Chord index since | 2026-09-30 17:00 UTC |\n\nThe dollar stables on BNB Chain have 18 decimals, not 6: 10 USDT is `\"10000000000000000000\"`. Read decimals from the token row, as everywhere.\n\n## Swaps under $100 are not indexed\n\nThe tape records swaps of $100 or more only (since it started). Every `/v1/chains/bnb/*` and `/v1/candles?chain=56` answer carries `ingestFloor` (`minTradeUsd: 100`). Token volumes, trade counts and wallet histories on this chain leave out the small swaps; say so when you show them. Quotes and swaps are not affected.\n\n## Chord contracts\n\nThe same proxies as every EVM chain Chord routes on: router `0x1b1fee89a381e595fe6536b99ba91f3e16e9601a`, fee collector `0x6c66229675fd9ceda9a9b2ea2bd983b3d8255834`, adapter registry `0x6cf25d2af1a58d7094b0ac253ae616a8e1f2ea3f`. Adapters come with every quote. Protocol fee: 5 bps by default, 0 on the dollar stables and WBNB.\n\n## Venues\n\nRouting covers PancakeSwap (V2, V3 and Infinity CL), Uniswap V3 and V4, Topaz and THENA V3. The data index covers every venue on the chain; `GET /v1/chains/bnb/venues` is the live list with share. Common ids: `pancake_v3` · `pancake_infinity_cl` · `pancake_v2` · `uniswap_v4` · `uniswap_v3` · `topaz` · `flap` · `thena_v3` · `fstswap`.\n\n## Endpoints\n\n| Need | Call |\n| --- | --- |\n| Freshness, coverage and the ingest floor | `GET /v1/chains/bnb/status` |\n| Chain totals, venue share, hourly and daily | `GET /v1/chains/bnb/overview` |\n| Every token traded in 24h | `GET /v1/chains/bnb/tokens` |\n| One token's hourly tape and venue split, its swaps | `GET /v1/chains/bnb/token/{address}`, `…/token/{address}/trades` |\n| Search | `GET /v1/tokens/search?q=&chain=56` |\n| Candles | `GET /v1/candles?chain=56&token=` |\n| A wallet's swaps and PnL | `GET /v1/chains/bnb/wallet/{address}`, `…/wallet/{address}/trades` |\n| Quote and swap | `GET /v1/quote?chain=56…`, `POST /v1/swap { chain: 56 }`, native BNB goes in `value` |\n\nThe database keeps the raw tape for about 3 days on this chain; a wallet's older days come from Chord's data lake, and the answer's `window` and `history` say which. There are no top-wallet, holder or liquidity boards for BNB Chain yet.","sections":[{"heading":"","anchor":"","text":"| | |\n| --- | --- |\n| Chain id | `56` (key `bnb` in `/v1/chains/{chain}/*`) |\n| Gas | BNB (zero address in the API; WBNB `0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c`) |\n| Blocks | ~450 ms |\n| Stable anchors | USDT `0x55d398326f99059fF775485246999027B3197955`, USDC `0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d`, USD1, FDUSD, BUSD: all **18 decimals** |\n| Explorer | [bscscan.com](https://bscscan.com) |\n| Chord index since | 2026-09-30 17:00 UTC |\n\nThe dollar stables on BNB Chain have 18 decimals, not 6: 10 USDT is `\"10000000000000000000\"`. Read decimals from the token row, as everywhere."},{"heading":"Swaps under $100 are not indexed","anchor":"swaps-under-100-are-not-indexed","text":"The tape records swaps of $100 or more only (since it started). Every `/v1/chains/bnb/*` and `/v1/candles?chain=56` answer carries `ingestFloor` (`minTradeUsd: 100`). Token volumes, trade counts and wallet histories on this chain leave out the small swaps; say so when you show them. Quotes and swaps are not affected."},{"heading":"Chord contracts","anchor":"chord-contracts","text":"The same proxies as every EVM chain Chord routes on: router `0x1b1fee89a381e595fe6536b99ba91f3e16e9601a`, fee collector `0x6c66229675fd9ceda9a9b2ea2bd983b3d8255834`, adapter registry `0x6cf25d2af1a58d7094b0ac253ae616a8e1f2ea3f`. Adapters come with every quote. Protocol fee: 5 bps by default, 0 on the dollar stables and WBNB."},{"heading":"Venues","anchor":"venues","text":"Routing covers PancakeSwap (V2, V3 and Infinity CL), Uniswap V3 and V4, Topaz and THENA V3. The data index covers every venue on the chain; `GET /v1/chains/bnb/venues` is the live list with share. Common ids: `pancake_v3` · `pancake_infinity_cl` · `pancake_v2` · `uniswap_v4` · `uniswap_v3` · `topaz` · `flap` · `thena_v3` · `fstswap`."},{"heading":"Endpoints","anchor":"endpoints","text":"| Need | Call |\n| --- | --- |\n| Freshness, coverage and the ingest floor | `GET /v1/chains/bnb/status` |\n| Chain totals, venue share, hourly and daily | `GET /v1/chains/bnb/overview` |\n| Every token traded in 24h | `GET /v1/chains/bnb/tokens` |\n| One token's hourly tape and venue split, its swaps | `GET /v1/chains/bnb/token/{address}`, `…/token/{address}/trades` |\n| Search | `GET /v1/tokens/search?q=&chain=56` |\n| Candles | `GET /v1/candles?chain=56&token=` |\n| A wallet's swaps and PnL | `GET /v1/chains/bnb/wallet/{address}`, `…/wallet/{address}/trades` |\n| Quote and swap | `GET /v1/quote?chain=56…`, `POST /v1/swap { chain: 56 }`, native BNB goes in `value` |\n\nThe database keeps the raw tape for about 3 days on this chain; a wallet's older days come from Chord's data lake, and the answer's `window` and `history` say which. There are no top-wallet, holder or liquidity boards for BNB Chain yet."}]},{"kind":"page","path":"/docs/networks/ethereum/","url":"https://getchord.xyz/docs/networks/ethereum/","title":"Ethereum","description":"Ethereum mainnet (1). Ids, anchors, contracts, venues and the /v1/chains/ethereum/* data family.","markdown":"| | |\n| --- | --- |\n| Chain id | `1` (key `ethereum` in `/v1/chains/{chain}/*`) |\n| Gas | ETH (zero address in the API; WETH `0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2`) |\n| Blocks | ~12 s |\n| Stable anchors | USDC `0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48` and USDT `0xdAC17F958D2ee523a2206206994597C13D831ec7` (6 decimals); DAI `0x6B175474E89094C44Da98b954EedeAC495271d0F` (18 decimals) |\n| Explorer | [etherscan.io](https://etherscan.io) |\n| Chord index since | 2026-10-08 17:00 UTC |\n\n## Chord contracts\n\nThe same proxies as every EVM chain Chord routes on: router `0x1b1fee89a381e595fe6536b99ba91f3e16e9601a`, fee collector `0x6c66229675fd9ceda9a9b2ea2bd983b3d8255834`, adapter registry `0x6cf25d2af1a58d7094b0ac253ae616a8e1f2ea3f`. Adapters come with every quote. Protocol fee: 5 bps by default, 0 on USDC, USDT, DAI, WETH and WBTC.\n\n## USDT approvals\n\nUSDT on Ethereum refuses a new `approve` while the spender still holds a non-zero allowance. Approve exactly the input amount (the swap uses all of it, so the allowance returns to 0). When an older allowance is left over, send `approve(spender, 0)` first: `/v1/meta/quote` and `/v1/meta/swap` say so with `approval.resetFirst: true`.\n\n## Venues\n\nRouting covers Uniswap V2, V3 and V4, PancakeSwap V3, SushiSwap V2 and V3. Curve, Fluid, Balancer and Ekubo are not routed yet; the data index reads the venues that emit Uniswap-shaped swap events (about 93 % of the chain's swaps). `GET /v1/chains/ethereum/venues` is the live list with share. Common ids: `uniswap_v3` · `uniswap_v4` · `uniswap_v2` · `pancake_v3` · `sushi_v3` · `sushi_v2` · `ring_v2` · `supernova_cl` · `shibaswap` · `fraxswap`.\n\n## Endpoints\n\n| Need | Call |\n| --- | --- |\n| Freshness and coverage | `GET /v1/chains/ethereum/status` |\n| Chain totals, venue share, hourly and daily | `GET /v1/chains/ethereum/overview` |\n| Every token traded in 24h | `GET /v1/chains/ethereum/tokens` |\n| One token's hourly tape and venue split, its swaps | `GET /v1/chains/ethereum/token/{address}`, `…/token/{address}/trades` |\n| Search | `GET /v1/tokens/search?q=&chain=1` |\n| Candles | `GET /v1/candles?chain=1&token=` |\n| A wallet's swaps and PnL | `GET /v1/chains/ethereum/wallet/{address}`, `…/wallet/{address}/trades` |\n| Quote and swap | `GET /v1/quote?chain=1…`, `POST /v1/swap { chain: 1 }`, native ETH goes in `value` |\n\n```bash\ncurl -s \"https://api.getchord.xyz/v1/quote?chain=1&inputMint=0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2&outputMint=0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48&amount=1000000000000000000\"\n```\n\n1 WETH to USDC on 2026-10-15: `outputAmount` 2452700960 (2,452.70 USDC), split 96 % Uniswap V3 and 4 % PancakeSwap V3.\n\nThere are no top-wallet, holder or liquidity boards for Ethereum yet.","sections":[{"heading":"","anchor":"","text":"| | |\n| --- | --- |\n| Chain id | `1` (key `ethereum` in `/v1/chains/{chain}/*`) |\n| Gas | ETH (zero address in the API; WETH `0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2`) |\n| Blocks | ~12 s |\n| Stable anchors | USDC `0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48` and USDT `0xdAC17F958D2ee523a2206206994597C13D831ec7` (6 decimals); DAI `0x6B175474E89094C44Da98b954EedeAC495271d0F` (18 decimals) |\n| Explorer | [etherscan.io](https://etherscan.io) |\n| Chord index since | 2026-10-08 17:00 UTC |"},{"heading":"Chord contracts","anchor":"chord-contracts","text":"The same proxies as every EVM chain Chord routes on: router `0x1b1fee89a381e595fe6536b99ba91f3e16e9601a`, fee collector `0x6c66229675fd9ceda9a9b2ea2bd983b3d8255834`, adapter registry `0x6cf25d2af1a58d7094b0ac253ae616a8e1f2ea3f`. Adapters come with every quote. Protocol fee: 5 bps by default, 0 on USDC, USDT, DAI, WETH and WBTC."},{"heading":"USDT approvals","anchor":"usdt-approvals","text":"USDT on Ethereum refuses a new `approve` while the spender still holds a non-zero allowance. Approve exactly the input amount (the swap uses all of it, so the allowance returns to 0). When an older allowance is left over, send `approve(spender, 0)` first: `/v1/meta/quote` and `/v1/meta/swap` say so with `approval.resetFirst: true`."},{"heading":"Venues","anchor":"venues","text":"Routing covers Uniswap V2, V3 and V4, PancakeSwap V3, SushiSwap V2 and V3. Curve, Fluid, Balancer and Ekubo are not routed yet; the data index reads the venues that emit Uniswap-shaped swap events (about 93 % of the chain's swaps). `GET /v1/chains/ethereum/venues` is the live list with share. Common ids: `uniswap_v3` · `uniswap_v4` · `uniswap_v2` · `pancake_v3` · `sushi_v3` · `sushi_v2` · `ring_v2` · `supernova_cl` · `shibaswap` · `fraxswap`."},{"heading":"Endpoints","anchor":"endpoints","text":"| Need | Call |\n| --- | --- |\n| Freshness and coverage | `GET /v1/chains/ethereum/status` |\n| Chain totals, venue share, hourly and daily | `GET /v1/chains/ethereum/overview` |\n| Every token traded in 24h | `GET /v1/chains/ethereum/tokens` |\n| One token's hourly tape and venue split, its swaps | `GET /v1/chains/ethereum/token/{address}`, `…/token/{address}/trades` |\n| Search | `GET /v1/tokens/search?q=&chain=1` |\n| Candles | `GET /v1/candles?chain=1&token=` |\n| A wallet's swaps and PnL | `GET /v1/chains/ethereum/wallet/{address}`, `…/wallet/{address}/trades` |\n| Quote and swap | `GET /v1/quote?chain=1…`, `POST /v1/swap { chain: 1 }`, native ETH goes in `value` |\n\n```bash\ncurl -s \"https://api.getchord.xyz/v1/quote?chain=1&inputMint=0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2&outputMint=0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48&amount=1000000000000000000\"\n```\n\n1 WETH to USDC on 2026-10-15: `outputAmount` 2452700960 (2,452.70 USDC), split 96 % Uniswap V3 and 4 % PancakeSwap V3.\n\nThere are no top-wallet, holder or liquidity boards for Ethereum yet."}]},{"kind":"page","path":"/docs/networks/monad/","url":"https://getchord.xyz/docs/networks/monad/","title":"Monad","description":"Chain 143, where Chord's routing engine started. Ids, anchors, contracts, the venues routing covers and where the chain's data is read.","markdown":"| | |\n| --- | --- |\n| Chain id | `143`, also the default of `/quote`, `/swap` and `/candles` when `chain` is omitted. Pass it anyway. |\n| Gas | MON (zero address in the API; WMON `0x3bd359C1119dA7Da1D913D1C4D2B7c461115433A`) |\n| Blocks | ~300 ms |\n| Stable anchor | USDC `0x754704Bc059F8C67012fEd69BC8A327a5aafb603` (6 decimals) |\n| Explorer | [monadscan.com](https://monadscan.com) |\n\n## Chord contracts\n\nThe same proxies as every EVM chain Chord routes on: router `0x1b1fee89a381e595fe6536b99ba91f3e16e9601a`, fee collector `0x6c66229675fd9ceda9a9b2ea2bd983b3d8255834`, adapter registry `0x6cf25d2af1a58d7094b0ac253ae616a8e1f2ea3f`. Adapters come with every quote. Protocol fee: 5 bps by default, 0 on dollar stables, MON / WMON and the majors.\n\nMonad is the only chain where `POST /v1/swap` takes `batch: \"7702\"`: one signature for approve and swap through an EIP-7702 delegate.\n\n## Venues\n\nRouting covers the AMMs (Uniswap V3 and V4, PancakeSwap V3, Capricorn V3, Atlantis, LFJ Liquidity Book), the order books Kuru and Hanji, the oracle-priced pools Metric, LFJ POE and WOOFi, Balancer V3, Curve StableSwap-NG, Mento FX, nad.fun (bonding curve before graduation and its DEX after), and buy-only deposits into the aprMON, shMON and gMON vaults. Composed hops go through WMON, shMON, AUSD and USDT0. The quote's `routePlan` names the venue of each leg.\n\n## Endpoints\n\n| Need | Call |\n| --- | --- |\n| Hourly swaps and USD, last 24 hours | `GET /v1/markets/monad/hourly` |\n| Token board by volume or change | `GET /v1/tokens/board?chain=143&sort=volume` |\n| One token: windows, markets, tape | `GET /v1/tokens/stats/{address}`, `GET /v1/tokens/trades/{address}` |\n| Search beyond the list | `GET /v1/tokens/search?q=&chain=143` |\n| Candles | `GET /v1/candles?chain=143&token=` |\n| Quote and swap | `GET /v1/quote?chain=143…`, `POST /v1/swap { chain: 143 }`, native MON goes in `value` |\n| Wallet PnL and trades, top wallets, liquidity | `chain=143` on `/v1/portfolio/{wallet}/pnl`, `/trades` and `/pnl-calendar`, `/v1/smart-money/top?source=onchain`, `/v1/lp/*` |\n| Holdings, 24h / 7d / 30d PnL and swaps | `GET /v1/portfolio/{wallet}?chains=143`, `GET /v1/portfolio/{wallet}/activity?chains=143` (`chains`, not `chain`) |\n| Live prices | WebSocket `/v1/ws/live`, channel `prices`, chain `143` |\n\nThere is no holder ledger for Monad tokens.","sections":[{"heading":"","anchor":"","text":"| | |\n| --- | --- |\n| Chain id | `143`, also the default of `/quote`, `/swap` and `/candles` when `chain` is omitted. Pass it anyway. |\n| Gas | MON (zero address in the API; WMON `0x3bd359C1119dA7Da1D913D1C4D2B7c461115433A`) |\n| Blocks | ~300 ms |\n| Stable anchor | USDC `0x754704Bc059F8C67012fEd69BC8A327a5aafb603` (6 decimals) |\n| Explorer | [monadscan.com](https://monadscan.com) |"},{"heading":"Chord contracts","anchor":"chord-contracts","text":"The same proxies as every EVM chain Chord routes on: router `0x1b1fee89a381e595fe6536b99ba91f3e16e9601a`, fee collector `0x6c66229675fd9ceda9a9b2ea2bd983b3d8255834`, adapter registry `0x6cf25d2af1a58d7094b0ac253ae616a8e1f2ea3f`. Adapters come with every quote. Protocol fee: 5 bps by default, 0 on dollar stables, MON / WMON and the majors.\n\nMonad is the only chain where `POST /v1/swap` takes `batch: \"7702\"`: one signature for approve and swap through an EIP-7702 delegate."},{"heading":"Venues","anchor":"venues","text":"Routing covers the AMMs (Uniswap V3 and V4, PancakeSwap V3, Capricorn V3, Atlantis, LFJ Liquidity Book), the order books Kuru and Hanji, the oracle-priced pools Metric, LFJ POE and WOOFi, Balancer V3, Curve StableSwap-NG, Mento FX, nad.fun (bonding curve before graduation and its DEX after), and buy-only deposits into the aprMON, shMON and gMON vaults. Composed hops go through WMON, shMON, AUSD and USDT0. The quote's `routePlan` names the venue of each leg."},{"heading":"Endpoints","anchor":"endpoints","text":"| Need | Call |\n| --- | --- |\n| Hourly swaps and USD, last 24 hours | `GET /v1/markets/monad/hourly` |\n| Token board by volume or change | `GET /v1/tokens/board?chain=143&sort=volume` |\n| One token: windows, markets, tape | `GET /v1/tokens/stats/{address}`, `GET /v1/tokens/trades/{address}` |\n| Search beyond the list | `GET /v1/tokens/search?q=&chain=143` |\n| Candles | `GET /v1/candles?chain=143&token=` |\n| Quote and swap | `GET /v1/quote?chain=143…`, `POST /v1/swap { chain: 143 }`, native MON goes in `value` |\n| Wallet PnL and trades, top wallets, liquidity | `chain=143` on `/v1/portfolio/{wallet}/pnl`, `/trades` and `/pnl-calendar`, `/v1/smart-money/top?source=onchain`, `/v1/lp/*` |\n| Holdings, 24h / 7d / 30d PnL and swaps | `GET /v1/portfolio/{wallet}?chains=143`, `GET /v1/portfolio/{wallet}/activity?chains=143` (`chains`, not `chain`) |\n| Live prices | WebSocket `/v1/ws/live`, channel `prices`, chain `143` |\n\nThere is no holder ledger for Monad tokens."}]},{"kind":"page","path":"/docs/networks/robinhood-chain/","url":"https://getchord.xyz/docs/networks/robinhood-chain/","title":"Robinhood Chain","description":"Chain 4663 — tokenized stocks and ETFs on-chain, 24/7. Ids, anchors, venues and the /v1/rh/* data family.","markdown":"| | |\n| --- | --- |\n| Chain id | `4663` |\n| Gas | ETH (zero address in the API; WETH `0x0Bd7D308f8E1639FAb988df18A8011f41EAcAD73`) |\n| Blocks | ~100 ms |\n| Stable anchor | USDG `0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168` (6 decimals) |\n| Explorer | [robin.etherscan.io](https://robin.etherscan.io) |\n| Public RPC | `https://rpc.mainnet.chain.robinhood.com` |\n| Chord index since | the chain's first swap (`genesisHour` on `/v1/rh/status`) |\n\n## Tokenized stocks\n\nEquities and ETFs are 18-decimal tokens tagged `stock` on the curated list (NVDA `0xd0601CE157Db5bdC3162BbaC2a2C8aF5320D9EEC`, AAPL `0xaF3D76f1834A1d425780943C99Ea8A608f8a93f9`, SPCX, …). They trade around the clock; `GET /v1/rh/stocks` reports each one's 24-hour tape, the issuer's NAV where published (`navUsd`, `basisPct`) and the share of the last seven days that traded outside the NYSE session (`offHours7d`). Protocol fee on WETH, USDG and every stock is 0 bps.\n\n## Chord contracts\n\nThe same proxies as Arc: router `0x1b1fee89a381e595fe6536b99ba91f3e16e9601a`, fee collector `0x6c66229675fd9ceda9a9b2ea2bd983b3d8255834`, adapter registry `0x6cf25d2af1a58d7094b0ac253ae616a8e1f2ea3f`. Adapters come with every quote.\n\n## Venues\n\nRouting covers Uniswap V3 and V4, GIGA V3, SwapHood V3, PancakeSwap V3, up v3 and the Metric OMM, plus composed hops through WETH and USDG. The data index covers every venue on the chain, including the ones routing does not use; `GET /v1/rh/venues` is the live list with ids and share. Common ids: `uniswap_v3` · `uniswap_v4` · `uniswap_v2` · `giga_v3` · `swaphood_v3` · `pancake_v3` · `up_v3` · `metric` · `nadfun_dex` · `pons_v2_curve`.\n\n## Endpoints\n\n| Need | Call |\n| --- | --- |\n| Chain totals, venue share, hourly and daily | `GET /v1/rh/overview` |\n| Every token traded in 24h | `GET /v1/rh/tokens?sort=volume` |\n| One token's hourly tape and venue split | `GET /v1/rh/token/{address}` |\n| Every stock with NAV basis and after-hours share | `GET /v1/rh/stocks` |\n| Price map for the curated list | `GET /v1/tokens/market?chain=4663` |\n| Curated list, search | `GET /v1/tokens?chain=4663`, `GET /v1/tokens/search?q=&chain=4663` |\n| Candles, tape, stats | `GET /v1/tokens/chart|trades|stats/{address}` (address-keyed) |\n| Quote and swap | `GET /v1/quote?chain=4663…`, `POST /v1/swap { chain: 4663 }` — native ETH goes in `value` |\n| Top wallets, wallet PnL and trades, liquidity | `chain=4663` on `/v1/smart-money/top`, `/v1/portfolio/{wallet}/pnl`, `/trades` and `/pnl-calendar`, `/v1/lp/*` |\n| Holdings, 24h / 7d / 30d PnL and swaps | `GET /v1/portfolio/{wallet}?chains=4663`, `GET /v1/portfolio/{wallet}/activity?chains=4663` (`chains`, not `chain`) |\n| Live prices | SSE `/v1/stream/market` event `rh-ticker` |\n\nFreshness: `GET /v1/rh/status`.","sections":[{"heading":"","anchor":"","text":"| | |\n| --- | --- |\n| Chain id | `4663` |\n| Gas | ETH (zero address in the API; WETH `0x0Bd7D308f8E1639FAb988df18A8011f41EAcAD73`) |\n| Blocks | ~100 ms |\n| Stable anchor | USDG `0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168` (6 decimals) |\n| Explorer | [robin.etherscan.io](https://robin.etherscan.io) |\n| Public RPC | `https://rpc.mainnet.chain.robinhood.com` |\n| Chord index since | the chain's first swap (`genesisHour` on `/v1/rh/status`) |"},{"heading":"Tokenized stocks","anchor":"tokenized-stocks","text":"Equities and ETFs are 18-decimal tokens tagged `stock` on the curated list (NVDA `0xd0601CE157Db5bdC3162BbaC2a2C8aF5320D9EEC`, AAPL `0xaF3D76f1834A1d425780943C99Ea8A608f8a93f9`, SPCX, …). They trade around the clock; `GET /v1/rh/stocks` reports each one's 24-hour tape, the issuer's NAV where published (`navUsd`, `basisPct`) and the share of the last seven days that traded outside the NYSE session (`offHours7d`). Protocol fee on WETH, USDG and every stock is 0 bps."},{"heading":"Chord contracts","anchor":"chord-contracts","text":"The same proxies as Arc: router `0x1b1fee89a381e595fe6536b99ba91f3e16e9601a`, fee collector `0x6c66229675fd9ceda9a9b2ea2bd983b3d8255834`, adapter registry `0x6cf25d2af1a58d7094b0ac253ae616a8e1f2ea3f`. Adapters come with every quote."},{"heading":"Venues","anchor":"venues","text":"Routing covers Uniswap V3 and V4, GIGA V3, SwapHood V3, PancakeSwap V3, up v3 and the Metric OMM, plus composed hops through WETH and USDG. The data index covers every venue on the chain, including the ones routing does not use; `GET /v1/rh/venues` is the live list with ids and share. Common ids: `uniswap_v3` · `uniswap_v4` · `uniswap_v2` · `giga_v3` · `swaphood_v3` · `pancake_v3` · `up_v3` · `metric` · `nadfun_dex` · `pons_v2_curve`."},{"heading":"Endpoints","anchor":"endpoints","text":"| Need | Call |\n| --- | --- |\n| Chain totals, venue share, hourly and daily | `GET /v1/rh/overview` |\n| Every token traded in 24h | `GET /v1/rh/tokens?sort=volume` |\n| One token's hourly tape and venue split | `GET /v1/rh/token/{address}` |\n| Every stock with NAV basis and after-hours share | `GET /v1/rh/stocks` |\n| Price map for the curated list | `GET /v1/tokens/market?chain=4663` |\n| Curated list, search | `GET /v1/tokens?chain=4663`, `GET /v1/tokens/search?q=&chain=4663` |\n| Candles, tape, stats | `GET /v1/tokens/chart|trades|stats/{address}` (address-keyed) |\n| Quote and swap | `GET /v1/quote?chain=4663…`, `POST /v1/swap { chain: 4663 }` — native ETH goes in `value` |\n| Top wallets, wallet PnL and trades, liquidity | `chain=4663` on `/v1/smart-money/top`, `/v1/portfolio/{wallet}/pnl`, `/trades` and `/pnl-calendar`, `/v1/lp/*` |\n| Holdings, 24h / 7d / 30d PnL and swaps | `GET /v1/portfolio/{wallet}?chains=4663`, `GET /v1/portfolio/{wallet}/activity?chains=4663` (`chains`, not `chain`) |\n| Live prices | SSE `/v1/stream/market` event `rh-ticker` |\n\nFreshness: `GET /v1/rh/status`."}]},{"kind":"page","path":"/docs/networks/solana/","url":"https://getchord.xyz/docs/networks/solana/","title":"Solana","description":"Solana on Chord — swaps through Chord's own router and Jupiter, best of both, open to everyone, and data from Chord's own tape of 11 venues; base58 addresses, units, the /v1/sol/trade/* and /v1/chains/solana/* families.","markdown":"| | |\n| --- | --- |\n| Chain id | none — the path segment is the literal `solana` (`/v1/chains/solana/*`) |\n| Addresses | base58, **case-sensitive** (mints, wallets, pools); signatures base58 |\n| Gas | SOL |\n| Quote anchors | USDC `EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v` > USDT `Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB` > wSOL `So11111111111111111111111111111111111111112` (in a SOL/USDC pool, SOL is the token) |\n| Trading | **open to everyone** since 2026-10-15: SOL ↔ any token through Chord's own router and Jupiter, whichever leaves the wallet with more (`/v1/sol/trade/*`, [below](#swaps)) |\n| Chord tape since | live from 2026-10-03 12:01 UTC, plus a backfill of the days before: read `coverageSince` on `GET /v1/chains/solana/overview` |\n\n## Swaps\n\nA Solana swap quoted by Chord is SOL against one token, bought or sold. For every quote Chord builds, at the same moment, the\ntransaction of each route below **for your wallet**, simulates it on the chain, and reads what your wallet would end up with:\ntokens for a buy, SOL for a sell, after every fee. You get the route that leaves you with the most.\n\n| `route` | What it is |\n| --- | --- |\n| `direct` | **Chord's own router.** It builds the swap itself, from the pool accounts, on Raydium AMM v4, CPMM and CLMM, Orca Whirlpool, Meteora DLMM and DAMM v2, and the launch curves Meteora DBC, Raydium LaunchLab, pump.fun and PumpSwap. Pools come from Chord's tape; a large order can be split over two pools (`hops`). No third party in the path. |\n| `jupiter` | Jupiter's swap API (Metis), without Jupiter's fee. |\n| `jupiter_meta` | Jupiter's order: Metis, Jupiter's RFQ market makers, DFlow and OKX bid for it. Jupiter's fee is inside the amount; on RFQ and gasless orders Jupiter or the market maker pays the network fee (`gasless: true`). |\n\nSo a swap through Chord gets Jupiter's price whenever Jupiter is better (majors, where most of the liquidity sits in prop AMMs and\nmarket makers only Jupiter reaches), and Chord's own route when it is as good (ties go to `direct`, then `jupiter`), when Jupiter has\nno route yet for a new token, or when Jupiter is down or rate-limited. `compared` in the answer shows what every route offered. A\nroute that would hand back less than half of the input's market value is refused.\n\n**Status.** Open to everyone since 2026-10-15 21:25 UTC, no key needed (an `X-API-Key` raises the rate limit, as everywhere else).\n`GET /v1/sol/trade/config` says, for the caller, whether the lane is `enabled`, `open` to everyone, and `allowed` for you. Chord\ntakes no fee on Solana today (`feeBps: 0`); Jupiter's own fee applies on `jupiter_meta` quotes and is already inside the amount.\n\n**One swap, step by step.** Amounts are base units as decimal strings: lamports for SOL, the token's smallest unit otherwise.\n\n1. `GET /v1/sol/trade/quote?mint=&side=buy|sell&amount=&wallet=&slippageBps=100` — `amount` is lamports for a buy, tokens (smallest unit) for a sell. The answer's `quote.tx` is an unsigned v0 transaction, base64, exactly the one simulated; `outAmount` is what the simulation delivered, `minOut` the least the transaction accepts.\n2. Sign `quote.tx` **unchanged** with the wallet. On `jupiter_meta` the wallet can be the second signer, not the fee payer.\n3. `POST /v1/sol/trade/send` with `{ \"tx\": \"<signed, base64>\" }`. Chord relays only a transaction it quoted in the last three minutes, signed by the wallet it quoted; `jupiter_meta` orders go through Jupiter's execute endpoint.\n4. Poll `GET /v1/sol/trade/tx/{signature}`: `pending`, then `confirmed` / `finalized` (with `receivedOut`, read from the chain with the same measure as the quote), `failed` or `expired`.\n\nAn RFQ quote carries `expireAt` (Unix seconds) and lives a few seconds: ask again when fewer than ten seconds are left.\n`GET /v1/sol/trade/balances?wallet=&mint=` and `/holdings?wallet=` give the wallet's SOL and token balances for a swap form.\n\n**Not covered.** Token ↔ token (SOL is always one side). Chord's own route does not go through a second pool (token → USDC → SOL)\nor reach prop AMMs and RFQ makers: for those tokens and sizes the Jupiter routes win and are what you get.\n\n## What the tape reads\n\nChord decodes the swap **events** of 11 venues straight from Solana blocks, and checks every swap against the pool vaults' balance changes in the same transaction:\n\nPumpSwap · pump.fun bonding curve · Meteora DBC · Meteora DAMM v2 · Meteora DLMM · Meteora pools (dynamic AMM v1) · Raydium CLMM · Raydium CPMM · Raydium AMM v4 · Raydium LaunchLab · Orca Whirlpool\n\nVenue ids in responses: `pumpswap` · `pumpfun` · `meteora_dbc` · `meteora_damm_v2` · `meteora_dlmm` · `meteora_pools` · `raydium_clmm` · `raydium_cpmm` · `raydium_v4` · `raydium_launchlab` · `orca`.\n\n## What it does not read\n\n- **Prop AMMs** (SolFi, HumidiFi and the like) and **order books**. Most SOL/USDC and other major-pair flow runs there, so those pairs show far less volume on Chord than on an all-market source. The tape is accurate for pump.fun, Meteora and Raydium style tokens; do not use it for a market-wide SOL volume.\n- **Transfers.** A wallet's PnL is average cost over the swaps inside the window. A token that arrived by transfer, or was bought before the window, and is then sold shows up as a sell without a buy: the position is marked `partial: true` and those sells carry no realized PnL. `heldAmount` is bought minus sold inside the window, never the on-chain balance.\n\n## Coverage and freshness\n\n- Totals are complete from `coverageSince` (Unix seconds, on `/overview`) to now; a \"24 hours\" window never starts before it (`coverageHours` under 24 = a partial day). Quote that field rather than a date.\n- `GET /v1/chains/solana/status` is the ingest's own health: `ok`, `lagSlots`, `blockAgeS` (age of the newest block written), swaps per minute, per-venue decode counters. A `false` `ok` or a large `blockAgeS` means every other route is behind by that much: say so when you show the numbers.\n- Boards and stats are cached for 10 to 30 seconds, the trader board for 5 minutes.\n\n## Addresses, units, names\n\n- **Never lower-case a Solana address.** Base58 is case-sensitive: a lower-cased mint is another string, refused with `400 BAD_ADDRESS` when it is no longer valid base58 and answered `404 TOKEN_NOT_FOUND` otherwise. EVM validators (`0x` + 40 hex) do not apply.\n- **Amounts are whole units**: `tokenAmount`, `heldAmount`, `supply` are in tokens with decimals applied; `quoteAmount` is in whole units of the pool's quote (SOL, USDC, USDT, or the other token of a token-to-token pool — see `pools[].quote`). Prices and `*Usd` fields are US dollars.\n- **Every timestamp is Unix seconds, `updatedAt` included** (elsewhere in the API `updatedAt` is milliseconds).\n- `symbol`, `name` and `image` are whatever the token's creator wrote. Many mints share a symbol: identify a token by its mint.\n- **Most of Solana's busiest tokens are wallets trading with themselves.** On 13 and 14 October 2026, about two thirds of the 400 most traded tokens on the tape (some 70 % of their volume) had under 3 % of their volume from wallets that went one way. The token boards leave out such volume-bot tapes, and tickers that imitate SOL, USDC or USDT on another mint: `screened` says how many and how much volume, every row carries `oneWayPct` (the share of 24-hour volume from wallets that bought or sold, not both at about the same size), `/chains/solana/token/{address}` carries `flow24h` and search rows carry `screen`. A low `oneWayPct` on a row that is shown (a deep market whose flow is mostly arbitrage) still means its volume is not demand.\n\n## Endpoints\n\n| Need | Call |\n| --- | --- |\n| Is the tape current | `GET /v1/chains/solana/status` |\n| 24-hour totals, venue share, hourly buckets, `coverageSince` | `GET /v1/chains/solana/overview` |\n| The 24-hour token board | `GET /v1/chains/solana/tokens?sort=volume\\|trades\\|change\\|new&limit=` |\n| Find a token by mint, symbol or name | `GET /v1/chains/solana/search?q=` (exact symbol or name; a mint returns that token) |\n| One token: price, change, market cap, liquidity, venues, pools, hourly | `GET /v1/chains/solana/token/{mint}?hours=24` (pass 24 or more: the 24-hour totals come from the same hourly rows) |\n| Newest prints of a token | `GET /v1/chains/solana/token/{mint}/trades?limit=&before=` |\n| Candles of the token's main pool (or `pool=`) | `GET /v1/chains/solana/token/{mint}/candles?tf=1m\\|5m\\|15m\\|1h\\|4h\\|1d&limit=` |\n| Who traded a token (whole UTC hours from `since`) | `GET /v1/chains/solana/token/{mint}/traders?hours=1..48&limit=` |\n| The day's traders by realized PnL or volume | `GET /v1/chains/solana/traders?sort=pnl\\|volume&days=1\\|2&limit=` |\n| A wallet's tokens and PnL | `GET /v1/chains/solana/wallet/{address}?days=1..45` |\n| A wallet's swaps | `GET /v1/chains/solana/wallet/{address}/trades?limit=&before=` |\n\nFull parameters, response fields and real examples: the **Solana data** section of the API reference. No key is needed. `/v1/candles`, `/v1/tokens/*`, `/v1/quote` and the other chain-id routes do not take Solana.\n\n```bash\ncurl -s \"https://api.getchord.xyz/v1/chains/solana/tokens?sort=trades&limit=5\"\ncurl -s \"https://api.getchord.xyz/v1/chains/solana/token/7VertkgF9KLhxxJXHX6uaWuoYZTP9LdGj2bWmVXVpump?hours=24\"\ncurl -s \"https://api.getchord.xyz/v1/chains/solana/token/7VertkgF9KLhxxJXHX6uaWuoYZTP9LdGj2bWmVXVpump/candles?tf=1h&limit=48\"\n```\n\n## Paging\n\n`/trades` routes take `before` (Unix seconds, exclusive). Pass the last row's `ts` for the next page; several swaps can share one second, so overlap with `ts + 1` and drop rows whose `tx` you already hold. A token's page looks back at most two days from `before`, a wallet's at most seven.","sections":[{"heading":"","anchor":"","text":"| | |\n| --- | --- |\n| Chain id | none — the path segment is the literal `solana` (`/v1/chains/solana/*`) |\n| Addresses | base58, **case-sensitive** (mints, wallets, pools); signatures base58 |\n| Gas | SOL |\n| Quote anchors | USDC `EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v` > USDT `Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB` > wSOL `So11111111111111111111111111111111111111112` (in a SOL/USDC pool, SOL is the token) |\n| Trading | **open to everyone** since 2026-10-15: SOL ↔ any token through Chord's own router and Jupiter, whichever leaves the wallet with more (`/v1/sol/trade/*`, [below](#swaps)) |\n| Chord tape since | live from 2026-10-03 12:01 UTC, plus a backfill of the days before: read `coverageSince` on `GET /v1/chains/solana/overview` |"},{"heading":"Swaps","anchor":"swaps","text":"A Solana swap quoted by Chord is SOL against one token, bought or sold. For every quote Chord builds, at the same moment, the\ntransaction of each route below **for your wallet**, simulates it on the chain, and reads what your wallet would end up with:\ntokens for a buy, SOL for a sell, after every fee. You get the route that leaves you with the most.\n\n| `route` | What it is |\n| --- | --- |\n| `direct` | **Chord's own router.** It builds the swap itself, from the pool accounts, on Raydium AMM v4, CPMM and CLMM, Orca Whirlpool, Meteora DLMM and DAMM v2, and the launch curves Meteora DBC, Raydium LaunchLab, pump.fun and PumpSwap. Pools come from Chord's tape; a large order can be split over two pools (`hops`). No third party in the path. |\n| `jupiter` | Jupiter's swap API (Metis), without Jupiter's fee. |\n| `jupiter_meta` | Jupiter's order: Metis, Jupiter's RFQ market makers, DFlow and OKX bid for it. Jupiter's fee is inside the amount; on RFQ and gasless orders Jupiter or the market maker pays the network fee (`gasless: true`). |\n\nSo a swap through Chord gets Jupiter's price whenever Jupiter is better (majors, where most of the liquidity sits in prop AMMs and\nmarket makers only Jupiter reaches), and Chord's own route when it is as good (ties go to `direct`, then `jupiter`), when Jupiter has\nno route yet for a new token, or when Jupiter is down or rate-limited. `compared` in the answer shows what every route offered. A\nroute that would hand back less than half of the input's market value is refused.\n\n**Status.** Open to everyone since 2026-10-15 21:25 UTC, no key needed (an `X-API-Key` raises the rate limit, as everywhere else).\n`GET /v1/sol/trade/config` says, for the caller, whether the lane is `enabled`, `open` to everyone, and `allowed` for you. Chord\ntakes no fee on Solana today (`feeBps: 0`); Jupiter's own fee applies on `jupiter_meta` quotes and is already inside the amount.\n\n**One swap, step by step.** Amounts are base units as decimal strings: lamports for SOL, the token's smallest unit otherwise.\n\n1. `GET /v1/sol/trade/quote?mint=&side=buy|sell&amount=&wallet=&slippageBps=100` — `amount` is lamports for a buy, tokens (smallest unit) for a sell. The answer's `quote.tx` is an unsigned v0 transaction, base64, exactly the one simulated; `outAmount` is what the simulation delivered, `minOut` the least the transaction accepts.\n2. Sign `quote.tx` **unchanged** with the wallet. On `jupiter_meta` the wallet can be the second signer, not the fee payer.\n3. `POST /v1/sol/trade/send` with `{ \"tx\": \"<signed, base64>\" }`. Chord relays only a transaction it quoted in the last three minutes, signed by the wallet it quoted; `jupiter_meta` orders go through Jupiter's execute endpoint.\n4. Poll `GET /v1/sol/trade/tx/{signature}`: `pending`, then `confirmed` / `finalized` (with `receivedOut`, read from the chain with the same measure as the quote), `failed` or `expired`.\n\nAn RFQ quote carries `expireAt` (Unix seconds) and lives a few seconds: ask again when fewer than ten seconds are left.\n`GET /v1/sol/trade/balances?wallet=&mint=` and `/holdings?wallet=` give the wallet's SOL and token balances for a swap form.\n\n**Not covered.** Token ↔ token (SOL is always one side). Chord's own route does not go through a second pool (token → USDC → SOL)\nor reach prop AMMs and RFQ makers: for those tokens and sizes the Jupiter routes win and are what you get."},{"heading":"What the tape reads","anchor":"what-the-tape-reads","text":"Chord decodes the swap **events** of 11 venues straight from Solana blocks, and checks every swap against the pool vaults' balance changes in the same transaction:\n\nPumpSwap · pump.fun bonding curve · Meteora DBC · Meteora DAMM v2 · Meteora DLMM · Meteora pools (dynamic AMM v1) · Raydium CLMM · Raydium CPMM · Raydium AMM v4 · Raydium LaunchLab · Orca Whirlpool\n\nVenue ids in responses: `pumpswap` · `pumpfun` · `meteora_dbc` · `meteora_damm_v2` · `meteora_dlmm` · `meteora_pools` · `raydium_clmm` · `raydium_cpmm` · `raydium_v4` · `raydium_launchlab` · `orca`."},{"heading":"What it does not read","anchor":"what-it-does-not-read","text":"- **Prop AMMs** (SolFi, HumidiFi and the like) and **order books**. Most SOL/USDC and other major-pair flow runs there, so those pairs show far less volume on Chord than on an all-market source. The tape is accurate for pump.fun, Meteora and Raydium style tokens; do not use it for a market-wide SOL volume.\n- **Transfers.** A wallet's PnL is average cost over the swaps inside the window. A token that arrived by transfer, or was bought before the window, and is then sold shows up as a sell without a buy: the position is marked `partial: true` and those sells carry no realized PnL. `heldAmount` is bought minus sold inside the window, never the on-chain balance."},{"heading":"Coverage and freshness","anchor":"coverage-and-freshness","text":"- Totals are complete from `coverageSince` (Unix seconds, on `/overview`) to now; a \"24 hours\" window never starts before it (`coverageHours` under 24 = a partial day). Quote that field rather than a date.\n- `GET /v1/chains/solana/status` is the ingest's own health: `ok`, `lagSlots`, `blockAgeS` (age of the newest block written), swaps per minute, per-venue decode counters. A `false` `ok` or a large `blockAgeS` means every other route is behind by that much: say so when you show the numbers.\n- Boards and stats are cached for 10 to 30 seconds, the trader board for 5 minutes."},{"heading":"Addresses, units, names","anchor":"addresses-units-names","text":"- **Never lower-case a Solana address.** Base58 is case-sensitive: a lower-cased mint is another string, refused with `400 BAD_ADDRESS` when it is no longer valid base58 and answered `404 TOKEN_NOT_FOUND` otherwise. EVM validators (`0x` + 40 hex) do not apply.\n- **Amounts are whole units**: `tokenAmount`, `heldAmount`, `supply` are in tokens with decimals applied; `quoteAmount` is in whole units of the pool's quote (SOL, USDC, USDT, or the other token of a token-to-token pool — see `pools[].quote`). Prices and `*Usd` fields are US dollars.\n- **Every timestamp is Unix seconds, `updatedAt` included** (elsewhere in the API `updatedAt` is milliseconds).\n- `symbol`, `name` and `image` are whatever the token's creator wrote. Many mints share a symbol: identify a token by its mint.\n- **Most of Solana's busiest tokens are wallets trading with themselves.** On 13 and 14 October 2026, about two thirds of the 400 most traded tokens on the tape (some 70 % of their volume) had under 3 % of their volume from wallets that went one way. The token boards leave out such volume-bot tapes, and tickers that imitate SOL, USDC or USDT on another mint: `screened` says how many and how much volume, every row carries `oneWayPct` (the share of 24-hour volume from wallets that bought or sold, not both at about the same size), `/chains/solana/token/{address}` carries `flow24h` and search rows carry `screen`. A low `oneWayPct` on a row that is shown (a deep market whose flow is mostly arbitrage) still means its volume is not demand."},{"heading":"Endpoints","anchor":"endpoints","text":"| Need | Call |\n| --- | --- |\n| Is the tape current | `GET /v1/chains/solana/status` |\n| 24-hour totals, venue share, hourly buckets, `coverageSince` | `GET /v1/chains/solana/overview` |\n| The 24-hour token board | `GET /v1/chains/solana/tokens?sort=volume\\|trades\\|change\\|new&limit=` |\n| Find a token by mint, symbol or name | `GET /v1/chains/solana/search?q=` (exact symbol or name; a mint returns that token) |\n| One token: price, change, market cap, liquidity, venues, pools, hourly | `GET /v1/chains/solana/token/{mint}?hours=24` (pass 24 or more: the 24-hour totals come from the same hourly rows) |\n| Newest prints of a token | `GET /v1/chains/solana/token/{mint}/trades?limit=&before=` |\n| Candles of the token's main pool (or `pool=`) | `GET /v1/chains/solana/token/{mint}/candles?tf=1m\\|5m\\|15m\\|1h\\|4h\\|1d&limit=` |\n| Who traded a token (whole UTC hours from `since`) | `GET /v1/chains/solana/token/{mint}/traders?hours=1..48&limit=` |\n| The day's traders by realized PnL or volume | `GET /v1/chains/solana/traders?sort=pnl\\|volume&days=1\\|2&limit=` |\n| A wallet's tokens and PnL | `GET /v1/chains/solana/wallet/{address}?days=1..45` |\n| A wallet's swaps | `GET /v1/chains/solana/wallet/{address}/trades?limit=&before=` |\n\nFull parameters, response fields and real examples: the **Solana data** section of the API reference. No key is needed. `/v1/candles`, `/v1/tokens/*`, `/v1/quote` and the other chain-id routes do not take Solana.\n\n```bash\ncurl -s \"https://api.getchord.xyz/v1/chains/solana/tokens?sort=trades&limit=5\"\ncurl -s \"https://api.getchord.xyz/v1/chains/solana/token/7VertkgF9KLhxxJXHX6uaWuoYZTP9LdGj2bWmVXVpump?hours=24\"\ncurl -s \"https://api.getchord.xyz/v1/chains/solana/token/7VertkgF9KLhxxJXHX6uaWuoYZTP9LdGj2bWmVXVpump/candles?tf=1h&limit=48\"\n```"},{"heading":"Paging","anchor":"paging","text":"`/trades` routes take `before` (Unix seconds, exclusive). Pass the last row's `ts` for the next page; several swaps can share one second, so overlap with `ts + 1` and drop rows whose `tx` you already hold. A token's page looks back at most two days from `before`, a wallet's at most seven."}]},{"kind":"page","path":"/docs/recipes/bridge-to-arc/","url":"https://getchord.xyz/docs/recipes/bridge-to-arc/","title":"Bridge to Arc","description":"Move USDC to Arc on Circle's CCTP rails, or bring any token from 60+ chains through LI.FI — the two bridge families and when to use which.","markdown":"**Goal**: a user with funds elsewhere ends up with USDC on Arc, ready to trade.\n\n## Which rail\n\n| | CCTP (`/v1/bridge2/*`) | LI.FI (`/v1/crosschain/*`) |\n| --- | --- | --- |\n| Moves | USDC only, native burn and mint | any token the provider routes, swapped and bridged |\n| From | Ethereum, Base, Arbitrum, OP Mainnet, Polygon, Avalanche, Monad and the other CCTP domains | 60+ chains including Monad and Robinhood Chain (Arc as a destination is subject to provider support) |\n| Speed | fast transfer, seconds to a few minutes | route-dependent, minutes |\n| Gas on Arc | none for the user — Chord's relayer submits the mint | destination gas handled by the route |\n| Fee | Circle's fee (`/bridge2/fee`) | provider fee + the app fee in `/crosschain/config` |\n\nUSDC in, Arc out: use CCTP. Anything else: LI.FI.\n\n## CCTP fast transfer\n\n1. **Read the table.** `GET /bridge2/config` — the chains with their CCTP domains and USDC addresses, the TokenMessenger and MessageTransmitter contracts, and the relayer (address, Arc balance, enabled).\n2. **Quote the fee.** `GET /bridge2/fee?src=6&dst=26` → `fastBps` and `standardBps`.\n3. **Burn on the source chain.** The user approves USDC to `contracts.tokenMessengerV2` and calls `depositForBurn` with the Arc domain (`arcDomain`), the recipient as a 32-byte address, and the fast-finality threshold from `fastFinalityThreshold`. This is the only signature.\n4. **Poll the attestation.** `GET /bridge2/status?srcDomain=6&tx=0x…` until `status: \"complete\"`.\n5. **Relay the mint.** `POST /bridge2/relay { \"srcDomain\": 6, \"tx\": \"0x…\" }` — Chord's relayer submits `receiveMessage` on Arc and returns the mint hash. `409 NOT_ATTESTED` means poll longer; `429 DAILY_CAP` means relay it yourself with the message and attestation from step 4.\n\nThe user never needs USDC on Arc for gas, because the relayer pays the mint.\n\n## LI.FI routes\n\n1. **Chains and tokens.** `GET /crosschain/config?provider=lifi` lists destinations; `GET /crosschain/currencies?chainId=8453&q=usdc&provider=lifi` lists bridgeable tokens on a chain.\n2. **Quote.** `POST /crosschain/quote` with `user`, `originChainId`, `destinationChainId`, `originCurrency`, `destinationCurrency`, `amount` (smallest unit), `slippageBps` and `provider: \"lifi\"`. The answer carries the provider's steps and fees and the transactions to sign on the origin chain; an approve step is prepended when the origin token is an ERC-20.\n3. **Sign in order** and keep the deposit hash.\n4. **Poll.** `GET /crosschain/status?requestId={depositHash}&provider=lifi&fromChain=8453&toChain=5042` until `success`, or `refund` / `failure`. `depositing` → `pending` → `submitted` → `success` is the happy path; `delayed` is a route waiting on the bridge.\n\nThe Chord app embeds the LI.FI widget for this flow; the endpoints above are the same contract for a custom UI.\n\n## After the bridge\n\nThe user holds USDC on Arc as the predeploy balance, which is also their gas. Quote a trade with `inputMint=0x3600000000000000000000000000000000000000` and follow the [Swap recipe](/docs/recipes/swap/).","sections":[{"heading":"","anchor":"","text":"**Goal**: a user with funds elsewhere ends up with USDC on Arc, ready to trade."},{"heading":"Which rail","anchor":"which-rail","text":"| | CCTP (`/v1/bridge2/*`) | LI.FI (`/v1/crosschain/*`) |\n| --- | --- | --- |\n| Moves | USDC only, native burn and mint | any token the provider routes, swapped and bridged |\n| From | Ethereum, Base, Arbitrum, OP Mainnet, Polygon, Avalanche, Monad and the other CCTP domains | 60+ chains including Monad and Robinhood Chain (Arc as a destination is subject to provider support) |\n| Speed | fast transfer, seconds to a few minutes | route-dependent, minutes |\n| Gas on Arc | none for the user — Chord's relayer submits the mint | destination gas handled by the route |\n| Fee | Circle's fee (`/bridge2/fee`) | provider fee + the app fee in `/crosschain/config` |\n\nUSDC in, Arc out: use CCTP. Anything else: LI.FI."},{"heading":"CCTP fast transfer","anchor":"cctp-fast-transfer","text":"1. **Read the table.** `GET /bridge2/config` — the chains with their CCTP domains and USDC addresses, the TokenMessenger and MessageTransmitter contracts, and the relayer (address, Arc balance, enabled).\n2. **Quote the fee.** `GET /bridge2/fee?src=6&dst=26` → `fastBps` and `standardBps`.\n3. **Burn on the source chain.** The user approves USDC to `contracts.tokenMessengerV2` and calls `depositForBurn` with the Arc domain (`arcDomain`), the recipient as a 32-byte address, and the fast-finality threshold from `fastFinalityThreshold`. This is the only signature.\n4. **Poll the attestation.** `GET /bridge2/status?srcDomain=6&tx=0x…` until `status: \"complete\"`.\n5. **Relay the mint.** `POST /bridge2/relay { \"srcDomain\": 6, \"tx\": \"0x…\" }` — Chord's relayer submits `receiveMessage` on Arc and returns the mint hash. `409 NOT_ATTESTED` means poll longer; `429 DAILY_CAP` means relay it yourself with the message and attestation from step 4.\n\nThe user never needs USDC on Arc for gas, because the relayer pays the mint."},{"heading":"LI.FI routes","anchor":"li-fi-routes","text":"1. **Chains and tokens.** `GET /crosschain/config?provider=lifi` lists destinations; `GET /crosschain/currencies?chainId=8453&q=usdc&provider=lifi` lists bridgeable tokens on a chain.\n2. **Quote.** `POST /crosschain/quote` with `user`, `originChainId`, `destinationChainId`, `originCurrency`, `destinationCurrency`, `amount` (smallest unit), `slippageBps` and `provider: \"lifi\"`. The answer carries the provider's steps and fees and the transactions to sign on the origin chain; an approve step is prepended when the origin token is an ERC-20.\n3. **Sign in order** and keep the deposit hash.\n4. **Poll.** `GET /crosschain/status?requestId={depositHash}&provider=lifi&fromChain=8453&toChain=5042` until `success`, or `refund` / `failure`. `depositing` → `pending` → `submitted` → `success` is the happy path; `delayed` is a route waiting on the bridge.\n\nThe Chord app embeds the LI.FI widget for this flow; the endpoints above are the same contract for a custom UI."},{"heading":"After the bridge","anchor":"after-the-bridge","text":"The user holds USDC on Arc as the predeploy balance, which is also their gas. Quote a trade with `inputMint=0x3600000000000000000000000000000000000000` and follow the [Swap recipe](/docs/recipes/swap/)."}]},{"kind":"page","path":"/docs/recipes/charts/","url":"https://getchord.xyz/docs/recipes/charts/","title":"Charts","description":"Candles from the tape, paging into history, live updates over the WebSocket, and trade markers.","markdown":"**Goal**: a candlestick chart for any indexed token on Arc or Robinhood Chain that loads in one call, pages backwards for history, and updates live.\n\n## Load\n\n```ts\nconst A = \"https://api.getchord.xyz/v1\";\nconst { candles, tf, source } = await fetch(`${A}/tokens/chart/${addr}?tf=1h`).then((r) => r.json());\n// candles: [{ t, o, h, l, c, v }] oldest first, up to 200\n```\n\nTimeframes: `1m` · `5m` · `15m` · `1h` · `4h` · `1d` · `1w`. `v` is USD volume in the bucket. `source: \"db\"` means Chord's own tape. A `404 UNKNOWN_TOKEN` means the address is neither on a curated list nor a side of an indexed pool.\n\n## Page into history\n\nPass the oldest `t` you have as `before`; each page is 200 candles.\n\n```ts\nasync function older() {\n  const first = candles[0]?.t;\n  const page = await fetch(`${A}/tokens/chart/${addr}?tf=1h&before=${first}`).then((r) => r.json());\n  candles.unshift(...page.candles);\n}\n```\n\n## Live\n\nSubscribe to the same token and timeframe on the WebSocket. The open candle is re-sent as it changes; `closed: true` seals it.\n\n```ts\nws.send(JSON.stringify({ op: \"sub\", channel: \"candles\", token: addr, tf: \"1h\" }));\nws.onmessage = (e) => {\n  const m = JSON.parse(e.data);\n  if (m.op !== \"candle\" || m.token !== addr || m.tf !== \"1h\") return;\n  const last = candles.at(-1);\n  if (last && last.t === m.candle.t) Object.assign(last, m.candle); else candles.push(m.candle);\n};\n```\n\nSwitching timeframes: unsubscribe the old `tf`, fetch the new, subscribe the new. Eight channels per connection is enough for a chart, a tape and the price feed.\n\n## Trade markers\n\nFor a connected wallet, `GET /portfolio/{wallet}/trades?chain=5042` returns its buys and sells (`t`, `side`, `usd`, `tokenAmt`, `token`, `tx`); filter by token and draw markers at `t`. For the whole market, `GET /tokens/trades/{address}?min=1000` gives the large prints.\n\n## Gaps\n\nA bucket with no trades has no candle. Draw the gap or carry the last close forward — but do not invent a bar; the API does not.","sections":[{"heading":"","anchor":"","text":"**Goal**: a candlestick chart for any indexed token on Arc or Robinhood Chain that loads in one call, pages backwards for history, and updates live."},{"heading":"Load","anchor":"load","text":"```ts\nconst A = \"https://api.getchord.xyz/v1\";\nconst { candles, tf, source } = await fetch(`${A}/tokens/chart/${addr}?tf=1h`).then((r) => r.json());\n// candles: [{ t, o, h, l, c, v }] oldest first, up to 200\n```\n\nTimeframes: `1m` · `5m` · `15m` · `1h` · `4h` · `1d` · `1w`. `v` is USD volume in the bucket. `source: \"db\"` means Chord's own tape. A `404 UNKNOWN_TOKEN` means the address is neither on a curated list nor a side of an indexed pool."},{"heading":"Page into history","anchor":"page-into-history","text":"Pass the oldest `t` you have as `before`; each page is 200 candles.\n\n```ts\nasync function older() {\n  const first = candles[0]?.t;\n  const page = await fetch(`${A}/tokens/chart/${addr}?tf=1h&before=${first}`).then((r) => r.json());\n  candles.unshift(...page.candles);\n}\n```"},{"heading":"Live","anchor":"live","text":"Subscribe to the same token and timeframe on the WebSocket. The open candle is re-sent as it changes; `closed: true` seals it.\n\n```ts\nws.send(JSON.stringify({ op: \"sub\", channel: \"candles\", token: addr, tf: \"1h\" }));\nws.onmessage = (e) => {\n  const m = JSON.parse(e.data);\n  if (m.op !== \"candle\" || m.token !== addr || m.tf !== \"1h\") return;\n  const last = candles.at(-1);\n  if (last && last.t === m.candle.t) Object.assign(last, m.candle); else candles.push(m.candle);\n};\n```\n\nSwitching timeframes: unsubscribe the old `tf`, fetch the new, subscribe the new. Eight channels per connection is enough for a chart, a tape and the price feed."},{"heading":"Trade markers","anchor":"trade-markers","text":"For a connected wallet, `GET /portfolio/{wallet}/trades?chain=5042` returns its buys and sells (`t`, `side`, `usd`, `tokenAmt`, `token`, `tx`); filter by token and draw markers at `t`. For the whole market, `GET /tokens/trades/{address}?min=1000` gives the large prints."},{"heading":"Gaps","anchor":"gaps","text":"A bucket with no trades has no candle. Draw the gap or carry the last close forward — but do not invent a bar; the API does not."}]},{"kind":"page","path":"/docs/recipes/discover-tokens/","url":"https://getchord.xyz/docs/recipes/discover-tokens/","title":"Discover tokens","description":"A markets board, a trending strip, a new-launches feed, search, and the attention signal — every discovery surface on Arc from four endpoints.","markdown":"**Goal**: the discovery layer of a trading app — what is traded, what is moving, what just launched, and search — on Arc.\n\n## Markets board\n\n`GET /arc/tokens` returns every token that traded in the last 24 hours (about 1,500 on a normal day), with price, change, buy/sell volume, trades, traders, market cap, pool counts per venue and honesty flags. Sort server-side; page with `offset`.\n\n```ts\nconst { tokens, total } = await fetch(`${A}/arc/tokens?sort=volume&limit=100&offset=0`).then((r) => r.json());\n```\n\n- Columns Chord shows: token (logo, symbol, `listed` check), price, 24h change, volume, buys / sells, traders, market cap (labelled FDV), pools.\n- `flags` present → grey the row and badge it. They already sort below clean rows.\n- `routable` → whether to draw a Buy button.\n- `includeUnlisted=1` adds tokens with no curated metadata or logo (most launches). Chord shows them, with the on-chain symbol.\n\nKeep the board moving between polls with the WebSocket `prices` channel — one subscription covers the whole board, prices and 24h counters alike, plus tokens trading for the first time:\n\n```ts\nws.send(JSON.stringify({ op: \"sub\", channel: \"prices\", chain: 5042 }));\n// { op: \"prices\", at, items: [{ address, priceUsd, ts, side, usd, volume24h, trades24h, buys24h, sells24h, … }] }\n//   apply by address; use the counters when `at` is later than the REST page's `updatedAt`\n// { op: \"new\", items: [{ address, symbol, name, totalSupply, firstTs, priceUsd }] } — prepend to a \"New\" list\n```\n\n## Trending\n\n`GET /arc/trending?limit=20` — movers of the last two hours, scored from the hourly rollup. Each row is a full token row plus `score`, `volNow`, `tradesNow`, `change1hPct` and `momentum`. Poll every 30 s.\n\n## New launches\n\n`GET /arc/graduated?hours=48&limit=100` — tokens whose first pool on Arc was created in the window, routable today and screened (impostor symbols, launch farms, no-sell tokens, too few traders removed). Newest first; `launchedAt`, `launcher`, `launcherName` and `creator` on each row; `screened` counts what each filter removed, which is worth showing (\"1,615 launch-farm tokens hidden\"). Poll every 60 s.\n\nPair it with `GET /arc/launchers?hours=24` for the launchpad strip: which launchers are active, pools per hour, and 24-hour volume over the pools each one created.\n\n## Search\n\n`GET /arc/tokens/search?q=argus&limit=10` — symbol, name or address over every token traded in the last 24 hours. Exact symbol first, then prefix, name, substring; listed tokens and volume break ties so the real ARGUS outranks a copy. A pasted address always returns that token. Debounce at 200 ms; `coverage` says how many tokens have a resolved name yet.\n\n## Attention\n\n`GET /arc/attention?days=1&limit=20` — what people on Chord are looking at (searches, views, questions to the analyst, watchlist adds). A demand signal, independent of price; use it for a \"people are watching\" rail.\n\n## Putting it together\n\nChord's markets page polls `/arc/tokens` every 20 s, `/arc/trending` every 30 s, `/arc/graduated` every 60 s, keeps prices live over the WebSocket, and runs search on demand. That is well inside the anonymous limit; a key is only needed when you serve many users from one server.","sections":[{"heading":"","anchor":"","text":"**Goal**: the discovery layer of a trading app — what is traded, what is moving, what just launched, and search — on Arc."},{"heading":"Markets board","anchor":"markets-board","text":"`GET /arc/tokens` returns every token that traded in the last 24 hours (about 1,500 on a normal day), with price, change, buy/sell volume, trades, traders, market cap, pool counts per venue and honesty flags. Sort server-side; page with `offset`.\n\n```ts\nconst { tokens, total } = await fetch(`${A}/arc/tokens?sort=volume&limit=100&offset=0`).then((r) => r.json());\n```\n\n- Columns Chord shows: token (logo, symbol, `listed` check), price, 24h change, volume, buys / sells, traders, market cap (labelled FDV), pools.\n- `flags` present → grey the row and badge it. They already sort below clean rows.\n- `routable` → whether to draw a Buy button.\n- `includeUnlisted=1` adds tokens with no curated metadata or logo (most launches). Chord shows them, with the on-chain symbol.\n\nKeep the board moving between polls with the WebSocket `prices` channel — one subscription covers the whole board, prices and 24h counters alike, plus tokens trading for the first time:\n\n```ts\nws.send(JSON.stringify({ op: \"sub\", channel: \"prices\", chain: 5042 }));\n// { op: \"prices\", at, items: [{ address, priceUsd, ts, side, usd, volume24h, trades24h, buys24h, sells24h, … }] }\n//   apply by address; use the counters when `at` is later than the REST page's `updatedAt`\n// { op: \"new\", items: [{ address, symbol, name, totalSupply, firstTs, priceUsd }] } — prepend to a \"New\" list\n```"},{"heading":"Trending","anchor":"trending","text":"`GET /arc/trending?limit=20` — movers of the last two hours, scored from the hourly rollup. Each row is a full token row plus `score`, `volNow`, `tradesNow`, `change1hPct` and `momentum`. Poll every 30 s."},{"heading":"New launches","anchor":"new-launches","text":"`GET /arc/graduated?hours=48&limit=100` — tokens whose first pool on Arc was created in the window, routable today and screened (impostor symbols, launch farms, no-sell tokens, too few traders removed). Newest first; `launchedAt`, `launcher`, `launcherName` and `creator` on each row; `screened` counts what each filter removed, which is worth showing (\"1,615 launch-farm tokens hidden\"). Poll every 60 s.\n\nPair it with `GET /arc/launchers?hours=24` for the launchpad strip: which launchers are active, pools per hour, and 24-hour volume over the pools each one created."},{"heading":"Search","anchor":"search","text":"`GET /arc/tokens/search?q=argus&limit=10` — symbol, name or address over every token traded in the last 24 hours. Exact symbol first, then prefix, name, substring; listed tokens and volume break ties so the real ARGUS outranks a copy. A pasted address always returns that token. Debounce at 200 ms; `coverage` says how many tokens have a resolved name yet."},{"heading":"Attention","anchor":"attention","text":"`GET /arc/attention?days=1&limit=20` — what people on Chord are looking at (searches, views, questions to the analyst, watchlist adds). A demand signal, independent of price; use it for a \"people are watching\" rail."},{"heading":"Putting it together","anchor":"putting-it-together","text":"Chord's markets page polls `/arc/tokens` every 20 s, `/arc/trending` every 30 s, `/arc/graduated` every 60 s, keeps prices live over the WebSocket, and runs search on demand. That is well inside the anonymous limit; a key is only needed when you serve many users from one server."}]},{"kind":"page","path":"/docs/recipes/launchpad-lifecycle/","url":"https://getchord.xyz/docs/recipes/launchpad-lifecycle/","title":"Launch lifecycle","description":"From a launcher creating a pool to a token with holders and liquidity — following a launch on Arc through the API.","markdown":"**Goal**: a launch feed and the forensics behind it. On Arc most tokens are born through a launcher contract that creates a Uniswap V4 pool (often with a hook that runs a bonding curve) or a V3 / V2 pool with seeded liquidity. Chord indexes every one.\n\n## 1. Who is launching\n\n`GET /arc/launchers?hours=24` — every launcher seen in the window: name and site where the registry knows it (Uniswap Liquidity Launcher, aka.fun, Argus, Minara.fun, Rapid Launch, Sharc.fun, Bozo, …), the pool shapes it creates (hook, fee, tick spacing), pools per hour and day, distinct creators, and the 24-hour tape over its pools (swaps, volume, wallets, active pools). The [Launchpads](/docs/launchpads/) page lists the named ones.\n\n## 2. What launched\n\n`GET /arc/graduated?hours=48` — tokens whose first pool was created in the window, routable today and screened. Each row has `launchedAt`, `launcher`, `launcherName`, `creator`, `ageSec` and the full 24-hour token row. `screened` counts what the filters removed:\n\n| Screen | Removes |\n| --- | --- |\n| `serial_creator` | one creator, eight or more pools in the window — a launch farm |\n| `impostor` | a symbol copying a listed token |\n| `no_sells` | buys only — a token that cannot be sold |\n| `few_traders` | too few distinct wallets |\n| `not_routable` | no pool the engine can quote |\n| `no_trades` · `no_symbol` | nothing happened, or no name on-chain |\n\nShow the counts. On a busy day the farm screen alone removes over a thousand pools.\n\n## 3. Is it real\n\nFor one launch, three calls tell you most of what matters:\n\n- `GET /arc/token/{address}/holders` — holder count, `heldByWalletsPct` (supply outside pools), `concentration.top10`, and the top rows tagged wallet / pool / burn. A launch where two wallets hold 90 % outside the pool is a different thing from one with 500 holders.\n- `GET /lp/token/{address}/pools?chain=5042` — the pools with `score`, `reasons` and `launch`: how much of the liquidity the launcher supplied and whether it has started pulling (`launcherRemovedUsd`, `launcherLastRemoveTs`).\n- `GET /tokens/stats/{address}` — buyers versus sellers per window, makers, and whether volume is many wallets or a few.\n\n`flags` on the token row (`wash`, `impostor`) and `suspect` on its pools are the same checks, precomputed.\n\n## 4. Trade it\n\nA launch that is `routable` quotes like any token: `GET /quote?chain=5042&inputMint=0x3600…0000&outputMint={address}&amount=…`. Hooked V4 pools route only through hooks the engine has verified end to end; a pool on an unknown hook is `NO_POOLS` until it is. Expect high `priceImpactPct` on a fresh curve, and simulate before signing.\n\n## 5. Watch it\n\n- Prices: WebSocket `prices` (chain 5042) for the board, `trades` for the token.\n- Liquidity: `GET /lp/events?chain=5042&token={address}` for adds and removes; `POST /lp/watch/pool` to get an alert when a pool drains.\n- Attention: `GET /arc/attention` shows what people on Chord are watching.\n\n## Ask instead\n\nThe analyst answers \"is this launch a rug\" in one call with the same data: `POST /v1/ask { \"question\": \"launch forensics on 0x…\", \"stream\": false }` with an API key. See [Ask agent API](/docs/agents/ask-api/).","sections":[{"heading":"","anchor":"","text":"**Goal**: a launch feed and the forensics behind it. On Arc most tokens are born through a launcher contract that creates a Uniswap V4 pool (often with a hook that runs a bonding curve) or a V3 / V2 pool with seeded liquidity. Chord indexes every one."},{"heading":"1. Who is launching","anchor":"1-who-is-launching","text":"`GET /arc/launchers?hours=24` — every launcher seen in the window: name and site where the registry knows it (Uniswap Liquidity Launcher, aka.fun, Argus, Minara.fun, Rapid Launch, Sharc.fun, Bozo, …), the pool shapes it creates (hook, fee, tick spacing), pools per hour and day, distinct creators, and the 24-hour tape over its pools (swaps, volume, wallets, active pools). The [Launchpads](/docs/launchpads/) page lists the named ones."},{"heading":"2. What launched","anchor":"2-what-launched","text":"`GET /arc/graduated?hours=48` — tokens whose first pool was created in the window, routable today and screened. Each row has `launchedAt`, `launcher`, `launcherName`, `creator`, `ageSec` and the full 24-hour token row. `screened` counts what the filters removed:\n\n| Screen | Removes |\n| --- | --- |\n| `serial_creator` | one creator, eight or more pools in the window — a launch farm |\n| `impostor` | a symbol copying a listed token |\n| `no_sells` | buys only — a token that cannot be sold |\n| `few_traders` | too few distinct wallets |\n| `not_routable` | no pool the engine can quote |\n| `no_trades` · `no_symbol` | nothing happened, or no name on-chain |\n\nShow the counts. On a busy day the farm screen alone removes over a thousand pools."},{"heading":"3. Is it real","anchor":"3-is-it-real","text":"For one launch, three calls tell you most of what matters:\n\n- `GET /arc/token/{address}/holders` — holder count, `heldByWalletsPct` (supply outside pools), `concentration.top10`, and the top rows tagged wallet / pool / burn. A launch where two wallets hold 90 % outside the pool is a different thing from one with 500 holders.\n- `GET /lp/token/{address}/pools?chain=5042` — the pools with `score`, `reasons` and `launch`: how much of the liquidity the launcher supplied and whether it has started pulling (`launcherRemovedUsd`, `launcherLastRemoveTs`).\n- `GET /tokens/stats/{address}` — buyers versus sellers per window, makers, and whether volume is many wallets or a few.\n\n`flags` on the token row (`wash`, `impostor`) and `suspect` on its pools are the same checks, precomputed."},{"heading":"4. Trade it","anchor":"4-trade-it","text":"A launch that is `routable` quotes like any token: `GET /quote?chain=5042&inputMint=0x3600…0000&outputMint={address}&amount=…`. Hooked V4 pools route only through hooks the engine has verified end to end; a pool on an unknown hook is `NO_POOLS` until it is. Expect high `priceImpactPct` on a fresh curve, and simulate before signing."},{"heading":"5. Watch it","anchor":"5-watch-it","text":"- Prices: WebSocket `prices` (chain 5042) for the board, `trades` for the token.\n- Liquidity: `GET /lp/events?chain=5042&token={address}` for adds and removes; `POST /lp/watch/pool` to get an alert when a pool drains.\n- Attention: `GET /arc/attention` shows what people on Chord are watching."},{"heading":"Ask instead","anchor":"ask-instead","text":"The analyst answers \"is this launch a rug\" in one call with the same data: `POST /v1/ask { \"question\": \"launch forensics on 0x…\", \"stream\": false }` with an API key. See [Ask agent API](/docs/agents/ask-api/)."}]},{"kind":"page","path":"/docs/recipes/lp-dashboard/","url":"https://getchord.xyz/docs/recipes/lp-dashboard/","title":"LP dashboard","description":"A pools screener, a pool page, a range planner and a positions view for liquidity providers on Arc.","markdown":"**Goal**: the liquidity side of a trading app — where the fees are, whether a pool is honest, what range to take, and how open positions are doing.\n\n## Headline strip\n\n`GET /lp/overview?chain=5042` — fees paid to LPs in 24 hours, the best real yield (≥ 25 traders, not suspect), liquidity added and removed, volume, TVL and providers over pools with ≥ $10k TVL, the six hottest pools by fees (`hot`) and the three biggest net inflows (`inflow`). One call, memoised 30 s.\n\n## Pools screener\n\n```ts\nconst { pools, total, hidden } = await fetch(`${A}/lp/pools?chain=5042&sort=fee_tvl&interval=24h&limit=50`).then((r) => r.json());\n```\n\nColumns: pair (`token0` / `token1` with logos and `impostor` flags), venue (`dex`), fee tier (`feeBps`), TVL, volume and fees for the interval, `feeTvlPct`, `aprPct`, traders (`wallets24h`), LP net flow (`lpAdd24h − lpRemove24h`), providers, age (`createdTs`), `score`.\n\n- Sorts: `fee_tvl` · `vol_24h` · `vol_1h` · `tvl` · `fees_24h` · `first_seen` · `lp_net_24h` · `trades_24h` · `score`.\n- Filters: `quote=USDC` (anchor), `dex=uniswap_v4`, `search=argus`, `minTvl=`, `small=1` (under $10k), `flagged=1` (show suspect pools, greyed).\n- `hidden` is how many rows the filters removed — show it; users ask.\n- `lpAccess: \"hooked\"` means a V4 hook can refuse adds. Do not offer a mint button on those.\n\n## Pool page\n\n`GET /lp/pools/{pool}?chain=5042` returns the row plus:\n\n- `hourly` — 7 days of volume, trades and price for the chart.\n- `topLps` — providers over 7 days with net dollars.\n- `health` — the score, its six parts and `reasons` in plain English.\n- `launch` — who launched it, the launcher's share of all liquidity ever added, and when it last pulled.\n- `mint` — what a wallet needs to add liquidity: manager, pool key, Permit2, tick spacing, native flag.\n\n`GET /lp/pools/{pool}/positions?chain=5042&limit=20` lists the open positions in the pool, largest first, valued live. `GET /lp/events?chain=5042&pool={pool}&minUsd=1000` is the add/remove tape.\n\n## Range planner\n\n```ts\nconst plan = await fetch(`${A}/lp/plan?chain=5042&token=${addr}&amountUsd=1000&days=7`).then((r) => r.json());\n```\n\n`bands.profiles` gives tight, balanced and wide ranges from the token's own volatility with the share of the last seven days inside each; `sims[]` backtests each against holding — fees, impermanent loss, exits, net versus hold, capital efficiency. Draw `bands.histogram` (hours the price spent in each bucket) behind the ranges. `young: true` means fewer than two days of candles: say so instead of drawing bands. For a user-drawn range call `GET /lp/simulate` with `lower` and `upper`.\n\n## Positions\n\n`GET /lp/positions?chain=5042&owner={wallet}&status=open` — each position with `valueUsd`, `uncollectedUsd`, `inRange`, `edgePct` (distance to the nearest edge), `pnlUsd` and `ageHours`; `summary` for the header. `GET /lp/position/{chain}/{manager}/{id}` opens one with its events and a hold-instead comparison. Closed positions page with `status=closed&limit=25&offset=25`, newest first, and `pool=` keeps one pool.\n\nAlerts: `POST /lp/watch { chain, wallet }` turns on out-of-range, fee-bar and drain alerts and returns a Telegram deep link; `GET /lp/watch?chain=&wallet=` is the inbox.\n\n## Leaderboard\n\n`GET /lp/leaderboard?chain=5042&sort=profit&limit=48` — providers by profit (all time, or `profit_7d` / `profit_30d`), win rate, fees, EV, age, invested, monthly profit or last activity, with inclusive filters (`minPositions`, `minWinRate`, `minEv`, `lastActiveDays`, …) and the last seven days of profit per wallet for a sparkline. Wallets whose profit came from the token's price rather than fees are left out and counted in `hidden`; `all=1` keeps them.\n\n## One wallet, one pool's providers\n\n`GET /lp/wallet/{address}?chain=5042` is the page behind a leaderboard row: the same figures for that wallet whether it is ranked or not (`summary`), one row per UTC day on which a position ended with the profit and the fees that landed on it (`history`: draw it as bars with a running total, or as a calendar), and the pools it provided to. `unscored` says how many of its positions the figures leave out and why.\n\n`GET /lp/pools/{pool}/lps?chain=5042` ranks a pool's providers by what they made there (profit, fees, positions, average age, win rate), where the pool's `topLps` ranks them by how much they moved.\n\n## Cadence\n\nOverview and screener every 30 s, pool page every 30 s, positions every 60 s. All are cached server-side at those intervals, so faster polling returns the same bytes.","sections":[{"heading":"","anchor":"","text":"**Goal**: the liquidity side of a trading app — where the fees are, whether a pool is honest, what range to take, and how open positions are doing."},{"heading":"Headline strip","anchor":"headline-strip","text":"`GET /lp/overview?chain=5042` — fees paid to LPs in 24 hours, the best real yield (≥ 25 traders, not suspect), liquidity added and removed, volume, TVL and providers over pools with ≥ $10k TVL, the six hottest pools by fees (`hot`) and the three biggest net inflows (`inflow`). One call, memoised 30 s."},{"heading":"Pools screener","anchor":"pools-screener","text":"```ts\nconst { pools, total, hidden } = await fetch(`${A}/lp/pools?chain=5042&sort=fee_tvl&interval=24h&limit=50`).then((r) => r.json());\n```\n\nColumns: pair (`token0` / `token1` with logos and `impostor` flags), venue (`dex`), fee tier (`feeBps`), TVL, volume and fees for the interval, `feeTvlPct`, `aprPct`, traders (`wallets24h`), LP net flow (`lpAdd24h − lpRemove24h`), providers, age (`createdTs`), `score`.\n\n- Sorts: `fee_tvl` · `vol_24h` · `vol_1h` · `tvl` · `fees_24h` · `first_seen` · `lp_net_24h` · `trades_24h` · `score`.\n- Filters: `quote=USDC` (anchor), `dex=uniswap_v4`, `search=argus`, `minTvl=`, `small=1` (under $10k), `flagged=1` (show suspect pools, greyed).\n- `hidden` is how many rows the filters removed — show it; users ask.\n- `lpAccess: \"hooked\"` means a V4 hook can refuse adds. Do not offer a mint button on those."},{"heading":"Pool page","anchor":"pool-page","text":"`GET /lp/pools/{pool}?chain=5042` returns the row plus:\n\n- `hourly` — 7 days of volume, trades and price for the chart.\n- `topLps` — providers over 7 days with net dollars.\n- `health` — the score, its six parts and `reasons` in plain English.\n- `launch` — who launched it, the launcher's share of all liquidity ever added, and when it last pulled.\n- `mint` — what a wallet needs to add liquidity: manager, pool key, Permit2, tick spacing, native flag.\n\n`GET /lp/pools/{pool}/positions?chain=5042&limit=20` lists the open positions in the pool, largest first, valued live. `GET /lp/events?chain=5042&pool={pool}&minUsd=1000` is the add/remove tape."},{"heading":"Range planner","anchor":"range-planner","text":"```ts\nconst plan = await fetch(`${A}/lp/plan?chain=5042&token=${addr}&amountUsd=1000&days=7`).then((r) => r.json());\n```\n\n`bands.profiles` gives tight, balanced and wide ranges from the token's own volatility with the share of the last seven days inside each; `sims[]` backtests each against holding — fees, impermanent loss, exits, net versus hold, capital efficiency. Draw `bands.histogram` (hours the price spent in each bucket) behind the ranges. `young: true` means fewer than two days of candles: say so instead of drawing bands. For a user-drawn range call `GET /lp/simulate` with `lower` and `upper`."},{"heading":"Positions","anchor":"positions","text":"`GET /lp/positions?chain=5042&owner={wallet}&status=open` — each position with `valueUsd`, `uncollectedUsd`, `inRange`, `edgePct` (distance to the nearest edge), `pnlUsd` and `ageHours`; `summary` for the header. `GET /lp/position/{chain}/{manager}/{id}` opens one with its events and a hold-instead comparison. Closed positions page with `status=closed&limit=25&offset=25`, newest first, and `pool=` keeps one pool.\n\nAlerts: `POST /lp/watch { chain, wallet }` turns on out-of-range, fee-bar and drain alerts and returns a Telegram deep link; `GET /lp/watch?chain=&wallet=` is the inbox."},{"heading":"Leaderboard","anchor":"leaderboard","text":"`GET /lp/leaderboard?chain=5042&sort=profit&limit=48` — providers by profit (all time, or `profit_7d` / `profit_30d`), win rate, fees, EV, age, invested, monthly profit or last activity, with inclusive filters (`minPositions`, `minWinRate`, `minEv`, `lastActiveDays`, …) and the last seven days of profit per wallet for a sparkline. Wallets whose profit came from the token's price rather than fees are left out and counted in `hidden`; `all=1` keeps them."},{"heading":"One wallet, one pool's providers","anchor":"one-wallet-one-pool-s-providers","text":"`GET /lp/wallet/{address}?chain=5042` is the page behind a leaderboard row: the same figures for that wallet whether it is ranked or not (`summary`), one row per UTC day on which a position ended with the profit and the fees that landed on it (`history`: draw it as bars with a running total, or as a calendar), and the pools it provided to. `unscored` says how many of its positions the figures leave out and why.\n\n`GET /lp/pools/{pool}/lps?chain=5042` ranks a pool's providers by what they made there (profit, fees, positions, average age, win rate), where the pool's `topLps` ranks them by how much they moved."},{"heading":"Cadence","anchor":"cadence","text":"Overview and screener every 30 s, pool page every 30 s, positions every 60 s. All are cached server-side at those intervals, so faster polling returns the same bytes."}]},{"kind":"page","path":"/docs/recipes/swap/","url":"https://getchord.xyz/docs/recipes/swap/","title":"Swap from your app","description":"Quote, approve, simulate, build, sign — the full non-custodial swap flow on Arc, with the edge cases that bite.","markdown":"**Goal**: a working swap button. Chord finds the route and builds the transaction; the user's wallet signs it. Chord never holds funds or keys.\n\n## 1. Resolve tokens and decimals\n\n```ts\nconst A = \"https://api.getchord.xyz/v1\";\nconst { tokens } = await fetch(`${A}/tokens?chain=5042`).then((r) => r.json());\nconst USDC = tokens.find((t) => t.symbol === \"USDC\"); // 0x3600…0000, 6 decimals\n```\n\nFor a token that is not on the curated list, `GET /arc/tokens/search?q=` returns its address and `decimals` from the chain. Never assume 18.\n\n## 2. Quote on intent\n\nQuote when the user has typed an amount and paused, not on every keystroke. Paint a first number with `fast=1` and replace it with the full answer.\n\n```ts\nconst params = new URLSearchParams({ chain: \"5042\", inputMint: USDC.address, outputMint: token.address, amount: (5n * 10n ** 6n).toString(), slippageBps: \"100\" });\nconst [fast, full] = await Promise.all([\n  fetch(`${A}/quote?${params}&fast=1`).then((r) => r.json()),\n  fetch(`${A}/quote?${params}`).then((r) => r.json()),\n]);\nconst quote = full; // never build from `fast` (preliminary: true)\nif (quote.routePlan.length === 0) return showNoRoute(quote.noRouteReason); // INSUFFICIENT_LIQUIDITY → suggest a smaller size\n```\n\nShow `outputAmount` (scaled by the output token's decimals), `priceImpactPct`, `feeBps`, and `otherAmountThreshold` as the minimum received.\n\n## 3. Approve the router when needed\n\nFor an ERC-20 input — and on Arc every input is one, since the native unit aliases to the USDC predeploy — the router must be allowed to pull `inputAmount`. The router address is `transaction.to` in the `/swap` answer (`0x1b1fee89a381e595fe6536b99ba91f3e16e9601a` on both chains). Read the allowance first and skip the approve when it is enough.\n\n```ts\nconst allowance = await publicClient.readContract({ address: USDC.address, abi: erc20Abi, functionName: \"allowance\", args: [wallet, ROUTER] });\nif (allowance < BigInt(quote.inputAmount)) {\n  await walletClient.writeContract({ address: USDC.address, abi: erc20Abi, functionName: \"approve\", args: [ROUTER, BigInt(quote.inputAmount)] });\n}\n```\n\n## 4. Build\n\n```ts\nconst { transaction } = await fetch(`${A}/swap`, {\n  method: \"POST\", headers: { \"Content-Type\": \"application/json\" },\n  body: JSON.stringify({ quoteResponse: quote, userPublicKey: wallet, chain: 5042 }),\n}).then((r) => r.json());\n```\n\nSend the quote back **unmodified**. A changed body is `400 ROUTE_MISMATCH`; a different `slippageBps` is `400 SLIPPAGE_MISMATCH` — re-quote instead. Pass `feeAccount` if you are a referrer.\n\n## 5. Simulate\n\n```ts\nconst sim = await fetch(`${A}/swap/simulate`, {\n  method: \"POST\", headers: { \"Content-Type\": \"application/json\" },\n  body: JSON.stringify({ chain: 5042, from: wallet, to: transaction.to, data: transaction.data, value: transaction.value }),\n}).then((r) => r.json());\nif (sim.ok === false && !/not approved/i.test(sim.revert)) return showRevert(sim.revert);\n```\n\nAn allowance revert right after the approve is expected (the approve may not be mined yet); proceed. Any other revert, stop.\n\n## 6. Sign and send\n\n```ts\nconst hash = await walletClient.sendTransaction({\n  to: transaction.to, data: transaction.data, value: BigInt(transaction.value), gas: BigInt(transaction.gasLimit), chain: arc,\n});\n```\n\nOn Arc `value` is always `0`. Wait for the receipt; the output lands in the user's wallet. Explorer: `https://explorer.arc.io/tx/${hash}`.\n\n## Edge cases\n\n- **Quote expired.** A quote is good for about 30 seconds. If the user idled, quote again before `/swap`.\n- **Price moved past the threshold.** The transaction reverts with insufficient output. Quote again; do not resubmit.\n- **Gateway dropped the send.** Arc's public gateway has been seen dropping one broadcast in six. Use a dedicated RPC for `sendRawTransaction` and retry with the same nonce on a timeout.\n- **Robinhood Chain.** Same flow with `chain: 4663`; native ETH is the zero address and is sent as `value`, WETH is wrapped for you. Stocks and USDG are 0 bps.\n- **Contracts calling the router.** `GET /swap/calldata` quotes and encodes in one call with the output to `msg.sender`.","sections":[{"heading":"","anchor":"","text":"**Goal**: a working swap button. Chord finds the route and builds the transaction; the user's wallet signs it. Chord never holds funds or keys."},{"heading":"1. Resolve tokens and decimals","anchor":"1-resolve-tokens-and-decimals","text":"```ts\nconst A = \"https://api.getchord.xyz/v1\";\nconst { tokens } = await fetch(`${A}/tokens?chain=5042`).then((r) => r.json());\nconst USDC = tokens.find((t) => t.symbol === \"USDC\"); // 0x3600…0000, 6 decimals\n```\n\nFor a token that is not on the curated list, `GET /arc/tokens/search?q=` returns its address and `decimals` from the chain. Never assume 18."},{"heading":"2. Quote on intent","anchor":"2-quote-on-intent","text":"Quote when the user has typed an amount and paused, not on every keystroke. Paint a first number with `fast=1` and replace it with the full answer.\n\n```ts\nconst params = new URLSearchParams({ chain: \"5042\", inputMint: USDC.address, outputMint: token.address, amount: (5n * 10n ** 6n).toString(), slippageBps: \"100\" });\nconst [fast, full] = await Promise.all([\n  fetch(`${A}/quote?${params}&fast=1`).then((r) => r.json()),\n  fetch(`${A}/quote?${params}`).then((r) => r.json()),\n]);\nconst quote = full; // never build from `fast` (preliminary: true)\nif (quote.routePlan.length === 0) return showNoRoute(quote.noRouteReason); // INSUFFICIENT_LIQUIDITY → suggest a smaller size\n```\n\nShow `outputAmount` (scaled by the output token's decimals), `priceImpactPct`, `feeBps`, and `otherAmountThreshold` as the minimum received."},{"heading":"3. Approve the router when needed","anchor":"3-approve-the-router-when-needed","text":"For an ERC-20 input — and on Arc every input is one, since the native unit aliases to the USDC predeploy — the router must be allowed to pull `inputAmount`. The router address is `transaction.to` in the `/swap` answer (`0x1b1fee89a381e595fe6536b99ba91f3e16e9601a` on both chains). Read the allowance first and skip the approve when it is enough.\n\n```ts\nconst allowance = await publicClient.readContract({ address: USDC.address, abi: erc20Abi, functionName: \"allowance\", args: [wallet, ROUTER] });\nif (allowance < BigInt(quote.inputAmount)) {\n  await walletClient.writeContract({ address: USDC.address, abi: erc20Abi, functionName: \"approve\", args: [ROUTER, BigInt(quote.inputAmount)] });\n}\n```"},{"heading":"4. Build","anchor":"4-build","text":"```ts\nconst { transaction } = await fetch(`${A}/swap`, {\n  method: \"POST\", headers: { \"Content-Type\": \"application/json\" },\n  body: JSON.stringify({ quoteResponse: quote, userPublicKey: wallet, chain: 5042 }),\n}).then((r) => r.json());\n```\n\nSend the quote back **unmodified**. A changed body is `400 ROUTE_MISMATCH`; a different `slippageBps` is `400 SLIPPAGE_MISMATCH` — re-quote instead. Pass `feeAccount` if you are a referrer."},{"heading":"5. Simulate","anchor":"5-simulate","text":"```ts\nconst sim = await fetch(`${A}/swap/simulate`, {\n  method: \"POST\", headers: { \"Content-Type\": \"application/json\" },\n  body: JSON.stringify({ chain: 5042, from: wallet, to: transaction.to, data: transaction.data, value: transaction.value }),\n}).then((r) => r.json());\nif (sim.ok === false && !/not approved/i.test(sim.revert)) return showRevert(sim.revert);\n```\n\nAn allowance revert right after the approve is expected (the approve may not be mined yet); proceed. Any other revert, stop."},{"heading":"6. Sign and send","anchor":"6-sign-and-send","text":"```ts\nconst hash = await walletClient.sendTransaction({\n  to: transaction.to, data: transaction.data, value: BigInt(transaction.value), gas: BigInt(transaction.gasLimit), chain: arc,\n});\n```\n\nOn Arc `value` is always `0`. Wait for the receipt; the output lands in the user's wallet. Explorer: `https://explorer.arc.io/tx/${hash}`."},{"heading":"Edge cases","anchor":"edge-cases","text":"- **Quote expired.** A quote is good for about 30 seconds. If the user idled, quote again before `/swap`.\n- **Price moved past the threshold.** The transaction reverts with insufficient output. Quote again; do not resubmit.\n- **Gateway dropped the send.** Arc's public gateway has been seen dropping one broadcast in six. Use a dedicated RPC for `sendRawTransaction` and retry with the same nonce on a timeout.\n- **Robinhood Chain.** Same flow with `chain: 4663`; native ETH is the zero address and is sent as `value`, WETH is wrapped for you. Stocks and USDG are 0 bps.\n- **Contracts calling the router.** `GET /swap/calldata` quotes and encodes in one call with the output to `msg.sender`."}]},{"kind":"page","path":"/docs/recipes/token-page/","url":"https://getchord.xyz/docs/recipes/token-page/","title":"Build a token page","description":"Header, chart, tape, venues, pools, holders and a trade card for one token on Arc — which calls, in what order, and what to stream.","markdown":"**Goal**: the page Chord itself shows for a token on Arc — price and change in the header, a candle chart, the trade tape, venue split, pools, holders, and a route card — built from six calls on load and two WebSocket channels after.\n\n## On load, in parallel\n\n| Component | Call | Read |\n| --- | --- | --- |\n| Header (symbol, name, logo, price, 24h change, market cap, flags) | `GET /arc/token/{address}?hours=24` | `token` — the full token row; `series` for a 24-hour volume bar |\n| Windowed stats (5m / 1h / 6h / 24h, ATH, 24h range, makers) | `GET /tokens/stats/{address}` | `windows`, `ath`, `range24h`, `markets` |\n| Chart | `GET /tokens/chart/{address}?tf=1h` | `candles` (200, oldest first); page back with `before` |\n| Trade tape | `GET /tokens/trades/{address}?limit=50` | `trades`, `stats24h` |\n| Pools | `GET /lp/token/{address}/pools?chain=5042` | pools ranked by health, with launch facts |\n| Holders | `GET /arc/token/{address}/holders?limit=20` | `holders`, `concentration`, `top` (each tagged wallet / pool / burn) |\n\n```ts\nconst A = \"https://api.getchord.xyz/v1\";\nconst [tok, stats, chart, tape, pools, holders] = await Promise.all([\n  `${A}/arc/token/${addr}?hours=24`, `${A}/tokens/stats/${addr}`, `${A}/tokens/chart/${addr}?tf=1h`,\n  `${A}/tokens/trades/${addr}?limit=50`, `${A}/lp/token/${addr}/pools?chain=5042`, `${A}/arc/token/${addr}/holders?limit=20`,\n].map((u) => fetch(u).then((r) => (r.ok ? r.json() : null))));\n```\n\nTreat a `null` (a `404` or `503`) per component: a `503 HOLDERS_PENDING` means the ledger just started tracking this token — show \"building\" and retry in a few minutes; a `404` on the chart means the token has no indexed pool yet.\n\n## Then stream\n\n```ts\nconst ws = new WebSocket(\"wss://api.getchord.xyz/v1/ws/live\");\nws.onopen = () => {\n  ws.send(JSON.stringify({ op: \"sub\", channel: \"candles\", token: addr, tf: \"1h\" }));\n  ws.send(JSON.stringify({ op: \"sub\", channel: \"trades\", token: addr }));\n};\nws.onmessage = (e) => {\n  const m = JSON.parse(e.data);\n  if (m.op === \"candle\") chart.upsert(m.candle);          // by t; closed:true seals the bucket\n  if (m.op === \"trades\") { tape.prepend(m.items); header.price = m.items[0].priceUsd; }\n};\n```\n\nThe header price is the latest print; a green dot while frames arrive is honest \"live\". Re-fetch `/arc/token` and `/tokens/stats` every 30–60 s for the rolled-up figures.\n\n## Header details\n\n- `token.listed` false: show the on-chain symbol with a \"not on the list\" hint; `logoURI` is a placeholder until art is found.\n- `token.flags` includes `wash` or `impostor`: badge it. The boards already sort such rows down; the page should say why.\n- `token.routable` false: hide the trade card, or show \"no route yet\".\n- `marketCapUsd` is fully diluted; label it FDV.\n\n## The trade card\n\nQuote on the user's amount with `GET /quote?chain=5042&inputMint=0x3600…0000&outputMint={address}&amount=…`, then follow the [Swap recipe](/docs/recipes/swap/). Link the row to `https://getchord.xyz/arc/token/{address}?side=buy` if you would rather hand off to Chord.\n\n## Venues and pools\n\n`tok.byDex` (24-hour share per venue id) makes the venue table; map ids to names with the [venue ids](/docs/resources/venue-ids/) table. `pools` from the liquidity family carries `score` and `reasons` — show the reasons on hover, they are the difference between a pool with fifty providers and one where the launcher holds everything.\n\n## Holders\n\n`heldByWalletsPct` is supply outside pools and burn sinks. `concentration.top10` above ~60 % on a token with thousands of holders is worth a badge. Rows tagged `pool` are the pools themselves; `burn` is the dead address.","sections":[{"heading":"","anchor":"","text":"**Goal**: the page Chord itself shows for a token on Arc — price and change in the header, a candle chart, the trade tape, venue split, pools, holders, and a route card — built from six calls on load and two WebSocket channels after."},{"heading":"On load, in parallel","anchor":"on-load-in-parallel","text":"| Component | Call | Read |\n| --- | --- | --- |\n| Header (symbol, name, logo, price, 24h change, market cap, flags) | `GET /arc/token/{address}?hours=24` | `token` — the full token row; `series` for a 24-hour volume bar |\n| Windowed stats (5m / 1h / 6h / 24h, ATH, 24h range, makers) | `GET /tokens/stats/{address}` | `windows`, `ath`, `range24h`, `markets` |\n| Chart | `GET /tokens/chart/{address}?tf=1h` | `candles` (200, oldest first); page back with `before` |\n| Trade tape | `GET /tokens/trades/{address}?limit=50` | `trades`, `stats24h` |\n| Pools | `GET /lp/token/{address}/pools?chain=5042` | pools ranked by health, with launch facts |\n| Holders | `GET /arc/token/{address}/holders?limit=20` | `holders`, `concentration`, `top` (each tagged wallet / pool / burn) |\n\n```ts\nconst A = \"https://api.getchord.xyz/v1\";\nconst [tok, stats, chart, tape, pools, holders] = await Promise.all([\n  `${A}/arc/token/${addr}?hours=24`, `${A}/tokens/stats/${addr}`, `${A}/tokens/chart/${addr}?tf=1h`,\n  `${A}/tokens/trades/${addr}?limit=50`, `${A}/lp/token/${addr}/pools?chain=5042`, `${A}/arc/token/${addr}/holders?limit=20`,\n].map((u) => fetch(u).then((r) => (r.ok ? r.json() : null))));\n```\n\nTreat a `null` (a `404` or `503`) per component: a `503 HOLDERS_PENDING` means the ledger just started tracking this token — show \"building\" and retry in a few minutes; a `404` on the chart means the token has no indexed pool yet."},{"heading":"Then stream","anchor":"then-stream","text":"```ts\nconst ws = new WebSocket(\"wss://api.getchord.xyz/v1/ws/live\");\nws.onopen = () => {\n  ws.send(JSON.stringify({ op: \"sub\", channel: \"candles\", token: addr, tf: \"1h\" }));\n  ws.send(JSON.stringify({ op: \"sub\", channel: \"trades\", token: addr }));\n};\nws.onmessage = (e) => {\n  const m = JSON.parse(e.data);\n  if (m.op === \"candle\") chart.upsert(m.candle);          // by t; closed:true seals the bucket\n  if (m.op === \"trades\") { tape.prepend(m.items); header.price = m.items[0].priceUsd; }\n};\n```\n\nThe header price is the latest print; a green dot while frames arrive is honest \"live\". Re-fetch `/arc/token` and `/tokens/stats` every 30–60 s for the rolled-up figures."},{"heading":"Header details","anchor":"header-details","text":"- `token.listed` false: show the on-chain symbol with a \"not on the list\" hint; `logoURI` is a placeholder until art is found.\n- `token.flags` includes `wash` or `impostor`: badge it. The boards already sort such rows down; the page should say why.\n- `token.routable` false: hide the trade card, or show \"no route yet\".\n- `marketCapUsd` is fully diluted; label it FDV."},{"heading":"The trade card","anchor":"the-trade-card","text":"Quote on the user's amount with `GET /quote?chain=5042&inputMint=0x3600…0000&outputMint={address}&amount=…`, then follow the [Swap recipe](/docs/recipes/swap/). Link the row to `https://getchord.xyz/arc/token/{address}?side=buy` if you would rather hand off to Chord."},{"heading":"Venues and pools","anchor":"venues-and-pools","text":"`tok.byDex` (24-hour share per venue id) makes the venue table; map ids to names with the [venue ids](/docs/resources/venue-ids/) table. `pools` from the liquidity family carries `score` and `reasons` — show the reasons on hover, they are the difference between a pool with fifty providers and one where the launcher holds everything."},{"heading":"Holders","anchor":"holders","text":"`heldByWalletsPct` is supply outside pools and burn sinks. `concentration.top10` above ~60 % on a token with thousands of holders is worth a badge. Rows tagged `pool` are the pools themselves; `burn` is the dead address."}]},{"kind":"page","path":"/docs/recipes/trader-dashboard/","url":"https://getchord.xyz/docs/recipes/trader-dashboard/","title":"Trader dashboard","description":"Top wallets on Arc, one wallet's PnL and history, its calendar, and its liquidity positions — a Nansen-style page from five calls.","markdown":"**Goal**: a \"who is winning\" board and a wallet profile page.\n\n## Top wallets\n\n```ts\nconst board = await fetch(`${A}/smart-money/top?chain=5042&source=onchain&window=7d&limit=50`).then((r) => r.json());\n```\n\n`wallets` are ranked by [Smart Score](/docs/concepts/wallet-pnl/#smart-score), with routers and bots already removed (`botsRemoved` says how many). Show `pnlUsd` (realized + open), `realizedUsd`, `winRate`, `trades`, `topToken` and `archetype`. `totalWallets` is how many qualified; `indexedToBlock` is the tape's head when the board was built. `503 CHAIN_NOT_ENABLED` means the board is not published for the chain yet.\n\nWindows: `24h` (rebuilt every 15 minutes), `7d` and `30d` (hourly), `all` (three-hourly). On Arc a live delta sits on top of the last rebuild, so polling every 30 s shows movement.\n\n## Wallet profile\n\nFour calls in parallel:\n\n| Panel | Call |\n| --- | --- |\n| Holdings and PnL per token | `GET /portfolio/{wallet}/pnl?chain=5042` |\n| Trade history (chart markers, activity list) | `GET /portfolio/{wallet}/trades?chain=5042` |\n| Calendar (realized PnL by day) | `GET /portfolio/{wallet}/pnl-calendar?chain=5042` |\n| Liquidity positions | `GET /lp/positions?chain=5042&owner={wallet}&status=all` |\n\n```ts\nconst [pnl, trades, cal, lp] = await Promise.all([\n  `${A}/portfolio/${w}/pnl?chain=5042`, `${A}/portfolio/${w}/trades?chain=5042`,\n  `${A}/portfolio/${w}/pnl-calendar?chain=5042`, `${A}/lp/positions?chain=5042&owner=${w}&status=all`,\n].map((u) => fetch(u).then((r) => r.json())));\n```\n\n- `pnl.tokens[]` gives realized, unrealized, average cost, current amount and value, ROI, and the **untracked** balance that arrived by transfer (no cost basis). Show untracked separately; it is not a loss or a gain.\n- `pnl` is cached stale-while-revalidate: `updatedAt` tells you how old the answer is; a first view of a busy wallet may take a few seconds.\n- `cal.days[]` (`date`, `realizedUsd`, `trades`) draws the calendar; `realizedTotal` reconciles with `pnl.realized`.\n- `lp.summary` (open, closed, wins, win rate, realized LP PnL, fees, open value) and `lp.positions[]` (each with live value, in-range, fees, `jit` / `unreconciled` flags) make the liquidity tab.\n\n## Is this wallet a bot?\n\nThe board already removed bots. For a wallet you look up directly, the tells are in the data: hundreds of trades a day from the first trade, buy-then-sell inside a minute, dozens of launches sniped. The Ask agent can answer \"is 0x… a bot\" with its wallet profile tool if you would rather not implement the heuristics.\n\n## Follow a trader\n\nThere is no server-side follow. Poll `GET /portfolio/{wallet}/trades?chain=5042` every 30–60 s and diff by `tx`, or subscribe to the WebSocket `trades` channel for the tokens the wallet holds and match `wallet` on incoming items.","sections":[{"heading":"","anchor":"","text":"**Goal**: a \"who is winning\" board and a wallet profile page."},{"heading":"Top wallets","anchor":"top-wallets","text":"```ts\nconst board = await fetch(`${A}/smart-money/top?chain=5042&source=onchain&window=7d&limit=50`).then((r) => r.json());\n```\n\n`wallets` are ranked by [Smart Score](/docs/concepts/wallet-pnl/#smart-score), with routers and bots already removed (`botsRemoved` says how many). Show `pnlUsd` (realized + open), `realizedUsd`, `winRate`, `trades`, `topToken` and `archetype`. `totalWallets` is how many qualified; `indexedToBlock` is the tape's head when the board was built. `503 CHAIN_NOT_ENABLED` means the board is not published for the chain yet.\n\nWindows: `24h` (rebuilt every 15 minutes), `7d` and `30d` (hourly), `all` (three-hourly). On Arc a live delta sits on top of the last rebuild, so polling every 30 s shows movement."},{"heading":"Wallet profile","anchor":"wallet-profile","text":"Four calls in parallel:\n\n| Panel | Call |\n| --- | --- |\n| Holdings and PnL per token | `GET /portfolio/{wallet}/pnl?chain=5042` |\n| Trade history (chart markers, activity list) | `GET /portfolio/{wallet}/trades?chain=5042` |\n| Calendar (realized PnL by day) | `GET /portfolio/{wallet}/pnl-calendar?chain=5042` |\n| Liquidity positions | `GET /lp/positions?chain=5042&owner={wallet}&status=all` |\n\n```ts\nconst [pnl, trades, cal, lp] = await Promise.all([\n  `${A}/portfolio/${w}/pnl?chain=5042`, `${A}/portfolio/${w}/trades?chain=5042`,\n  `${A}/portfolio/${w}/pnl-calendar?chain=5042`, `${A}/lp/positions?chain=5042&owner=${w}&status=all`,\n].map((u) => fetch(u).then((r) => r.json())));\n```\n\n- `pnl.tokens[]` gives realized, unrealized, average cost, current amount and value, ROI, and the **untracked** balance that arrived by transfer (no cost basis). Show untracked separately; it is not a loss or a gain.\n- `pnl` is cached stale-while-revalidate: `updatedAt` tells you how old the answer is; a first view of a busy wallet may take a few seconds.\n- `cal.days[]` (`date`, `realizedUsd`, `trades`) draws the calendar; `realizedTotal` reconciles with `pnl.realized`.\n- `lp.summary` (open, closed, wins, win rate, realized LP PnL, fees, open value) and `lp.positions[]` (each with live value, in-range, fees, `jit` / `unreconciled` flags) make the liquidity tab."},{"heading":"Is this wallet a bot?","anchor":"is-this-wallet-a-bot","text":"The board already removed bots. For a wallet you look up directly, the tells are in the data: hundreds of trades a day from the first trade, buy-then-sell inside a minute, dozens of launches sniped. The Ask agent can answer \"is 0x… a bot\" with its wallet profile tool if you would rather not implement the heuristics."},{"heading":"Follow a trader","anchor":"follow-a-trader","text":"There is no server-side follow. Poll `GET /portfolio/{wallet}/trades?chain=5042` every 30–60 s and diff by `tx`, or subscribe to the WebSocket `trades` channel for the tokens the wallet holds and match `wallet` on incoming items."}]},{"kind":"page","path":"/docs/resources/changelog/","url":"https://getchord.xyz/docs/resources/changelog/","title":"Changelog","description":"What changed in the API, newest first.","markdown":"## 2026-10-16\n\n- **Chord for agents and answer engines**: every docs page has a Markdown twin (add `.md` to its path, or send `Accept: text/markdown`), and [`/llms.txt`](/llms.txt) now lists them all with a line each. Agents can find Chord's tools from the domain alone: [`/.well-known/api-catalog`](/.well-known/api-catalog) (RFC 9727), [`/.well-known/ai-catalog.json`](/.well-known/ai-catalog.json) with an MCP server card for each server (`https://api.getchord.xyz/v1/mcp/server-card`, `https://getchord.xyz/docs/mcp/server-card`), and [`/.well-known/agent-skills/index.json`](/.well-known/agent-skills/index.json) with the skill as one archive. `/llms-full.txt`, `/openapi.json` and `/skill.md` answer at the site root. See [llms.txt, Markdown and discovery files](/docs/agents/llms-txt/).\n- **Solana swaps are open to everyone** (2026-10-15 21:25 UTC): `/v1/sol/trade/quote`, `/send` and `/tx/{signature}` answer every caller, no key needed. Each quote builds Chord's own route and Jupiter's for the wallet, simulates both and returns the one that leaves the wallet with more; the wallet signs the returned transaction unchanged. See [Solana](/docs/networks/solana/#swaps).\n- **Robinhood Chain token list: one token per symbol.** A stock token owns its ticker (memes reusing GME, AMC, NET, FLY or BULL are left out); among memes that share a symbol the busiest in the last 24 hours stays. `/v1/tokens/search?chain=4663` follows the same rule, and lists the others as `verified: false` when they traded in the last 24 hours. Boards, token pages and charts are unchanged.\n- **Chord routes Solana swaps itself**: `/v1/sol/trade/quote` now builds a third route of Chord's own, `direct`, on Raydium AMM v4 / CPMM / CLMM, Orca Whirlpool, Meteora DLMM / DAMM v2, Meteora DBC and Raydium LaunchLab (plus pump.fun and PumpSwap, as before), with pools from Chord's tape and up to two pools per swap. It is built and simulated for the wallet next to Jupiter's swap API and Jupiter's order; the wallet gets whichever leaves it with more. New `venue` values on a quote: `raydium_v4`, `raydium_cpmm`, `raydium_clmm`, `orca`, `meteora_dlmm`, `meteora_damm_v2`, `meteora_dbc`, `raydium_launchlab`; `hops` lists the pools and their share. See [Solana](/docs/networks/solana/#swaps-beta).\n- **Fixed in the reference**: `GET /v1/tokens` and `GET /v1/logo/{chain}/{address}` list all eight EVM chains (they have answered on 43114, 8453, 56, 42161 and 1 since each chain went public; the reference said `5042`, `4663` and `143`). The function-calling manifest at `/agent/tools.json` carries `arbitrum` and `ethereum` like the hosted MCP.\n- **Robinhood Chain token list**: a look-alike USDG (`0x5fc54b6c…d168`, no trades) is no longer listed beside the real one (`0x5fc5360d…d168`). A token that takes the symbol of a chain anchor under another address is left out.\n\n## 2026-10-15\n\n- **Ethereum (1) is public**: `/v1/chains/ethereum/*`, `/v1/candles?chain=1`, `/v1/tokens/search?chain=1`, the hosted MCP and Ask read it; `/v1/quote` and `/v1/swap` route on it through the same Chord router (Uniswap V2 / V3 / V4, PancakeSwap V3, SushiSwap V2 / V3). Ethereum's USDT refuses a new approval over a left-over one: `/v1/meta` answers carry `approval.resetFirst`. See [Ethereum](/docs/networks/ethereum/).\n- **Arbitrum One (42161) is public**: `/v1/chains/arbitrum/*`, `/v1/candles?chain=42161`, `/v1/tokens/search?chain=42161`, the hosted MCP and Ask read it; `/v1/quote` and `/v1/swap` route on it through the same Chord router. See [Arbitrum](/docs/networks/arbitrum/).\n- **Every chain has a network page**: [Monad](/docs/networks/monad/), [Avalanche](/docs/networks/avalanche/), [Base](/docs/networks/base/), [BNB Chain](/docs/networks/bnb-chain/) and [Arbitrum](/docs/networks/arbitrum/) join Arc, Robinhood Chain and Solana, with ids, anchors, contracts, venues and the routes that serve each one.\n- **Fixed in the reference**: `/v1/quote`, `/v1/swap`, `/v1/swap/calldata` and `/v1/swap/simulate` list chains `43114`, `8453`, `56` and `42161`. The first three have answered on those chains since 2026-10-02; the reference said `5042`, `4663` and `143` only.\n\n## 2026-10-11\n\n- **Backtests are in the reference**: `GET /v1/backtest` replays a bar-close strategy (Supertrend, EMA cross, RSI, Donchian, buy and hold) over stored candles of any Hyperliquid perp and 13 FX pairs and metals; `GET /v1/fx/lake` shows how far the FX store is filled. The reference now states the model, every parameter with its default, and that this endpoint's times are in milliseconds. The endpoint has been live since 2026-09-24.\n- **Fixed**: `/v1/backtest` upper-cased the symbol, so Hyperliquid's k-prefixed perps (`kPEPE`, `kSHIB`, `kBONK`, `kFLOKI`, `kLUNC`, `kNEIRO`, `kDOGS`) found no bars. The symbol is now matched without case.\n\n## 2026-10-04\n\n- **Solana data, read-only** (public since 2026-10-04): `GET /v1/chains/solana/status`, `/overview`, `/tokens`, `/search`, `/token/{mint}` (+ `/trades`, `/candles`, `/traders`), `/traders`, `/wallet/{address}` (+ `/trades`). Chord's own tape of the swap events of 11 venues (PumpSwap, pump.fun, Meteora, Raydium, Orca); prop AMMs and order books are not read. Addresses are base58 and case-sensitive; `updatedAt` on these routes is Unix seconds. See [Solana](/docs/networks/solana/).\n\n## 2026-09-30\n\n- **Live boards on Robinhood Chain**: the WebSocket `prices` channel now serves chain `4663` as well as `5042` (and `143`), every print within ~400 ms.\n- **Live 24h counters**: `prices` items on Arc and Robinhood Chain carry `volume24h`, `trades24h` (and on Arc `buyVolume24h`, `sellVolume24h`, `buys24h`, `sells24h`); frames carry `at`. `GET /v1/tokens/market?chain=4663` returns `updatedAt` and, like `/v1/arc/tokens`, already includes trades the hourly rollup has not counted yet.\n- **First-time tokens**: `new` frames on the same subscription, with on-chain name and supply.\n\n## 2026-09-20\n\n- **Docs**: this site, with the API reference generated from the OpenAPI document and `llms.txt`.\n- **Liquidity**: `GET /v1/lp/overview` (fees paid to LPs, best real yield, flows, hot pools), `GET /v1/lp/plan` and `GET /v1/lp/simulate` (range bands and backtests), `GET /v1/lp/pools/{pool}` now returns `health`, `launch` and `mint`, `GET /v1/lp/token/{address}/pools` ranks by health.\n- **Top wallets on Arc** move between rebuilds: a live delta of the last minutes' trades sits on the rolled board (`live` in the response).\n\n## 2026-09-19\n\n- **Venue names on Arc**: `synthra_v3`, `sushi_v2`, `sushi_v3`, `dyorswap` and `slipstream_fork` replace factory-keyed ids for those venues.\n- **Honesty flags** on token rows (`wash`, `impostor`) and pool rows (`suspect`, `token0.impostor`); boards sort flagged rows last and `/lp/pools` hides suspect pools unless `flagged=1`.\n\n## 2026-09-18\n\n- **Liquidity family** `/v1/lp/*` on Arc, Robinhood Chain and Monad: events, pools, positions, leaderboard, watch alerts.\n- **Ask agent API**: `POST /v1/ask` accepts a developer API key and `stream: false`; `GET /v1/ask/picks`; research notes via `POST /v1/ask/report`.\n- **Token art round two**: logos resolved from the token's own creation transaction; the logo proxy serves every Arc row.\n\n## 2026-09-17\n\n- **Holder ledger**: `GET /v1/arc/token/{address}/holders` — balances from Transfer logs, tagged wallet / pool / burn, with concentration.\n- **Launch radar**: `GET /v1/arc/launchers` and launcher names on `GET /v1/arc/graduated`.\n- **Attention**: `GET /v1/arc/attention`.\n\n## 2026-09-16\n\n- **Trading live on Arc**: the router, fee collector and adapter registry at the same addresses as the other chains; `/quote` and `/swap` with `chain=5042`. Uniswap V4 pools route with native USDC, including verified launchpad hooks. The native sentinel aliases to the USDC predeploy.\n- **Live Arc prices** over `/v1/ws/live` channel `prices`.\n- **Bridge**: `/v1/bridge2/*` (Circle CCTP fast transfer to Arc with a gasless mint relay) and LI.FI on `/v1/crosschain/*` (`provider=lifi`).\n- **Portfolio and top wallets** on Arc (`chain=5042`).\n\n## 2026-09-15\n\n- **Arc index**: the trade tape, hourly and daily rollups, and `/v1/arc/*` (status, overview, venues, tokens, search, trending, token).\n- **Token list** for Arc: `GET /v1/tokens?chain=5042`.\n\n## 2026-09-08\n\n- **Chord** launches with the Robinhood Chain index: `/v1/rh/*` (overview, venues, tokens, token, stocks), the stocks page and the developer portal with API keys.","sections":[{"heading":"2026-10-16","anchor":"2026-10-16","text":"- **Chord for agents and answer engines**: every docs page has a Markdown twin (add `.md` to its path, or send `Accept: text/markdown`), and [`/llms.txt`](/llms.txt) now lists them all with a line each. Agents can find Chord's tools from the domain alone: [`/.well-known/api-catalog`](/.well-known/api-catalog) (RFC 9727), [`/.well-known/ai-catalog.json`](/.well-known/ai-catalog.json) with an MCP server card for each server (`https://api.getchord.xyz/v1/mcp/server-card`, `https://getchord.xyz/docs/mcp/server-card`), and [`/.well-known/agent-skills/index.json`](/.well-known/agent-skills/index.json) with the skill as one archive. `/llms-full.txt`, `/openapi.json` and `/skill.md` answer at the site root. See [llms.txt, Markdown and discovery files](/docs/agents/llms-txt/).\n- **Solana swaps are open to everyone** (2026-10-15 21:25 UTC): `/v1/sol/trade/quote`, `/send` and `/tx/{signature}` answer every caller, no key needed. Each quote builds Chord's own route and Jupiter's for the wallet, simulates both and returns the one that leaves the wallet with more; the wallet signs the returned transaction unchanged. See [Solana](/docs/networks/solana/#swaps).\n- **Robinhood Chain token list: one token per symbol.** A stock token owns its ticker (memes reusing GME, AMC, NET, FLY or BULL are left out); among memes that share a symbol the busiest in the last 24 hours stays. `/v1/tokens/search?chain=4663` follows the same rule, and lists the others as `verified: false` when they traded in the last 24 hours. Boards, token pages and charts are unchanged.\n- **Chord routes Solana swaps itself**: `/v1/sol/trade/quote` now builds a third route of Chord's own, `direct`, on Raydium AMM v4 / CPMM / CLMM, Orca Whirlpool, Meteora DLMM / DAMM v2, Meteora DBC and Raydium LaunchLab (plus pump.fun and PumpSwap, as before), with pools from Chord's tape and up to two pools per swap. It is built and simulated for the wallet next to Jupiter's swap API and Jupiter's order; the wallet gets whichever leaves it with more. New `venue` values on a quote: `raydium_v4`, `raydium_cpmm`, `raydium_clmm`, `orca`, `meteora_dlmm`, `meteora_damm_v2`, `meteora_dbc`, `raydium_launchlab`; `hops` lists the pools and their share. See [Solana](/docs/networks/solana/#swaps-beta).\n- **Fixed in the reference**: `GET /v1/tokens` and `GET /v1/logo/{chain}/{address}` list all eight EVM chains (they have answered on 43114, 8453, 56, 42161 and 1 since each chain went public; the reference said `5042`, `4663` and `143`). The function-calling manifest at `/agent/tools.json` carries `arbitrum` and `ethereum` like the hosted MCP.\n- **Robinhood Chain token list**: a look-alike USDG (`0x5fc54b6c…d168`, no trades) is no longer listed beside the real one (`0x5fc5360d…d168`). A token that takes the symbol of a chain anchor under another address is left out."},{"heading":"2026-10-15","anchor":"2026-10-15","text":"- **Ethereum (1) is public**: `/v1/chains/ethereum/*`, `/v1/candles?chain=1`, `/v1/tokens/search?chain=1`, the hosted MCP and Ask read it; `/v1/quote` and `/v1/swap` route on it through the same Chord router (Uniswap V2 / V3 / V4, PancakeSwap V3, SushiSwap V2 / V3). Ethereum's USDT refuses a new approval over a left-over one: `/v1/meta` answers carry `approval.resetFirst`. See [Ethereum](/docs/networks/ethereum/).\n- **Arbitrum One (42161) is public**: `/v1/chains/arbitrum/*`, `/v1/candles?chain=42161`, `/v1/tokens/search?chain=42161`, the hosted MCP and Ask read it; `/v1/quote` and `/v1/swap` route on it through the same Chord router. See [Arbitrum](/docs/networks/arbitrum/).\n- **Every chain has a network page**: [Monad](/docs/networks/monad/), [Avalanche](/docs/networks/avalanche/), [Base](/docs/networks/base/), [BNB Chain](/docs/networks/bnb-chain/) and [Arbitrum](/docs/networks/arbitrum/) join Arc, Robinhood Chain and Solana, with ids, anchors, contracts, venues and the routes that serve each one.\n- **Fixed in the reference**: `/v1/quote`, `/v1/swap`, `/v1/swap/calldata` and `/v1/swap/simulate` list chains `43114`, `8453`, `56` and `42161`. The first three have answered on those chains since 2026-10-02; the reference said `5042`, `4663` and `143` only."},{"heading":"2026-10-11","anchor":"2026-10-11","text":"- **Backtests are in the reference**: `GET /v1/backtest` replays a bar-close strategy (Supertrend, EMA cross, RSI, Donchian, buy and hold) over stored candles of any Hyperliquid perp and 13 FX pairs and metals; `GET /v1/fx/lake` shows how far the FX store is filled. The reference now states the model, every parameter with its default, and that this endpoint's times are in milliseconds. The endpoint has been live since 2026-09-24.\n- **Fixed**: `/v1/backtest` upper-cased the symbol, so Hyperliquid's k-prefixed perps (`kPEPE`, `kSHIB`, `kBONK`, `kFLOKI`, `kLUNC`, `kNEIRO`, `kDOGS`) found no bars. The symbol is now matched without case."},{"heading":"2026-10-04","anchor":"2026-10-04","text":"- **Solana data, read-only** (public since 2026-10-04): `GET /v1/chains/solana/status`, `/overview`, `/tokens`, `/search`, `/token/{mint}` (+ `/trades`, `/candles`, `/traders`), `/traders`, `/wallet/{address}` (+ `/trades`). Chord's own tape of the swap events of 11 venues (PumpSwap, pump.fun, Meteora, Raydium, Orca); prop AMMs and order books are not read. Addresses are base58 and case-sensitive; `updatedAt` on these routes is Unix seconds. See [Solana](/docs/networks/solana/)."},{"heading":"2026-09-30","anchor":"2026-09-30","text":"- **Live boards on Robinhood Chain**: the WebSocket `prices` channel now serves chain `4663` as well as `5042` (and `143`), every print within ~400 ms.\n- **Live 24h counters**: `prices` items on Arc and Robinhood Chain carry `volume24h`, `trades24h` (and on Arc `buyVolume24h`, `sellVolume24h`, `buys24h`, `sells24h`); frames carry `at`. `GET /v1/tokens/market?chain=4663` returns `updatedAt` and, like `/v1/arc/tokens`, already includes trades the hourly rollup has not counted yet.\n- **First-time tokens**: `new` frames on the same subscription, with on-chain name and supply."},{"heading":"2026-09-20","anchor":"2026-09-20","text":"- **Docs**: this site, with the API reference generated from the OpenAPI document and `llms.txt`.\n- **Liquidity**: `GET /v1/lp/overview` (fees paid to LPs, best real yield, flows, hot pools), `GET /v1/lp/plan` and `GET /v1/lp/simulate` (range bands and backtests), `GET /v1/lp/pools/{pool}` now returns `health`, `launch` and `mint`, `GET /v1/lp/token/{address}/pools` ranks by health.\n- **Top wallets on Arc** move between rebuilds: a live delta of the last minutes' trades sits on the rolled board (`live` in the response)."},{"heading":"2026-09-19","anchor":"2026-09-19","text":"- **Venue names on Arc**: `synthra_v3`, `sushi_v2`, `sushi_v3`, `dyorswap` and `slipstream_fork` replace factory-keyed ids for those venues.\n- **Honesty flags** on token rows (`wash`, `impostor`) and pool rows (`suspect`, `token0.impostor`); boards sort flagged rows last and `/lp/pools` hides suspect pools unless `flagged=1`."},{"heading":"2026-09-18","anchor":"2026-09-18","text":"- **Liquidity family** `/v1/lp/*` on Arc, Robinhood Chain and Monad: events, pools, positions, leaderboard, watch alerts.\n- **Ask agent API**: `POST /v1/ask` accepts a developer API key and `stream: false`; `GET /v1/ask/picks`; research notes via `POST /v1/ask/report`.\n- **Token art round two**: logos resolved from the token's own creation transaction; the logo proxy serves every Arc row."},{"heading":"2026-09-17","anchor":"2026-09-17","text":"- **Holder ledger**: `GET /v1/arc/token/{address}/holders` — balances from Transfer logs, tagged wallet / pool / burn, with concentration.\n- **Launch radar**: `GET /v1/arc/launchers` and launcher names on `GET /v1/arc/graduated`.\n- **Attention**: `GET /v1/arc/attention`."},{"heading":"2026-09-16","anchor":"2026-09-16","text":"- **Trading live on Arc**: the router, fee collector and adapter registry at the same addresses as the other chains; `/quote` and `/swap` with `chain=5042`. Uniswap V4 pools route with native USDC, including verified launchpad hooks. The native sentinel aliases to the USDC predeploy.\n- **Live Arc prices** over `/v1/ws/live` channel `prices`.\n- **Bridge**: `/v1/bridge2/*` (Circle CCTP fast transfer to Arc with a gasless mint relay) and LI.FI on `/v1/crosschain/*` (`provider=lifi`).\n- **Portfolio and top wallets** on Arc (`chain=5042`)."},{"heading":"2026-09-15","anchor":"2026-09-15","text":"- **Arc index**: the trade tape, hourly and daily rollups, and `/v1/arc/*` (status, overview, venues, tokens, search, trending, token).\n- **Token list** for Arc: `GET /v1/tokens?chain=5042`."},{"heading":"2026-09-08","anchor":"2026-09-08","text":"- **Chord** launches with the Robinhood Chain index: `/v1/rh/*` (overview, venues, tokens, token, stocks), the stocks page and the developer portal with API keys."}]},{"kind":"page","path":"/docs/resources/faq/","url":"https://getchord.xyz/docs/resources/faq/","title":"FAQ","description":"Short answers to the questions integrators ask first.","markdown":"**Do I need a key?**\nNo, to read. Anonymous calls get 60 requests a minute per IP (300 on the token and portfolio reads). A key raises that to your plan and is required for the Ask agent API.\n\n**Is Chord custodial?**\nNo. `/swap` returns an unsigned transaction; your wallet signs and broadcasts. Chord never holds funds or keys, on any plan.\n\n**Where do prices come from?**\nFrom Chord's own index of every swap on the chain, priced at index time against the chain's anchors. No third-party price API on the request path. `priceUsd` on a token row is the last trade on the token's dominant venue.\n\n**Why does `/quote` return an empty route?**\nNo venue fills that size honestly. `noRouteReason` says `INSUFFICIENT_LIQUIDITY` (try a smaller amount) or `NO_POOLS` (no pool against an anchor, or only on an unverified hook). The engine never fabricates a price.\n\n**Why is my Arc transaction's `value` 0 when I sell \"native\" USDC?**\nBecause on Arc the native unit and the USDC predeploy are one balance, and the router pulls the predeploy by `transferFrom`. Approve the router on `0x3600…0000` like any ERC-20. See [Chains, addresses and amounts](/docs/concepts/chains-and-amounts/).\n\n**How fresh is the data?**\nRead `coverage` on rollup answers and `/v1/arc/status`, `/v1/rh/status`, `/v1/lp/status` for the lanes. Prices over WebSocket are per print. See [Data freshness](/docs/concepts/data-freshness/).\n\n**What is a 503 `NOT_READY`?**\nA lane that has not run on this deployment yet, or a token the holder ledger just started tracking. Retry later; do not show it as \"no data\".\n\n**Why are some tokens missing from `/v1/tokens`?**\n`/v1/tokens` is the curated list. `/v1/arc/tokens?includeUnlisted=1` is every token that traded in 24 hours, listed or not, with the on-chain symbol.\n\n**How are bots removed from the top-wallets board?**\nBy cadence (hundreds of transactions a day from the first trade), nonce rate and deny lists, and behaviour (bursts, sub-minute round trips, sniping dozens of launches). `botsRemoved` counts each pass.\n\n**Can I stream Arc prices?**\nYes — subscribe to the `prices` channel on `/v1/ws/live` with `chain: 5042`. One subscription covers the whole board.\n\n**Can I get the whole API in one file?**\n[openapi.json](/docs/openapi.json). And this documentation as text at [llms.txt](/docs/llms.txt).\n\n**Where do fees go?**\nThe protocol fee on the output token (5 bps by default on every chain, 0 on USDC / EURC / USDG / stocks) goes to the fee collector; a referrer passed as `feeAccount` earns 50 % of it on that swap. Quotes and API usage are free.","sections":[{"heading":"","anchor":"","text":"**Do I need a key?**\nNo, to read. Anonymous calls get 60 requests a minute per IP (300 on the token and portfolio reads). A key raises that to your plan and is required for the Ask agent API.\n\n**Is Chord custodial?**\nNo. `/swap` returns an unsigned transaction; your wallet signs and broadcasts. Chord never holds funds or keys, on any plan.\n\n**Where do prices come from?**\nFrom Chord's own index of every swap on the chain, priced at index time against the chain's anchors. No third-party price API on the request path. `priceUsd` on a token row is the last trade on the token's dominant venue.\n\n**Why does `/quote` return an empty route?**\nNo venue fills that size honestly. `noRouteReason` says `INSUFFICIENT_LIQUIDITY` (try a smaller amount) or `NO_POOLS` (no pool against an anchor, or only on an unverified hook). The engine never fabricates a price.\n\n**Why is my Arc transaction's `value` 0 when I sell \"native\" USDC?**\nBecause on Arc the native unit and the USDC predeploy are one balance, and the router pulls the predeploy by `transferFrom`. Approve the router on `0x3600…0000` like any ERC-20. See [Chains, addresses and amounts](/docs/concepts/chains-and-amounts/).\n\n**How fresh is the data?**\nRead `coverage` on rollup answers and `/v1/arc/status`, `/v1/rh/status`, `/v1/lp/status` for the lanes. Prices over WebSocket are per print. See [Data freshness](/docs/concepts/data-freshness/).\n\n**What is a 503 `NOT_READY`?**\nA lane that has not run on this deployment yet, or a token the holder ledger just started tracking. Retry later; do not show it as \"no data\".\n\n**Why are some tokens missing from `/v1/tokens`?**\n`/v1/tokens` is the curated list. `/v1/arc/tokens?includeUnlisted=1` is every token that traded in 24 hours, listed or not, with the on-chain symbol.\n\n**How are bots removed from the top-wallets board?**\nBy cadence (hundreds of transactions a day from the first trade), nonce rate and deny lists, and behaviour (bursts, sub-minute round trips, sniping dozens of launches). `botsRemoved` counts each pass.\n\n**Can I stream Arc prices?**\nYes — subscribe to the `prices` channel on `/v1/ws/live` with `chain: 5042`. One subscription covers the whole board.\n\n**Can I get the whole API in one file?**\n[openapi.json](/docs/openapi.json). And this documentation as text at [llms.txt](/docs/llms.txt).\n\n**Where do fees go?**\nThe protocol fee on the output token (5 bps by default on every chain, 0 on USDC / EURC / USDG / stocks) goes to the fee collector; a referrer passed as `feeAccount` earns 50 % of it on that swap. Quotes and API usage are free."}]},{"kind":"page","path":"/docs/resources/troubleshooting/","url":"https://getchord.xyz/docs/resources/troubleshooting/","title":"Troubleshooting","description":"The failures integrators hit, what they mean, and the fix.","markdown":"## `400 INVALID_PARAMS` on `/quote`\n\nThe message names the parameter. The usual ones: `amount` sent as a float or with decimals (it must be an integer string in the smallest unit); `inputMint` equal to `outputMint`; a chain id the API does not serve.\n\n## `400 SLIPPAGE_MISMATCH` on `/swap`\n\nYou sent a `slippageBps` that differs from the quote's. The signed minimum is the quote's `otherAmountThreshold`; the field on `/swap` is a consistency check. Omit it, or quote again at the slippage you want.\n\n## `400 ROUTE_MISMATCH` on `/swap`\n\nThe quote body was edited between `/quote` and `/swap` (re-serialised numbers, dropped fields). Pass the parsed object back untouched.\n\n## The transaction reverts with insufficient output\n\nThe price moved past `otherAmountThreshold` between quote and execution. Quote again. Do not resubmit an old transaction — and if the route is a fresh launchpad curve, expect the number to move fast.\n\n## The transaction reverts before the wallet opens\n\nRun `POST /v1/swap/simulate`. `revert` names it: `Router is not approved…` means approve first (an approve that is not mined yet also triggers this — proceed); `ERC20InsufficientBalance` means the wallet does not hold `inputAmount`; a paused venue is muted within seconds, quote again.\n\n## Broadcast times out on Arc\n\nThe public gateway has been seen dropping one send in six. Broadcast through a dedicated RPC and, on a timeout, resend the same signed transaction (same nonce) rather than rebuilding.\n\n## `404 UNKNOWN_TOKEN` on charts, trades or stats\n\nThe address is neither on a curated list nor a side of an indexed pool. For Arc, check `GET /v1/arc/tokens/search?q=0x…` — if it returns a row with `pools` counts, the token is indexed and the chart will fill as trades arrive; if not, the token has no pool yet.\n\n## `503 HOLDERS_PENDING`\n\nThe holder ledger just pinned the token. The backfill walks Transfer logs back to the creation block; retry in a few minutes and read `complete`.\n\n## `503 CHAIN_NOT_ENABLED` on `/smart-money/top`\n\nThe board is not published for that chain on this deployment, or `source=onchain` was omitted on 5042 / 4663.\n\n## `429` on a page that \"only reads\"\n\nLogos, token reads and the default bucket are separate. A list page that paints hundreds of logos uses the logo bucket (3,000 a minute); table reads use the data bucket (300); `/arc/*` and `/lp/*` use the default (60). If you serve many users from one server IP, use a key so the limit is yours.\n\n## Numbers differ from another explorer\n\nChord counts every swap with no dust floor, attributes wallets through routers and executors, flags wash volume instead of summing it, and prices a token on its dominant venue. Read [Data freshness and honesty](/docs/concepts/data-freshness/) before comparing.\n\n## WebSocket disconnects after ~100 s behind a proxy\n\nThe server pings every 25 s; make sure your proxy passes WebSocket frames and does not idle-close at a lower interval. Reconnect with jittered backoff and re-subscribe — the server keeps no state for a closed socket.\n\n## Still stuck\n\n`GET /v1/health` for the service, `/v1/arc/status` · `/v1/rh/status` · `/v1/lp/status` for the lanes. Then the Chord developer page has the contact.","sections":[{"heading":"400 INVALID_PARAMS on /quote","anchor":"400-invalid-params-on-quote","text":"The message names the parameter. The usual ones: `amount` sent as a float or with decimals (it must be an integer string in the smallest unit); `inputMint` equal to `outputMint`; a chain id the API does not serve."},{"heading":"400 SLIPPAGE_MISMATCH on /swap","anchor":"400-slippage-mismatch-on-swap","text":"You sent a `slippageBps` that differs from the quote's. The signed minimum is the quote's `otherAmountThreshold`; the field on `/swap` is a consistency check. Omit it, or quote again at the slippage you want."},{"heading":"400 ROUTE_MISMATCH on /swap","anchor":"400-route-mismatch-on-swap","text":"The quote body was edited between `/quote` and `/swap` (re-serialised numbers, dropped fields). Pass the parsed object back untouched."},{"heading":"The transaction reverts with insufficient output","anchor":"the-transaction-reverts-with-insufficient-output","text":"The price moved past `otherAmountThreshold` between quote and execution. Quote again. Do not resubmit an old transaction — and if the route is a fresh launchpad curve, expect the number to move fast."},{"heading":"The transaction reverts before the wallet opens","anchor":"the-transaction-reverts-before-the-wallet-opens","text":"Run `POST /v1/swap/simulate`. `revert` names it: `Router is not approved…` means approve first (an approve that is not mined yet also triggers this — proceed); `ERC20InsufficientBalance` means the wallet does not hold `inputAmount`; a paused venue is muted within seconds, quote again."},{"heading":"Broadcast times out on Arc","anchor":"broadcast-times-out-on-arc","text":"The public gateway has been seen dropping one send in six. Broadcast through a dedicated RPC and, on a timeout, resend the same signed transaction (same nonce) rather than rebuilding."},{"heading":"404 UNKNOWN_TOKEN on charts, trades or stats","anchor":"404-unknown-token-on-charts-trades-or-stats","text":"The address is neither on a curated list nor a side of an indexed pool. For Arc, check `GET /v1/arc/tokens/search?q=0x…` — if it returns a row with `pools` counts, the token is indexed and the chart will fill as trades arrive; if not, the token has no pool yet."},{"heading":"503 HOLDERS_PENDING","anchor":"503-holders-pending","text":"The holder ledger just pinned the token. The backfill walks Transfer logs back to the creation block; retry in a few minutes and read `complete`."},{"heading":"503 CHAIN_NOT_ENABLED on /smart-money/top","anchor":"503-chain-not-enabled-on-smart-money-top","text":"The board is not published for that chain on this deployment, or `source=onchain` was omitted on 5042 / 4663."},{"heading":"429 on a page that \"only reads\"","anchor":"429-on-a-page-that-only-reads","text":"Logos, token reads and the default bucket are separate. A list page that paints hundreds of logos uses the logo bucket (3,000 a minute); table reads use the data bucket (300); `/arc/*` and `/lp/*` use the default (60). If you serve many users from one server IP, use a key so the limit is yours."},{"heading":"Numbers differ from another explorer","anchor":"numbers-differ-from-another-explorer","text":"Chord counts every swap with no dust floor, attributes wallets through routers and executors, flags wash volume instead of summing it, and prices a token on its dominant venue. Read [Data freshness and honesty](/docs/concepts/data-freshness/) before comparing."},{"heading":"WebSocket disconnects after ~100 s behind a proxy","anchor":"websocket-disconnects-after-100-s-behind-a-proxy","text":"The server pings every 25 s; make sure your proxy passes WebSocket frames and does not idle-close at a lower interval. Reconnect with jittered backoff and re-subscribe — the server keeps no state for a closed socket."},{"heading":"Still stuck","anchor":"still-stuck","text":"`GET /v1/health` for the service, `/v1/arc/status` · `/v1/rh/status` · `/v1/lp/status` for the lanes. Then the Chord developer page has the contact."}]},{"kind":"page","path":"/docs/resources/venue-ids/","url":"https://getchord.xyz/docs/resources/venue-ids/","title":"Venue ids","description":"The dex ids that appear in routePlan, byDex, pools and venue tables, with display names.","markdown":"Every `dex` field — in a quote's `routePlan`, a token's `byDex`, a pool row, a venue table — is a stable id string set by the engine and the indexer. Map it to a name for display.\n\n## Arc (5042)\n\n| id | Display name | Note |\n| --- | --- | --- |\n| `uniswap_v4` | Uniswap V4 | includes hooked launchpad pools |\n| `uniswap_v3` | Uniswap V3 | |\n| `uniswap_v2` | Uniswap V2 | |\n| `pools_trade` | Pools.trade | V4 pools created by the Pools.trade launcher |\n| `synthra_v3` | Synthra | |\n| `sushi_v3` | SushiSwap V3 | |\n| `sushi_v2` | SushiSwap V2 | |\n| `dyorswap` | DYORSwap | |\n| `slipstream_fork` | Aero | an Aerodrome Slipstream fork |\n| `v3fork_<8hex>` | V3 fork `<8hex>` | unnamed V3 factory, keyed by its first 8 hex |\n| `v2fork_<8hex>` | V2 fork `<8hex>` | unnamed V2 factory |\n\n## Robinhood Chain (4663)\n\n| id | Display name |\n| --- | --- |\n| `uniswap_v3` | Uniswap V3 |\n| `uniswap_v4` | Uniswap V4 |\n| `uniswap_v2` | Uniswap V2 |\n| `giga_v3` | GIGA V3 |\n| `swaphood_v3` | SwapHood V3 |\n| `pancake_v3` | PancakeSwap V3 |\n| `up_v3` | up v3 |\n| `metric` | Metric OMM |\n| `nadfun_dex` | nad.fun DEX |\n| `pons_v2_curve` | Pons bonding curve |\n\n## Monad (143)\n\n| id | Display name |\n| --- | --- |\n| `uniswap_v4` | Uniswap V4 |\n| `uniswap_v3` | Uniswap V3 |\n| `pancake_v3` | PancakeSwap V3 |\n| `capricorn` | Capricorn V3 |\n| `atlantis` | Atlantis |\n| `lfj` | LFJ (Trader Joe) |\n| `lfj_poe` | LFJ POE |\n| `kuru` | Kuru |\n| `hanji` | Hanji |\n| `metric` | Metric |\n| `woofi` | WOOFi |\n| `balancer_v3` | Balancer V3 |\n| `curve` | Curve |\n| `mento` | Mento |\n| `erc4626` | Vault deposit |\n| `nadfun_bc` · `nadfun_bc_v2` | Nad.fun |\n| `nadfun_dex` | Nad.fun DEX |\n\n## Avalanche (43114)\n\n| id | Display name |\n| --- | --- |\n| `pharaoh_v3` | Pharaoh V3 |\n| `pharaoh_dlmm` | Pharaoh DLMM |\n| `uniswap_v3` | Uniswap V3 |\n| `uniswap_v4` | Uniswap V4 |\n| `blackhole_v3` | Blackhole CL |\n| `blackhole_v2` | Blackhole |\n| `lfj_lb_v22` · `lfj_lb_v21` | LFJ Liquidity Book |\n| `lfj_v1` | LFJ V1 |\n| `pangolin_v3` | Pangolin V3 |\n| `pangolin_v2` | Pangolin V2 |\n\n## Base (8453)\n\n| id | Display name |\n| --- | --- |\n| `aerodrome_slipstream` · `aerodrome_slipstream_2` · `aerodrome_slipstream_3` | Aerodrome Slipstream (three deployments) |\n| `aerodrome_v2` | Aerodrome V2 |\n| `uniswap_v3` | Uniswap V3 |\n| `uniswap_v4` | Uniswap V4 |\n| `uniswap_v2` | Uniswap V2 |\n| `pancake_v3` | PancakeSwap V3 |\n| `hydrex_integral` | Hydrex |\n| `quickswap_v4` | QuickSwap V4 |\n| `sushi_v3` | SushiSwap V3 |\n\n## BNB Chain (56)\n\n| id | Display name |\n| --- | --- |\n| `pancake_v3` | PancakeSwap V3 |\n| `pancake_infinity_cl` | PancakeSwap Infinity |\n| `pancake_v2` | PancakeSwap V2 |\n| `uniswap_v4` | Uniswap V4 |\n| `uniswap_v3` | Uniswap V3 |\n| `topaz` | Topaz |\n| `thena_v3` | THENA V3 |\n| `flap` | Flap |\n| `fstswap` | FstSwap |\n\n## Arbitrum (42161)\n\n| id | Display name |\n| --- | --- |\n| `uniswap_v3` | Uniswap V3 |\n| `uniswap_v4` | Uniswap V4 |\n| `uniswap_v2` | Uniswap V2 |\n| `pancake_v3` | PancakeSwap V3 |\n| `pancake_v2` | PancakeSwap V2 |\n| `camelot_v3` | Camelot V3 |\n| `camelot_v2` | Camelot V2 |\n| `sushi_v3` | SushiSwap V3 |\n| `sushi_v2` | SushiSwap V2 |\n| `ramses_v2` | Ramses V2 |\n\n## Ethereum (1)\n\n| id | Display name |\n| --- | --- |\n| `uniswap_v3` | Uniswap V3 |\n| `uniswap_v4` | Uniswap V4 |\n| `uniswap_v2` | Uniswap V2 |\n| `pancake_v3` | PancakeSwap V3 |\n| `pancake_v2` | PancakeSwap V2 |\n| `sushi_v3` | SushiSwap V3 |\n| `sushi_v2` | SushiSwap V2 |\n| `ring_v2` | Ring |\n| `supernova_cl` | Supernova CL |\n| `supernova_amm` | Supernova AMM |\n| `shibaswap` | ShibaSwap |\n| `defi_swap` | DefiSwap |\n| `fraxswap` | Fraxswap |\n\n## Solana\n\n| id | Display name |\n| --- | --- |\n| `pumpswap` | PumpSwap |\n| `pumpfun` | pump.fun (bonding curve) |\n| `meteora_dbc` | Meteora DBC |\n| `meteora_damm_v2` | Meteora DAMM v2 |\n| `meteora_dlmm` | Meteora DLMM |\n| `meteora_pools` | Meteora pools (dynamic AMM v1) |\n| `raydium_clmm` | Raydium CLMM |\n| `raydium_cpmm` | Raydium CPMM |\n| `raydium_v4` | Raydium AMM v4 |\n| `raydium_launchlab` | Raydium LaunchLab |\n| `orca` | Orca Whirlpool |\n\nThe live lists with volume and share: `GET /v1/arc/venues`, `GET /v1/rh/venues`, `GET /v1/chains/{avalanche,base,bnb,arbitrum,ethereum}/venues` and `venues` on `GET /v1/chains/solana/overview`. Monad has no venue table; a quote's `routePlan` names its venues. An id you do not recognise is a fork the index labelled by factory; show the id.","sections":[{"heading":"","anchor":"","text":"Every `dex` field — in a quote's `routePlan`, a token's `byDex`, a pool row, a venue table — is a stable id string set by the engine and the indexer. Map it to a name for display."},{"heading":"Arc (5042)","anchor":"arc-5042","text":"| id | Display name | Note |\n| --- | --- | --- |\n| `uniswap_v4` | Uniswap V4 | includes hooked launchpad pools |\n| `uniswap_v3` | Uniswap V3 | |\n| `uniswap_v2` | Uniswap V2 | |\n| `pools_trade` | Pools.trade | V4 pools created by the Pools.trade launcher |\n| `synthra_v3` | Synthra | |\n| `sushi_v3` | SushiSwap V3 | |\n| `sushi_v2` | SushiSwap V2 | |\n| `dyorswap` | DYORSwap | |\n| `slipstream_fork` | Aero | an Aerodrome Slipstream fork |\n| `v3fork_<8hex>` | V3 fork `<8hex>` | unnamed V3 factory, keyed by its first 8 hex |\n| `v2fork_<8hex>` | V2 fork `<8hex>` | unnamed V2 factory |"},{"heading":"Robinhood Chain (4663)","anchor":"robinhood-chain-4663","text":"| id | Display name |\n| --- | --- |\n| `uniswap_v3` | Uniswap V3 |\n| `uniswap_v4` | Uniswap V4 |\n| `uniswap_v2` | Uniswap V2 |\n| `giga_v3` | GIGA V3 |\n| `swaphood_v3` | SwapHood V3 |\n| `pancake_v3` | PancakeSwap V3 |\n| `up_v3` | up v3 |\n| `metric` | Metric OMM |\n| `nadfun_dex` | nad.fun DEX |\n| `pons_v2_curve` | Pons bonding curve |"},{"heading":"Monad (143)","anchor":"monad-143","text":"| id | Display name |\n| --- | --- |\n| `uniswap_v4` | Uniswap V4 |\n| `uniswap_v3` | Uniswap V3 |\n| `pancake_v3` | PancakeSwap V3 |\n| `capricorn` | Capricorn V3 |\n| `atlantis` | Atlantis |\n| `lfj` | LFJ (Trader Joe) |\n| `lfj_poe` | LFJ POE |\n| `kuru` | Kuru |\n| `hanji` | Hanji |\n| `metric` | Metric |\n| `woofi` | WOOFi |\n| `balancer_v3` | Balancer V3 |\n| `curve` | Curve |\n| `mento` | Mento |\n| `erc4626` | Vault deposit |\n| `nadfun_bc` · `nadfun_bc_v2` | Nad.fun |\n| `nadfun_dex` | Nad.fun DEX |"},{"heading":"Avalanche (43114)","anchor":"avalanche-43114","text":"| id | Display name |\n| --- | --- |\n| `pharaoh_v3` | Pharaoh V3 |\n| `pharaoh_dlmm` | Pharaoh DLMM |\n| `uniswap_v3` | Uniswap V3 |\n| `uniswap_v4` | Uniswap V4 |\n| `blackhole_v3` | Blackhole CL |\n| `blackhole_v2` | Blackhole |\n| `lfj_lb_v22` · `lfj_lb_v21` | LFJ Liquidity Book |\n| `lfj_v1` | LFJ V1 |\n| `pangolin_v3` | Pangolin V3 |\n| `pangolin_v2` | Pangolin V2 |"},{"heading":"Base (8453)","anchor":"base-8453","text":"| id | Display name |\n| --- | --- |\n| `aerodrome_slipstream` · `aerodrome_slipstream_2` · `aerodrome_slipstream_3` | Aerodrome Slipstream (three deployments) |\n| `aerodrome_v2` | Aerodrome V2 |\n| `uniswap_v3` | Uniswap V3 |\n| `uniswap_v4` | Uniswap V4 |\n| `uniswap_v2` | Uniswap V2 |\n| `pancake_v3` | PancakeSwap V3 |\n| `hydrex_integral` | Hydrex |\n| `quickswap_v4` | QuickSwap V4 |\n| `sushi_v3` | SushiSwap V3 |"},{"heading":"BNB Chain (56)","anchor":"bnb-chain-56","text":"| id | Display name |\n| --- | --- |\n| `pancake_v3` | PancakeSwap V3 |\n| `pancake_infinity_cl` | PancakeSwap Infinity |\n| `pancake_v2` | PancakeSwap V2 |\n| `uniswap_v4` | Uniswap V4 |\n| `uniswap_v3` | Uniswap V3 |\n| `topaz` | Topaz |\n| `thena_v3` | THENA V3 |\n| `flap` | Flap |\n| `fstswap` | FstSwap |"},{"heading":"Arbitrum (42161)","anchor":"arbitrum-42161","text":"| id | Display name |\n| --- | --- |\n| `uniswap_v3` | Uniswap V3 |\n| `uniswap_v4` | Uniswap V4 |\n| `uniswap_v2` | Uniswap V2 |\n| `pancake_v3` | PancakeSwap V3 |\n| `pancake_v2` | PancakeSwap V2 |\n| `camelot_v3` | Camelot V3 |\n| `camelot_v2` | Camelot V2 |\n| `sushi_v3` | SushiSwap V3 |\n| `sushi_v2` | SushiSwap V2 |\n| `ramses_v2` | Ramses V2 |"},{"heading":"Ethereum (1)","anchor":"ethereum-1","text":"| id | Display name |\n| --- | --- |\n| `uniswap_v3` | Uniswap V3 |\n| `uniswap_v4` | Uniswap V4 |\n| `uniswap_v2` | Uniswap V2 |\n| `pancake_v3` | PancakeSwap V3 |\n| `pancake_v2` | PancakeSwap V2 |\n| `sushi_v3` | SushiSwap V3 |\n| `sushi_v2` | SushiSwap V2 |\n| `ring_v2` | Ring |\n| `supernova_cl` | Supernova CL |\n| `supernova_amm` | Supernova AMM |\n| `shibaswap` | ShibaSwap |\n| `defi_swap` | DefiSwap |\n| `fraxswap` | Fraxswap |"},{"heading":"Solana","anchor":"solana","text":"| id | Display name |\n| --- | --- |\n| `pumpswap` | PumpSwap |\n| `pumpfun` | pump.fun (bonding curve) |\n| `meteora_dbc` | Meteora DBC |\n| `meteora_damm_v2` | Meteora DAMM v2 |\n| `meteora_dlmm` | Meteora DLMM |\n| `meteora_pools` | Meteora pools (dynamic AMM v1) |\n| `raydium_clmm` | Raydium CLMM |\n| `raydium_cpmm` | Raydium CPMM |\n| `raydium_v4` | Raydium AMM v4 |\n| `raydium_launchlab` | Raydium LaunchLab |\n| `orca` | Orca Whirlpool |\n\nThe live lists with volume and share: `GET /v1/arc/venues`, `GET /v1/rh/venues`, `GET /v1/chains/{avalanche,base,bnb,arbitrum,ethereum}/venues` and `venues` on `GET /v1/chains/solana/overview`. Monad has no venue table; a quote's `routePlan` names its venues. An id you do not recognise is a fork the index labelled by factory; show the id."}]}],"operations":[{"kind":"operation","operationId":"getQuote","method":"GET","path":"/v1/quote","tag":"Quote and swap","summary":"Best route for a swap","description":"Quotes every venue on the chain in parallel, splits the order across venues when that improves the output, composes a two-hop route through the chain's anchors when no direct pool wins, and returns the best.\n\n**Use it for**: a price before a trade, a route card, an agent deciding whether to buy, a bot comparing venues.\n\n**Notes**\n- Amounts are strings in the token's smallest unit. On Arc the USDC predeploy has 6 decimals, native USDC 18 — send the predeploy address `0x3600…0000` (the zero address is an alias for it on 5042).\n- A quote is a live read of the venues and is good for about 30 seconds. Re-quote before you build if you waited longer.\n- `fast=1` returns a single-hop answer in about 400 ms marked `preliminary`; run the full quote alongside and replace it.\n- `only=` pins one venue and bypasses the routing safety gates — it needs an API key.\n- An empty `routePlan` is a real answer (no route at this size); read `noRouteReason`.","url":"https://getchord.xyz/docs/api-reference/operations/getquote/","parameters":[{"name":"chain","in":"query","required":false,"type":"integer","enum":[5042,4663,143,43114,8453,56,42161,1],"default":143,"description":"Chain id: `5042` Arc · `4663` Robinhood Chain · `143` Monad · `43114` Avalanche C-Chain · `8453` Base · `56` BNB Chain · `42161` Arbitrum One · `1` Ethereum. Omitted = 143. Always pass it."},{"name":"inputMint","in":"query","required":true,"type":"string","description":"Token you sell. The zero address means the native unit (an alias for the USDC predeploy on Arc; ETH on Robinhood Chain)."},{"name":"outputMint","in":"query","required":true,"type":"string","description":"Token you buy."},{"name":"amount","in":"query","required":true,"type":"string","description":"Input amount, smallest unit."},{"name":"slippageBps","in":"query","required":false,"type":"integer","default":50,"description":"Slippage tolerance in basis points; sets `otherAmountThreshold`."},{"name":"fast","in":"query","required":false,"type":"integer","enum":[0,1],"description":"1 = progressive first frame (single-hop, ~400 ms, `preliminary: true`)."},{"name":"only","in":"query","required":false,"type":"string","description":"Debug: restrict routing to one venue id. Requires `X-API-Key`."}],"requestBody":null,"responses":{"200":"The best route. `routePlan` empty + `outputAmount` \"0\" = no route.","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","502":"The routing engine or an upstream did not answer (`ENGINE_ERROR`, `ROUTE_ERROR`).","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"inputMint":"string — EVM address, hex, case-insensitive.","outputMint":"string — EVM address, hex, case-insensitive.","inputAmount":"string — Amount in the token's smallest unit, as a decimal string. Never a float.","outputAmount":"string — Amount in the token's smallest unit, as a decimal string. Never a float.","otherAmountThreshold":"string — Minimum output after fee and slippage — the number the transaction enforces.","slippageBps":"integer","priceImpactPct":"string — Percent, as a string, against the spot rate of the same route.","routePlan":[{"percent":"integer — Share of the input this leg carries.","swapInfo":"object"}],"noRouteReason":"string — Only when `routePlan` is empty: `INSUFFICIENT_LIQUIDITY` (try a smaller amount) or `NO_POOLS`.","gasEstimate":"string — Gas units, from the venue quoter or the RPC.","gasCostUSD":"string","blockNumber":"integer","timeTaken":"number — Engine seconds.","feeBps":"integer — Protocol fee on the output token, per token on-chain (`FeeCollector.feeBpsFor`): 5 bps by default on every chain, 0 on the stablecoins and majors a chain exempts (USDC / EURC on Arc, WETH / USDG and stocks on Robinhood Chain), capped at 100.","feeAmount":"string — Amount in the token's smallest unit, as a decimal string. Never a float.","feeMint":"string — EVM address, hex, case-insensitive.","feeTier":"string — `major` · `stable` · `standard` · `meme` · `new`.","preliminary":"boolean — Present only on `fast=1` answers: single-hop, ~400 ms, replace it with the full quote."},"example":{"inputMint":"0x3600000000000000000000000000000000000000","outputMint":"0x171a4217b86a807a64eb94757db6849fb4bdbaa0","inputAmount":"5000000","outputAmount":"465","otherAmountThreshold":"460","slippageBps":100,"priceImpactPct":"92.51","routePlan":[{"percent":100,"swapInfo":{"dex":"uniswap_v4","pool":"0xdd9da42901118c475e6efb78117100e611c675e2c53bc801c4d2bfdd504b2e8d","inputMint":"0x3600000000000000000000000000000000000000","outputMint":"0x171a4217b86a807a64eb94757db6849fb4bdbaa0","inputAmount":"5000000","outputAmount":"465","adapter":"0xd1d86d370f40471B79D9938B27F6ea040EbD6888","extraData":"0x000000000000000000000000171a4217b86a807a64eb94757db6849fb4bdbaa00000000000000000000000003600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017700000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000"}}],"gasEstimate":"318189","gasCostUSD":"0","blockNumber":21808240,"timeTaken":0.643,"feeBps":25,"feeAmount":"1","feeMint":"0x171a4217b86a807a64eb94757db6849fb4bdbaa0","feeTier":"meme"}},"security":null},{"kind":"operation","operationId":"buildSwap","method":"POST","path":"/v1/swap","tag":"Quote and swap","summary":"Build an unsigned swap transaction","description":"Turns a quote into a transaction against the Chord router. You sign it and broadcast it; Chord never sees a key and never holds funds.\n\n**Notes**\n- Send the `/quote` body back unmodified. `chain` must match the quote.\n- For an ERC-20 input, approve the router (`transaction.to`) for at least `inputAmount` first — or run `/swap/simulate` and let it tell you.\n- `slippageBps` is a consistency check only: the signed minimum output is the quote's `otherAmountThreshold`. A different value is refused with `SLIPPAGE_MISMATCH` — re-quote at the slippage you want.\n- On Arc the native sentinel aliases to the USDC predeploy: a \"native\" input is pulled by `transferFrom`, a \"native\" output is delivered as the predeploy, and `value` is always 0.\n- `batch: \"7702\"` is Monad-only (EIP-7702 one-signature approve+swap); it is ignored on every other chain.","url":"https://getchord.xyz/docs/api-reference/operations/buildswap/","parameters":[],"requestBody":{"schema":{"quoteResponse":{"inputMint":"string — EVM address, hex, case-insensitive.","outputMint":"string — EVM address, hex, case-insensitive.","inputAmount":"string — Amount in the token's smallest unit, as a decimal string. Never a float.","outputAmount":"string — Amount in the token's smallest unit, as a decimal string. Never a float.","otherAmountThreshold":"string — Minimum output after fee and slippage — the number the transaction enforces.","slippageBps":"integer","priceImpactPct":"string — Percent, as a string, against the spot rate of the same route.","routePlan":["object"],"noRouteReason":"string — Only when `routePlan` is empty: `INSUFFICIENT_LIQUIDITY` (try a smaller amount) or `NO_POOLS`.","gasEstimate":"string — Gas units, from the venue quoter or the RPC.","gasCostUSD":"string","blockNumber":"integer","timeTaken":"number — Engine seconds.","feeBps":"integer — Protocol fee on the output token, per token on-chain (`FeeCollector.feeBpsFor`): 5 bps by default on every chain, 0 on the stablecoins and majors a chain exempts (USDC / EURC on Arc, WETH / USDG and stocks on Robinhood Chain), capped at 100.","feeAmount":"string — Amount in the token's smallest unit, as a decimal string. Never a float.","feeMint":"string — EVM address, hex, case-insensitive.","feeTier":"string — `major` · `stable` · `standard` · `meme` · `new`.","preliminary":"boolean — Present only on `fast=1` answers: single-hop, ~400 ms, replace it with the full quote."},"userPublicKey":"string — Wallet that signs and receives the output.","chain":"integer (5042|4663|143|43114|8453|56|42161|1) — Must match the quote.","slippageBps":"integer — Optional consistency check — same value the quote was requested with.","feeAccount":"string — Referrer credited with the referral share of the protocol fee.","wrapUnwrapMON":"boolean — Wrap / unwrap the native unit around the swap where the chain has a wrapped native (not Arc).","usePermit2":"boolean","batch":"string (7702)"},"example":{"quoteResponse":{"…":"the /v1/quote body"},"userPublicKey":"0xb145400da27a2497d9fc2cd5621f2bfd37617af4","chain":5042}},"responses":{"200":"Sign `transaction` with any wallet library and submit it to the chain in `chainId`.","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","502":"The routing engine or an upstream did not answer (`ENGINE_ERROR`, `ROUTE_ERROR`)."},"response":{"schema":{"transaction":{"to":"string — EVM address, hex, case-insensitive.","data":"string — Calldata.","value":"string — Amount in the token's smallest unit, as a decimal string. Never a float.","gasLimit":"string","chainId":"integer"},"lastValidBlockHeight":"integer — Block after which the quote should be considered stale.","batch7702":"object — Monad only — the one-signature approve+swap plan."},"example":{"transaction":{"to":"0x1b1fee89a381e595fe6536b99ba91f3e16e9601a","data":"0xdc72a437…","value":"0","gasLimit":"1500000","chainId":5042},"lastValidBlockHeight":21808340}},"security":null},{"kind":"operation","operationId":"swapCalldata","method":"GET","path":"/v1/swap/calldata","tag":"Quote and swap","summary":"Quote and build in one call","description":"For contracts and bots that call the router directly: routes and encodes in a single request. The output goes to `msg.sender`; the caller approves the router for `tokenIn` and sends the calldata.","url":"https://getchord.xyz/docs/api-reference/operations/swapcalldata/","parameters":[{"name":"chain","in":"query","required":false,"type":"integer","enum":[5042,4663,143,43114,8453,56,42161,1],"default":143,"description":"Chain id: `5042` Arc · `4663` Robinhood Chain · `143` Monad · `43114` Avalanche C-Chain · `8453` Base · `56` BNB Chain · `42161` Arbitrum One · `1` Ethereum. Omitted = 143."},{"name":"tokenIn","in":"query","required":true,"type":"string","description":"Token the caller approves and sends."},{"name":"tokenOut","in":"query","required":true,"type":"string","description":"Token returned to msg.sender."},{"name":"amountIn","in":"query","required":true,"type":"string","description":""},{"name":"slippageBps","in":"query","required":false,"type":"integer","default":100,"description":"Sets `minOut` on the returned calldata."}],"requestBody":null,"responses":{"200":"Router call.","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","404":"Nothing at this identity (`NOT_FOUND`, `UNKNOWN_TOKEN`, `NO_ROUTE`).","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","502":"The routing engine or an upstream did not answer (`ENGINE_ERROR`, `ROUTE_ERROR`)."},"response":{"schema":{"to":"string — EVM address, hex, case-insensitive.","data":"string","value":"string — Amount in the token's smallest unit, as a decimal string. Never a float.","minOut":"string — Minimum output, human units.","expectedOut":"string — Quoted output, human units.","gasLimit":"string"},"example":{"to":"0x1b1fee89a381e595fe6536b99ba91f3e16e9601a","data":"0x…","value":"0","minOut":"0.0942","expectedOut":"0.0951","gasLimit":"1000000"}},"security":null},{"kind":"operation","operationId":"simulateSwap","method":"POST","path":"/v1/swap/simulate","tag":"Quote and swap","summary":"Simulate a built transaction before signing","description":"`eth_call`s the built calldata from the user's address and estimates gas, so a revert is caught before the wallet opens. Known selectors are decoded (`NotRouter`, a paused Kuru market, allowance and balance errors). An allowance revert is advisory: approve first, then swap.","url":"https://getchord.xyz/docs/api-reference/operations/simulateswap/","parameters":[],"requestBody":{"schema":{"chain":"integer (5042|4663|143|43114|8453|56|42161|1)","from":"string — EVM address, hex, case-insensitive.","to":"string — EVM address, hex, case-insensitive.","data":"string — Calldata from `/swap`.","value":"string — Amount in the token's smallest unit, as a decimal string. Never a float."},"example":{"chain":5042,"from":"0xb145400da27a2497d9fc2cd5621f2bfd37617af4","to":"0x1b1fee89a381e595fe6536b99ba91f3e16e9601a","data":"0xdc72a437…","value":"0"}},"responses":{"200":"`ok: true` with the simulated output and gas, or `ok: false` with the decoded revert.","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"ok":"boolean","amountOut":"string|null — Simulated output, smallest unit.","gas":"integer|null — Estimated gas units.","revert":"string — Decoded reason (when `ok` is false).","selector":"string|null — 4-byte error selector."},"example":{"ok":true,"amountOut":"465","gas":318189}},"security":null},{"kind":"operation","operationId":"metaQuote","method":"GET","path":"/v1/meta/quote","tag":"Meta aggregator","summary":"Quote on any chain: Chord first, a fallback only when it fails","description":"One call that ends in a route you can sign or an honest \"no route anywhere\". Without `taker` it is a price; with `taker` it also returns the unsigned transaction, the approval it needs and a simulation.\n\n**Policy**\n1. Chord's own router is always asked first, with its normal budget.\n2. A fallback is asked only when Chord fails: the engine timed out, errored or is down; there is no route; Chord refuses the route itself (value guard, taxed token, stale bonding-curve route); the chain's router is not live; or the built transaction fails simulation. A better price elsewhere is not a reason. A user error (unknown token, bad amount) never falls back.\n3. Fallbacks are tried in the chain's order (`GET /meta/providers`); the first answer that passes every check wins. Per provider 4 s, whole request 9 s, a circuit breaker per provider and chain.\n\n**Safety, on every fallback answer**\n- The transaction target and the approval spender must be on Chord's allowlist for that provider and chain, and deployed there.\n- `minAmountOut` comes from your slippage; a provider minimum below it is refused.\n- The value guard of `/quote` applies: an output worth 30 % less than the input at Chord's prices is refused. An unpriced token gets a security scan (`safety`); a honeypot is refused.\n- With `taker`, the transaction is simulated as that wallet and must deliver at least `minAmountOut`. A fallback transaction that cannot be simulated is never returned.\n- Without `taker`, a fallback price is shown only after the provider BUILT the route and it was simulated for a placeholder wallet (`PRICE_CHECKED`); a provider that prices a size but will not build it is skipped. The placeholder's transaction is never returned.\n- An input the simulation cannot supply (a balance that is not a plain storage mapping, e.g. rebasing shares) while the taker does not hold it: HTTP 422 `INPUT_NOT_SIMULATABLE` — hold the input and ask again.\n\n**Notes**\n- `provider: null` with HTTP 200 means every provider looked and none has a route. HTTP 503 `UNAVAILABLE` means nobody could answer right now: retry, do not conclude the pair is untradeable.\n- The answer is good until `expiresAt` (30 s). Quote again before signing if you waited.","url":"https://getchord.xyz/docs/api-reference/operations/metaquote/","parameters":[{"name":"chain","in":"query","required":true,"type":"string","description":"Chain id or key: `143` monad · `4663` robinhood · `5042` arc · `43114` avalanche · `8453` base · `56` bnb · `42161` arbitrum · `1` ethereum."},{"name":"tokenIn","in":"query","required":true,"type":"string","description":"Token you sell. The zero address = the chain's native asset (on Arc it aliases to the USDC predeploy). `inputMint` is accepted too."},{"name":"tokenOut","in":"query","required":true,"type":"string","description":"Token you buy. `outputMint` is accepted too."},{"name":"amount","in":"query","required":true,"type":"string","description":"Input amount, smallest unit."},{"name":"slippageBps","in":"query","required":false,"type":"integer","default":50,"description":"Sets `minAmountOut`."},{"name":"taker","in":"query","required":false,"type":"string","description":"The wallet that signs and receives. With it the answer carries `tx`, `approval` and `simulation`. `userPublicKey` is accepted too."}],"requestBody":null,"responses":{"200":"The quote. Read `provider` and `fallbackReason` before anything else.","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","422":"The request is valid but cannot be served as asked (`INPUT_NOT_SIMULATABLE` on `/meta/*`: a route exists, but the input token cannot be supplied in a simulation and the taker does not hold it — hold the input and ask again).","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"integer — Chain id.","tokenIn":"string — EVM address, hex, case-insensitive.","tokenOut":"string — EVM address, hex, case-insensitive.","amountIn":"string — Amount in the token's smallest unit, as a decimal string. Never a float.","taker":"string|null — The wallet the transaction was built and simulated for; null on a price-only quote.","slippageBps":"integer — The slippage `minAmountOut` reflects.","provider":"string|null — Who answered: `chord` (Chord's own router), `kyberswap`, `monorail`, `lifi`, `relay`. `null` = no provider has a route.","fallbackReason":"string|null — `null` when Chord answered. Otherwise why it did not: `no_route`, `insufficient_liquidity`, `engine_error`, `engine_timeout`, `engine_down`, `value_guard`, `taxed_token`, `route_stale`, `chain_not_live`, `build_failed`, `simulation_failed`.","attempts":[{"provider":"string — `chord`, `kyberswap`, `monorail`, `lifi` or `relay`.","status":"string — `ok`, or why this provider did not produce the answer: `no_route`, `timeout`, `http_error`, `rate_limited`, `invalid_response`, `not_allowlisted`, `calldata_mismatch`, `min_out_too_low`, `value_gap`, `unsafe_token`, `simulation_failed`, `unverified`, `breaker_open`, `skipped`; for Chord also `engine_error`, `engine_timeout`, `engine_down`, `route_refused`, `build_failed`, `chain_not_live`.","ms":"integer — Time spent on this provider.","error":"string|null — Short reason from a fixed vocabulary, never provider text."}],"amountOut":"string — What the taker receives after every fee, smallest unit of `tokenOut`. (`/quote`'s `outputAmount` is before Chord's fee; this is after.)","minAmountOut":"string — The minimum the transaction enforces, from the slippage you asked for.","priceImpactPct":"string|null — Percent, when the provider states one.","valueLossPct":"number|null — Output value against input value at Chord's own prices, percent (negative = worth more). `null` when Chord has no reliable price for a side: see `safety` and `warnings`.","feeBps":"integer — Chord path: Chord's protocol fee on the output. Fallback: the integrator fee Chord added (0 today); the provider's own fees are already inside `amountOut`.","feeRecipient":"string|null — EVM address, hex, case-insensitive.","route":{"venues":["string"]},"tx":{"to":"string — EVM address, hex, case-insensitive.","data":"string — Calldata.","value":"string — Amount in the token's smallest unit, as a decimal string. Never a float.","gas":"string|null — Gas limit to sign with.","chainId":"integer"},"approval":{"token":"string — EVM address, hex, case-insensitive.","spender":"string — EVM address, hex, case-insensitive.","amount":"string — Amount in the token's smallest unit, as a decimal string. Never a float.","resetFirst":"boolean — Present only for a token that reverts `approve(x > 0)` while its allowance is non-zero (USDT on Ethereum). `true` = the taker has a left-over allowance: send `approve(spender, 0)` first, then this approval."},"simulation":{"ok":"boolean|null — `true` = ran and delivered at least `minAmountOut`; `null` = no verdict (only ever returned on the Chord path).","amountOut":"string — Amount in the token's smallest unit, as a decimal string. Never a float.","gasUsed":"integer","revert":"string","reason":"string"},"safety":{"source":"string — `goplus`","token":"string — EVM address, hex, case-insensitive.","worstFlag":"string — `none`, `low`, `medium`, `high`.","honeypot":"boolean|null","buyTaxPct":"number|null","sellTaxPct":"number|null","risks":["string"]},"warnings":["string"],"quoteId":"string — Pass to `POST /meta/swap` within 2 minutes.","expiresAt":"integer — Unix time, seconds, UTC."},"example":{"chain":8453,"tokenIn":"0x833589fcd6edb6e08f4c7c32d4f71b54bda02913","tokenOut":"0x4200000000000000000000000000000000000006","amountIn":"10000000","taker":"0x00000000000000000000000000000000000c0ffe","slippageBps":50,"provider":"chord","fallbackReason":null,"attempts":[{"provider":"chord","status":"ok","ms":222,"error":null}],"amountOut":"3727897844407334","minAmountOut":"3709258355185298","priceImpactPct":"0.0000","valueLossPct":-0.02,"feeBps":0,"feeRecipient":"0x6c66229675fd9ceda9a9b2ea2bd983b3d8255834","route":{"venues":["aerodrome_slipstream_3"]},"tx":{"to":"0x1b1fee89a381e595fe6536b99ba91f3e16e9601a","data":"0xdc72a437…","value":"0","gas":"1000000","chainId":8453},"approval":{"token":"0x833589fcd6edb6e08f4c7c32d4f71b54bda02913","spender":"0x1b1fee89a381e595fe6536b99ba91f3e16e9601a","amount":"10000000"},"simulation":{"ok":true,"amountOut":"3727897844407334","gasUsed":456590},"safety":null,"warnings":["INSUFFICIENT_BALANCE: the taker holds less than the input amount; the transaction was simulated with the input supplied."],"quoteId":"8f722080-92a4-493d-aa16-a06f468a581e","expiresAt":1791055797}},"security":null},{"kind":"operation","operationId":"metaSwap","method":"POST","path":"/v1/meta/swap","tag":"Meta aggregator","summary":"Unsigned transaction on any chain: Chord first, a fallback only when it fails","description":"The same answer as `/meta/quote` with a `taker` required: an UNSIGNED transaction, simulated as the taker. Chord never signs and never holds funds.\n\nSend the pair and amount, or the `quoteId` of a `/meta/quote` answer from the last 2 minutes. The policy runs again at the current state, so `provider` can differ from the quote's: compare before you sign.\n\n**Before signing**\n- `approval` not null: send `token.approve(spender, amount)` first. `spender` is `tx.to`. With `approval.resetFirst: true` (USDT on Ethereum, a left-over allowance) send `approve(spender, 0)` before it.\n- When `provider` is not `chord`, `tx.to` is that aggregator's router. Show the user which provider it is.\n\n**Policy**\n1. Chord's own router is always asked first, with its normal budget.\n2. A fallback is asked only when Chord fails: the engine timed out, errored or is down; there is no route; Chord refuses the route itself (value guard, taxed token, stale bonding-curve route); the chain's router is not live; or the built transaction fails simulation. A better price elsewhere is not a reason. A user error (unknown token, bad amount) never falls back.\n3. Fallbacks are tried in the chain's order (`GET /meta/providers`); the first answer that passes every check wins. Per provider 4 s, whole request 9 s, a circuit breaker per provider and chain.\n\n**Safety, on every fallback answer**\n- The transaction target and the approval spender must be on Chord's allowlist for that provider and chain, and deployed there.\n- `minAmountOut` comes from your slippage; a provider minimum below it is refused.\n- The value guard of `/quote` applies: an output worth 30 % less than the input at Chord's prices is refused. An unpriced token gets a security scan (`safety`); a honeypot is refused.\n- With `taker`, the transaction is simulated as that wallet and must deliver at least `minAmountOut`. A fallback transaction that cannot be simulated is never returned.\n- Without `taker`, a fallback price is shown only after the provider BUILT the route and it was simulated for a placeholder wallet (`PRICE_CHECKED`); a provider that prices a size but will not build it is skipped. The placeholder's transaction is never returned.\n- An input the simulation cannot supply (a balance that is not a plain storage mapping, e.g. rebasing shares) while the taker does not hold it: HTTP 422 `INPUT_NOT_SIMULATABLE` — hold the input and ask again.","url":"https://getchord.xyz/docs/api-reference/operations/metaswap/","parameters":[],"requestBody":{"schema":{"chain":"string — Chain id or key.","tokenIn":"string — EVM address, hex, case-insensitive.","tokenOut":"string — EVM address, hex, case-insensitive.","amount":"string — Amount in the token's smallest unit, as a decimal string. Never a float.","slippageBps":"integer","taker":"string — The wallet that signs and receives.","quoteId":"string — Instead of chain / tokens / amount: the id of a `/meta/quote` answer (valid 2 minutes)."},"example":{"chain":8453,"tokenIn":"0x833589fcd6edb6e08f4c7c32d4f71b54bda02913","tokenOut":"0x4200000000000000000000000000000000000006","amount":"10000000","slippageBps":50,"taker":"0x00000000000000000000000000000000000c0ffe"}},"responses":{"200":"Sign `tx` with any wallet library and submit it to the chain in `tx.chainId`.","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","404":"No provider has a route for this pair and size (`NO_ROUTE`); the body carries `fallbackReason` and `attempts`.","410":"Unknown or expired `quoteId` (`QUOTE_EXPIRED`). Send the full params.","422":"The request is valid but cannot be served as asked (`INPUT_NOT_SIMULATABLE` on `/meta/*`: a route exists, but the input token cannot be supplied in a simulation and the taker does not hold it — hold the input and ask again).","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"integer — Chain id.","tokenIn":"string — EVM address, hex, case-insensitive.","tokenOut":"string — EVM address, hex, case-insensitive.","amountIn":"string — Amount in the token's smallest unit, as a decimal string. Never a float.","taker":"string|null — The wallet the transaction was built and simulated for; null on a price-only quote.","slippageBps":"integer — The slippage `minAmountOut` reflects.","provider":"string|null — Who answered: `chord` (Chord's own router), `kyberswap`, `monorail`, `lifi`, `relay`. `null` = no provider has a route.","fallbackReason":"string|null — `null` when Chord answered. Otherwise why it did not: `no_route`, `insufficient_liquidity`, `engine_error`, `engine_timeout`, `engine_down`, `value_guard`, `taxed_token`, `route_stale`, `chain_not_live`, `build_failed`, `simulation_failed`.","attempts":[{"provider":"string — `chord`, `kyberswap`, `monorail`, `lifi` or `relay`.","status":"string — `ok`, or why this provider did not produce the answer: `no_route`, `timeout`, `http_error`, `rate_limited`, `invalid_response`, `not_allowlisted`, `calldata_mismatch`, `min_out_too_low`, `value_gap`, `unsafe_token`, `simulation_failed`, `unverified`, `breaker_open`, `skipped`; for Chord also `engine_error`, `engine_timeout`, `engine_down`, `route_refused`, `build_failed`, `chain_not_live`.","ms":"integer — Time spent on this provider.","error":"string|null — Short reason from a fixed vocabulary, never provider text."}],"amountOut":"string — What the taker receives after every fee, smallest unit of `tokenOut`. (`/quote`'s `outputAmount` is before Chord's fee; this is after.)","minAmountOut":"string — The minimum the transaction enforces, from the slippage you asked for.","priceImpactPct":"string|null — Percent, when the provider states one.","valueLossPct":"number|null — Output value against input value at Chord's own prices, percent (negative = worth more). `null` when Chord has no reliable price for a side: see `safety` and `warnings`.","feeBps":"integer — Chord path: Chord's protocol fee on the output. Fallback: the integrator fee Chord added (0 today); the provider's own fees are already inside `amountOut`.","feeRecipient":"string|null — EVM address, hex, case-insensitive.","route":{"venues":["string"]},"tx":{"to":"string — EVM address, hex, case-insensitive.","data":"string — Calldata.","value":"string — Amount in the token's smallest unit, as a decimal string. Never a float.","gas":"string|null — Gas limit to sign with.","chainId":"integer"},"approval":{"token":"string — EVM address, hex, case-insensitive.","spender":"string — EVM address, hex, case-insensitive.","amount":"string — Amount in the token's smallest unit, as a decimal string. Never a float.","resetFirst":"boolean — Present only for a token that reverts `approve(x > 0)` while its allowance is non-zero (USDT on Ethereum). `true` = the taker has a left-over allowance: send `approve(spender, 0)` first, then this approval."},"simulation":{"ok":"boolean|null — `true` = ran and delivered at least `minAmountOut`; `null` = no verdict (only ever returned on the Chord path).","amountOut":"string — Amount in the token's smallest unit, as a decimal string. Never a float.","gasUsed":"integer","revert":"string","reason":"string"},"safety":{"source":"string — `goplus`","token":"string — EVM address, hex, case-insensitive.","worstFlag":"string — `none`, `low`, `medium`, `high`.","honeypot":"boolean|null","buyTaxPct":"number|null","sellTaxPct":"number|null","risks":["string"]},"warnings":["string"],"quoteId":"string — Pass to `POST /meta/swap` within 2 minutes.","expiresAt":"integer — Unix time, seconds, UTC."},"example":{"chain":8453,"tokenIn":"0x833589fcd6edb6e08f4c7c32d4f71b54bda02913","tokenOut":"0x4200000000000000000000000000000000000006","amountIn":"10000000","taker":"0x00000000000000000000000000000000000c0ffe","slippageBps":50,"provider":"chord","fallbackReason":null,"attempts":[{"provider":"chord","status":"ok","ms":222,"error":null}],"amountOut":"3727897844407334","minAmountOut":"3709258355185298","priceImpactPct":"0.0000","valueLossPct":-0.02,"feeBps":0,"feeRecipient":"0x6c66229675fd9ceda9a9b2ea2bd983b3d8255834","route":{"venues":["aerodrome_slipstream_3"]},"tx":{"to":"0x1b1fee89a381e595fe6536b99ba91f3e16e9601a","data":"0xdc72a437…","value":"0","gas":"1000000","chainId":8453},"approval":{"token":"0x833589fcd6edb6e08f4c7c32d4f71b54bda02913","spender":"0x1b1fee89a381e595fe6536b99ba91f3e16e9601a","amount":"10000000"},"simulation":{"ok":true,"amountOut":"3727897844407334","gasUsed":456590},"safety":null,"warnings":["INSUFFICIENT_BALANCE: the taker holds less than the input amount; the transaction was simulated with the input supplied."],"quoteId":"8f722080-92a4-493d-aa16-a06f468a581e","expiresAt":1791055797}},"security":null},{"kind":"operation","operationId":"metaProviders","method":"GET","path":"/v1/meta/providers","tag":"Meta aggregator","summary":"Fallback order and breaker state per chain","description":"Which aggregators stand behind Chord's router on each chain, in the order they are tried, and whether each one's circuit breaker is closed. `first` is always `chord`.","url":"https://getchord.xyz/docs/api-reference/operations/metaproviders/","parameters":[],"requestBody":null,"responses":{"200":"Per chain.","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"policy":"string","chains":[{"chain":"integer","key":"string","first":"string — Always `chord`.","fallbacks":"array"}]},"example":{"policy":"Chord's router answers first; a fallback is used only when Chord fails, never for a better price.","chains":[{"chain":143,"key":"monad","first":"chord","fallbacks":[{"provider":"kyberswap","breaker":"closed"},{"provider":"monorail","breaker":"closed"},{"provider":"relay","breaker":"closed"}]},{"chain":4663,"key":"robinhood","first":"chord","fallbacks":[{"provider":"kyberswap","breaker":"closed"},{"provider":"lifi","breaker":"closed"},{"provider":"relay","breaker":"closed"}]},{"chain":5042,"key":"arc","first":"chord","fallbacks":[{"provider":"kyberswap","breaker":"closed"},{"provider":"lifi","breaker":"closed"},{"provider":"relay","breaker":"closed"}]},{"chain":43114,"key":"avalanche","first":"chord","fallbacks":[{"provider":"kyberswap","breaker":"closed"},{"provider":"lifi","breaker":"closed"},{"provider":"relay","breaker":"closed"}]},{"chain":8453,"key":"base","first":"chord","fallbacks":[{"provider":"kyberswap","breaker":"closed"},{"provider":"lifi","breaker":"closed"},{"provider":"relay","breaker":"closed"}]},{"chain":56,"key":"bnb","first":"chord","fallbacks":[{"provider":"kyberswap","breaker":"closed"},{"provider":"lifi","breaker":"closed"},{"provider":"relay","breaker":"closed"}]}]}},"security":null},{"kind":"operation","operationId":"arcStatus","method":"GET","path":"/v1/arc/status","tag":"Arc data","summary":"Index freshness and depth","description":"Is the Arc rollup fresh, how far back it reaches, and the state of the pool index and the holder ledger. Check this before trusting a quiet number.\n\nServed from Chord's rollup and index tables (every swap on Arc summed by hour, token and venue), never from a raw scan — so calls are cheap and every answer carries its coverage. No key needed. `503 NOT_READY` until the rollup has run on the deployment.","url":"https://getchord.xyz/docs/api-reference/operations/arcstatus/","parameters":[],"requestBody":null,"responses":{"200":"","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"integer","enabled":"boolean","recentAt":"integer|null — Unix time, seconds, UTC.","staleSec":"integer|null","floorHour":"integer|null","genesisHour":"integer|null","backfillComplete":"boolean","index":{"pools":"integer — V2 + V3 pools indexed.","v4Pools":"integer","cursor":"integer — Last block the pool crawler processed.","genesis":"boolean — Pool discovery reached genesis."},"holders":"object|null — Holder-ledger lane state (tracked tokens, completed backfills, cursors).","updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":{"chain":5042,"enabled":true,"recentAt":1789891429,"staleSec":423,"floorHour":1780520400,"genesisHour":1780520400,"backfillComplete":true,"index":{"pools":30528,"v4Pools":190394,"cursor":21808222,"genesis":true},"holders":{"enabled":true,"tracked":1000,"complete":225,"forwardCursor":21808247,"from":21273472,"backfilling":"0x3600000000000000000000000000000000000000"},"updatedAt":1789891853280}},"security":null},{"kind":"operation","operationId":"arcOverview","method":"GET","path":"/v1/arc/overview","tag":"Arc data","summary":"Chain totals","description":"Last 24 hours (volume, swaps, tokens), venue share, 24 hourly buckets and up to 30 daily rows. The numbers on Chord's landing page come from this call.\n\nServed from Chord's rollup and index tables (every swap on Arc summed by hour, token and venue), never from a raw scan — so calls are cheap and every answer carries its coverage. No key needed. `503 NOT_READY` until the rollup has run on the deployment.","url":"https://getchord.xyz/docs/api-reference/operations/arcoverview/","parameters":[],"requestBody":null,"responses":{"200":"","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"integer","last24h":{"volUsd":"number","swaps":"integer","tokens":"integer","sinceHour":"integer"},"venues24h":[{"dex":"string","volUsd":"number","trades":"integer","tokens":"integer","sharePct":"number"}],"hourly24":[{"hour":"integer","volUsd":"number","swaps":"integer"}],"daily":[{"day":"integer","swaps":"integer","volUsd":"number","tokens":"integer","wallets":"integer — Attributed wallets only.","venues":"integer"}],"coverage":{"recentAt":"integer|null — Unix time, seconds, UTC.","stale":"boolean — True when the most recent rolled-up hour is older than the lane's freshness bar.","floorHour":"integer|null — Oldest hour the rollup has reached so far.","genesisHour":"integer|null — The chain's first indexed hour.","backfillComplete":"boolean — True once the rollup reaches genesis — before that, long windows undercount."},"updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":{"chain":5042,"last24h":{"volUsd":70377594.2336901,"swaps":788926,"tokens":6288,"sinceHour":1789808400},"venues24h":[{"dex":"uniswap_v4","volUsd":55014882.201828234,"trades":683313,"tokens":4059,"sharePct":78.17101849084284},{"dex":"uniswap_v3","volUsd":12910961.69548591,"trades":91957,"tokens":2163,"sharePct":18.345272861437724}],"hourly24":[{"hour":1789808400,"volUsd":3234644.52212066,"swaps":50225},{"hour":1789812000,"volUsd":2223745.3392903497,"swaps":36071}],"daily":[{"day":1787356800,"swaps":5712,"volUsd":609934.6437347728,"tokens":292,"wallets":768,"venues":4},{"day":1787443200,"swaps":3057,"volUsd":241890.2647458107,"tokens":274,"wallets":508,"venues":6}],"coverage":{"recentAt":1789891429,"stale":false,"floorHour":1780520400,"genesisHour":1780520400,"backfillComplete":true},"updatedAt":1789891764243}},"security":null},{"kind":"operation","operationId":"arcVenues","method":"GET","path":"/v1/arc/venues","tag":"Arc data","summary":"Venue share over a window","description":"Per-venue volume, trades and share for 1–180 days, with a daily series per venue. Venue ids are listed under Resources → Venue ids.\n\nServed from Chord's rollup and index tables (every swap on Arc summed by hour, token and venue), never from a raw scan — so calls are cheap and every answer carries its coverage. No key needed. `503 NOT_READY` until the rollup has run on the deployment.","url":"https://getchord.xyz/docs/api-reference/operations/arcvenues/","parameters":[{"name":"days","in":"query","required":false,"type":"integer","default":30,"description":"Window length."}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"integer","days":"integer","since":"integer — Unix time, seconds, UTC.","venues":[{"dex":"string","volUsd":"number","trades":"integer","sharePct":"number","series":"array"}],"totals":{"volUsd":"number","trades":"integer"},"updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":{"chain":5042,"days":2,"since":1789776000,"venues":[{"dex":"uniswap_v4","volUsd":68035852.94572023,"trades":984421,"sharePct":75.67924527197266,"series":[{"day":1789776000,"volUsd":58377642.50907503,"trades":798150,"tokens":4499},{"day":1789862400,"volUsd":9658210.4366452,"trades":186271,"tokens":1536}]},{"dex":"uniswap_v3","volUsd":18354272.62782195,"trades":133374,"sharePct":20.41625760314611,"series":[{"day":1789776000,"volUsd":14284128.68933594,"trades":103080,"tokens":2418},{"day":1789862400,"volUsd":4070143.9384860075,"trades":30294,"tokens":728}]}],"totals":{"volUsd":89900279.3978931,"trades":1135137},"updatedAt":1789891853672}},"security":null},{"kind":"operation","operationId":"arcTokens","method":"GET","path":"/v1/arc/tokens","tag":"Arc data","summary":"Every token traded in the last 24 hours","description":"The Markets board: price, change, volume split, trade counts, attributed traders, market cap, pool counts per venue and honesty flags for every token that traded on Arc in the last 24 hours — listed or not. Rows flagged `wash` or `impostor` sort below clean rows.\n\n**Use it for**: a markets table, a screener, \"what is moving on Arc\". For a single token use `/arc/token/{address}`; for search use `/arc/tokens/search`.\n\nServed from Chord's rollup and index tables (every swap on Arc summed by hour, token and venue), never from a raw scan — so calls are cheap and every answer carries its coverage. No key needed. `503 NOT_READY` until the rollup has run on the deployment.","url":"https://getchord.xyz/docs/api-reference/operations/arctokens/","parameters":[{"name":"limit","in":"query","required":false,"type":"integer","default":100,"description":""},{"name":"offset","in":"query","required":false,"type":"integer","default":0,"description":""},{"name":"sort","in":"query","required":false,"type":"string","enum":["volume","trades","traders","change","mcap"],"default":"volume","description":"Descending."},{"name":"includeUnlisted","in":"query","required":false,"type":"integer","enum":[0,1],"default":0,"description":"1 = include tokens without curated metadata or a logo."}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"integer","sinceHour":"integer","tradersSince":"integer — Start of the trader-count window.","sort":"string","offset":"integer","tokens":[{"address":"string — EVM address, hex, case-insensitive.","symbol":"string|null","name":"string|null","decimals":"integer|null","logoURI":"string|null — Logo through Chord's proxy (`/v1/logo/5042/{address}`, 128 px WebP).","logoUriRaw":"string|null — The upstream logo URL the proxy fetched, when there is one.","tags":"array","listed":"boolean — On the curated Arc token list (metadata and logo vetted).","priceUsd":"number|null — Last trade price on the token's dominant venue, USD.","change24hPct":"number|null","volume24h":"number — USD, every venue, no dust floor.","buyVolume24h":"number","sellVolume24h":"number","trades24h":"integer","buys24h":"integer","sells24h":"integer","traders":"integer — Distinct attributed wallets over the board's day window. Routers, executors and bots are not wallets.","lastTradeTs":"integer — Unix time, seconds, UTC.","totalSupply":"number|null — `totalSupply()` in whole tokens. Null when unreadable.","marketCapUsd":"number|null — totalSupply × price — fully diluted, since nothing on-chain says what is locked.","pools":"object","routable":"boolean — The engine can quote this token today (at least one pool against a routing anchor).","flags":"array"}],"total":"integer","updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":{"chain":5042,"sinceHour":1789808400,"tradersSince":1789776000,"sort":"volume","offset":0,"tokens":[{"address":"0x171a4217b86a807a64eb94757db6849fb4bdbaa0","symbol":"cirBTC","name":"cirBTC","decimals":8,"logoURI":"https://api.getchord.xyz/v1/logo/5042/0x171a4217b86a807a64eb94757db6849fb4bdbaa0","tags":[],"listed":true,"priceUsd":80423.22925858323,"change24hPct":-1.0826513878648192,"volume24h":5689551.810770997,"buyVolume24h":2765666.247710997,"sellVolume24h":2923885.56306,"trades24h":19472,"buys24h":10554,"sells24h":8918,"traders":3203,"lastTradeTs":1789891845,"totalSupply":336.81495614,"marketCapUsd":27087746.435366876,"pools":{"v3":21,"v2":5,"v4":483,"byDex":{"uniswap_v3":10,"v2fork_a2448256":1,"slipstream_fork":2,"v3fork_5bfbceb7":6,"v3fork_bb74f231":2,"v2fork_49aa1c63":2,"v3fork_711492df":1,"sushi_v2":2,"uniswap_v4":483}},"routable":true,"logoUriRaw":"https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/bitcoin/info/logo.png"},{"address":"0xece5ca8bf9220718e5727754026757512212cb3c","symbol":"ARGUS","name":"Argus","decimals":18,"logoURI":"https://api.getchord.xyz/v1/logo/5042/0xece5ca8bf9220718e5727754026757512212cb3c","tags":[],"listed":true,"priceUsd":0.01923385111168061,"change24hPct":12.687321807963436,"volume24h":4051551.451917998,"buyVolume24h":2089331.6579039998,"sellVolume24h":1962219.7940139996,"trades24h":25479,"buys24h":13716,"sells24h":11763,"traders":4549,"lastTradeTs":1789891399,"totalSupply":1000000000,"marketCapUsd":19233851.11168061,"pools":{"v3":15,"v2":5,"v4":1141,"byDex":{"uniswap_v3":12,"v2fork_e64d552a":1,"v2fork_a1a044ff":1,"v3fork_cae668d0":1,"uniswap_v2":1,"v3fork_aa5865dc":1,"synthra_v3":1,"sushi_v2":2,"uniswap_v4":1141}},"routable":true,"logoUriRaw":"https://coin-images.coingecko.com/coins/images/102178392/large/argus-token.png?1789463380"}],"total":1528,"updatedAt":1789891853851}},"security":null},{"kind":"operation","operationId":"arcSearch","method":"GET","path":"/v1/arc/tokens/search","tag":"Arc data","summary":"Search tokens","description":"Symbol, name or address over every token traded in the last 24 hours. Exact symbol first, then prefix, then name, then substring; listed tokens and volume break ties so the real ARGUS outranks a same-named copy. A pasted contract address always returns that token, even with no 24-hour row. `coverage` says how many tokens have a resolved name yet (about a minute after a boot).","url":"https://getchord.xyz/docs/api-reference/operations/arcsearch/","parameters":[{"name":"q","in":"query","required":true,"type":"string","description":"Symbol, name or address fragment."},{"name":"limit","in":"query","required":false,"type":"integer","default":20,"description":""}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"integer","q":"string","tokens":[{"address":"string — EVM address, hex, case-insensitive.","symbol":"string|null","name":"string|null","decimals":"integer|null","logoURI":"string|null — Logo through Chord's proxy (`/v1/logo/5042/{address}`, 128 px WebP).","logoUriRaw":"string|null — The upstream logo URL the proxy fetched, when there is one.","tags":"array","listed":"boolean — On the curated Arc token list (metadata and logo vetted).","priceUsd":"number|null — Last trade price on the token's dominant venue, USD.","change24hPct":"number|null","volume24h":"number — USD, every venue, no dust floor.","buyVolume24h":"number","sellVolume24h":"number","trades24h":"integer","buys24h":"integer","sells24h":"integer","traders":"integer — Distinct attributed wallets over the board's day window. Routers, executors and bots are not wallets.","lastTradeTs":"integer — Unix time, seconds, UTC.","totalSupply":"number|null — `totalSupply()` in whole tokens. Null when unreadable.","marketCapUsd":"number|null — totalSupply × price — fully diluted, since nothing on-chain says what is locked.","pools":"object","routable":"boolean — The engine can quote this token today (at least one pool against a routing anchor).","flags":"array"}],"total":"integer","coverage":{"resolved":"integer","total":"integer"},"updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":{"chain":5042,"q":"argus","tokens":[{"address":"0xece5ca8bf9220718e5727754026757512212cb3c","symbol":"ARGUS","name":"Argus","decimals":18,"logoURI":"https://api.getchord.xyz/v1/logo/5042/0xece5ca8bf9220718e5727754026757512212cb3c","tags":[],"listed":true,"priceUsd":0.018829227933149367,"change24hPct":10.31671479507974,"volume24h":4045502.7263479983,"buyVolume24h":2085285.1237909999,"sellVolume24h":1960217.6025569995,"trades24h":25431,"buys24h":13691,"sells24h":11740,"traders":4548,"lastTradeTs":1789890980,"totalSupply":null,"marketCapUsd":null,"pools":{"v3":15,"v2":5,"v4":1141,"byDex":{"uniswap_v3":12,"v2fork_e64d552a":1,"v2fork_a1a044ff":1,"v3fork_cae668d0":1,"uniswap_v2":1,"v3fork_aa5865dc":1,"synthra_v3":1,"sushi_v2":2,"uniswap_v4":1141}},"routable":true,"logoUriRaw":"https://coin-images.coingecko.com/coins/images/102178392/large/argus-token.png?1789463380"}],"total":1,"coverage":{"resolved":240,"total":6270},"updatedAt":1789891854005}},"security":null},{"kind":"operation","operationId":"arcTrending","method":"GET","path":"/v1/arc/trending","tag":"Arc data","summary":"Movers of the last two hours","description":"Tokens scored on volume and trade acceleration over the last two hours, from the hourly rollup. Each row is a full token row plus the score and its inputs.","url":"https://getchord.xyz/docs/api-reference/operations/arctrending/","parameters":[{"name":"limit","in":"query","required":false,"type":"integer","default":20,"description":""}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"integer","window":"string","tokens":[["object","object"]],"updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":{"chain":5042,"window":"2h","tokens":[{"address":"0xc1347b8f2b79af2f150d26f350eb974cd7dab6f3","symbol":"ARK","name":"Ark","decimals":18,"logoURI":"https://api.getchord.xyz/v1/logo/5042/0xc1347b8f2b79af2f150d26f350eb974cd7dab6f3","tags":[],"listed":true,"priceUsd":0.000040595162215532016,"change24hPct":293.1545690698809,"volume24h":22263.892306000005,"buyVolume24h":14913.083264000003,"sellVolume24h":7350.809042000001,"trades24h":443,"buys24h":305,"sells24h":138,"traders":186,"lastTradeTs":1789891841,"totalSupply":1000000000,"marketCapUsd":40595.162215532015,"pools":{"v3":1,"v2":0,"v4":4,"byDex":{"uniswap_v3":1,"uniswap_v4":4}},"routable":true,"score":14.783,"volNow":17096.819990000004,"tradesNow":328,"change1hPct":16.748692419251164,"momentum":33.1,"logoUriRaw":"https://ark-ai.xyz/api/uploads/578af1067cda7e6bd593deff82c2eb46.jpg"},{"address":"0x11435e6c80944f8d8a5f34c3fabd5dd06e7c7367","symbol":"MCAT","name":"Stealth Cat","decimals":18,"logoURI":"https://api.getchord.xyz/v1/logo/5042/0x11435e6c80944f8d8a5f34c3fabd5dd06e7c7367","tags":[],"listed":true,"priceUsd":0.0015085540687515264,"change24hPct":302.92128960120704,"volume24h":44245.77249448278,"buyVolume24h":26326.794866251035,"sellVolume24h":17918.97762823173,"trades24h":124,"buys24h":74,"sells24h":50,"traders":38,"lastTradeTs":1789887925,"totalSupply":1000000000,"marketCapUsd":1508554.0687515265,"pools":{"v3":0,"v2":0,"v4":1,"byDex":{"uniswap_v4":1}},"routable":false,"score":14.154,"volNow":43073.29349448278,"tradesNow":119,"change1hPct":302.92128960120704,"momentum":18.4,"logoUriRaw":"https://ipfs.filebase.io/ipfs/QmcQFUJagLR9nUss299zLcy5HM3AKyUuNuKf5uFieitRNm"}],"updatedAt":1789891854247}},"security":null},{"kind":"operation","operationId":"arcGraduated","method":"GET","path":"/v1/arc/graduated","tag":"Arc data","summary":"New launches","description":"Tokens whose first pool on Arc was created inside the window, routable by the engine today and screened: impostor symbols, launch farms (one creator, many pools), no-sell tokens and too few traders are removed and counted in `screened`. Newest first, with the launcher named where the registry knows it.\n\n**Use it for**: a \"new pairs\" feed, launch forensics, an agent watching launches.","url":"https://getchord.xyz/docs/api-reference/operations/arcgraduated/","parameters":[{"name":"hours","in":"query","required":false,"type":"integer","default":48,"description":""},{"name":"limit","in":"query","required":false,"type":"integer","default":100,"description":""}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"integer","hours":"integer","tokens":[["object","object"]],"total":"integer","screened":{"not_routable":"integer","impostor":"integer","no_sells":"integer","few_traders":"integer","serial_creator":"integer","no_trades":"integer","no_symbol":"integer"},"updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":{"chain":5042,"hours":48,"tokens":[{"address":"0xf31599ae7a1a2c7e3d99f2bf307c44a71196e987","symbol":"DePIN","name":"X DePIN","decimals":18,"logoURI":null,"tags":[],"listed":false,"priceUsd":0.000011092869541991106,"change24hPct":null,"volume24h":55.392897000000005,"buyVolume24h":55.392897000000005,"sellVolume24h":0,"trades24h":2,"buys24h":2,"sells24h":0,"traders":3,"lastTradeTs":1789891653,"totalSupply":1000000000,"marketCapUsd":11092.869541991106,"pools":{"v3":0,"v2":1,"v4":0,"byDex":{"uniswap_v2":1}},"routable":true,"launchedAt":1789891314,"launcher":"0x89e5db8b5aa49aa85ac63f691524311aeb649eba","creator":"0xd4bd5a99286f728f9529dc8a1fc8b1c702c04497","ageSec":540,"launcherName":null},{"address":"0xa210789b8b0666afa2d4ed00cf701083a2d72c52","symbol":"RWA","name":"X RWA","decimals":18,"logoURI":null,"tags":[],"listed":false,"priceUsd":0.000011336625606769674,"change24hPct":null,"volume24h":430.557449,"buyVolume24h":430.557449,"sellVolume24h":0,"trades24h":17,"buys24h":17,"sells24h":0,"traders":17,"lastTradeTs":1789891140,"totalSupply":1000000000,"marketCapUsd":11336.625606769674,"pools":{"v3":0,"v2":1,"v4":0,"byDex":{"uniswap_v2":1}},"routable":true,"launchedAt":1789890414,"launcher":"0x89e5db8b5aa49aa85ac63f691524311aeb649eba","creator":"0xd4bd5a99286f728f9529dc8a1fc8b1c702c04497","ageSec":1440,"launcherName":null}],"total":85,"screened":{"not_routable":2614,"impostor":4,"no_sells":13,"few_traders":68,"serial_creator":1615,"no_trades":23098,"no_symbol":0},"updatedAt":1789891854594}},"security":null},{"kind":"operation","operationId":"arcLaunchers","method":"GET","path":"/v1/arc/launchers","tag":"Arc data","summary":"Who is creating pools","description":"Launcher contracts on Arc (Uniswap V4 direct, Uniswap Liquidity Launcher, aka.fun, Argus, Minara.fun, Rapid Launch, …): the pool shapes each one creates, pools per hour and day, distinct creators, and 24-hour tape stats over the pools it created. The Launchpads section lists the named ones.","url":"https://getchord.xyz/docs/api-reference/operations/arclaunchers/","parameters":[{"name":"hours","in":"query","required":false,"type":"integer","default":24,"description":""}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"integer","hours":"integer","launchers":[{"launcher":"string — EVM address, hex, case-insensitive.","name":"string|null","site":"string|null","logo":"string|null","kinds":"array","shapes":"array","pools1h":"integer","pools24h":"integer","creators24h":"integer — Distinct creator wallets.","firstSeen":"integer — Unix time, seconds, UTC.","lastSeen":"integer — Unix time, seconds, UTC.","swaps24h":"integer|null","volume24h":"number|null","wallets24h":"integer|null","activePools24h":"integer|null"}],"updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":{"chain":5042,"hours":24,"launchers":[{"launcher":"0x8366a39cc670b4001a1121b8f6a443a643e40951","name":"Uniswap V4 PoolManager (direct)","site":"https://app.uniswap.org","logo":"/launchers/uniswap.png","kinds":["v4"],"shapes":[{"hooks":"0x4d850668513130fda0dd37b9a905b5e393ede844","fee":0,"tickSpacing":60,"pools":3},{"hooks":"0x0000000000000000000000000000000000000000","fee":3000,"tickSpacing":60,"pools":3}],"pools1h":4,"pools24h":66,"creators24h":56,"firstSeen":1789474488,"lastSeen":1789891301,"swaps24h":12880,"volume24h":24433932.86648278,"wallets24h":649,"activePools24h":96},{"launcher":"0x6049c9a0e26405c0985f9e3685c87d0ae917f82b","name":"Uniswap Liquidity Launcher","site":"https://github.com/Uniswap/sdks","logo":"/launchers/uniswap.png","kinds":["v4"],"shapes":[{"hooks":"0x0000000000000000000000000000000000000000","fee":10000,"tickSpacing":200,"pools":330},{"hooks":"0x0000000000000000000000000000000000000000","fee":2500,"tickSpacing":50,"pools":295}],"pools1h":35,"pools24h":2030,"creators24h":935,"firstSeen":1789481791,"lastSeen":1789891349,"swaps24h":431537,"volume24h":18499363.187061056,"wallets24h":5773,"activePools24h":2065}],"updatedAt":1789891854880}},"security":null},{"kind":"operation","operationId":"arcAttention","method":"GET","path":"/v1/arc/attention","tag":"Arc data","summary":"What people on Chord are looking at","description":"Tokens ranked by attention on Chord itself — searches, token-page views, Ask questions and watchlist adds — over 1–7 days. A demand signal, not a price signal.","url":"https://getchord.xyz/docs/api-reference/operations/arcattention/","parameters":[{"name":"days","in":"query","required":false,"type":"integer","default":1,"description":""},{"name":"limit","in":"query","required":false,"type":"integer","default":20,"description":""}],"requestBody":null,"responses":{"200":""},"response":{"schema":{"chain":"integer","days":"integer","rows":[{"token":"string — EVM address, hex, case-insensitive.","score":"number","ask":"integer","search":"integer","view":"integer","watch":"integer"}],"updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":{"chain":5042,"days":1,"rows":[{"token":"0xece5ca8bf9220718e5727754026757512212cb3c","score":8,"ask":1,"search":2,"view":3,"watch":0},{"token":"0x972b159ca91baec0ec88f2c114cf1d7aa5db240e","score":6,"ask":0,"search":0,"view":6,"watch":0}],"updatedAt":1789891855038}},"security":null},{"kind":"operation","operationId":"arcToken","method":"GET","path":"/v1/arc/token/{address}","tag":"Arc data","summary":"One token: hourly tape and venue split","description":"The token row plus an hourly series (1–720 hours) and the venue split for the window. Feeds Chord's token page header, volume bars and venue table. A token with no 24-hour row comes back as `{ address, listed: false }`.","url":"https://getchord.xyz/docs/api-reference/operations/arctoken/","parameters":[{"name":"address","in":"path","required":true,"type":"string","description":""},{"name":"hours","in":"query","required":false,"type":"integer","default":168,"description":"Hourly buckets to return."}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"integer","token":"…","hours":"integer","series":[{"hour":"integer","volUsd":"number","buyUsd":"number","sellUsd":"number","trades":"integer","buys":"integer","sells":"integer","priceLast":"number|null"}],"byDex":[{"dex":"string","volUsd":"number","trades":"integer","sharePct":"number"}],"updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":{"chain":5042,"token":{"address":"0x171a4217b86a807a64eb94757db6849fb4bdbaa0","symbol":"cirBTC","name":"cirBTC","decimals":8,"logoURI":"https://api.getchord.xyz/v1/logo/5042/0x171a4217b86a807a64eb94757db6849fb4bdbaa0","tags":[],"listed":true,"priceUsd":80423.22925858323,"change24hPct":-1.0826513878648192,"volume24h":5689551.810770997,"buyVolume24h":2765666.247710997,"sellVolume24h":2923885.56306,"trades24h":19472,"buys24h":10554,"sells24h":8918,"traders":3203,"lastTradeTs":1789891845,"totalSupply":336.81495614,"marketCapUsd":27087746.435366876,"pools":{"v3":21,"v2":5,"v4":483,"byDex":{"uniswap_v3":10,"v2fork_a2448256":1,"slipstream_fork":2,"v3fork_5bfbceb7":6,"v3fork_bb74f231":2,"v2fork_49aa1c63":2,"v3fork_711492df":1,"sushi_v2":2,"uniswap_v4":483}},"routable":true,"logoUriRaw":"https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/bitcoin/info/logo.png"},"hours":2,"series":[{"hour":1789887600,"volUsd":109750.71408699999,"buyUsd":59532.95500899996,"sellUsd":50217.759078,"trades":465,"buys":247,"sells":218,"priceLast":80315.09208021293},{"hour":1789891200,"volUsd":14523.166291000001,"buyUsd":13047.791779000001,"sellUsd":1475.374512,"trades":32,"buys":23,"sells":9,"priceLast":80404.02465976504}],"byDex":[{"dex":"uniswap_v3","volUsd":100905.00920399999,"trades":460,"sharePct":81.1956695140446},{"dex":"slipstream_fork","volUsd":23247.566194,"trades":28,"sharePct":18.706719483843752}],"updatedAt":1789891855212}},"security":null},{"kind":"operation","operationId":"arcTokenPools","method":"GET","path":"/v1/arc/token/{address}/pools","tag":"Arc data","summary":"Every indexed pool for a token","description":"V2 pairs, V3 pools and V4 pool ids (with hooks) that hold the token, with the creation block. For LP-oriented ranking use `/lp/token/{address}/pools`.","url":"https://getchord.xyz/docs/api-reference/operations/arctokenpools/","parameters":[{"name":"address","in":"path","required":true,"type":"string","description":""}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"integer","token":"string — EVM address, hex, case-insensitive.","pools":[{"pool":"string — A pool: a 20-byte contract address (V2 / V3) or a 32-byte Uniswap V4 pool id.","dex":"string","kind":"string (clmm|v2|v4)","token0":"string — EVM address, hex, case-insensitive.","token1":"string — EVM address, hex, case-insensitive.","fee":"integer|null — Fee in pips (100 = 0.01%).","hooks":"string — EVM address, hex, case-insensitive.","createdBlock":"integer"}],"updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":{"chain":5042,"token":"0x171a4217b86a807a64eb94757db6849fb4bdbaa0","pools":[{"pool":"0x82916bee18fcef517b26c72d7cb5f13694e1db41","dex":"uniswap_v3","kind":"clmm","token0":"0x171a4217b86a807a64eb94757db6849fb4bdbaa0","token1":"0x3600000000000000000000000000000000000000","fee":100,"createdBlock":21076890},{"pool":"0xecd988913031a292bcf0e4e07ccd5815c8969a48","dex":"uniswap_v3","kind":"clmm","token0":"0x171a4217b86a807a64eb94757db6849fb4bdbaa0","token1":"0x3600000000000000000000000000000000000000","fee":3000,"createdBlock":21081300}],"updatedAt":1789891855402}},"security":null},{"kind":"operation","operationId":"arcTokenHolders","method":"GET","path":"/v1/arc/token/{address}/holders","tag":"Arc data","summary":"Holder ledger","description":"Top balances from Chord's own Transfer-log ledger, each tagged wallet / pool / burn, with the holder count, the share of supply outside pools and burn sinks, and concentration (top 1 / 5 / 10 / 20 / 50 / 100). A token the ledger does not track yet is pinned for tracking and answers `503 HOLDERS_PENDING` — retry in a few minutes. A tracked token whose backfill has not reached its creation block answers 200 with `complete: false` (never a guess from the tape).","url":"https://getchord.xyz/docs/api-reference/operations/arctokenholders/","parameters":[{"name":"address","in":"path","required":true,"type":"string","description":""},{"name":"limit","in":"query","required":false,"type":"integer","default":50,"description":"Top rows."}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"integer","token":"string — EVM address, hex, case-insensitive.","tracked":"boolean","complete":"boolean — Backfill reached the creation block — balances are the full ledger.","coverage":{"addedBlock":"integer|null","floorBlock":"integer|null","backfillCursor":"integer|null","forwardCursor":"integer|null","logs":"integer"},"decimals":"integer|null","totalSupply":"string|null — Smallest unit.","holders":"integer","heldByWalletsPct":"number|null","concentration":{"top1":"number","top5":"number","top10":"number","top20":"number","top50":"number","top100":"number"},"top":[{"holder":"string — EVM address, hex, case-insensitive.","balance":"string — Smallest unit.","amount":"number|null — Whole tokens.","sharePct":"number|null","kind":"string (wallet|pool|burn)"}],"updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":{"chain":5042,"token":"0x171a4217b86a807a64eb94757db6849fb4bdbaa0","tracked":true,"complete":true,"coverage":{"addedBlock":21273471,"floorBlock":560194,"backfillCursor":560194,"forwardCursor":21808247,"logs":68037},"decimals":8,"totalSupply":"33681495614","holders":2599,"heldByWalletsPct":96.0477,"concentration":{"top1":63.64,"top5":90.91,"top10":90.91,"top20":90.91,"top50":90.91,"top100":90.91},"top":[{"holder":"0x34cd04070dd72b14e241112f6d83812df5af7fcd","balance":"21451899028","amount":214.51899,"sharePct":63.6904,"kind":"wallet"},{"holder":"0x82916bee18fcef517b26c72d7cb5f13694e1db41","balance":"6776124246","amount":67.761242,"sharePct":20.1182,"kind":"pool"}],"updatedAt":1789891855690}},"security":null},{"kind":"operation","operationId":"arcTokenTrades","method":"GET","path":"/v1/arc/token/{address}/trades","tag":"Arc data","summary":"Latest prints","description":"The last N swaps of one token straight from Chord's own Arc tape (newest first): venue, side, size, USD, price, wallet (`null` until resolved) and pool. Bounded and index-served — the mobile token page's Feed tab.","url":"https://getchord.xyz/docs/api-reference/operations/arctokentrades/","parameters":[{"name":"address","in":"path","required":true,"type":"string","description":""},{"name":"limit","in":"query","required":false,"type":"integer","default":50,"description":"Newest rows."}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"integer","token":"string — EVM address, hex, case-insensitive.","trades":[{"tx":"string","logIndex":"integer","dex":"string","side":"string (buy|sell)","tokenAmt":"number — Whole tokens.","usd":"number","priceUsd":"number","ts":"integer — Unix time, seconds, UTC.","wallet":"string|null — EVM address, hex, case-insensitive.","pool":"string — Pool address or V4 poolId."}],"updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":{"chain":5042,"token":"0x171a4217b86a807a64eb94757db6849fb4bdbaa0","trades":[{"tx":"0xbebd037b84ae0fba9229fb3e01f983833cbd637983ba254d4dba71ddad861764","logIndex":22,"dex":"uniswap_v3","side":"buy","tokenAmt":0.00000843,"usd":0.70542,"priceUsd":83679.71530249111,"ts":1790709599,"wallet":"0x7fe73969faf9d867ac49add1860bc121ff199272","pool":"0x82916bee18fcef517b26c72d7cb5f13694e1db41"},{"tx":"0xbdd5f399dd4ead2281042560db54dbfa13c6b44c4ed873baad4daea84dfed472","logIndex":3,"dex":"uniswap_v3","side":"buy","tokenAmt":0.003,"usd":250.846064,"priceUsd":83615.35466666667,"ts":1790709590,"wallet":"0xee93f91e457522d89ee19c2affba87352c365465","pool":"0x82916bee18fcef517b26c72d7cb5f13694e1db41"}],"updatedAt":1790709635583}},"security":null},{"kind":"operation","operationId":"listTokens","method":"GET","path":"/v1/tokens","tag":"Tokens and charts","summary":"Curated token list","description":"Metadata for the tokens Chord routes and labels: address, symbol, name, decimals, logo, tags. On Arc the list leads with the USDC predeploy (the gas token's ERC-20 face) and EURC; on Robinhood Chain with ETH, WETH, USDG and every tokenized stock. Read `decimals` here instead of assuming 18.","url":"https://getchord.xyz/docs/api-reference/operations/listtokens/","parameters":[{"name":"chain","in":"query","required":true,"type":"integer","enum":[5042,4663,143,43114,8453,56,42161,1],"default":143,"description":"Chain id: `5042` Arc · `4663` Robinhood Chain · `143` Monad · `43114` Avalanche C-Chain · `8453` Base · `56` BNB Chain · `42161` Arbitrum One · `1` Ethereum. Omitted = 143."}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …)."},"response":{"schema":{"tokens":[{"address":"string — EVM address, hex, case-insensitive.","symbol":"string","name":"string","decimals":"integer","logoURI":"string|null","logoUriRaw":"string|null","verified":"boolean","tags":"array","liquidityUsd":"number|null"}]},"example":{"tokens":[{"address":"0x3600000000000000000000000000000000000000","symbol":"USDC","name":"USD Coin","decimals":6,"logoURI":"https://api.nullterminal.xyz/v1/logo/5042/0x3600000000000000000000000000000000000000","verified":true,"tags":["stablecoin"],"logoUriRaw":"https://assets.coingecko.com/coins/images/6319/small/usdc.png"},{"address":"0xbef5f6d51cb62b58e6a8f77868681825c6fe21c1","symbol":"EURC","name":"Euro Coin","decimals":6,"logoURI":"https://api.nullterminal.xyz/v1/logo/5042/0xbef5f6d51cb62b58e6a8f77868681825c6fe21c1","verified":true,"tags":["stablecoin","fx"],"logoUriRaw":"https://assets.coingecko.com/coins/images/26045/small/euro.png"}]}},"security":null},{"kind":"operation","operationId":"marketMap","method":"GET","path":"/v1/tokens/market","tag":"Tokens and charts","summary":"Price map","description":"Price, 24-hour change, volume and trade count for every priced token in Chord's index of the chain (thousands of rows, not just the curated list), in one call, keyed by lower-cased address.\n\n- `4663` Robinhood Chain: every row also carries a 24-point hourly `spark` and `liquidityUsd` where known; the answer has `updatedAt`, the time the live overlay was applied.\n- `5042` Arc: from the Arc hourly rollup. `change24h` and `liquidityUsd` appear only when known; no `spark`, no `updatedAt`.\n\nFor names, logos and honesty flags use `/arc/tokens` or `/rh/tokens`. Always pass `chain`: omitted, it answers for Monad.","url":"https://getchord.xyz/docs/api-reference/operations/marketmap/","parameters":[{"name":"chain","in":"query","required":true,"type":"integer","enum":[4663,5042],"description":"Chain id: `4663` Robinhood Chain · `5042` Arc."}],"requestBody":null,"responses":{"200":""},"response":{"schema":{"market":{},"updatedAt":"integer — 4663 only. Server time (ms) the live overlay was applied; compare with a WebSocket `prices` frame's `at`."},"example":{"market":{"0xd0601ce157db5bdc3162bbac2a2c8af5320d9eec":{"priceUsd":220.97,"change24h":-0.71,"volume24h":34504046,"txns24h":103172,"spark":[221.4,221.1,220.9]}},"updatedAt":1790708400000}},"security":null},{"kind":"operation","operationId":"searchTokens","method":"GET","path":"/v1/tokens/search","tag":"Tokens and charts","summary":"Search tokens on a chain","description":"Symbol, name or address. What it searches depends on `chain`:\n\n- `4663` Robinhood Chain: the curated list (`verified: true`, stocks tagged `stock`) plus tokens that traded in the last 24 hours and are not on it (`verified: false`, no logo).\n- `5042` Arc: every token traded in the last 24 hours, the same index as `/arc/tokens/search`. `verified` is true for tokens on the curated Arc list.\n- `43114` / `8453` / `56` / `42161` / `1`: that chain's token list, all `verified: true`. A chain that is not public yet answers `404 CHAIN_NOT_PUBLIC` unless the request carries an `X-API-Key`.\n- no `chain`, or `143`: Monad off-list discovery. Tokens found through DexScreener that are **not** on the curated Monad list, with a logo and on-chain decimals, all `verified: false`. This mode answers `{ tokens }` only, returns up to 8 rows whatever `limit` says, and returns an empty list for a query under 2 characters.\n\nRanking: the exact address, then the exact symbol, a symbol prefix, a name prefix, then any substring; verified rows first within a rank, one row per address. A leading `$` is ignored. Treat `verified: false` as unvetted and check the address before trading it.\n\n**Arc**: `/arc/tokens/search` returns full board rows (price, volume, pools, flags) for the same query.","url":"https://getchord.xyz/docs/api-reference/operations/searchtokens/","parameters":[{"name":"q","in":"query","required":true,"type":"string","description":"Symbol, name or address fragment."},{"name":"chain","in":"query","required":false,"type":"integer","enum":[4663,5042,43114,8453,56,42161,1,143],"default":143,"description":"Chain id: `4663` Robinhood Chain · `5042` Arc · `43114` Avalanche C-Chain · `8453` Base · `56` BNB Chain · `42161` Arbitrum One · `1` Ethereum · `143` Monad. Omitted = 143. Pass the chain you want: the default is Monad off-list discovery."},{"name":"limit","in":"query","required":false,"type":"integer","default":8,"description":"Rows to return, clamped to 1–25. Ignored in Monad mode."}],"requestBody":null,"responses":{"200":"Matches, best first. An empty `tokens` is a real answer.","400":"`BAD_CHAIN` (a chain this route does not search) or `BAD_QUERY` (`q` empty or longer than 64 characters). Monad mode does not validate `q`.","404":"`CHAIN_NOT_PUBLIC`: the chain is not public yet and the request has no `X-API-Key`."},"response":{"schema":{"chain":"integer — The chain searched. Absent in Monad mode.","q":"string — The query as received. Absent in Monad mode.","tokens":[{"address":"string — EVM address, hex, case-insensitive.","symbol":"string","name":"string","decimals":"integer|null — ERC-20 decimals. Null for an off-list token whose decimals are not resolved yet.","logoURI":"string|null — Logo URL when known. Absent on off-list Robinhood Chain rows.","verified":"boolean — On the chain's curated list. False = found by the index or by discovery, not vetted.","tags":"array","liquidityUsd":"number|null — Monad mode only: liquidity of the deepest DexScreener pair."}]},"example":{"chain":4663,"q":"NVDA","tokens":[{"address":"0xd0601CE157Db5bdC3162BbaC2a2C8aF5320D9EEC","symbol":"NVDA","name":"NVIDIA • Robinhood Token","decimals":18,"logoURI":"https://cdn.robinhood.com/ncw_assets/logos/0xd0601ce157db5bdc3162bbac2a2c8af5320d9eec.png","verified":true,"tags":["stock"]}]}},"security":null},{"kind":"operation","operationId":"tokenChart","method":"GET","path":"/v1/tokens/chart/{address}","tag":"Tokens and charts","summary":"Candles","description":"OHLCV candles from Chord's own tape, address-keyed — one call serves Arc and Robinhood Chain tokens (addresses cannot collide). 200 candles per page; `before` pages backwards for unlimited history. A token that is not on a curated list and not a side of an indexed pool is `404 UNKNOWN_TOKEN`. For live candles subscribe on `/v1/ws/live` (see Streaming).","url":"https://getchord.xyz/docs/api-reference/operations/tokenchart/","parameters":[{"name":"address","in":"path","required":true,"type":"string","description":""},{"name":"tf","in":"query","required":false,"type":"string","enum":["1m","5m","15m","1h","4h","1d","1w"],"default":"1h","description":"Timeframe."},{"name":"before","in":"query","required":false,"type":"integer","description":"Return the 200 candles before this time (paging)."}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","404":"Nothing at this identity (`NOT_FOUND`, `UNKNOWN_TOKEN`, `NO_ROUTE`).","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"candles":[{"t":"integer — Unix time, seconds, UTC.","o":"number","h":"number","l":"number","c":"number","v":"number — USD volume in the bucket."}],"tf":"string","source":"string — `db` = Chord's tape."},"example":{"candles":[{"t":1789520400,"o":76161.46230007616,"h":93752.28222071448,"l":73286.91828508611,"c":73301.06410779823,"v":22676.53},{"t":1789524000,"o":73332.39663202444,"h":75694.61170208515,"l":73332.39663202444,"c":75694.61170208515,"v":173955.23}],"tf":"1h","source":"db"}},"security":null},{"kind":"operation","operationId":"candles","method":"GET","path":"/v1/candles","tag":"Tokens and charts","summary":"Candles (data API)","description":"OHLCV for any token Chord indexes on Arc, Robinhood Chain, Avalanche, Base, BNB Chain, Arbitrum, Ethereum or Monad, built only from Chord's own index — never a third-party feed, so `source` is always `index`. 1m / 5m / 15m come from a 1-minute rollup that keeps history after raw trades are retired; 1h and above from the hourly rollup; the newest minutes straight from the tape. Each candle carries `n`, the trades in the bucket. Buckets without a trade are absent unless `fill=1`, which carries the previous close through them.\n\nPaging: the default window ends with the still-open bucket (`forming: true`) and holds `limit` buckets. A `from`–`to` range wider than `limit` keeps the newest buckets; ask for the previous page with `to` = this page's `from`. The token must trade on the chain you name — `404 UNKNOWN_TOKEN` says which chain it trades on when it is another one. The zero address stands for the chain's native asset (its wrapped twin, or the USDC predeploy on Arc). For live candles subscribe on `/v1/ws/live` (see Streaming).\n\n**Avalanche, Base, BNB Chain** (`43114`, `8453`, `56`): candles come from chain-keyed tables, so one address on two chains is two tokens, and `404 UNKNOWN_TOKEN` means no indexed trades on the chain you named. These chains answer once their tape runs and, until the chain is public, only to requests with an `X-API-Key` (`400 UNSUPPORTED_CHAIN` otherwise; all three are public today). Where the tape runs with an ingest floor (BNB Chain, $100 today) the response carries `ingestFloor`, and `v` and `n` count only trades at or above it.","url":"https://getchord.xyz/docs/api-reference/operations/candles/","parameters":[{"name":"chain","in":"query","required":false,"type":"integer","enum":[5042,4663,43114,8453,56,42161,1,143],"default":143,"description":"Chain id: `5042` Arc · `4663` Robinhood Chain · `43114` Avalanche C-Chain · `8453` Base · `56` BNB Chain · `42161` Arbitrum One · `1` Ethereum · `143` Monad. Omitted = 143."},{"name":"token","in":"query","required":true,"type":"string","description":"Token address."},{"name":"tf","in":"query","required":false,"type":"string","enum":["1m","5m","15m","1h","4h","1d","1w"],"default":"1h","description":"Timeframe."},{"name":"from","in":"query","required":false,"type":"integer","description":"Start, inclusive. Default: `to` minus `limit` buckets."},{"name":"to","in":"query","required":false,"type":"integer","description":"End, exclusive, snapped up to a bucket edge. Default: the end of the open bucket."},{"name":"limit","in":"query","required":false,"type":"integer","default":300,"description":"Buckets per page."},{"name":"fill","in":"query","required":false,"type":"string","enum":["1"],"description":"Carry the previous close through empty buckets (v = 0, n = 0)."}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","404":"Nothing at this identity (`NOT_FOUND`, `UNKNOWN_TOKEN`, `NO_ROUTE`).","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"integer","token":"string — EVM address, hex, case-insensitive.","tf":"string","source":"string — Always `index`.","from":"integer — Unix time, seconds, UTC.","to":"integer — Unix time, seconds, UTC.","forming":"boolean — The last candle is the still-open bucket.","ingestFloor":{"minTradeUsd":"number — Trades under this USD value (at index time) are not in the index, so every count, volume and candle covers trades at or above it. 0 = every priced trade.","history":["object"]},"candles":[{"t":"integer — Unix time, seconds, UTC.","o":"number","h":"number","l":"number","c":"number","v":"number — USD volume in the bucket.","n":"integer|null — Trades in the bucket."}]},"example":{"chain":5042,"token":"0x171a4217b86a807a64eb94757db6849fb4bdbaa0","tf":"1h","source":"index","from":1790704800,"to":1790712000,"forming":true,"candles":[{"t":1790704800,"o":83084.16874661468,"h":83761.32352941176,"l":82504.09836065574,"c":83716.00512163893,"v":236698.5,"n":976},{"t":1790708400,"o":83676.16747181964,"h":83758.25396825396,"l":82970.76923076923,"c":83590.35733333333,"v":28901.4,"n":212}]}},"security":null},{"kind":"operation","operationId":"tokenTrades","method":"GET","path":"/v1/tokens/trades/{address}","tag":"Tokens and charts","summary":"Trade tape","description":"Recent swaps of a token, newest first, with the venue, side, size, price and the attributed wallet. Filter by side, venue, minimum size or wallet; page with `page`. `stats24h` sums the day.","url":"https://getchord.xyz/docs/api-reference/operations/tokentrades/","parameters":[{"name":"address","in":"path","required":true,"type":"string","description":""},{"name":"side","in":"query","required":false,"type":"string","enum":["buy","sell"],"description":""},{"name":"dex","in":"query","required":false,"type":"string","description":"Venue id."},{"name":"min","in":"query","required":false,"type":"number","description":"Minimum USD."},{"name":"wallet","in":"query","required":false,"type":"string","description":""},{"name":"limit","in":"query","required":false,"type":"integer","default":25,"description":""},{"name":"page","in":"query","required":false,"type":"integer","default":1,"description":""}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","404":"Nothing at this identity (`NOT_FOUND`, `UNKNOWN_TOKEN`, `NO_ROUTE`)."},"response":{"schema":{"trades":[{"tx":"string — Transaction hash.","logIndex":"integer","dex":"string","side":"string (buy|sell)","tokenAmt":"number","usd":"number","priceUsd":"number","ts":"integer — Unix time, seconds, UTC.","wallet":"string|null — EVM address, hex, case-insensitive."}],"total":"integer","page":"integer","pageSize":"integer","dexes":["string"],"stats24h":{"buys":"integer","sells":"integer","buyUsd":"number","sellUsd":"number"}},"example":{"trades":[{"tx":"0x4e0bda6af0d4e75c98049cc7c64c5fb9112dcb7e397d68f851cfc01406df33db","logIndex":41,"dex":"uniswap_v3","side":"buy","tokenAmt":0.00587394,"usd":472.372001,"priceUsd":80418.25435738193,"ts":1789891817,"wallet":"0x0e177f6758872e474c8adb191fbd33352495911d"},{"tx":"0xac5d6408c433ced6e93e0b5d4118f5f726511c0e0514f4ea6a9a7cb98552cde4","logIndex":3,"dex":"uniswap_v3","side":"buy","tokenAmt":0.01154339,"usd":928.183258,"priceUsd":80408.20400246374,"ts":1789891817,"wallet":"0x870c73c98a14b6956b79247e1a1cdc68ba0060ee"}],"total":2001,"page":1,"pageSize":2,"dexes":["slipstream_fork","uniswap_v3"],"stats24h":{"buys":11127,"sells":9332,"buyUsd":2902488.248025012,"sellUsd":3019938.981532}}},"security":null},{"kind":"operation","operationId":"tokenStats","method":"GET","path":"/v1/tokens/stats/{address}","tag":"Tokens and charts","summary":"Windowed stats","description":"DexScreener-style windows (5 m, 1 h, 6 h, 24 h): change, transactions, buys/sells, buy/sell volume, makers, buyers, sellers — plus all-time high, 24-hour range, first trade, total transactions and the markets (pools) the token trades on. Cached with stale-while-revalidate, so it answers fast and refreshes in the background.","url":"https://getchord.xyz/docs/api-reference/operations/tokenstats/","parameters":[{"name":"address","in":"path","required":true,"type":"string","description":""}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","404":"Nothing at this identity (`NOT_FOUND`, `UNKNOWN_TOKEN`, `NO_ROUTE`)."},"response":{"schema":{"priceUsd":"number|null","windows":{"m5":{"change":"number — Percent.","txns":"integer","buys":"integer","sells":"integer","buyVol":"number","sellVol":"number","makers":"integer","buyers":"integer","sellers":"integer"},"h1":{"change":"number — Percent.","txns":"integer","buys":"integer","sells":"integer","buyVol":"number","sellVol":"number","makers":"integer","buyers":"integer","sellers":"integer"},"h6":{"change":"number — Percent.","txns":"integer","buys":"integer","sells":"integer","buyVol":"number","sellVol":"number","makers":"integer","buyers":"integer","sellers":"integer"},"h24":{"change":"number — Percent.","txns":"integer","buys":"integer","sells":"integer","buyVol":"number","sellVol":"number","makers":"integer","buyers":"integer","sellers":"integer"}},"liquidityUsd":"number|null","ath":{"priceUsd":"number","ts":"integer — Unix time, seconds, UTC."},"range24h":{"high":"number","low":"number"},"firstTradeTs":"integer|null — Unix time, seconds, UTC.","totalTxns":"integer","markets":[{"dex":"string","pool":"string — A pool: a 20-byte contract address (V2 / V3) or a 32-byte Uniswap V4 pool id.","txns24h":"integer","vol24h":"number","makers24h":"integer"}]},"example":{"priceUsd":80418.25435738193,"windows":{"m5":{"change":0,"txns":26,"buys":12,"sells":14,"buyVol":3176.8774229999995,"sellVol":3214.276456,"makers":16,"buyers":10,"sellers":8},"h1":{"change":0.12,"txns":405,"buys":217,"sells":188,"buyVol":64728.724117999926,"sellVol":46488.608315000005,"makers":149,"buyers":95,"sellers":79},"h6":{"change":-0.81,"txns":5797,"buys":2956,"sells":2841,"buyVol":877524.8736700043,"sellVol":985143.4303749993,"makers":850,"buyers":530,"sellers":535},"h24":{"change":-0.87,"txns":20459,"buys":11127,"sells":9332,"buyVol":2902488.2480250364,"sellVol":3019938.9815319907,"makers":2942,"buyers":2228,"sellers":1933}},"liquidityUsd":null,"ath":{"priceUsd":93752.28222071448,"ts":1789520400},"range24h":{"high":81967.21311475411,"low":79796.7741935484},"firstTradeTs":1789520400,"totalTxns":78768,"markets":[{"dex":"uniswap_v3","pool":"0x82916bee18fcef517b26c72d7cb5f13694e1db41","txns24h":17884,"vol24h":5118587.965404977,"makers24h":2673},{"dex":"slipstream_fork","pool":"0xd945caee4635bcd7fb8a9fa74dc1d0c4c1472782","txns24h":1744,"vol24h":787999.6481669984,"makers24h":347}]}},"security":null},{"kind":"operation","operationId":"tokenLogo","method":"GET","path":"/v1/logo/{chain}/{address}","tag":"Tokens and charts","summary":"Token logo","description":"A 128 px WebP of the token's logo, fetched once from the upstream source and cached on disk. A placeholder image (200) when there is none — never a 404, so an `<img>` never breaks. Every `logoURI` in Arc rows points here.","url":"https://getchord.xyz/docs/api-reference/operations/tokenlogo/","parameters":[{"name":"chain","in":"path","required":true,"type":"integer","enum":[5042,4663,143,43114,8453,56,42161,1],"description":""},{"name":"address","in":"path","required":true,"type":"string","description":""}],"requestBody":null,"responses":{"200":"`image/webp` (or the SVG placeholder)."},"response":null,"security":null},{"kind":"operation","operationId":"smartMoneyTop","method":"GET","path":"/v1/smart-money/top","tag":"Top wallets","summary":"Wallets ranked by Smart Score","description":"Which wallets make money on the chain, from the tape, ranked by a skill-adjusted score rather than raw profit (realized-weighted, luck-corrected, recency-decayed). Routers, executors and bots are removed before ranking (`botsRemoved` counts them). On Arc the board moves between rebuilds: a live delta of the last minutes' trades sits on top of the last roll (`live`).\n\n**Notes**: `source=onchain` is required on 5042 / 4663. The board is rebuilt on a schedule per window (15 min for 24h, hourly for 7d / 30d, 3 h for all) and served from cache in between. `503 CHAIN_NOT_ENABLED` until the board is published for the chain.","url":"https://getchord.xyz/docs/api-reference/operations/smartmoneytop/","parameters":[{"name":"chain","in":"query","required":true,"type":"integer","enum":[5042,4663,143],"default":143,"description":"Chain id: `5042` Arc · `4663` Robinhood Chain · `143` Monad. Omitted = 143."},{"name":"source","in":"query","required":true,"type":"string","enum":["onchain","nullterminal"],"description":"`onchain` = every venue, from the tape. Required on 5042 and 4663."},{"name":"window","in":"query","required":false,"type":"string","enum":["24h","7d","30d","all"],"default":"all","description":""},{"name":"category","in":"query","required":false,"type":"string","enum":["all","memes","majors"],"default":"all","description":""},{"name":"limit","in":"query","required":false,"type":"integer","default":50,"description":""}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"wallets":[{"wallet":"string — EVM address, hex, case-insensitive.","pnlUsd":"number — Realized plus open PnL at current prices.","realizedUsd":"number","unrealizedUsd":"number","volumeUsd":"number","trades":"integer","tokensTraded":"integer","winningTokens":"integer","winRate":"number — 0–1.","topToken":"object","lastActiveTs":"integer — Unix time, seconds, UTC.","pnlMeme":"number","pnlMajor":"number","memeVol":"number","archetype":"string — `degen` · `allrounder` · `majors` …","memeShare":"number","winRateAdj":"number — Luck-corrected win rate.","smartScore":"number — The ranking key: realized-weighted, luck-corrected, recency-decayed profit."}],"totalWallets":"integer — Wallets that qualified after the bot passes.","window":"string","category":"string","chain":"integer","source":"string","indexedToBlock":"integer — The chain block the tape had reached when this board was built.","updatedAt":"integer — Unix time, milliseconds — when the server built this answer.","live":"object — Arc only — the in-memory delta on top of the last roll.","botsRemoved":{"cadence":"integer","nonceOrDenylist":"integer","behavior":"integer"},"note":"string"},"example":{"wallets":[{"wallet":"0xb145400da27a2497d9fc2cd5621f2bfd37617af4","pnlUsd":85260.25886163529,"realizedUsd":28166.924288181075,"unrealizedUsd":57093.33457345421,"volumeUsd":68986.38694614707,"trades":49,"tokensTraded":5,"winningTokens":3,"winRate":0.6,"topToken":{"symbol":"ARGUS","pnlUsd":85345.61369765387},"lastActiveTs":1789890946,"pnlMeme":85260.25886163529,"pnlMajor":0,"memeVol":68986.38694614707,"archetype":"degen","memeShare":1,"winRateAdj":0.5294117647058824,"smartScore":43067.763434718785},{"wallet":"0xf8218b98f49b86c7e491079591acc08ee4fd6e7e","pnlUsd":53891.271617383565,"realizedUsd":26940.46261686956,"unrealizedUsd":26950.809000514004,"volumeUsd":150140.03604099998,"trades":70,"tokensTraded":11,"winningTokens":9,"winRate":0.8181818181818182,"topToken":{"symbol":"ARGUS","pnlUsd":22862.25828632662},"lastActiveTs":1789890046,"pnlMeme":53891.271617383565,"pnlMajor":0,"memeVol":150140.03604099998,"archetype":"degen","memeShare":1,"winRateAdj":0.6521739130434783,"smartScore":32966.26695083121}],"totalWallets":92826,"window":"7d","category":"all","chain":5042,"source":"onchain","indexedToBlock":21808217,"updatedAt":1789891859855,"live":{"rollStamp":1789891728,"buckets":21,"rows":253,"seen":1261,"ingested":1261,"skippedDup":0,"computedAt":0},"botsRemoved":{"cadence":325,"nonceOrDenylist":5,"behavior":37},"note":"ranked by Smart Score — skill-adjusted, realized-weighted profit (est. at current prices)"}},"security":null},{"kind":"operation","operationId":"portfolio","method":"GET","path":"/v1/portfolio/{wallet}","tag":"Portfolio","summary":"Holdings and PnL on every chain","description":"What one wallet holds on Chord's eight EVM chains, and on Solana when you pass its Solana address, with its PnL over the last 24 hours, 7 days and 30 days. One rule for every chain, per token and window: the USD from its sales minus the USD of its buys inside the window, plus what is held now at today's price, minus what was held at the window's start at that hour's close. No cost basis is involved, and transfers are neutral: a token that arrived by transfer only adds its price move, and a quantity bought in the window that left with no sale on the tape (sent, bridged out) counts as sold at the window's average buy price, neither a gain nor a loss. Stablecoins are left out of PnL and counted in `cashUsd`.\n\n**Use it for**: a wallet or portfolio page, \"how did this wallet do this week\", an agent sizing a trade against what the wallet already holds.\n\n**Notes**\n- **Coverage first.** A window is `complete` only when the chain's swap tape covers all of it. When it does not (the tape starts later, a hole in the history), `usd`, `pct` and `fromTs` are null: show a dash, never a partial number as a whole one. A total window is complete only when every chain in the answer is, chains that could not be read included. BNB Chain does not record swaps under $100: its windows still count as complete, and `coverage.ingestFloorUsd` says so.\n- **Holdings** = the chain's token list plus every token the wallet swapped in the last 30 days, read on-chain (Solana: its 50 largest holdings). A token with no price Chord trusts (no measured liquidity, not on the chain's board) has `priceUsd: null`, comes last and is in no total. Priced holdings under $0.01 are folded into `dust`.\n- **Each chain answers on its own deadline.** One that cannot be read is `status: \"unavailable\"` with a `reason` inside the 200 and is left out of the totals' value; `partial` = the balances were read, part of the rest was not.\n- **Times are milliseconds** in this answer (`asOf`, `fromTs`, `tapeFromTs`), unlike most of this API.\n- **Cache**: kept 45 seconds per wallet, Solana address and chain set (10 seconds when a chain could not be read); a copy up to 10 minutes old may be served once while a refresh runs (`asOf` says when it was computed). `fresh=1` recomputes, only for a request with an `X-API-Key` or an Ask session; otherwise it is ignored.\n- **Without an API key (or an Ask session)**: a cached answer is served to anyone. One IP may start at most 10 new reads every 10 minutes (this route and `/activity` together), and every such caller together a limited number a minute; past either the answer is 429 `RATE_LIMITED` or 503 `BUSY` with `Retry-After`, and nothing is read. Send an `X-API-Key` for more.","url":"https://getchord.xyz/docs/api-reference/operations/portfolio/","parameters":[{"name":"wallet","in":"path","required":true,"type":"string","description":""},{"name":"sol","in":"query","required":false,"type":"string","description":"The wallet's Solana address. Adds Solana to the default scope."},{"name":"chains","in":"query","required":false,"type":"string","default":"all","description":"`all` = the eight EVM chains, plus Solana when `sol` is given. Or a comma list of chain ids (`143`, `4663`, `5042`, `43114`, `8453`, `56`, `42161`, `1`) and `solana` (which needs `sol`). Answered in registry order, Solana last. This route does not read `chain`: `chain=5042` on its own still answers for every chain, so send `chains=5042` for Arc alone."},{"name":"fresh","in":"query","required":false,"type":"string","enum":["1"],"description":"Recompute instead of serving the cached answer. Honoured only with an `X-API-Key` or an Ask session."}],"requestBody":null,"responses":{"200":"","400":"`INVALID_ADDRESS` (the wallet), `INVALID_SOL_ADDRESS`, `BAD_CHAINS`, or `SOL_REQUIRED` (`chains` names `solana` without `sol`).","429":"`RATE_LIMITED`: without an API key, this IP started its 10 new portfolio reads of the last 10 minutes (`Retry-After`); a portfolio read in the last 10 minutes still answers. Or `RATE_LIMIT_EXCEEDED`, the per-minute limit of every route.","503":"`BUSY`: too many new portfolio reads are running for callers without a key right now (`Retry-After`). `UNAVAILABLE`: the answer itself could not be built. A chain that cannot be read is not a 503: it comes back `status: \"unavailable\"` inside a 200."},"response":{"schema":{"wallet":"string — EVM address, lower-case.","sol":"string|null — The Solana address as given, or null.","asOf":"integer — Unix time, milliseconds. When this answer was computed. A cached answer keeps its own `asOf`.","totals":{"valueUsd":"number — Sum of `valueUsd` over the chains that were read.","cashUsd":"number","pnl":{"24h":"object","7d":"object","30d":"object"}},"chains":[{"chain":"integer|string — EVM chain id, or `solana`.","key":"string — Registry key (`monad`, `base`, …) or `solana`.","name":"string","status":"string (ok|partial|unavailable) — `ok` = read. `partial` = balances read, part of the rest (prices, the tape, some tokens) not, and `reason` says which. `unavailable` = not read at all: in no total, every window without a number.","reason":"string — Present unless `ok`. One plain sentence for a person.","valueUsd":"number — Sum of the priced holdings, small balances included.","cashUsd":"number — The part of `valueUsd` held in stablecoins.","pnl":"object","coverage":"object","holdings":"array","dust":"object","unpriced":"integer — Holdings with `priceUsd: null` (listed at the end of `holdings`)."}]},"example":null},"security":null},{"kind":"operation","operationId":"portfolioActivity","method":"GET","path":"/v1/portfolio/{wallet}/activity","tag":"Portfolio","summary":"Swaps on every chain","description":"The wallet's swaps on every chain in scope, merged newest first, one keyset page at a time. Each item is one side of a swap seen from the wallet: `buy` = it received `token`, `sell` = it gave it.\n\n**Notes**\n- Pass the page's `cursor` back as `cursor` for the next page; `cursor: null` = nothing older. One transaction's rows stay on one page, so a page can hold fewer than `limit` items.\n- A chain that could not be read for a page is listed in `unavailable` and keeps its place: the next page asks it again. `items: []` with `unavailable` set is an outage, not an empty history.\n- How far back: Monad, Robinhood Chain and Arc, their raw tape (45 days); Avalanche, Base, BNB Chain, Arbitrum One and Ethereum, their raw tape and then, where Chord's history lake holds older days, up to 5,000 older swaps; Solana, 45 days. EVM swaps under $0.10 are left out.\n- `ts` is in milliseconds.\n- Pages are not cached: without an API key (or an Ask session) each page counts against the budget it shares with `GET /portfolio/{wallet}` (10 new reads per IP every 10 minutes, a limited number a minute for every such caller together); past it 429 `RATE_LIMITED` or 503 `BUSY` with `Retry-After`.","url":"https://getchord.xyz/docs/api-reference/operations/portfolioactivity/","parameters":[{"name":"wallet","in":"path","required":true,"type":"string","description":""},{"name":"sol","in":"query","required":false,"type":"string","description":"The wallet's Solana address. Adds Solana to the default scope."},{"name":"chains","in":"query","required":false,"type":"string","default":"all","description":"`all` = the eight EVM chains, plus Solana when `sol` is given. Or a comma list of chain ids (`143`, `4663`, `5042`, `43114`, `8453`, `56`, `42161`, `1`) and `solana` (which needs `sol`). Answered in registry order, Solana last. This route does not read `chain`: `chain=5042` on its own still answers for every chain, so send `chains=5042` for Arc alone."},{"name":"cursor","in":"query","required":false,"type":"string","description":"The `cursor` of the previous page."},{"name":"limit","in":"query","required":false,"type":"integer","default":50,"description":"Items per page."}],"requestBody":null,"responses":{"200":"","400":"`INVALID_ADDRESS`, `INVALID_SOL_ADDRESS`, `BAD_CHAINS`, `SOL_REQUIRED`, `BAD_LIMIT` (1 to 100) or `BAD_CURSOR` (not a cursor of this route).","429":"`RATE_LIMITED`: without an API key, this IP started its 10 new portfolio reads of the last 10 minutes, pages included (`Retry-After`). Or `RATE_LIMIT_EXCEEDED`, the per-minute limit of every route.","503":"`BUSY`: too many new portfolio reads are running for callers without a key right now (`Retry-After`). `UNAVAILABLE`: the page itself could not be built (a chain that cannot be read is listed in `unavailable` inside a 200)."},"response":{"schema":{"items":[{"ts":"integer — Unix time, milliseconds.","chain":"integer|string — EVM chain id, or `solana`.","side":"string (buy|sell) — `buy` = the wallet received `token`; `sell` = it gave it.","token":"object","amount":"string — Whole tokens, decimal string.","valueUsd":"number|null","priceUsd":"number|null","tx":"string — Transaction hash, or the Solana signature (case kept).","explorer":"string|null — The transaction on the chain's explorer.","venue":"string|null — Venue display name."}],"cursor":"string|null — Opaque. Pass it back for the next page; null = nothing older.","unavailable":[{"chain":"integer|string — EVM chain id, or `solana`.","reason":"string"}]},"example":null},"security":null},{"kind":"operation","operationId":"walletPnl","method":"GET","path":"/v1/portfolio/{wallet}/pnl","tag":"Portfolio","summary":"Realized and open PnL per token","description":"Average-cost PnL for one wallet from the tape: realized on sells, unrealized on what is still held at current prices, ROI, and the untracked balance that arrived by transfer (no cost basis, excluded from PnL). Cached with stale-while-revalidate (a day-old answer beats a $0 skeleton).\n\nPortfolio routes answer an empty 200 shape rather than a 5xx when the tape read fails — treat an empty `tokens` list as \"nothing yet\" and retry later.","url":"https://getchord.xyz/docs/api-reference/operations/walletpnl/","parameters":[{"name":"wallet","in":"path","required":true,"type":"string","description":""},{"name":"chain","in":"query","required":false,"type":"string","enum":["5042","4663","143","all"],"default":"all","description":"One chain, or `all` to merge chains with a `byChain` breakdown."}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …)."},"response":{"schema":{"tokens":[{"token":"string — EVM address, hex, case-insensitive.","symbol":"string|null","logo":"string|null","realizedUsd":"number","unrealizedUsd":"number","totalUsd":"number","costRemaining":"number","curValue":"number","curAmount":"number","avgCost":"number — Average cost per token, USD.","roiPct":"number|null","untrackedAmount":"number — Balance that arrived by transfer (no cost basis).","untrackedValue":"number"}],"realized":"number","unrealized":"number","total":"number","exitedWithoutSale":"object — Present when bought quantity left the wallet with no sale on the tape (a transfer out, or a sale credited to another address): `{tokens, costUsd, top: [{symbol, costUsd}]}`. Its result is unknown and NOT in the PnL above.","byChain":"object — Only with `chain=all`.","updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":{"tokens":[{"token":"0xece5ca8bf9220718e5727754026757512212cb3c","symbol":"ARGUS","logo":"https://coin-images.coingecko.com/coins/images/102178392/large/argus-token.png?1789463380","realizedUsd":30462.864779627198,"unrealizedUsd":11700.939232721703,"totalUsd":42163.804012348905,"costRemaining":1286.137220108177,"curValue":12987.07645282988,"curAmount":744055.9147763874,"avgCost":0.0017285491514366933,"roiPct":909.7737822825419,"untrackedAmount":0,"untrackedValue":0},{"token":"0x66927743a8a841ca09575a4ccdcd090c761adcec","symbol":"HYCI","logo":"https://ipfs.filebase.io/ipfs/bafybeiezh2g4uhqy2bzdq4elwkzek55q5ccs4gpyyki672a4i3olf3u224","realizedUsd":181.713005,"unrealizedUsd":0,"totalUsd":181.713005,"costRemaining":0,"curValue":0,"curAmount":0,"avgCost":0.000042576384935211256,"roiPct":null,"untrackedAmount":0,"untrackedValue":0}],"realized":30488.101882774274,"unrealized":11700.939232721703,"total":42189.04111549597,"updatedAt":1789809277093}},"security":null},{"kind":"operation","operationId":"walletBalances","method":"GET","path":"/v1/wallet/{wallet}/balances","tag":"Portfolio","summary":"Holdings on every chain","description":"What a wallet holds right now on Chord's six chains (Monad, Robinhood Chain, Arc, Avalanche, Base, BNB Chain), read on-chain: the native coin plus every token on Chord's list for each chain, priced by Chord's own maps. `raw` is the exact balance in the token's smallest unit (use it for a Max button); `amount` is the same number in whole tokens. Each chain answers on its own deadline: a slow or failing chain comes back `unavailable` with a reason and the others still answer. Only listed tokens are seen; a token outside Chord's lists will not show. Cached 15 s per wallet and chain set.","url":"https://getchord.xyz/docs/api-reference/operations/walletbalances/","parameters":[{"name":"wallet","in":"path","required":true,"type":"string","description":""},{"name":"chains","in":"query","required":false,"type":"string","description":"Comma list of chain ids (143, 4663, 5042, 43114, 8453, 56). Default: all six; unknown ids are ignored."}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …)."},"response":{"schema":{"wallet":"string — EVM address, hex, case-insensitive.","totalUsd":"number — Sum of priced holdings.","updatedAt":"integer — Unix time, milliseconds — when the server built this answer.","chains":[{"chain":"integer","name":"string","status":"string (ok|unavailable|no_rpc)","reason":"string — Only when not ok.","totalUsd":"number","holdings":"array"}]},"example":{"wallet":"0x0d36a315083033d3d097950c9e494acc04588f99","chains":[{"chain":8453,"name":"Base","status":"ok","totalUsd":1221.38,"holdings":[{"symbol":"ETH","name":null,"address":null,"native":true,"decimals":18,"raw":"454663939527832318","amount":"0.454663939527832318","priceUsd":2686.342436128022,"valueUsd":1221.38,"logoURI":null,"stable":false},{"symbol":"WETH","name":null,"address":"0x4200000000000000000000000000000000000006","native":false,"decimals":18,"raw":"148044","amount":"0.000000000000148044","priceUsd":2686.342436128022,"valueUsd":0,"logoURI":null,"stable":false}]}],"totalUsd":1221.38,"updatedAt":1791052461304}},"security":null},{"kind":"operation","operationId":"walletTrades","method":"GET","path":"/v1/portfolio/{wallet}/trades","tag":"Portfolio","summary":"Trade history","description":"The wallet's buys and sells on the chain, newest first — the markers on a portfolio chart.\n\nPortfolio routes answer an empty 200 shape rather than a 5xx when the tape read fails — treat an empty `tokens` list as \"nothing yet\" and retry later.","url":"https://getchord.xyz/docs/api-reference/operations/wallettrades/","parameters":[{"name":"wallet","in":"path","required":true,"type":"string","description":""},{"name":"chain","in":"query","required":false,"type":"integer","enum":[5042,4663,143],"default":143,"description":"Chain id: `5042` Arc · `4663` Robinhood Chain · `143` Monad. Omitted = 143."}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …)."},"response":{"schema":{"trades":[{"t":"integer — Unix time, seconds, UTC.","side":"string (buy|sell)","usd":"number","tokenAmt":"number","token":"string — EVM address, hex, case-insensitive.","symbol":"string|null","tx":"string — Transaction hash."}],"updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":{"trades":[{"t":1789890946,"side":"buy","usd":198,"tokenAmt":5293562.144446149,"token":"0x08adbf431569a1aacac2606d2adcd18f4ebf2a71","symbol":"GLITCH","tx":"0x25c5fd4de14a7592e39f0b803538cdbe1601a927f630da46fe9107c3afc89f83"},{"t":1789890762,"side":"buy","usd":297,"tokenAmt":8471531.758406071,"token":"0x08adbf431569a1aacac2606d2adcd18f4ebf2a71","symbol":"GLITCH","tx":"0xf261bcb6c8d8bf3fe9debbd9f012396c8e025eafbcb047d40c5ee66013df9ef9"}],"updatedAt":1789891871018}},"security":null},{"kind":"operation","operationId":"walletPnlCalendar","method":"GET","path":"/v1/portfolio/{wallet}/pnl-calendar","tag":"Portfolio","summary":"Realized PnL by day","description":"Day-by-day realized PnL (UTC days) with the trade count, from the same average-cost model as `/pnl`, so the day sums reconcile with `realized` by construction.\n\nPortfolio routes answer an empty 200 shape rather than a 5xx when the tape read fails — treat an empty `tokens` list as \"nothing yet\" and retry later.","url":"https://getchord.xyz/docs/api-reference/operations/walletpnlcalendar/","parameters":[{"name":"wallet","in":"path","required":true,"type":"string","description":""},{"name":"chain","in":"query","required":false,"type":"integer","enum":[5042,4663,143],"default":143,"description":"Chain id: `5042` Arc · `4663` Robinhood Chain · `143` Monad. Omitted = 143."}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …)."},"response":{"schema":{"days":[{"date":"string — YYYY-MM-DD","realizedUsd":"number","trades":"integer"}],"firstDate":"string|null","realizedTotal":"number","updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":{"days":[{"date":"2026-08-19","realizedUsd":0,"trades":6},{"date":"2026-08-20","realizedUsd":0,"trades":2}],"firstDate":"2026-08-19","realizedTotal":34046.5607144201,"updatedAt":1789891871239}},"security":null},{"kind":"operation","operationId":"lpOverview","method":"GET","path":"/v1/lp/overview","tag":"Liquidity","summary":"Liquidity headline","description":"The pools page pulse: fees paid to LPs in 24 hours (top 100 pools by fees), the best real yield (≥ 25 traders, not suspect), dollars added and removed, volume, TVL and providers over pools with ≥ $10k TVL, the six hottest pools by fees and the three biggest net inflows. Memoised 30 s.","url":"https://getchord.xyz/docs/api-reference/operations/lpoverview/","parameters":[{"name":"chain","in":"query","required":true,"type":"integer","enum":[5042,4663,143],"description":"Chain id: `5042` Arc · `4663` Robinhood Chain · `143` Monad."}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …)."},"response":{"schema":{"chain":"integer","pools24h":"integer","tvlUsd":"number","vol24hUsd":"number","fees24hUsd":"number","feesPoolsCounted":"integer","lpAdd24hUsd":"number","lpRemove24hUsd":"number","providers24h":"integer","best":{"pool":"string — A pool: a 20-byte contract address (V2 / V3) or a 32-byte Uniswap V4 pool id.","pair":"string","token0":{"address":"string — EVM address, hex, case-insensitive.","symbol":"string|null — Symbol from the contract, or null while unresolved.","decimals":"integer|null — ERC-20 decimals.","logo":"string|null — Logo URL, or null.","impostor":"boolean — True when the symbol copies the chain's anchor (a token called USDC that is not the USDC predeploy). Flagged, never hidden."},"token1":{"address":"string — EVM address, hex, case-insensitive.","symbol":"string|null — Symbol from the contract, or null while unresolved.","decimals":"integer|null — ERC-20 decimals.","logo":"string|null — Logo URL, or null.","impostor":"boolean — True when the symbol copies the chain's anchor (a token called USDC that is not the USDC predeploy). Flagged, never hidden."},"dex":"string","feeTvlPct":"number","aprPct":"number|null","tvlUsd":"number|null"},"hot":[{"pool":"string — A pool: a 20-byte contract address (V2 / V3) or a 32-byte Uniswap V4 pool id.","pair":"string","token0":"object","token1":"object","dex":"string","feeBps":"number|null","fees24hUsd":"number","feeTvlPct":"number|null","tvlUsd":"number|null","vol24hUsd":"number","wallets24h":"integer"}],"inflow":[{"pool":"string — A pool: a 20-byte contract address (V2 / V3) or a 32-byte Uniswap V4 pool id.","pair":"string","token0":"object","token1":"object","dex":"string","netUsd":"number","tvlUsd":"number|null"}],"updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":{"chain":5042,"pools24h":416,"tvlUsd":59062379.766785584,"vol24hUsd":32606366.761442985,"fees24hUsd":108337.05880814306,"feesPoolsCounted":31,"lpAdd24hUsd":18682513.45246684,"lpRemove24hUsd":26568879.80331895,"providers24h":1750,"best":{"pool":"0xf53f02d9041d00bbd92235b4c902b9f350c554a8ed2dc64fa0a4585aac413f09","pair":"USDC / MURMUR","token0":{"address":"0x3600000000000000000000000000000000000000","symbol":"USDC","decimals":6,"logo":"https://coin-images.coingecko.com/coins/images/6319/large/USDC.png?1769615602","impostor":false},"token1":{"address":"0x8faae5592b9acc27a79fca745c6b872adf514a5d","symbol":"MURMUR","decimals":18,"logo":"https://cdn.dexscreener.com/cms/images/QUq-IqT1GLQNkxMx?width=800&height=800&quality=95&format=auto","impostor":false},"dex":"uniswap_v4","feeTvlPct":14.40921999562047,"aprPct":5259.365298401472,"tvlUsd":12650.66},"hot":[{"pool":"0x6a3bacaa6493734c1ac221ebf42cf530a96c1e02","pair":"USDC / ARGUS","token0":{"address":"0x3600000000000000000000000000000000000000","symbol":"USDC","decimals":6,"logo":"https://coin-images.coingecko.com/coins/images/6319/large/USDC.png?1769615602","impostor":false},"token1":{"address":"0xece5ca8bf9220718e5727754026757512212cb3c","symbol":"ARGUS","decimals":18,"logo":"https://cdn.dexscreener.com/cms/images/0lkViejHOEfB3StE?width=800&height=800&quality=95&format=auto","impostor":false},"dex":"uniswap_v3","feeBps":100,"fees24hUsd":21874.53260752,"feeTvlPct":2.0870143590342853,"tvlUsd":1048125.64,"vol24hUsd":2187453.260752,"wallets24h":598},{"pool":"0xb3f441e8871840ecfcb284e5cbb5b9c21a50e961e1c50109bdced25e429f00cc","pair":"USDC / ARGUS","token0":{"address":"0x3600000000000000000000000000000000000000","symbol":"USDC","decimals":6,"logo":"https://coin-images.coingecko.com/coins/images/6319/large/USDC.png?1769615602","impostor":false},"token1":{"address":"0xece5ca8bf9220718e5727754026757512212cb3c","symbol":"ARGUS","decimals":18,"logo":"https://cdn.dexscreener.com/cms/images/0lkViejHOEfB3StE?width=800&height=800&quality=95&format=auto","impostor":false},"dex":"uniswap_v4","feeBps":98.5,"fees24hUsd":14338.80123860194,"feeTvlPct":4.759044987124094,"tvlUsd":301295.77,"vol24hUsd":1455715.861786999,"wallets24h":313}],"inflow":[{"pool":"0xd945caee4635bcd7fb8a9fa74dc1d0c4c1472782","pair":"cirBTC / USDC","token0":{"address":"0x171a4217b86a807a64eb94757db6849fb4bdbaa0","symbol":"cirBTC","decimals":8,"logo":"https://coin-images.coingecko.com/coins/images/102172745/large/cirbtc.jpg?1775204071","impostor":false},"token1":{"address":"0x3600000000000000000000000000000000000000","symbol":"USDC","decimals":6,"logo":"https://coin-images.coingecko.com/coins/images/6319/large/USDC.png?1769615602","impostor":false},"dex":"slipstream_fork","netUsd":44469.43327364928,"tvlUsd":570213.05},{"pool":"0xa2ed014384e061ec2aaccea186d41798dcf4da29264c44a676d3006fdc252ae0","pair":"USDC / ARCOON","token0":{"address":"0x3600000000000000000000000000000000000000","symbol":"USDC","decimals":6,"logo":"https://coin-images.coingecko.com/coins/images/6319/large/USDC.png?1769615602","impostor":false},"token1":{"address":"0x4621a0baa0b5d97aae77704cf2a84dabe78a4fed","symbol":"ARCOON","decimals":18,"logo":"https://ipfs.filebase.io/ipfs/bafybeiecv2b5gkrr5q4cesftgirntp4roqixhcily6ynfjitgdcunxm3x4","impostor":false},"dex":"uniswap_v4","netUsd":24000.000013,"tvlUsd":142471.24}],"updatedAt":1789891860138}},"security":null},{"kind":"operation","operationId":"lpPools","method":"GET","path":"/v1/lp/pools","tag":"Liquidity","summary":"Pools ranked for a liquidity provider","description":"Every indexed pool with volume by window, fees (volume × the pool's fee tier), TVL, fee/TVL and an annualised yardstick, LP adds / removes / providers in 24 hours, trader counts, and a 0–100 health score. Pools under $10k TVL are hidden unless `small=1`; wash and launch-farm pools are hidden unless `flagged=1` (they come back with `suspect: true`). `category=stocks` keeps the pools with a tokenized stock or ETF on one side (Robinhood Chain only: `400 BAD_CATEGORY` elsewhere, `503 CATEGORY_UNAVAILABLE` while the token list cannot be read).\n\n**Use it for**: an LP screener, \"where are the fees on Arc\", a pool picker for a token.","url":"https://getchord.xyz/docs/api-reference/operations/lppools/","parameters":[{"name":"chain","in":"query","required":true,"type":"integer","enum":[5042,4663,143],"description":"Chain id: `5042` Arc · `4663` Robinhood Chain · `143` Monad."},{"name":"sort","in":"query","required":false,"type":"string","enum":["fee_tvl","vol_24h","vol_1h","tvl","fees_24h","first_seen","lp_net_24h","trades_24h","score"],"default":"fee_tvl","description":""},{"name":"interval","in":"query","required":false,"type":"string","enum":["1h","6h","24h"],"default":"24h","description":"Window the fee/TVL sort uses."},{"name":"minTvl","in":"query","required":false,"type":"number","description":"Default 10000 unless `small=1`."},{"name":"quote","in":"query","required":false,"type":"string","description":"Anchor symbol filter (e.g. `USDC`)."},{"name":"dex","in":"query","required":false,"type":"string","description":"Venue id filter."},{"name":"search","in":"query","required":false,"type":"string","description":"Symbol or address."},{"name":"small","in":"query","required":false,"type":"integer","enum":[0,1],"default":0,"description":"1 = include pools under $10k TVL."},{"name":"flagged","in":"query","required":false,"type":"integer","enum":[0,1],"default":0,"description":"1 = include suspect pools."},{"name":"category","in":"query","required":false,"type":"string","enum":["stocks"],"description":"Robinhood Chain (4663): pools with a tokenized stock or ETF on one side."},{"name":"maxTvl","in":"query","required":false,"type":"number","description":"Range filters: every bound is inclusive, unset = off, and a row whose figure the index does not have fails a set bound."},{"name":"minVol","in":"query","required":false,"type":"number","description":"Volume of the `interval`, dollars."},{"name":"maxVol","in":"query","required":false,"type":"number","description":""},{"name":"minFees","in":"query","required":false,"type":"number","description":"Fees of the `interval`, dollars."},{"name":"maxFees","in":"query","required":false,"type":"number","description":""},{"name":"minAgeH","in":"query","required":false,"type":"number","description":"Hours since the pool was created (since its first trade when the creation is unknown)."},{"name":"maxAgeH","in":"query","required":false,"type":"number","description":""},{"name":"minFeePct","in":"query","required":false,"type":"number","description":"Fee tier in percent (0.3 = 30 bps)."},{"name":"maxFeePct","in":"query","required":false,"type":"number","description":""},{"name":"limit","in":"query","required":false,"type":"integer","default":50,"description":""},{"name":"offset","in":"query","required":false,"type":"integer","default":0,"description":""}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"integer","sort":"string","interval":"string","minTvl":"number","flagged":"boolean","category":"string — Present when the list was narrowed to a category.","hidden":"integer — Rows removed by the filters.","total":"integer","limit":"integer","offset":"integer","pools":[{"pool":"string — A pool: a 20-byte contract address (V2 / V3) or a 32-byte Uniswap V4 pool id.","dex":"string","kind":"string (v2|clmm|v4)","feeBps":"number|null","hooks":"string|null — EVM address, hex, case-insensitive.","lpAccess":"string (open|hooked|unknown) — `hooked` = a V4 hook can refuse adds.","tickSpacing":"integer|null","token0":"object","token1":"object","tokenSide":"integer|null — Which side is the non-anchor token (0 or 1).","tvlUsd":"number|null","tvlSrc":"string|null — Where TVL came from (`onchain`, `dexscreener`, …).","tvlAt":"integer|null — Unix time, seconds, UTC.","vol":"object","fees":"object","feeTvlPct":"object","aprPct":"number|null — 24h fee/TVL × 365 — a full-range yardstick, not a promise.","trades24h":"integer","wallets24h":"integer","priceUsd":"number|null","lpAdd24h":"number","lpRemove24h":"number","providers24h":"integer","firstSeenTs":"integer — Unix time, seconds, UTC.","createdTs":"integer|null — Unix time, seconds, UTC.","lastTradeHour":"integer","turnover24h":"number|null — 24h volume ÷ TVL.","suspect":"boolean — Wash or launch-farm printing (volume without traders, dust TVL under real volume, turnover no honest pool reaches). Hidden by default; `flagged=1` shows them.","score":"integer — 0–100 health score (traders, TVL, yield sanity, LP flow, age, penalties).","marketCapUsd":"number|null — The tracked token's price × its total supply on this chain (for a bridged token: what was bridged here). On the list only; `null` when the pool tracks neither side, the tracked side is the native coin, or the supply is not on record yet."}],"updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":{"chain":5042,"sort":"fee_tvl","interval":"24h","minTvl":10000,"flagged":false,"hidden":148,"total":1207,"limit":2,"offset":0,"pools":[{"pool":"0xf53f02d9041d00bbd92235b4c902b9f350c554a8ed2dc64fa0a4585aac413f09","dex":"uniswap_v4","kind":"v4","feeBps":98.8,"hooks":null,"lpAccess":"open","tickSpacing":99,"token0":{"address":"0x3600000000000000000000000000000000000000","symbol":"USDC","decimals":6,"logo":"https://coin-images.coingecko.com/coins/images/6319/large/USDC.png?1769615602","impostor":false},"token1":{"address":"0x8faae5592b9acc27a79fca745c6b872adf514a5d","symbol":"MURMUR","decimals":18,"logo":"https://cdn.dexscreener.com/cms/images/QUq-IqT1GLQNkxMx?width=800&height=800&quality=95&format=auto","impostor":false},"tokenSide":1,"tvlUsd":12650.66,"tvlSrc":"dexscreener","tvlAt":1789891603,"vol":{"h1":176.542824,"h6":38476.48885700001,"h24":184500.14476700005,"d7":279614.0964730001},"fees":{"h1":1.74424310112,"h6":380.1477099071601,"h24":1822.8614302979606},"feeTvlPct":{"h1":0.01378776365122452,"h6":3.0049634557182006,"h24":14.40921999562047},"aprPct":5259.365298401472,"trades24h":3050,"wallets24h":131,"priceUsd":0.0007671677499328048,"lpAdd24h":10038.913414765322,"lpRemove24h":7583.743885515528,"providers24h":25,"firstSeenTs":1789693200,"createdTs":1789695461,"lastTradeHour":1789891200,"turnover24h":14.584230764798047,"suspect":false,"score":54},{"pool":"0x5e794e5d3d01c045ddfb2448c4afd557ec297d1dee49b28923dc0ada3425f780","dex":"uniswap_v4","kind":"v4","feeBps":100,"hooks":"0x863233bec01b92f137677e0cdf69bce697a26044","lpAccess":"open","tickSpacing":200,"token0":{"address":"0x3600000000000000000000000000000000000000","symbol":"USDC","decimals":6,"logo":"https://coin-images.coingecko.com/coins/images/6319/large/USDC.png?1769615602","impostor":false},"token1":{"address":"0xb7c934ff18730c24e6113bb4bc5a68feef16fd29","symbol":"ARCUS","decimals":18,"logo":"https://cdn.dexscreener.com/cms/images/5y5kHHeZlCoSxlaq?width=800&height=800&quality=95&format=auto","impostor":false},"tokenSide":1,"tvlUsd":67762.97,"tvlSrc":"dexscreener","tvlAt":1789891603,"vol":{"h1":1737.729194,"h6":98528.85847099999,"h24":738635.9835579997,"d7":1514816.5901679986},"fees":{"h1":17.377291940000003,"h6":985.2885847099998,"h24":7386.359835579997},"feeTvlPct":{"h1":0.025644230086137018,"h6":1.454022137326625,"h24":10.90028939932827},"aprPct":3978.605630754819,"trades24h":5942,"wallets24h":353,"priceUsd":0.0004984252802693936,"lpAdd24h":960.0917324579016,"lpRemove24h":872.6609130846944,"providers24h":11,"firstSeenTs":1789567200,"createdTs":1789570672,"lastTradeHour":1789891200,"turnover24h":10.900289399328273,"suspect":false,"score":62}],"updatedAt":1789891860349}},"security":null},{"kind":"operation","operationId":"lpPool","method":"GET","path":"/v1/lp/pools/{pool}","tag":"Liquidity","summary":"One pool","description":"The pool row plus its hourly series (the last 168 hours by default; `hours` up to 720), the top providers over 7 days, the health score with its parts and reasons, launch facts (who launched it, how much of the liquidity the launcher holds and has pulled), and `mint` — what a wallet needs to add liquidity here (the position manager, the pool key, Permit2, tick spacing).","url":"https://getchord.xyz/docs/api-reference/operations/lppool/","parameters":[{"name":"pool","in":"path","required":true,"type":"string","description":""},{"name":"chain","in":"query","required":true,"type":"integer","enum":[5042,4663,143],"description":"Chain id: `5042` Arc · `4663` Robinhood Chain · `143` Monad."},{"name":"hours","in":"query","required":false,"type":"integer","description":"Hours of the hourly series, 24 to 720 (default 168)"}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","404":"Nothing at this identity (`NOT_FOUND`, `UNKNOWN_TOKEN`, `NO_ROUTE`)."},"response":{"schema":[{"pool":"string — A pool: a 20-byte contract address (V2 / V3) or a 32-byte Uniswap V4 pool id.","dex":"string","kind":"string (v2|clmm|v4)","feeBps":"number|null","hooks":"string|null — EVM address, hex, case-insensitive.","lpAccess":"string (open|hooked|unknown) — `hooked` = a V4 hook can refuse adds.","tickSpacing":"integer|null","token0":{"address":"string — EVM address, hex, case-insensitive.","symbol":"string|null — Symbol from the contract, or null while unresolved.","decimals":"integer|null — ERC-20 decimals.","logo":"string|null — Logo URL, or null.","impostor":"boolean — True when the symbol copies the chain's anchor (a token called USDC that is not the USDC predeploy). Flagged, never hidden."},"token1":{"address":"string — EVM address, hex, case-insensitive.","symbol":"string|null — Symbol from the contract, or null while unresolved.","decimals":"integer|null — ERC-20 decimals.","logo":"string|null — Logo URL, or null.","impostor":"boolean — True when the symbol copies the chain's anchor (a token called USDC that is not the USDC predeploy). Flagged, never hidden."},"tokenSide":"integer|null — Which side is the non-anchor token (0 or 1).","tvlUsd":"number|null","tvlSrc":"string|null — Where TVL came from (`onchain`, `dexscreener`, …).","tvlAt":"integer|null — Unix time, seconds, UTC.","vol":{"h1":"number","h6":"number","h24":"number","d7":"number"},"fees":{"h1":"number|null","h6":"number|null","h24":"number|null"},"feeTvlPct":{"h1":"number|null","h6":"number|null","h24":"number|null"},"aprPct":"number|null — 24h fee/TVL × 365 — a full-range yardstick, not a promise.","trades24h":"integer","wallets24h":"integer","priceUsd":"number|null","lpAdd24h":"number","lpRemove24h":"number","providers24h":"integer","firstSeenTs":"integer — Unix time, seconds, UTC.","createdTs":"integer|null — Unix time, seconds, UTC.","lastTradeHour":"integer","turnover24h":"number|null — 24h volume ÷ TVL.","suspect":"boolean — Wash or launch-farm printing (volume without traders, dust TVL under real volume, turnover no honest pool reaches). Hidden by default; `flagged=1` shows them.","score":"integer — 0–100 health score (traders, TVL, yield sanity, LP flow, age, penalties).","marketCapUsd":"number|null — The tracked token's price × its total supply on this chain (for a bridged token: what was bridged here). On the list only; `null` when the pool tracks neither side, the tracked side is the native coin, or the supply is not on record yet."},{"chain":"integer","hourly":["object"],"topLps":["object"],"health":{"score":"integer","parts":"object","reasons":"array"},"launch":{"launcher":"string|null — EVM address, hex, case-insensitive.","launcherName":"string|null","creator":"string|null — EVM address, hex, case-insensitive.","hooks":"string|null — EVM address, hex, case-insensitive.","launchedTs":"integer|null — Unix time, seconds, UTC.","launcherLpAddedUsd":"number","totalLpAddedUsd":"number","launcherSharePct":"number|null","launcherLastRemoveTs":"integer|null — Unix time, seconds, UTC.","launcherRemovedUsd":"number"},"mint":{"kind":"string","manager":"string|null — EVM address, hex, case-insensitive.","permit2":"string — EVM address, hex, case-insensitive.","token0":"string — EVM address, hex, case-insensitive.","token1":"string — EVM address, hex, case-insensitive.","feePips":"integer|null","tickSpacing":"integer|null","hooks":"string — EVM address, hex, case-insensitive.","feeRaw":"integer|null — V4 dynamic-fee pools carry the 0x800000 flag.","nativeCurrency0":"boolean"},"updatedAt":"integer — Unix time, milliseconds — when the server built this answer."}],"example":{"chain":5042,"pool":"0xf53f02d9041d00bbd92235b4c902b9f350c554a8ed2dc64fa0a4585aac413f09","dex":"uniswap_v4","kind":"v4","feeBps":98.8,"hooks":null,"lpAccess":"open","tickSpacing":99,"token0":{"address":"0x3600000000000000000000000000000000000000","symbol":"USDC","decimals":6,"logo":"https://coin-images.coingecko.com/coins/images/6319/large/USDC.png?1769615602","impostor":false},"token1":{"address":"0x8faae5592b9acc27a79fca745c6b872adf514a5d","symbol":"MURMUR","decimals":18,"logo":"https://cdn.dexscreener.com/cms/images/QUq-IqT1GLQNkxMx?width=800&height=800&quality=95&format=auto","impostor":false},"tokenSide":1,"tvlUsd":12650.66,"tvlSrc":"dexscreener","tvlAt":1789891603,"vol":{"h1":176.542824,"h6":38476.48885700001,"h24":184500.14476700005,"d7":279614.0964730001},"fees":{"h1":1.74424310112,"h6":380.1477099071601,"h24":1822.8614302979606},"feeTvlPct":{"h1":0.01378776365122452,"h6":3.0049634557182006,"h24":14.40921999562047},"aprPct":5259.365298401472,"trades24h":3050,"wallets24h":131,"priceUsd":0.0007671677499328048,"lpAdd24h":8037.861902775549,"lpRemove24h":7583.743885515529,"providers24h":25,"firstSeenTs":1789693200,"createdTs":1789695461,"lastTradeHour":1789891200,"turnover24h":14.584230764798047,"suspect":false,"hourly":[{"hour":1789693200,"vol":398.305695,"trades":24,"price":0.00008817848931962542},{"hour":1789696800,"vol":1958.7937559999996,"trades":77,"price":0.00010307489720874844}],"topLps":[{"wallet":"0x25cacb704ed0852428e7cc0687bca45ee8c21848","addUsd":5763.889211498252,"removeUsd":0,"netUsd":5763.889211498252,"events":1,"lastTs":1789695461},{"wallet":"0x5db28691cbfc2ceeca1d919f0749b64013c25432","addUsd":3885.2424150632846,"removeUsd":1296.008402,"netUsd":2589.2340130632847,"events":254,"lastTs":1789886789}],"health":{"score":34,"parts":{"traders":17.6,"tvl":13.7,"yieldSanity":4,"lpFlow":15,"age":3.2,"penalties":20},"reasons":["the launcher holds 100% of the liquidity added","fee/TVL over 10 %/day: volume is not organic or TVL is not the whole picture"]},"launch":{"launcher":"0x6049c9a0e26405c0985f9e3685c87d0ae917f82b","launcherName":"Uniswap Liquidity Launcher","creator":"0x25cacb704ed0852428e7cc0687bca45ee8c21848","hooks":null,"launchedTs":1789695461,"launcherLpAddedUsd":15907.554822267326,"totalLpAddedUsd":15907.554822267326,"launcherSharePct":100,"launcherLastRemoveTs":1789888952,"launcherRemovedUsd":7697.230608504608},"mint":{"kind":"v4","manager":"0x6049c9a0e26405c0985f9e3685c87d0ae917f82b","permit2":"0x000000000022d473030f116ddee9f6b43ac78ba3","token0":"0x3600000000000000000000000000000000000000","token1":"0x8faae5592b9acc27a79fca745c6b872adf514a5d","feePips":9880,"tickSpacing":99,"hooks":"0x0000000000000000000000000000000000000000","feeRaw":9880,"nativeCurrency0":false},"updatedAt":1789891869303}},"security":null},{"kind":"operation","operationId":"lpPoolPositions","method":"GET","path":"/v1/lp/pools/{pool}/positions","tag":"Liquidity","summary":"Open positions in a pool","description":"Managed positions (V3 NPM / V4 PositionManager NFTs) open in the pool, largest first, valued live.","url":"https://getchord.xyz/docs/api-reference/operations/lppoolpositions/","parameters":[{"name":"pool","in":"path","required":true,"type":"string","description":""},{"name":"chain","in":"query","required":true,"type":"integer","enum":[5042,4663,143],"description":"Chain id: `5042` Arc · `4663` Robinhood Chain · `143` Monad."},{"name":"limit","in":"query","required":false,"type":"integer","default":20,"description":""}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …)."},"response":{"schema":{"chain":"integer","pool":"string — A pool: a 20-byte contract address (V2 / V3) or a 32-byte Uniswap V4 pool id.","positions":[{"manager":"string — EVM address, hex, case-insensitive.","tokenId":"string","pool":"string|null — A pool: a 20-byte contract address (V2 / V3) or a 32-byte Uniswap V4 pool id.","dex":"string|null","kind":"string (v3|v4)","owner":"string|null — EVM address, hex, case-insensitive.","token":"string|null — EVM address, hex, case-insensitive.","anchor":"string|null — EVM address, hex, case-insensitive.","tickLower":"integer|null","tickUpper":"integer|null","symbol":"string|null","anchorSymbol":"string|null","logo":"string|null","inUsd":"number — Dollars added.","outUsd":"number — Dollars removed.","feesUsd":"number — Fees collected.","adds":"integer","removes":"integer","collects":"integer","openedTs":"integer|null — Unix time, seconds, UTC.","lastTs":"integer — Unix time, seconds, UTC.","closedTs":"integer|null — Unix time, seconds, UTC.","burned":"boolean","status":"string (open|closed)","valueUsd":"number|null — Live value of the liquidity (open positions).","uncollectedUsd":"number|null — Uncollected fees (V3).","inRange":"boolean|null","pnlUsd":"number|null — Liquidity leg only.","pnlPct":"number|null","ageHours":"number|null","edgePct":"number|null — Distance from the price to the nearest range edge, percent.","jit":"boolean — Opened and closed within seconds — a swap trick, shown but not scored.","unreconciled":"boolean — Dollars out exceed dollars in by far — the tape missed an add; shown, never scored."}],"updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":{"chain":5042,"pool":"0xf53f02d9041d00bbd92235b4c902b9f350c554a8ed2dc64fa0a4585aac413f09","positions":[{"manager":"0x6049c9a0e26405c0985f9e3685c87d0ae917f82b","tokenId":"187740","pool":"0xf53f02d9041d00bbd92235b4c902b9f350c554a8ed2dc64fa0a4585aac413f09","dex":"uniswap_v4","kind":"v4","owner":"0x25cacb704ed0852428e7cc0687bca45ee8c21848","token":"0x8faae5592b9acc27a79fca745c6b872adf514a5d","anchor":"0x3600000000000000000000000000000000000000","tickLower":331254,"tickUpper":375408,"symbol":"MURMUR","anchorSymbol":"USDC","logo":"https://cdn.dexscreener.com/cms/images/QUq-IqT1GLQNkxMx?width=800&height=800&quality=95&format=auto","inUsd":5763.889211498252,"outUsd":0,"feesUsd":0,"adds":1,"removes":0,"collects":0,"openedTs":1789695461,"lastTs":1789695461,"closedTs":null,"burned":false,"status":"open","valueUsd":5408.735694717618,"uncollectedUsd":2141.275199916123,"inRange":true,"edgePct":427.51,"pnlUsd":1786.1216831354886,"pnlPct":30.988133491053144,"ageHours":54.55777777777778,"jit":false,"unreconciled":false},{"manager":"0x6049c9a0e26405c0985f9e3685c87d0ae917f82b","tokenId":"223792","pool":"0xf53f02d9041d00bbd92235b4c902b9f350c554a8ed2dc64fa0a4585aac413f09","dex":"uniswap_v4","kind":"v4","owner":"0x2e41ff7889197ceab7ca505fe08fb54a9da07ab8","token":"0x8faae5592b9acc27a79fca745c6b872adf514a5d","anchor":"0x3600000000000000000000000000000000000000","tickLower":336204,"tickUpper":357291,"symbol":"MURMUR","anchorSymbol":"USDC","logo":"https://cdn.dexscreener.com/cms/images/QUq-IqT1GLQNkxMx?width=800&height=800&quality=95&format=auto","inUsd":797.4331141591955,"outUsd":0,"feesUsd":0,"adds":1,"removes":0,"collects":0,"openedTs":1789888226,"lastTs":1789888226,"closedTs":null,"burned":false,"status":"open","valueUsd":752.4410624979616,"uncollectedUsd":5.447723353719422,"inRange":true,"edgePct":156.14,"pnlUsd":-39.544328307514434,"pnlPct":-4.958952369216512,"ageHours":1.0119444444444445,"jit":false,"unreconciled":false}],"updatedAt":1789891870022}},"security":null},{"kind":"operation","operationId":"lpPoolLps","method":"GET","path":"/v1/lp/pools/{pool}/lps","tag":"Liquidity","summary":"A pool's providers by profit","description":"The wallets that provided to one pool, most profitable first. Profit is the wallet board's: value out + fees − value in on closed positions, plus the fees of open ones. Scored like the board: positions of `minIn` dollars or more, none that opened and closed inside a minute, none the tape could not reconcile. `total` counts the wallets with a scored position in the pool.\n\n**Use it for**: \"who earns in this pool\", a provider table on a pool page.","url":"https://getchord.xyz/docs/api-reference/operations/lppoollps/","parameters":[{"name":"pool","in":"path","required":true,"type":"string","description":""},{"name":"chain","in":"query","required":true,"type":"integer","enum":[5042,4663,143],"description":"Chain id: `5042` Arc · `4663` Robinhood Chain · `143` Monad."},{"name":"limit","in":"query","required":false,"type":"integer","default":20,"description":"Out of range is `400 BAD_LIMIT`."}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …)."},"response":{"schema":{"chain":"integer","pool":"string — A pool: a 20-byte contract address (V2 / V3) or a 32-byte Uniswap V4 pool id.","minIn":"number — Dollars in under this are not scored.","total":"integer — Wallets with a scored position in the pool.","rows":[{"wallet":"string — EVM address, hex, case-insensitive.","positions":"integer","open":"integer","closed":"integer","wins":"integer","winRatePct":"number|null — Null with no closed position.","profitUsd":"number","feesUsd":"number","inUsd":"number — Dollars the wallet put into the pool, summed over its positions.","avgAgeHours":"number|null","lastTs":"integer — Unix time, seconds, UTC."}],"updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":{"chain":5042,"pool":"0xf53f02d9041d00bbd92235b4c902b9f350c554a8ed2dc64fa0a4585aac413f09","minIn":20,"total":60,"rows":[{"wallet":"0x5db28691cbfc2ceeca1d919f0749b64013c25432","positions":2,"open":0,"closed":2,"wins":1,"winRatePct":50,"profitUsd":898.4072651256388,"feesUsd":1473.5195824012221,"inUsd":4971.427097120565,"avgAgeHours":85.54625,"lastTs":1790521219},{"wallet":"0x2e41ff7889197ceab7ca505fe08fb54a9da07ab8","positions":2,"open":0,"closed":2,"wins":2,"winRatePct":100,"profitUsd":602.4129568209053,"feesUsd":431.0974968623506,"inUsd":1101.9782460581446,"avgAgeHours":66.98930555555556,"lastTs":1790168420}],"updatedAt":1791831160142}},"security":null},{"kind":"operation","operationId":"lpWallet","method":"GET","path":"/v1/lp/wallet/{address}","tag":"Liquidity","summary":"One wallet's LP record","description":"Everything the wallet board knows about one wallet, whether it is ranked or not: win rate, fees, profit, expected value per position, average invested / age / monthly profit and the 7-day / 30-day / all-time windows (`summary`); one row per UTC day with the profit and the fees that landed on it (`history`: a closed position's result on the day it ended, an open position's fees on the days they were paid; `realizedPositions` = the positions that ended that day, `positions` adds the open ones last touched on it); the pools it provided to (`pools`, up to 60, by number of positions).\n\nThe figures use the board's row rules, so a wallet opened from `/lp/leaderboard` shows the same numbers: `unscored` says how many ledger positions were left out and why (each under the first reason that fits), and `ledger` counts every position, scored or not. `operator: true` = 500 or more scored positions, an account the board does not rank. `truncated: true` = the wallet holds more than 20,000 positions and the figures cover the newest 20,000.\n\n**Use it for**: a wallet page, \"is this LP worth following\", a PnL calendar.","url":"https://getchord.xyz/docs/api-reference/operations/lpwallet/","parameters":[{"name":"address","in":"path","required":true,"type":"string","description":"Not a 0x address is `400 BAD_WALLET`."},{"name":"chain","in":"query","required":true,"type":"integer","enum":[5042,4663,143],"description":"Chain id: `5042` Arc · `4663` Robinhood Chain · `143` Monad."},{"name":"unit","in":"query","required":false,"type":"string","enum":["usd","native"],"default":"usd","description":"`native` = every money field of the answer in the chain's own coin (ETH on Robinhood Chain, MON on Monad; Arc's coin is USDC), each deposit, withdrawal and fee converted at the coin's price of its own hour, and live values at the price now. The fields keep their `…Usd` names; `unit` and `unitSymbol` in the answer say what they carry. The row rules (the $20 floor, the 20x bound) stay in dollars, so both units score the same positions. `503 UNIT_NOT_READY` while a chain's ledger is being rebuilt with these figures; another value is `400 BAD_UNIT`."}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …)."},"response":{"schema":{"chain":"integer","wallet":"string — EVM address, hex, case-insensitive.","unit":"string (usd|native) — `usd` or `native`: the unit of every money field in this answer.","unitSymbol":"string — `USD`, or the chain's coin (`ETH`, `MON`, `USDC`).","summary":{"positions":"integer — Scored positions.","open":"integer","closed":"integer","wins":"integer","winRatePct":"number|null","pools":"integer","feesUsd":"number","profitUsd":"number","evUsd":"number|null — Expected value per position.","avgAgeHours":"number|null","avgInvestedUsd":"number|null","avgMonthlyProfitUsd":"number|null — Profit to date over the months since the first position, never less than one week.","windows":{"d7":"object","d30":"object","all":"object"},"firstTs":"integer|null — Unix time, seconds, UTC.","lastTs":"integer|null — Unix time, seconds, UTC."},"history":[{"day":"string — YYYY-MM-DD, UTC","profitUsd":"number","feesUsd":"number","positions":"integer — Positions that ended (or, open, were last touched) on the day."}],"pools":[{"pool":"string — A pool: a 20-byte contract address (V2 / V3) or a 32-byte Uniswap V4 pool id.","token":"string|null — EVM address, hex, case-insensitive.","anchor":"string|null — EVM address, hex, case-insensitive.","positions":"integer","open":"integer","inUsd":"number","profitUsd":"number","feesUsd":"number","symbol":"string|null","anchorSymbol":"string|null","logo":"string|null"}],"ledger":{"positions":"integer","open":"integer","closed":"integer"},"unscored":{"small":"integer — Under `minIn` dollars.","jit":"integer — Opened and closed inside a minute.","unreconciled":"integer — Far more dollars out than the index saw go in.","partial":"integer — Opened before the index started.","unlistedPool":"integer — On a pool the pool list hides as thin or suspect."},"minIn":"number","truncated":"boolean","operator":"boolean","updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":{"chain":5042,"wallet":"0x5db28691cbfc2ceeca1d919f0749b64013c25432","summary":{"positions":2,"open":0,"closed":2,"wins":1,"winRatePct":50,"pools":1,"feesUsd":1473.5195824012221,"profitUsd":898.4072651256388,"evUsd":449.2036325628194,"avgAgeHours":85.54625,"avgInvestedUsd":2485.7135485602826,"avgMonthlyProfitUsd":1220.1586855458952,"windows":{"d7":{"positions":0,"profitUsd":0,"feesUsd":0},"d30":{"positions":2,"profitUsd":898.4072651256388,"feesUsd":1473.5195824012221},"all":{"positions":2,"profitUsd":898.4072651256388,"feesUsd":1473.5195824012221}},"firstTs":1789922677,"lastTs":1790521219},"history":[{"day":"2026-09-22","profitUsd":1767.3683024312918,"feesUsd":556.5679612124811,"positions":1},{"day":"2026-09-27","profitUsd":-868.961037305653,"feesUsd":916.9516211887411,"positions":1}],"pools":[{"pool":"0xf53f02d9041d00bbd92235b4c902b9f350c554a8ed2dc64fa0a4585aac413f09","token":"0x8faae5592b9acc27a79fca745c6b872adf514a5d","anchor":"0x3600000000000000000000000000000000000000","positions":2,"open":0,"inUsd":4971.427097120565,"profitUsd":898.4072651256388,"feesUsd":1473.5195824012221,"symbol":"MURMUR","anchorSymbol":"USDC","logo":"https://cdn.dexscreener.com/cms/images/QUq-IqT1GLQNkxMx?width=800&height=800&quality=95&format=auto"}],"ledger":{"positions":2,"open":0,"closed":2},"unscored":{"small":0,"jit":0,"unreconciled":0,"partial":0,"unlistedPool":0,"cluster":0},"minIn":20,"truncated":false,"operator":false,"updatedAt":1791831176348}},"security":null},{"kind":"operation","operationId":"lpPositions","method":"GET","path":"/v1/lp/positions","tag":"Liquidity","summary":"A wallet's positions","description":"Every managed position a wallet holds or held: dollars in and out, fees collected, live value and uncollected fees (V3), in-range, PnL on the liquidity leg, age, and the JIT / unreconciled flags; with a summary (open, closed, wins, realized PnL, fees, open value).","url":"https://getchord.xyz/docs/api-reference/operations/lppositions/","parameters":[{"name":"chain","in":"query","required":true,"type":"integer","enum":[5042,4663,143],"description":"Chain id: `5042` Arc · `4663` Robinhood Chain · `143` Monad."},{"name":"unit","in":"query","required":false,"type":"string","enum":["usd","native"],"default":"usd","description":"`native` = every money field of the answer in the chain's own coin (ETH on Robinhood Chain, MON on Monad; Arc's coin is USDC), each deposit, withdrawal and fee converted at the coin's price of its own hour, and live values at the price now. The fields keep their `…Usd` names; `unit` and `unitSymbol` in the answer say what they carry. The row rules (the $20 floor, the 20x bound) stay in dollars, so both units score the same positions. `503 UNIT_NOT_READY` while a chain's ledger is being rebuilt with these figures; another value is `400 BAD_UNIT`."},{"name":"owner","in":"query","required":true,"type":"string","description":""},{"name":"status","in":"query","required":false,"type":"string","enum":["open","closed","all"],"default":"all","description":""},{"name":"token","in":"query","required":false,"type":"string","description":"Only positions holding this token."},{"name":"pool","in":"query","required":false,"type":"string","description":"Only positions in this pool."},{"name":"limit","in":"query","required":false,"type":"integer","default":100,"description":""},{"name":"offset","in":"query","required":false,"type":"integer","default":0,"description":"Rows to skip, newest first: page through a wallet's closed positions. Out of range is `400 BAD_OFFSET`."}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …)."},"response":{"schema":{"chain":"integer","owner":"string — EVM address, hex, case-insensitive.","status":"string","positions":[{"manager":"string — EVM address, hex, case-insensitive.","tokenId":"string","pool":"string|null — A pool: a 20-byte contract address (V2 / V3) or a 32-byte Uniswap V4 pool id.","dex":"string|null","kind":"string (v3|v4)","owner":"string|null — EVM address, hex, case-insensitive.","token":"string|null — EVM address, hex, case-insensitive.","anchor":"string|null — EVM address, hex, case-insensitive.","tickLower":"integer|null","tickUpper":"integer|null","symbol":"string|null","anchorSymbol":"string|null","logo":"string|null","inUsd":"number — Dollars added.","outUsd":"number — Dollars removed.","feesUsd":"number — Fees collected.","adds":"integer","removes":"integer","collects":"integer","openedTs":"integer|null — Unix time, seconds, UTC.","lastTs":"integer — Unix time, seconds, UTC.","closedTs":"integer|null — Unix time, seconds, UTC.","burned":"boolean","status":"string (open|closed)","valueUsd":"number|null — Live value of the liquidity (open positions).","uncollectedUsd":"number|null — Uncollected fees (V3).","inRange":"boolean|null","pnlUsd":"number|null — Liquidity leg only.","pnlPct":"number|null","ageHours":"number|null","edgePct":"number|null — Distance from the price to the nearest range edge, percent.","jit":"boolean — Opened and closed within seconds — a swap trick, shown but not scored.","unreconciled":"boolean — Dollars out exceed dollars in by far — the tape missed an add; shown, never scored."}],"summary":{"open":"integer","closed":"integer","wins":"integer","winRatePct":"number|null","realizedPnlUsd":"number","feesUsd":"number","openValueUsd":"number"},"updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":{"chain":5042,"owner":"0xb145400da27a2497d9fc2cd5621f2bfd37617af4","status":"all","positions":[],"summary":{"open":0,"closed":0,"wins":0,"winRatePct":null,"realizedPnlUsd":0,"feesUsd":0,"openValueUsd":0},"updatedAt":1789891871406}},"security":null},{"kind":"operation","operationId":"lpPosition","method":"GET","path":"/v1/lp/position/{chain}/{manager}/{id}","tag":"Liquidity","summary":"One position","description":"A position by its NFT: the valued row, its events, and a hold-instead comparison (what the same tokens would be worth unpooled). `native` carries the same position in the chain's own coin (`nativeSymbol`): what went in, came out and was paid as fees, each event converted at the coin's price of its own hour, and the value and waiting fees at the coin's price now. It is null while the chain's ledger has no figures in its coin.","url":"https://getchord.xyz/docs/api-reference/operations/lpposition/","parameters":[{"name":"chain","in":"path","required":true,"type":"integer","enum":[5042,4663,143],"description":""},{"name":"manager","in":"path","required":true,"type":"string","description":"Position manager contract."},{"name":"id","in":"path","required":true,"type":"string","description":"Token id."}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","404":"Nothing at this identity (`NOT_FOUND`, `UNKNOWN_TOKEN`, `NO_ROUTE`)."},"response":{"schema":{"chain":"integer","position":{"manager":"string — EVM address, hex, case-insensitive.","tokenId":"string","pool":"string|null — A pool: a 20-byte contract address (V2 / V3) or a 32-byte Uniswap V4 pool id.","dex":"string|null","kind":"string (v3|v4)","owner":"string|null — EVM address, hex, case-insensitive.","token":"string|null — EVM address, hex, case-insensitive.","anchor":"string|null — EVM address, hex, case-insensitive.","tickLower":"integer|null","tickUpper":"integer|null","symbol":"string|null","anchorSymbol":"string|null","logo":"string|null","inUsd":"number — Dollars added.","outUsd":"number — Dollars removed.","feesUsd":"number — Fees collected.","adds":"integer","removes":"integer","collects":"integer","openedTs":"integer|null — Unix time, seconds, UTC.","lastTs":"integer — Unix time, seconds, UTC.","closedTs":"integer|null — Unix time, seconds, UTC.","burned":"boolean","status":"string (open|closed)","valueUsd":"number|null — Live value of the liquidity (open positions).","uncollectedUsd":"number|null — Uncollected fees (V3).","inRange":"boolean|null","pnlUsd":"number|null — Liquidity leg only.","pnlPct":"number|null","ageHours":"number|null","edgePct":"number|null — Distance from the price to the nearest range edge, percent.","jit":"boolean — Opened and closed within seconds — a swap trick, shown but not scored.","unreconciled":"boolean — Dollars out exceed dollars in by far — the tape missed an add; shown, never scored."},"events":[{"kind":"string","usd":"number","feeUsd":"number","tokenAmt":"number","anchorAmt":"number","tx":"string — Transaction hash.","ts":"integer — Unix time, seconds, UTC.","block":"integer"}],"hold":{"tokenIn":"number","anchorIn":"number","priceNowUsd":"number|null","holdValueUsd":"number|null","lpValueUsd":"number|null","lpVsHoldUsd":"number|null","basis":"string"},"native":{"in":"number — In, in the coin.","out":"number — Out, in the coin.","fees":"number — Fees paid out, in the coin.","value":"number|null — Value now at the coin's price now; null for a closed position.","uncollected":"number|null — Fees waiting, at the coin's price now.","pnl":"number|null — Closed: out + fees − in. Open: value + waiting + out + fees − in.","pnlPct":"number|null — `pnl` in percent of `in`."},"nativeSymbol":"string|null — The chain's coin (`ETH`, `MON`, `USDC`); null with `native`.","updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":null},"security":null},{"kind":"operation","operationId":"lpLeaderboard","method":"GET","path":"/v1/lp/leaderboard","tag":"Liquidity","summary":"Best liquidity providers","description":"LP wallets from the ledger: win rate, fees, pools, expected value per position, average age / invested / monthly profit, profit over 7 / 30 days / all time, the last seven days of profit and what they provide to. Every filter bound is inclusive; unset = off.\n\nThe board is **fee-checked**: a wallet whose profit is positive while the fees it collected are under a tenth of that profit made it on the token's price (liquidity on a launch pulled into the buyers), not by providing, and is left out; `hidden` counts them and `all=1` keeps them in. The check reads the window the board ranks by (`profit_7d` → 7 days, `profit_30d` → 30 days, every other sort → all time). Every sort ranks inside the 400 most profitable wallets of its window that pass the filters; `total` is that count. A window sort lists only wallets with a position that ended or was touched in the window.","url":"https://getchord.xyz/docs/api-reference/operations/lpleaderboard/","parameters":[{"name":"chain","in":"query","required":true,"type":"integer","enum":[5042,4663,143],"description":"Chain id: `5042` Arc · `4663` Robinhood Chain · `143` Monad."},{"name":"unit","in":"query","required":false,"type":"string","enum":["usd","native"],"default":"usd","description":"`native` = every money field of the answer in the chain's own coin (ETH on Robinhood Chain, MON on Monad; Arc's coin is USDC), each deposit, withdrawal and fee converted at the coin's price of its own hour, and live values at the price now. The fields keep their `…Usd` names; `unit` and `unitSymbol` in the answer say what they carry. The row rules (the $20 floor, the 20x bound) stay in dollars, so both units score the same positions. `503 UNIT_NOT_READY` while a chain's ledger is being rebuilt with these figures; another value is `400 BAD_UNIT`."},{"name":"sort","in":"query","required":false,"type":"string","enum":["profit","profit_7d","profit_30d","win_rate","avg_age","positions","pools","ev","avg_invested","monthly_profit","fees","last_activity"],"default":"profit","description":"`profit` = all time. An unknown value is `400 BAD_SORT`."},{"name":"limit","in":"query","required":false,"type":"integer","default":48,"description":""},{"name":"all","in":"query","required":false,"type":"string","enum":["0","1"],"description":"1 = keep the wallets the fee check leaves out."},{"name":"minIn","in":"query","required":false,"type":"number","default":20,"description":"Ignore positions under this many dollars."},{"name":"minPositions","in":"query","required":false,"type":"integer","description":""},{"name":"minAgeHours","in":"query","required":false,"type":"number","description":""},{"name":"minWinRate","in":"query","required":false,"type":"number","description":"Percent."},{"name":"minEv","in":"query","required":false,"type":"number","description":""},{"name":"minProfit","in":"query","required":false,"type":"number","description":""},{"name":"minMonthly","in":"query","required":false,"type":"number","description":""},{"name":"maxFirstTs","in":"query","required":false,"type":"integer","description":"Only wallets active before this time."},{"name":"lastActiveDays","in":"query","required":false,"type":"number","description":""},{"name":"minFees","in":"query","required":false,"type":"number","description":"Fees collected, all time."}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …)."},"response":{"schema":{"chain":"integer","sort":"string","minIn":"number","filters":"object","feeCheck":"boolean — The fee check was applied.","hidden":"integer — Wallets passing the filters that the fee check left out.","total":"integer — Wallets the board ranks.","rows":[{"wallet":"string — EVM address, hex, case-insensitive.","winRatePct":"number|null","feesUsd":"number","pools":"integer","evUsd":"number|null — Expected value per position.","avgAgeHours":"number|null","avgInvestedUsd":"number|null","avgMonthlyProfitUsd":"number|null","windows":"object","open":"integer","closed":"integer","wins":"integer","firstTs":"integer|null — Unix time, seconds, UTC.","lastTs":"integer — Unix time, seconds, UTC.","daily":"array","tokens":"array"}],"updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":{"chain":5042,"sort":"profit","minIn":20,"filters":{},"rows":[{"wallet":"0x50550bf5c09b38e5c574c190cef88b859694a44a","winRatePct":75,"feesUsd":13516.447234,"pools":5,"evUsd":55.95264399437404,"avgAgeHours":53.940039682539684,"avgInvestedUsd":8802.035202296884,"avgMonthlyProfitUsd":54574.16597590998,"windows":{"d7":{"positions":7,"profitUsd":13643.541493977495},"d30":{"positions":7,"profitUsd":13643.541493977495},"all":{"positions":7,"profitUsd":13643.541493977495}},"open":3,"closed":4,"wins":3,"firstTs":1789524227,"lastTs":1789695131,"daily":[{"day":"2026-09-14","profitUsd":0},{"day":"2026-09-15","profitUsd":0}],"tokens":[{"address":"0xbc43ce8dec648ea298c4275559b81d6261c90b67","symbol":"TOLLY","logo":"https://cdn.dexscreener.com/cms/images/LquZIzWeLJoeUE4x?width=800&height=800&quality=95&format=auto","inUsd":56621.88931640096,"positions":4},{"address":"0xa163d7624da3b5d9182c50eab5b8cd247ae861bb","symbol":"Minara","logo":"https://static.minara.ai/minara-fun/token-logos/1a464bd3cbb6e0db661556f18b784344754785730da3bf9752e383e7e5a2605a.png","inUsd":13303.485575872332,"positions":1}]},{"wallet":"0x4705173e07dc8acde8a826a96883848d0a4bb2cf","winRatePct":null,"feesUsd":12121.658648,"pools":1,"evUsd":null,"avgAgeHours":50.736111111111114,"avgInvestedUsd":1585.3021168837654,"avgMonthlyProfitUsd":48486.634592,"windows":{"d7":{"positions":5,"profitUsd":12121.658648},"d30":{"positions":5,"profitUsd":12121.658648},"all":{"positions":5,"profitUsd":12121.658648}},"open":5,"closed":0,"wins":0,"firstTs":1789644774,"lastTs":1789742574,"daily":[{"day":"2026-09-14","profitUsd":0},{"day":"2026-09-15","profitUsd":0}],"tokens":[{"address":"0x2ba0f44bdfc17fba30eda9cdbecb908ca45b043b","symbol":"CRCL","logo":"https://cdn.dexscreener.com/cms/images/Y-swLma-R46hqFvc?width=800&height=800&quality=95&format=auto","inUsd":7926.5105844188265,"positions":5}]}],"updatedAt":1789891861738}},"security":null},{"kind":"operation","operationId":"lpEvents","method":"GET","path":"/v1/lp/events","tag":"Liquidity","summary":"Liquidity events","description":"Adds, removes and fee collects on one token, wallet or pool, newest first, each valued in dollars where the pool has an anchor side. One of `token`, `wallet` or `pool` is required.","url":"https://getchord.xyz/docs/api-reference/operations/lpevents/","parameters":[{"name":"chain","in":"query","required":true,"type":"integer","enum":[5042,4663,143],"description":"Chain id: `5042` Arc · `4663` Robinhood Chain · `143` Monad."},{"name":"token","in":"query","required":false,"type":"string","description":""},{"name":"wallet","in":"query","required":false,"type":"string","description":""},{"name":"pool","in":"query","required":false,"type":"string","description":""},{"name":"kind","in":"query","required":false,"type":"string","enum":["add","remove","collect"],"description":""},{"name":"minUsd","in":"query","required":false,"type":"number","description":""},{"name":"limit","in":"query","required":false,"type":"integer","default":40,"description":""},{"name":"offset","in":"query","required":false,"type":"integer","default":0,"description":""}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …)."},"response":{"schema":{"chain":"integer","events":[{"tx":"string — Transaction hash.","logIndex":"integer","pool":"string — A pool: a 20-byte contract address (V2 / V3) or a 32-byte Uniswap V4 pool id.","dex":"string","kind":"string (add|remove|collect)","wallet":"string|null — EVM address, hex, case-insensitive.","token":"string — EVM address, hex, case-insensitive.","tokenAmt":"number","anchor":"string — EVM address, hex, case-insensitive.","anchorAmt":"number","usd":"number — Dollars that entered or left the pool.","priced":"boolean — False when the event could not be valued (no anchor side).","tickLower":"integer|null","tickUpper":"integer|null","block":"integer","ts":"integer — Unix time, seconds, UTC.","manager":"string|null — EVM address, hex, case-insensitive.","tokenId":"string|null — Position NFT id, for managed positions."}],"limit":"integer","offset":"integer","updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":{"chain":5042,"events":[{"tx":"0x74acfa695f6ea11770a2356a49b750c9c5e0685a8ee106ebfae67ccd049d4ba6","logIndex":20,"pool":"0xf53f02d9041d00bbd92235b4c902b9f350c554a8ed2dc64fa0a4585aac413f09","dex":"uniswap_v4","kind":"remove","wallet":"0xc85d3ed2dfa128888e658e3a947f24bfa96db654","token":"0x8faae5592b9acc27a79fca745c6b872adf514a5d","tokenAmt":0,"anchor":"0x3600000000000000000000000000000000000000","anchorAmt":90.769723,"usd":90.769723,"priced":true,"tickLower":352440,"tickUpper":354519,"block":21802531,"ts":1789888952},{"tx":"0x74acfa695f6ea11770a2356a49b750c9c5e0685a8ee106ebfae67ccd049d4ba6","logIndex":18,"pool":"0xf53f02d9041d00bbd92235b4c902b9f350c554a8ed2dc64fa0a4585aac413f09","dex":"uniswap_v4","kind":"remove","wallet":"0xc85d3ed2dfa128888e658e3a947f24bfa96db654","token":"0x8faae5592b9acc27a79fca745c6b872adf514a5d","tokenAmt":0,"anchor":"0x3600000000000000000000000000000000000000","anchorAmt":72.615778,"usd":72.615778,"priced":true,"tickLower":350361,"tickUpper":352440,"block":21802531,"ts":1789888952}],"limit":2,"offset":0,"updatedAt":1789891870679}},"security":null},{"kind":"operation","operationId":"lpToken","method":"GET","path":"/v1/lp/token/{address}","tag":"Liquidity","summary":"Liquidity flow for a token","description":"Adds, removes and net dollars over the window, one-sided (token-only) events counted but not valued, just-in-time liquidity (same-transaction add and remove) called out so the totals read right, the top providers and the pools by net flow.","url":"https://getchord.xyz/docs/api-reference/operations/lptoken/","parameters":[{"name":"address","in":"path","required":true,"type":"string","description":""},{"name":"chain","in":"query","required":true,"type":"integer","enum":[5042,4663,143],"description":"Chain id: `5042` Arc · `4663` Robinhood Chain · `143` Monad."},{"name":"hours","in":"query","required":false,"type":"integer","default":24,"description":""}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …)."},"response":{"schema":{"chain":"integer","token":"string — EVM address, hex, case-insensitive.","hours":"integer","adds":"integer","addUsd":"number","removes":"integer","removeUsd":"number","netUsd":"number","tokenOnlyAdds":"integer","tokenOnlyRemoves":"integer","jitTxs":"integer","jitUsd":"number","providers":"integer","top":[{"wallet":"string — EVM address, hex, case-insensitive.","netUsd":"number","addedUsd":"number","removedUsd":"number","events":"integer","lastTs":"integer — Unix time, seconds, UTC."}],"pools":[{"pool":"string — A pool: a 20-byte contract address (V2 / V3) or a 32-byte Uniswap V4 pool id.","dex":"string","netUsd":"number","events":"integer"}],"updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":{"chain":5042,"token":"0x171a4217b86a807a64eb94757db6849fb4bdbaa0","hours":24,"adds":200,"addUsd":274228.1437317083,"removes":176,"removeUsd":2291418.4063887238,"netUsd":-2017190.2626570156,"tokenOnlyAdds":5,"tokenOnlyRemoves":30,"jitTxs":18,"jitUsd":39153.40135616365,"providers":51,"top":[{"wallet":"0xa77401a1640e4f090fd5d08b7350b59d6a99b0fd","netUsd":-2064877.6495731266,"addedUsd":0,"removedUsd":2063818.8216671266,"events":2,"lastTs":1789845091},{"wallet":"0x08d0d1d9d58675fea6e36670d85a9e8dad89f465","netUsd":21439.05777238525,"addedUsd":21439.05777238525,"removedUsd":0,"events":1,"lastTs":1789817213}],"pools":[{"pool":"0x82916bee18fcef517b26c72d7cb5f13694e1db41","dex":"uniswap_v3","netUsd":-2065710.8817895816,"events":88},{"pool":"0xd945caee4635bcd7fb8a9fa74dc1d0c4c1472782","dex":"slipstream_fork","netUsd":44581.441725988414,"events":282}],"updatedAt":1789891863259}},"security":null},{"kind":"operation","operationId":"lpTokenPools","method":"GET","path":"/v1/lp/token/{address}/pools","tag":"Liquidity","summary":"A token's pools by health","description":"The token's pools ranked by the 0–100 health score with the reasons behind it, and launch facts on Arc (launcher, its share of the liquidity, when it last pulled).","url":"https://getchord.xyz/docs/api-reference/operations/lptokenpools/","parameters":[{"name":"address","in":"path","required":true,"type":"string","description":""},{"name":"chain","in":"query","required":true,"type":"integer","enum":[5042,4663,143],"description":"Chain id: `5042` Arc · `4663` Robinhood Chain · `143` Monad."}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …)."},"response":{"schema":{"chain":"integer","token":"string — EVM address, hex, case-insensitive.","pools":[{"pool":"string — A pool: a 20-byte contract address (V2 / V3) or a 32-byte Uniswap V4 pool id.","dex":"string","kind":"string","feeBps":"number|null","tvlUsd":"number|null","vol24h":"number","aprPct":"number|null","score":"integer","reasons":"array","launch":"object|null — Launch facts (see /lp/pools/{pool})."}],"updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":{"chain":5042,"token":"0x171a4217b86a807a64eb94757db6849fb4bdbaa0","pools":[{"pool":"0xd945caee4635bcd7fb8a9fa74dc1d0c4c1472782","dex":"slipstream_fork","kind":"clmm","feeBps":6,"tvlUsd":570213.05,"vol24h":772749.320668,"aprPct":29.678749237025,"score":75,"reasons":[],"launch":null},{"pool":"0xc955cbfb9d03cde6f78901a81740264f895b9c00025beb9115cf2d7b86b3ee5a","dex":"uniswap_v4","kind":"v4","feeBps":30,"tvlUsd":14896.68,"vol24h":13956.785425999999,"aprPct":102.59118166913699,"score":47,"reasons":["the launcher holds 100% of the liquidity added"],"launch":{"launcher":"0x6049c9a0e26405c0985f9e3685c87d0ae917f82b","launcherName":"Uniswap Liquidity Launcher","creator":"0x8007221ab6bdb20496eb74d038cbc5d590d1bea9","hooks":null,"launchedTs":1789559316,"launcherLpAddedUsd":69592.12438223744,"totalLpAddedUsd":69592.12438223744,"launcherSharePct":100,"launcherLastRemoveTs":1789838701,"launcherRemovedUsd":51498.944581131305}}],"updatedAt":1789891866065}},"security":null},{"kind":"operation","operationId":"lpPlan","method":"GET","path":"/v1/lp/plan","tag":"Liquidity","summary":"Plan a position","description":"Range bands for a token from its own volatility (tight / balanced / wide, with the share of the last seven days each range would have stayed inside) and each profile backtested on Chord's candles against holding — fees, impermanent loss, exits, time in range. Needs at least 24 hourly candles and an anchored pool (`404 NOT_ENOUGH_HISTORY` otherwise). `young: true` means under two days of candles — the bands are a launch's noise.","url":"https://getchord.xyz/docs/api-reference/operations/lpplan/","parameters":[{"name":"chain","in":"query","required":true,"type":"integer","enum":[5042,4663,143],"description":"Chain id: `5042` Arc · `4663` Robinhood Chain · `143` Monad."},{"name":"token","in":"query","required":true,"type":"string","description":""},{"name":"amountUsd","in":"query","required":false,"type":"number","default":1000,"description":""},{"name":"days","in":"query","required":false,"type":"integer","default":7,"description":"Backtest window."},{"name":"pool","in":"query","required":false,"type":"string","description":"Pin a pool; default = the token's best anchored pool."}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","404":"Nothing at this identity (`NOT_FOUND`, `UNKNOWN_TOKEN`, `NO_ROUTE`)."},"response":{"schema":{"chain":"integer","token":"string — EVM address, hex, case-insensitive.","amountUsd":"number","days":"integer","bands":{"priceUsd":"number","hourlyVolPct":"number","dailyVolPct":"number","candles":"integer","young":"boolean","profiles":["object"],"histogram":["object"]},"sims":[{"profile":"string","lower":"number","upper":"number","sim":"object"}],"updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":{"chain":5042,"token":"0x171a4217b86a807a64eb94757db6849fb4bdbaa0","amountUsd":1000,"days":7,"bands":{"priceUsd":80418.25,"hourlyVolPct":0.44,"dailyVolPct":2.1,"candles":104,"young":false,"profiles":[{"profile":"tight","horizonHours":24,"lower":78711.94,"upper":82161.56,"widthPct":2.2,"last7dInsidePct":42},{"profile":"balanced","horizonHours":72,"lower":76059.95,"upper":85026.29,"widthPct":5.7,"last7dInsidePct":82}],"histogram":[{"lo":73301.06,"hi":73799.8,"hours":1},{"lo":73799.8,"hi":74301.94,"hours":0}]},"sims":[{"profile":"tight","lower":78711.94,"upper":82161.56,"sim":{"pool":"0x82916bee18fcef517b26c72d7cb5f13694e1db41","dex":"uniswap_v3","feeBps":1,"tvlUsd":11239238.75,"days":7,"hours":104,"hoursInRange":1,"inRangePct":1,"exits":1,"lower":71745.77,"upper":74890.09,"unreliable":null,"entryPrice":73301.06,"exitPrice":80418.25,"priceChangePct":9.7,"feesUsd":0.01,"lpValueEndUsd":1005.39,"holdValueEndUsd":1048.55,"ilUsd":-43.16,"netVsHoldUsd":-43.15,"totalReturnUsd":5.4,"totalReturnPct":0.54,"feeAprPct":0.1,"capitalEfficiency":50,"shareOfPoolPct":0.443,"note":"Backtest on the last 7 days of Chord's own candles and this pool's hourly volume at today's TVL — what would have happened, not what will."}},{"profile":"balanced","lower":76059.95,"upper":85026.29,"sim":{"pool":"0x82916bee18fcef517b26c72d7cb5f13694e1db41","dex":"uniswap_v3","feeBps":1,"tvlUsd":11239238.75,"days":7,"hours":104,"hoursInRange":53,"inRangePct":51,"exits":1,"lower":69328.48,"upper":77501.28,"unreliable":null,"entryPrice":73301.06,"exitPrice":80418.25,"priceChangePct":9.7,"feesUsd":3.03,"lpValueEndUsd":1014.13,"holdValueEndUsd":1048.55,"ilUsd":-34.42,"netVsHoldUsd":-31.39,"totalReturnUsd":17.16,"totalReturnPct":1.72,"feeAprPct":15.8,"capitalEfficiency":36.4,"shareOfPoolPct":0.323,"note":"Backtest on the last 7 days of Chord's own candles and this pool's hourly volume at today's TVL — what would have happened, not what will."}}],"updatedAt":1789891866541}},"security":null},{"kind":"operation","operationId":"lpSimulate","method":"GET","path":"/v1/lp/simulate","tag":"Liquidity","summary":"Backtest one range","description":"One explicit price range replayed over the last `days` of candles in the token's pool: fees earned at the pool's real tier and the position's share, impermanent loss, exits, LP value versus hold.","url":"https://getchord.xyz/docs/api-reference/operations/lpsimulate/","parameters":[{"name":"chain","in":"query","required":true,"type":"integer","enum":[5042,4663,143],"description":"Chain id: `5042` Arc · `4663` Robinhood Chain · `143` Monad."},{"name":"token","in":"query","required":true,"type":"string","description":""},{"name":"lower","in":"query","required":true,"type":"number","description":"Lower price, USD."},{"name":"upper","in":"query","required":true,"type":"number","description":"Upper price, USD (> lower)."},{"name":"amountUsd","in":"query","required":false,"type":"number","default":1000,"description":""},{"name":"days","in":"query","required":false,"type":"integer","default":7,"description":""},{"name":"pool","in":"query","required":false,"type":"string","description":""}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","404":"Nothing at this identity (`NOT_FOUND`, `UNKNOWN_TOKEN`, `NO_ROUTE`)."},"response":{"schema":[{"chain":"integer","token":"string — EVM address, hex, case-insensitive.","updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},{"pool":"string — A pool: a 20-byte contract address (V2 / V3) or a 32-byte Uniswap V4 pool id.","dex":"string","feeBps":"number|null","tvlUsd":"number|null","days":"integer","hours":"integer — Candles replayed.","hoursInRange":"integer","inRangePct":"number","exits":"integer — Times the price left the range.","lower":"number","upper":"number","unreliable":"string|null — Why the number should not be trusted, when it should not.","entryPrice":"number","exitPrice":"number","priceChangePct":"number","feesUsd":"number","lpValueEndUsd":"number","holdValueEndUsd":"number","ilUsd":"number — Impermanent loss (negative = loss).","netVsHoldUsd":"number","totalReturnUsd":"number","totalReturnPct":"number","feeAprPct":"number","capitalEfficiency":"number — Versus full range.","shareOfPoolPct":"number","note":"string"}],"example":null},"security":null},{"kind":"operation","operationId":"lpWatchStatus","method":"GET","path":"/v1/lp/watch","tag":"Liquidity","summary":"Watch state and alert inbox","description":"Whether the wallet's positions are watched, how many Telegram chats receive its alerts, the alert thresholds, the last alerts, and the pools on its watchlist.","url":"https://getchord.xyz/docs/api-reference/operations/lpwatchstatus/","parameters":[{"name":"chain","in":"query","required":true,"type":"integer","enum":[5042,4663,143],"description":"Chain id: `5042` Arc · `4663` Robinhood Chain · `143` Monad."},{"name":"wallet","in":"query","required":true,"type":"string","description":""}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …)."},"response":{"schema":{"chain":"integer","wallet":"string — EVM address, hex, case-insensitive.","watched":"boolean","telegramChats":"integer","feeBarUsd":"number — Alert when uncollected fees pass this.","drainPct":"number — Alert when a pool loses this share of its liquidity.","telegramBot":"string|null — Bot username for the deep link.","alerts":[{"kind":"string","chain":"integer","wallet":"string — EVM address, hex, case-insensitive.","manager":"string — EVM address, hex, case-insensitive.","tokenId":"string","pool":"string|null — A pool: a 20-byte contract address (V2 / V3) or a 32-byte Uniswap V4 pool id.","token":"string|null — EVM address, hex, case-insensitive.","symbol":"string|null","text":"string","usd":"number|null","ts":"integer — Unix time, seconds, UTC.","href":"string|null — Where the wallet's owner acts on the alert: the position's page for a mark, the pool with the same range for a followed wallet's new position."}],"pools":["string — A pool: a 20-byte contract address (V2 / V3) or a 32-byte Uniswap V4 pool id."],"marks":"object — Take-profit / stop-loss marks by `<manager>:<tokenId>`.","following":["string — EVM address, hex, case-insensitive."],"updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":null},"security":null},{"kind":"operation","operationId":"lpWatch","method":"POST","path":"/v1/lp/watch","tag":"Liquidity","summary":"Watch a wallet's positions","description":"Turns on in-app alerts for the wallet's positions (out of range, fees to collect, pool draining) and returns a one-hour Telegram deep link that routes the same alerts to a chat.","url":"https://getchord.xyz/docs/api-reference/operations/lpwatch/","parameters":[],"requestBody":{"schema":{"chain":"integer (5042|4663|143)","wallet":"string — EVM address, hex, case-insensitive."},"example":{"chain":5042,"wallet":"0xb145400da27a2497d9fc2cd5621f2bfd37617af4"}},"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …)."},"response":{"schema":{"watched":"boolean","telegramChats":"integer","feeBarUsd":"number","drainPct":"number","code":"string","tgLink":"string|null — `https://t.me/<bot>?start=lp_<code>`, valid one hour."},"example":null},"security":null},{"kind":"operation","operationId":"lpUnwatch","method":"DELETE","path":"/v1/lp/watch","tag":"Liquidity","summary":"Stop watching a wallet","description":"","url":"https://getchord.xyz/docs/api-reference/operations/lpunwatch/","parameters":[],"requestBody":{"schema":{"chain":"integer (5042|4663|143)","wallet":"string — EVM address, hex, case-insensitive."},"example":{"chain":5042,"wallet":"0xb145400da27a2497d9fc2cd5621f2bfd37617af4"}},"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …)."},"response":{"schema":{"watched":"boolean"},"example":null},"security":null},{"kind":"operation","operationId":"lpWatchPool","method":"POST","path":"/v1/lp/watch/pool","tag":"Liquidity","summary":"Watch a pool","description":"Adds a pool to the wallet's watchlist — drain alerts without holding a position.","url":"https://getchord.xyz/docs/api-reference/operations/lpwatchpool/","parameters":[],"requestBody":{"schema":{"chain":"integer (5042|4663|143)","wallet":"string — EVM address, hex, case-insensitive.","pool":"string — A pool: a 20-byte contract address (V2 / V3) or a 32-byte Uniswap V4 pool id."},"example":{"chain":5042,"wallet":"0xb145400da27a2497d9fc2cd5621f2bfd37617af4","pool":"0xf53f02d9041d00bbd92235b4c902b9f350c554a8ed2dc64fa0a4585aac413f09"}},"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …)."},"response":{"schema":{"pools":["string — A pool: a 20-byte contract address (V2 / V3) or a 32-byte Uniswap V4 pool id."]},"example":null},"security":null},{"kind":"operation","operationId":"lpUnwatchPool","method":"DELETE","path":"/v1/lp/watch/pool","tag":"Liquidity","summary":"Stop watching a pool","description":"","url":"https://getchord.xyz/docs/api-reference/operations/lpunwatchpool/","parameters":[],"requestBody":{"schema":{"chain":"integer (5042|4663|143)","wallet":"string — EVM address, hex, case-insensitive.","pool":"string — A pool: a 20-byte contract address (V2 / V3) or a 32-byte Uniswap V4 pool id."},"example":{"chain":5042,"wallet":"0xb145400da27a2497d9fc2cd5621f2bfd37617af4","pool":"0xf53f02d9041d00bbd92235b4c902b9f350c554a8ed2dc64fa0a4585aac413f09"}},"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …)."},"response":{"schema":{"pools":["string — A pool: a 20-byte contract address (V2 / V3) or a 32-byte Uniswap V4 pool id."]},"example":null},"security":null},{"kind":"operation","operationId":"lpWatchMark","method":"POST","path":"/v1/lp/watch/mark","tag":"Liquidity","summary":"Set a take-profit / stop-loss alert on a position","description":"A mark on one open position: when its PnL (percent of the dollars that went in, live value and fees included) crosses the take-profit or the stop-loss, one alert goes to the wallet's inbox and linked Telegram chats with a link to the position, and the mark is removed. It is an alert, not an order: nothing is signed or closed for the wallet. Both values null removes the mark. The wallet is watched from then on; positions are checked every two minutes. A mark with `unit: \"native\"` waits (it never falls back to dollars) while the chain has no figures in its coin.","url":"https://getchord.xyz/docs/api-reference/operations/lpwatchmark/","parameters":[],"requestBody":{"schema":{"chain":"integer (5042|4663|143)","wallet":"string — EVM address, hex, case-insensitive.","manager":"string — EVM address, hex, case-insensitive.","tokenId":"string — The position's id on its manager, decimal.","tpPct":"number|null — Above 0, at most 10000.","slPct":"number|null — Between -100 and 0.","unit":"string (usd|native) — `native` = count the percent in the chain's own coin: what went in and what the position is worth now, both in ETH / MON (`native` of `GET /lp/position`). The coin moving against the dollar then crosses nothing. Default `usd`."},"example":{"chain":4663,"wallet":"0xb145400da27a2497d9fc2cd5621f2bfd37617af4","manager":"0x58daec3116aae6d93017baaea7749052e8a04fa7","tokenId":"2990642","tpPct":20,"slPct":-15}},"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …)."},"response":{"schema":{"chain":"integer","wallet":"string — EVM address, hex, case-insensitive.","marks":"object"},"example":null},"security":null},{"kind":"operation","operationId":"lpWatchFollow","method":"POST","path":"/v1/lp/watch/follow","tag":"Liquidity","summary":"Follow a liquidity provider","description":"Alerts for `wallet` when `target` opens or closes a position, from now on (a follow does not replay the wallet's past). An \"opened\" alert links to the same pool with the same range; nothing is copied for the wallet. At most 10 followed wallets.","url":"https://getchord.xyz/docs/api-reference/operations/lpwatchfollow/","parameters":[],"requestBody":{"schema":{"chain":"integer (5042|4663|143)","wallet":"string — EVM address, hex, case-insensitive.","target":"string — EVM address, hex, case-insensitive.","on":"boolean — false = stop following. Default true."},"example":{"chain":4663,"wallet":"0xb145400da27a2497d9fc2cd5621f2bfd37617af4","target":"0x5b0dbd62f7639bef7a1ae1c4ff9408105946a9b9","on":true}},"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …)."},"response":{"schema":{"chain":"integer","wallet":"string — EVM address, hex, case-insensitive.","following":["string — EVM address, hex, case-insensitive."]},"example":null},"security":null},{"kind":"operation","operationId":"lpStatus","method":"GET","path":"/v1/lp/status","tag":"Liquidity","summary":"Liquidity lane state","description":"Per-chain cursors, heads, last tick, pool-stat floors and position counts for the liquidity indexer — the freshness check for everything under `/lp`.","url":"https://getchord.xyz/docs/api-reference/operations/lpstatus/","parameters":[],"requestBody":null,"responses":{"200":""},"response":{"schema":"object — Lane state per chain (`lanes`, `pools`, `positions`).","example":{"enabled":true,"chains":[5042,4663],"lanes":{"143":{"cursor":106412087,"head":106412087,"chunk":4000,"rows":2,"lastTick":1789891861000,"last":{"logs":0,"rows":0,"unknownPools":0,"resolved":0,"nonAnchored":0,"noDecimals":0,"noRate":0,"noSqrt":0,"tokenOnly":0,"managed":0,"collects":0,"transfers":0},"tickStartedAt":1789891860977,"attrib":{"txs":0,"set":0,"floor":1789891861,"idle":true,"at":1789891861000},"behind":0,"running":true},"4663":{"cursor":67785681,"head":67785681,"chunk":4000,"rows":1322,"lastTick":1789891861864,"last":{"logs":115,"rows":24,"unknownPools":0,"resolved":3,"nonAnchored":44,"noDecimals":0,"noRate":0,"noSqrt":0,"tokenOnly":3,"managed":19,"collects":11,"transfers":10},"tickStartedAt":1789891861137,"attrib":{"txs":0,"set":0,"floor":1789891861,"idle":true,"at":1789891861866},"behind":0,"running":true},"5042":{"cursor":21808258,"head":21808258,"chunk":4000,"rows":77,"lastTick":1789891858995,"last":{"logs":3,"rows":2,"unknownPools":2,"resolved":0,"nonAnchored":0,"noDecimals":0,"noRate":0,"noSqrt":0,"tokenOnly":0,"managed":1,"collects":1,"transfers":2},"tickStartedAt":1789891858105,"attrib":{"txs":300,"set":0,"floor":1789538828,"idle":false,"at":1789891860035},"behind":0,"running":true}},"pools":{"143":{"floor":1789146000,"tvlRows":164,"hourlyRows":14539},"4663":{"floor":1789146000,"tvlRows":879,"hourlyRows":154120},"5042":{"floor":1789146000,"tvlRows":1816,"hourlyRows":245072}},"positions":{"143":{"cursor":"106411386:64","positions":982,"open":326},"4663":{"cursor":"67785366:7","positions":161730,"open":44557},"5042":{"cursor":"21808179:20","positions":249663,"open":195886}}}},"security":null},{"kind":"operation","operationId":"pointsRules","method":"GET","path":"/v1/points/rules","tag":"Points","summary":"Points program rules","description":"Season, current week, points per dollar, the weekly pool, the daily cap, streak multipliers, referral bonuses and the tiers — and the plain-English rules of what counts. Only swaps executed through Chord on Arc score.","url":"https://getchord.xyz/docs/api-reference/operations/pointsrules/","parameters":[],"requestBody":null,"responses":{"200":""},"response":{"schema":{"chain":"integer","season":"integer","seasonStart":"integer — Unix time, seconds, UTC.","currentWeek":"integer","weekLengthSec":"integer","pointsPerUsd":"number","minTradeUsd":"number","weekPool":"number","dayCapUsd":"number","referredBonusPct":"number","referralBonusPct":"number","streak":[{"days":"integer","multiplier":"number"}],"counts":"string","size":"string","pool":"string","tiers":[{"name":"string","topRanks":"integer|null","topPct":"number|null","note":"string"}],"provisional":"string"},"example":{"chain":5042,"season":1,"seasonStart":1789516800,"currentWeek":1,"weekLengthSec":604800,"pointsPerUsd":0.1,"minTradeUsd":1,"weekPool":1000000,"dayCapUsd":50000,"referredBonusPct":10,"referralBonusPct":10,"streak":[{"days":5,"multiplier":1.25},{"days":3,"multiplier":1.1}],"counts":"Swaps executed through Chord on Arc (chain 5042). Swaps made elsewhere on Arc, or on any other chain, do not count.","size":"The dollar size of the trade as priced by Chord's own index (one route leg, never the sum of hops).","pool":"Each week a fixed pool of points is split among traders in proportion to their weighted volume. Your points for a week settle when the week closes.","tiers":[{"name":"Challenger","topRanks":10,"topPct":null,"note":"top 10 of the season"},{"name":"Diamond","topRanks":null,"topPct":1,"note":"top 1% of scored wallets"}],"provisional":"Points are provisional until the week closes and can be voided for wash trading or self-dealing. Routers, bots and relayers are never scored."}},"security":null},{"kind":"operation","operationId":"pointsLeaderboard","method":"GET","path":"/v1/points/leaderboard","tag":"Points","summary":"Weekly or season leaderboard","description":"Wallets ranked by points for one week or the whole season, with base points, referral and streak bonuses, volume, trades, days active and tier. `503 NOT_ENABLED` while the program is off on the deployment.","url":"https://getchord.xyz/docs/api-reference/operations/pointsleaderboard/","parameters":[{"name":"scope","in":"query","required":false,"type":"string","enum":["week","season"],"default":"week","description":""},{"name":"week","in":"query","required":false,"type":"string","description":"Week number or `current`."},{"name":"limit","in":"query","required":false,"type":"integer","default":100,"description":""}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"integer","season":"integer","scope":"string","week":"integer|null","weekBounds":{"from":"integer — Unix time, seconds, UTC.","to":"integer — Unix time, seconds, UTC."},"seasonStart":"integer — Unix time, seconds, UTC.","currentWeek":"integer","weekPool":"number","rows":[{"rank":"integer","wallet":"string — EVM address, hex, case-insensitive.","points":"number","basePoints":"number","referralBonus":"number","streakBonus":"number","volumeUsd":"number","trades":"integer","daysActive":"integer","tier":"string|null","lastTradeTs":"integer — Unix time, seconds, UTC."}],"totalWallets":"integer","totalPoints":"number","totalVolumeUsd":"number","indexedToBlock":"integer|null","updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":null},"security":null},{"kind":"operation","operationId":"pointsWallet","method":"GET","path":"/v1/points/wallet/{address}","tag":"Points","summary":"One wallet's standing","description":"Season and current-week points, rank, tier and volume for a wallet.","url":"https://getchord.xyz/docs/api-reference/operations/pointswallet/","parameters":[{"name":"address","in":"path","required":true,"type":"string","description":""}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":"object — `{ chain, season, wallet, seasonStart, currentWeek, weekPool, season_: {points, basePoints, referralBonus, streakBonus, volumeUsd, trades, rank, tier, totalWallets}, week: {…} }`","example":null},"security":null},{"kind":"operation","operationId":"askStatus","method":"GET","path":"/v1/ask/status","tag":"Ask agent","summary":"Is the analyst on","description":"Whether Ask is enabled, whether guest sessions are open, and today's token budget.","url":"https://getchord.xyz/docs/api-reference/operations/askstatus/","parameters":[],"requestBody":null,"responses":{"200":""},"response":{"schema":{"enabled":"boolean","chain":"integer","guest":"boolean","privy":"boolean — The server accepts Privy sign-in (the Ask wallet)","budget":{"used":"integer","total":"integer"}},"example":{"enabled":true,"chain":5042,"guest":true,"budget":{"used":41707,"total":4000000}}},"security":null},{"kind":"operation","operationId":"ask","method":"POST","path":"/v1/ask","tag":"Ask agent","summary":"Ask the analyst","description":"Chord's analyst over the Arc index and the router — 40+ tools (trending, a token's flow, holders and risk, support and resistance, top traders on a token, a wallet's PnL and trades, largest prints, launches, depth, a bridge quote, read-only SQL over the index). Returns the answer, source links, an optional route card, tables and charts the analysis produced, and a report when one was built. It analyses: a plan (zones, tranches, an exit, the level where the idea is wrong) is written only when the question asks for one, and is illustrative, with its assumptions stated.\n\n**Layout**: `text` is the whole answer on its own. The optional fields `shape`, `parts`, `details`, `followUpKinds` and `focus` say how the chat lays it out: `parts` is the same answer in order, with the tables and charts of `viz` placed inside the text (in `text` a placed table is written out as a Markdown table), and `details` is further depth the chat folds, which `text` does not repeat. A client that ignores them loses nothing of the answer.\n\n**Auth**: a developer API key (`X-API-Key`) or a Google session bearer. Metered per key per day against the deployment's token budget; 8 questions a minute per caller.\n\n**Agents**: send `\"stream\": false` for one JSON answer (5–40 s). Without it the response is `text/event-stream` with `status` events (which tool is running), one `answer` event, then `done`.","url":"https://getchord.xyz/docs/api-reference/operations/ask/","parameters":[],"requestBody":{"schema":{"question":"string — May be empty when `images` is set.","stream":"boolean — false = one JSON response instead of SSE.","history":[{"role":"string (user|assistant)","content":"string","images":"array"}],"wallet":"string — The caller's wallet, so \"my PnL\" resolves.","mode":"string (quick|deep) — How long an answer to write. `quick`: the shortest form (the verdict, its claim, at most three rows of evidence, 120 words at most), faster. `deep`: a judgement or an explanation comes back as a full research note (`shape: \"report\"`), any other answer with a longer folded `details`. Omitted: the length the question calls for. Any other value is ignored.","images":["string"]},"example":{"question":"What is moving on Arc right now, and is ARGUS still being bought by real wallets?","stream":false}},"responses":{"200":"With `stream: false`: the whole answer. Otherwise `text/event-stream`.","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","401":"Missing or unknown credential (`UNAUTHORIZED`).","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"text":"string — The answer, Markdown, complete on its own: a table the answer placed is written out in it (its first 8 rows and 6 columns). `details` is not repeated here.","citations":[{"label":"string — What the link is.","href":"string — A Chord page as a path under `https://getchord.xyz` (`/arc/token/0x…`), or the source's own URL.","tier":"integer (1|2|3|4) — Deep answers only: 1 primary data (Chord's index, an exchange, an explorer, DefiLlama, CoinGecko, an official page), 2 major media, 3 a blog or another site, 4 social.","kind":"string (index|data|official|media|blog|social|other) — Deep answers only: the kind of source (`index` = Chord's own index)."}],"quote":"object|null — A route card when the question implied a trade: the two tokens, the amounts in whole tokens, the venues, price impact, fee and a link to the trade on Chord. A preview, not a `/v1/quote` response: `/v1/swap` needs a fresh `/v1/quote`.","artifact":"object|null — The token the answer is about: its stats, where volume traded (support, resistance, VWAP), a report link when one was built.","walletArtifact":"object|null","viz":["object — Tables and charts (`kind`: table · bar · line · donut), at most 6: the ones `parts` and `details` place come first, in that order."],"toolsUsed":["string"],"tokens":"integer — Model tokens spent.","followUps":["string"],"assets":["object — Price chips for the assets the answer names (symbol, label, price, 24h change), at most 8. A chip of a token Chord checked in this answer carries `risk` `{ verdict, reasons }`: `avoid`, `caution` or `ok` from Chord's safety check (`GET /v1/security/token/{chain}/{address}`), its reasons worst first."],"revokes":[{"chainId":"integer — Chain id.","kind":"string (erc20|nft) — `erc20` = `approve(spender, 0)`, `nft` = `setApprovalForAll(spender, false)`.","token":"string — EVM address, hex, case-insensitive.","spender":"string — EVM address, hex, case-insensitive.","to":"string — Where the revoke is sent: the token or the NFT collection.","data":"string — The calldata, hex.","value":"string","label":"string — What the button says (`Revoke USDT for 0x… (1inch Aggregation Router v6)`)."}],"shape":"string (fact|explain|brief|board|why|overview|compare|post|do|report|auto) — The kind of answer the question got: a single fact, an explanation, a call with its evidence (`brief`), a ranked list (`board`), why something moves, a market overview, a comparison, something to post, something to do on Chord, a full report, or `auto` when nothing matched.","parts":[{"oneOf":["object","object"]}],"details":{"text":"string — The folded part as Markdown, placed tables written out.","parts":["…"]},"followUpKinds":["string"],"focus":"integer|null — Index into `assets` of the one asset the answer is about, when there is one."},"example":null},"security":[{"ApiKey":[]},{"Session":[]}]},{"kind":"operation","operationId":"getTokenSecurity","method":"GET","path":"/v1/security/token/{chain}/{address}","tag":"Token safety","summary":"Is a token safe","description":"Chord's safety report for one token: the same report the Ask analyst, the trade dock and the trade card read.\n\n**What runs**: on the EVM chains, Chord's own contract scan (proxy wiring and who can upgrade it, the owner and what the owner can do: mint, block wallets, pause, change taxes or limits), a $20 buy and its sell back through Chord's router simulated as a test wallet (nothing is sent), the transfer-tax probe, GoPlus, Sourcify and Chord's own tape screen (wash trading, buyer clusters, rugs, buyers who cannot sell, a copied ticker). On Solana: RugCheck, GoPlus, Jupiter and the screen of Chord's Solana tape (mint and freeze authority, Token-2022 extensions, LP lock, holders, the creator's history). A source that does not answer leaves its checks `unknown` and the report `partial`; it is never read as a pass.\n\n**Use it for**: \"is this token safe to buy\", a rug or honeypot check before a trade, an agent's pre-trade gate (refuse `avoid`, warn on `caution`).\n\n**Notes**\n- Cached 10 minutes (2 to 3 minutes when a source did not answer, seconds when nothing could test selling an unvetted token or the check was cut short on Chord's side; such a partial report is sent `Cache-Control: private, max-age=10`). A report built cold on an EVM chain can take up to about 20 seconds. An address with no contract answers 404 at once.\n- A report already cached answers anyone. Without an API key (or an Ask session), one IP builds at most 10 new reports every 10 minutes, and every such caller together a limited number a minute; past either the answer is 429 or 503 `BUSY` with `Retry-After`, and nothing is checked. Send an `X-API-Key` for more.\n- `verdict` is decided in code from `checks`. No verdict rests on GoPlus alone: when only GoPlus answered, the report is `partial` and says Chord's own checks did not run. A reading from GoPlus names it \"GoPlus (Powered by Go+ Security)\".\n- A Solana mint is used exactly as given (base58 is case-sensitive).","url":"https://getchord.xyz/docs/api-reference/operations/gettokensecurity/","parameters":[{"name":"chain","in":"path","required":true,"type":"string","description":"Chain id or name: `1` / `ethereum`, `56` / `bnb`, `143` / `monad`, `4663` / `robinhood`, `5042` / `arc`, `8453` / `base`, `42161` / `arbitrum`, `43114` / `avalanche`, or `solana`."},{"name":"address","in":"path","required":true,"type":"string","description":"The token contract (0x followed by 40 hex characters), or the Solana mint exactly as written (base58, 32 bytes)."}],"requestBody":null,"responses":{"200":"The report.","400":"`UNSUPPORTED_CHAIN` (a chain Chord does not check, or one not served yet) or `INVALID_ADDRESS`.","404":"`NOT_A_CONTRACT`: the chain answered and there is no contract at this address. `NOT_A_MINT`: no Solana source knows this address as a token.","429":"`RATE_LIMITED`: without an API key, this IP built its 10 new reports of the last 10 minutes (`Retry-After`); cached reports still answer. Or `RATE_LIMIT_EXCEEDED`, the per-minute limit of every route.","503":"`BUSY`: too many new reports are being built for callers without a key right now (`Retry-After`). `UNAVAILABLE`: the check could not run just now. Retry; do not treat either as a clean result."},"response":{"schema":{"chain":"… — The chain id, or `solana`.","address":"string — The token (0x, lower-cased) or the Solana mint (case kept).","symbol":"string|null — As the contract or the token list names it: chosen by whoever launched the token.","name":"string|null","verdict":"string (avoid|caution|ok|unknown) — Decided in code from the checks, never by a model. `avoid`: it cannot be sold, a sell tax of 30% or more, a scam verdict of Chord's tape screen, or a copy of a listed token's ticker. `caution`: a check that warns (taxes of 5 to 30%, an owner who can mint, block wallets or pause, code one wallet can upgrade, unverified source, unlocked liquidity one provider can pull, top 10 holders over 60% …). `ok`: none of that, with two independent sources answering and a sell test passing. `unknown`: too few sources, or nothing could test selling it. Never read `ok` as a guarantee.","score":"integer|null — 0 (worst) to 100, in the verdict's band; null when the verdict is `unknown`.","checks":[{"id":"string — Stable id, snake_case: `honeypot`, `buy_tax`, `sell_tax`, `transfer_tax`, `round_trip`, `owner_can_mint`, `blacklist`, `pausable`, `owner_privileges`, `hidden_owner`, `proxy_upgradeable`, `unverified_source`, `lp_unlocked`, `top10_holders`, `creator_holds`, `creator_history`, `tape_screen`, `impostor_ticker`, `own_checks` …; Solana adds `freeze_authority`, `mint_authority`, `token2022_extensions`, `mutable_metadata`, `liquidity` …","label":"string — Short English label (`Sell tax`, `Owner can mint`).","status":"string (pass|warn|fail|unknown) — `unknown` = the source that reads it did not answer, or nothing could test it. Never `pass` for a check that did not run.","detail":"string — One sentence with the measured number (`Selling loses 40% to the token's own tax (Chord simulation 40%, GoPlus 40%).`).","source":"string — Who read it, in words, at most 60 characters (`Chord simulation`, `Chord contract scan`, `Chord tape`, `RugCheck`, `Sourcify`). A reading from GoPlus says `GoPlus (Powered by Go+ Security)`."}],"facts":"object — The numbers behind the checks: `buyTaxPct`, `sellTaxPct`, `transferTaxPct`, `honeypot`, `owner`, `ownerRenounced`, `proxy`, `implementation`, `upgrader`, `verifiedSource`, `mintable`, `blacklist`, `pausable`, `lpLockedPct`, `top10Pct`, `holders`, `creator`, `creatorPct`, `screenLevel`, `screenReasons`, `simulation` (Chord's $20 buy and sell back: status, taxes, round trip), `reasons` (the counted reasons, worst first), `answered` / `missing` (the sources), `goplusOnly` (only GoPlus answered: the report is partial). Solana adds `mintAuthority`, `freezeAuthority`, `token2022Extensions`, `permanentDelegate`, `liquidityUsd`, `pools`, `topHolders`, `jupiterVerified`, `rugcheckScore` …","sources":[{"label":"string","href":"string"}],"checkedAt":"integer — Unix time, milliseconds — when the server built this answer.","partial":"boolean — True when at least one source did not answer, or when GoPlus was the only one that did.","vetted":"boolean — On a list Chord trusts (stock / ETF / bridged list token, the bridge provider's list, Monad's verified list, a registry anchor; on Solana Jupiter-verified majors): the issuer's own powers (mint, freeze, pause, upgrades) are listed but do not raise the verdict. Taxes and the sell test still count."},"example":null},"security":null},{"kind":"operation","operationId":"askPicks","method":"GET","path":"/v1/ask/picks","tag":"Ask agent","summary":"Ask Picks board","description":"The analyst's current picks (rebuilt every four hours over tokens with real activity): side, score, confidence, the reasons for and against, and the facts behind them, plus the seven-day track record: picks graded, the share that moved their way and the average move. It carries no targets or stops.","url":"https://getchord.xyz/docs/api-reference/operations/askpicks/","parameters":[],"requestBody":null,"responses":{"200":""},"response":{"schema":{"chain":"integer","computedAt":"integer|null — Unix time, seconds, UTC.","picks":[{"ts":"integer — Unix time, seconds, UTC.","token":"string — EVM address, hex, case-insensitive.","symbol":"string|null","side":"string (bullish|bearish)","score":"number","confidence":"string (low|medium|high)","priceUsd":"number","why":"array","against":"array","facts":"object"}],"trackRecord7d":{"graded":"integer","open":"integer","rightWayPct":"number|null — Of the graded picks that have a price move so far, the share that moved the pick's way, percent. Null while none has one.","avgMovePct":"number|null — Their average move in the pick's direction, percent. Null while none has one."}},"example":{"chain":5042,"computedAt":1789891756,"picks":[{"ts":1789891743,"token":"0xbc43ce8dec648ea298c4275559b81d6261c90b67","symbol":"TOLLY","side":"bullish","score":3.93,"confidence":"medium","priceUsd":0.0044422,"why":["buyers 64% of the last hour (156 trades)","59.8% of buying from wallets that are not bots or routers"],"against":[],"facts":{"change24hPct":3.451327756586764,"buyShare1h":64,"buyShare24h":53,"realBuyerPct":59.8,"top10Pct":22.6,"vsVwapPct":1.3,"lastHourVsPriorPct":44,"lastHourUsd":27067,"lastHourTrades":156,"volume24h":633338,"traders":1919}},{"ts":1789891755,"token":"0x70857041fef0ced97f9e01e7ccc21889afe3f6f4","symbol":"CRA","side":"bullish","score":3.71,"confidence":"medium","priceUsd":0.00014232,"why":["volume 284% above the prior six hours","70.3% of buying from wallets that are not bots or routers"],"against":[],"facts":{"change24hPct":-27.189832782274127,"buyShare1h":43,"buyShare24h":49,"realBuyerPct":70.3,"top10Pct":11.81,"vsVwapPct":-21.6,"lastHourVsPriorPct":284,"lastHourUsd":6334,"lastHourTrades":71,"volume24h":104328,"traders":587}}],"trackRecord7d":{"graded":120,"open":38,"avgMovePct":2.4}}},"security":null},{"kind":"operation","operationId":"askReport","method":"POST","path":"/v1/ask/report","tag":"Ask agent","summary":"Build a research note","description":"Builds Chord's three-page research note for a token (HTML → PDF in the browser, plus Markdown) and returns links good for seven days.","url":"https://getchord.xyz/docs/api-reference/operations/askreport/","parameters":[],"requestBody":{"schema":{"token":"string — Address or symbol on Arc.","summary":"string — Optional analyst text to place on the first page."},"example":{"token":"ARGUS"}},"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","401":"Missing or unknown credential (`UNAUTHORIZED`).","404":"Nothing at this identity (`NOT_FOUND`, `UNKNOWN_TOKEN`, `NO_ROUTE`).","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"id":"string","url":"string — HTML.","mdUrl":"string — Markdown."},"example":null},"security":[{"Session":[]}]},{"kind":"operation","operationId":"askImageUpload","method":"POST","path":"/v1/ask/image","tag":"Ask agent","summary":"Attach an image","description":"Uploads one image for a question (PNG, JPEG, WebP, GIF first frame; ≤ 12 MB). It is re-encoded as a JPEG no wider or taller than 2048 px, with its metadata (EXIF, GPS) removed, and kept 30 days. Send the returned `id` in `images` of `POST /v1/ask`. 30 uploads per 10 minutes per caller.","url":"https://getchord.xyz/docs/api-reference/operations/askimageupload/","parameters":[],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","401":"Missing or unknown credential (`UNAUTHORIZED`).","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"id":"string — 32 hex characters.","url":"string — `/v1/ask/image/{id}`.","width":"integer","height":"integer","bytes":"integer"},"example":null},"security":[{"ApiKey":[]},{"Session":[]}]},{"kind":"operation","operationId":"askImage","method":"GET","path":"/v1/ask/image/{id}","tag":"Ask agent","summary":"Fetch an attached image","description":"The stored JPEG. Public by unguessable id (an `<img>` sends no bearer), 30 days.","url":"https://getchord.xyz/docs/api-reference/operations/askimage/","parameters":[{"name":"id","in":"path","required":true,"type":"string","description":"Image id."}],"requestBody":null,"responses":{"200":"`image/jpeg`.","404":"Nothing at this identity (`NOT_FOUND`, `UNKNOWN_TOKEN`, `NO_ROUTE`)."},"response":null,"security":null},{"kind":"operation","operationId":"askReportGet","method":"GET","path":"/v1/ask/report/{id}","tag":"Ask agent","summary":"Fetch a report","description":"The note as HTML, or Markdown with a `.md` suffix. Public by unguessable id, seven days.","url":"https://getchord.xyz/docs/api-reference/operations/askreportget/","parameters":[{"name":"id","in":"path","required":true,"type":"string","description":"Report id, optionally with `.md`."}],"requestBody":null,"responses":{"200":"`text/html` or `text/markdown`.","404":"Nothing at this identity (`NOT_FOUND`, `UNKNOWN_TOKEN`, `NO_ROUTE`)."},"response":null,"security":null},{"kind":"operation","operationId":"askExport","method":"GET","path":"/v1/ask/export/{id}","tag":"Ask agent","summary":"Fetch a CSV export","description":"A table the analyst exported, as CSV (one hour).","url":"https://getchord.xyz/docs/api-reference/operations/askexport/","parameters":[{"name":"id","in":"path","required":true,"type":"string","description":"Export id, optionally with `.csv`."}],"requestBody":null,"responses":{"200":"`text/csv`.","404":"Nothing at this identity (`NOT_FOUND`, `UNKNOWN_TOKEN`, `NO_ROUTE`)."},"response":null,"security":null},{"kind":"operation","operationId":"bridge2Config","method":"GET","path":"/v1/bridge2/config","tag":"Bridge","summary":"CCTP chain table","description":"Circle CCTP V2 fast transfer to and from Arc: the chains and domains, USDC addresses, the TokenMessenger / MessageTransmitter contracts, and the Arc-side relayer (address, balance, enabled). The browser signs the burn; Chord proxies the attestation and relays the Arc mint.","url":"https://getchord.xyz/docs/api-reference/operations/bridge2config/","parameters":[],"requestBody":null,"responses":{"200":""},"response":{"schema":{"provider":"string","fastFinalityThreshold":"integer","arcDomain":"integer","contracts":{"tokenMessengerV2":"string — EVM address, hex, case-insensitive.","messageTransmitterV2":"string — EVM address, hex, case-insensitive."},"chains":[{"chainId":"integer","domain":"integer","name":"string","usdc":"string — EVM address, hex, case-insensitive."}],"relayer":{"address":"string|null — EVM address, hex, case-insensitive.","arcBalance":"string|null — Wei.","enabled":"boolean"}},"example":{"provider":"cctp-v2","fastFinalityThreshold":1000,"arcDomain":26,"contracts":{"tokenMessengerV2":"0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d","messageTransmitterV2":"0x81D40F21F12A8F0E3252Bccb954D722d4c464B64"},"chains":[{"chainId":5042,"domain":26,"name":"Arc","usdc":"0x3600000000000000000000000000000000000000"},{"chainId":143,"domain":15,"name":"Monad","usdc":"0x754704Bc059F8C67012fEd69BC8A327a5aafb603"}],"relayer":{"address":"0x66449F79050828abb7A205434C0971dBA7a44C38","arcBalance":"1646165237063978241","enabled":true}}},"security":null},{"kind":"operation","operationId":"bridge2Fee","method":"GET","path":"/v1/bridge2/fee","tag":"Bridge","summary":"CCTP fee","description":"Circle's minimum fee for a fast and a standard transfer between two domains, in basis points.","url":"https://getchord.xyz/docs/api-reference/operations/bridge2fee/","parameters":[{"name":"src","in":"query","required":true,"type":"integer","description":"Source CCTP domain."},{"name":"dst","in":"query","required":true,"type":"integer","description":"Destination CCTP domain."}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"src":"integer","dst":"integer","fastBps":"number","standardBps":"number"},"example":null},"security":null},{"kind":"operation","operationId":"bridge2Status","method":"GET","path":"/v1/bridge2/status","tag":"Bridge","summary":"Attestation status","description":"Iris status for a burn transaction: `not_found`, `pending` or `complete` with the message and attestation when ready.","url":"https://getchord.xyz/docs/api-reference/operations/bridge2status/","parameters":[{"name":"srcDomain","in":"query","required":true,"type":"integer","description":""},{"name":"tx","in":"query","required":true,"type":"string","description":"The burn transaction."}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"status":"string (not_found|pending|complete)","srcDomain":"integer","tx":"string — Transaction hash.","message":"string|null","attestation":"string|null","eventNonce":"string|null","decoded":"object|null"},"example":null},"security":null},{"kind":"operation","operationId":"bridge2Relay","method":"POST","path":"/v1/bridge2/relay","tag":"Bridge","summary":"Relay the Arc mint","description":"Once attested, Chord's relayer submits `receiveMessage` on Arc so the recipient needs no gas there. `409 NOT_ATTESTED` until Iris completes; `429 DAILY_CAP`; `503 RELAYER_OFF`.","url":"https://getchord.xyz/docs/api-reference/operations/bridge2relay/","parameters":[],"requestBody":{"schema":{"srcDomain":"integer","tx":"string — Transaction hash."},"example":{"srcDomain":6,"tx":"0x…"}},"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","409":"`NOT_ATTESTED` or `IN_FLIGHT`.","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","502":"The routing engine or an upstream did not answer (`ENGINE_ERROR`, `ROUTE_ERROR`).","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"ok":"boolean","txHash":"string — Transaction hash."},"example":null},"security":null},{"kind":"operation","operationId":"xswapPlan","method":"POST","path":"/v1/xswap/plan","tag":"Bridge","summary":"Cross-chain swap plan","description":"Quotes a token on one chain into a token on another two ways at once — **composed** (Chord's router on the origin → USDC/USDG rail → Chord's router on the destination) and **direct** (Relay end to end) — and names the one that lands more. Long-tail tokens on Arc / Monad / Robinhood only route on the composed path. Fees come back as three lines (protocol · bridge · network) and `gas` says who pays on each side. `MIN_SIZE` below 10 USD of the bridged stable.","url":"https://getchord.xyz/docs/api-reference/operations/xswapplan/","parameters":[],"requestBody":{"schema":{"user":"string — EVM address, hex, case-insensitive.","chainIn":"integer (143|4663|5042)","chainOut":"integer (143|4663|5042)","tokenIn":"string — EVM address, hex, case-insensitive.","tokenOut":"string — EVM address, hex, case-insensitive.","amount":"string — Amount in the token's smallest unit, as a decimal string. Never a float.","slippageBps":"integer","recipient":"string — EVM address, hex, case-insensitive.","rail":"string (auto|relay|cctp) — Force a rail; `auto` applies the corridor rules (Robinhood → Relay; Monad ↔ Arc → CCTP when the mint relayer is funded; else Relay)."},"example":{"user":"0xb145400da27a2497d9fc2cd5621f2bfd37617af4","chainIn":5042,"chainOut":143,"tokenIn":"0x3600000000000000000000000000000000000000","tokenOut":"0x350035555e10d9afaf1566aaebfced5ba6c27777","amount":"1000000000","slippageBps":100}},"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","404":"Nothing at this identity (`NOT_FOUND`, `UNKNOWN_TOKEN`, `NO_ROUTE`).","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","502":"The routing engine or an upstream did not answer (`ENGINE_ERROR`, `ROUTE_ERROR`).","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"best":"string (composed|direct)","composed":{"chainIn":"integer","chainOut":"integer","tokenIn":"string — EVM address, hex, case-insensitive.","tokenOut":"string — EVM address, hex, case-insensitive.","amountIn":"string — Amount in the token's smallest unit, as a decimal string. Never a float.","amountOut":"string — Amount in the token's smallest unit, as a decimal string. Never a float.","legs":["…"],"timeEstimateSec":"number","rail":"string (relay|cctp)","railReason":"string — Why this rail.","fees":{"protocol":"object","bridge":"object","network":"object","totalUsd":"number"},"gas":{"origin":"string","dest":"string"},"minAnchorUnits":"string — Amount in the token's smallest unit, as a decimal string. Never a float.","bridge":"object — Rail-shaped: `{ rail, requestId, checkEndpoint, steps[], fees, details }` — sign `steps` in order on the origin chain (an `approval` item may be skipped when the allowance covers it)."},"direct":{"chainIn":"integer","chainOut":"integer","tokenIn":"string — EVM address, hex, case-insensitive.","tokenOut":"string — EVM address, hex, case-insensitive.","amountIn":"string — Amount in the token's smallest unit, as a decimal string. Never a float.","amountOut":"string — Amount in the token's smallest unit, as a decimal string. Never a float.","legs":["…"],"timeEstimateSec":"number","rail":"string (relay|cctp)","railReason":"string — Why this rail.","fees":{"protocol":"object","bridge":"object","network":"object","totalUsd":"number"},"gas":{"origin":"string","dest":"string"},"minAnchorUnits":"string — Amount in the token's smallest unit, as a decimal string. Never a float.","bridge":"object — Rail-shaped: `{ rail, requestId, checkEndpoint, steps[], fees, details }` — sign `steps` in order on the origin chain (an `approval` item may be skipped when the allowance covers it)."},"errors":"object — Per-path failure `{ code, message }` when a path could not be quoted."},"example":null},"security":null},{"kind":"operation","operationId":"xswapQuote","method":"POST","path":"/v1/xswap/quote","tag":"Bridge","summary":"Composed cross-chain quote","description":"The composed path only (see `/xswap/plan`).","url":"https://getchord.xyz/docs/api-reference/operations/xswapquote/","parameters":[],"requestBody":{"schema":{"user":"string — EVM address, hex, case-insensitive.","chainIn":"integer (143|4663|5042)","chainOut":"integer (143|4663|5042)","tokenIn":"string — EVM address, hex, case-insensitive.","tokenOut":"string — EVM address, hex, case-insensitive.","amount":"string — Amount in the token's smallest unit, as a decimal string. Never a float.","slippageBps":"integer","recipient":"string — EVM address, hex, case-insensitive.","rail":"string (auto|relay|cctp) — Force a rail; `auto` applies the corridor rules (Robinhood → Relay; Monad ↔ Arc → CCTP when the mint relayer is funded; else Relay)."},"example":{"user":"0xb145400da27a2497d9fc2cd5621f2bfd37617af4","chainIn":5042,"chainOut":143,"tokenIn":"0x3600000000000000000000000000000000000000","tokenOut":"0x350035555e10d9afaf1566aaebfced5ba6c27777","amount":"1000000000","slippageBps":100}},"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","404":"Nothing at this identity (`NOT_FOUND`, `UNKNOWN_TOKEN`, `NO_ROUTE`).","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","502":"The routing engine or an upstream did not answer (`ENGINE_ERROR`, `ROUTE_ERROR`).","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chainIn":"integer","chainOut":"integer","tokenIn":"string — EVM address, hex, case-insensitive.","tokenOut":"string — EVM address, hex, case-insensitive.","amountIn":"string — Amount in the token's smallest unit, as a decimal string. Never a float.","amountOut":"string — Amount in the token's smallest unit, as a decimal string. Never a float.","legs":[{"oneOf":["object","object"]}],"timeEstimateSec":"number","rail":"string (relay|cctp)","railReason":"string — Why this rail.","fees":{"protocol":{"originBps":"integer","destBps":"integer","usd":"number"},"bridge":{"rail":"string","usd":"number","bps":"number","appFeeBps":"integer — App fee added on Relay."},"network":{"usd":"number — Flat per relayer-paid transaction.","covered":"boolean — true = we eat it (Arc mint).","mode":"string (user|usdc-gas|gasless|solver|none)"},"totalUsd":"number"},"gas":{"origin":"string","dest":"string"},"minAnchorUnits":"string — Amount in the token's smallest unit, as a decimal string. Never a float.","bridge":"object — Rail-shaped: `{ rail, requestId, checkEndpoint, steps[], fees, details }` — sign `steps` in order on the origin chain (an `approval` item may be skipped when the allowance covers it)."},"example":null},"security":null},{"kind":"operation","operationId":"xswapOrder","method":"POST","path":"/v1/xswap/order","tag":"Bridge","summary":"Register a cross-chain order","description":"Quotes and records the order the wallet is about to sign so it can be resumed after a refresh: the server tracks the bridge (Relay status or Circle attestation), mints CCTP transfers on Arc, and re-quotes the final leg at the amount that actually arrived. Poll `GET /xswap/order?id=`. `path: \"direct\"` registers the Relay end-to-end candidate instead.","url":"https://getchord.xyz/docs/api-reference/operations/xswaporder/","parameters":[],"requestBody":{"schema":{"user":"string — EVM address, hex, case-insensitive.","chainIn":"integer (143|4663|5042)","chainOut":"integer (143|4663|5042)","tokenIn":"string — EVM address, hex, case-insensitive.","tokenOut":"string — EVM address, hex, case-insensitive.","amount":"string — Amount in the token's smallest unit, as a decimal string. Never a float.","slippageBps":"integer","recipient":"string — EVM address, hex, case-insensitive.","rail":"string (auto|relay|cctp) — Force a rail; `auto` applies the corridor rules (Robinhood → Relay; Monad ↔ Arc → CCTP when the mint relayer is funded; else Relay).","path":"string (composed|direct)"},"example":{"user":"0xb145400da27a2497d9fc2cd5621f2bfd37617af4","chainIn":5042,"chainOut":143,"tokenIn":"0x3600000000000000000000000000000000000000","tokenOut":"0x350035555e10d9afaf1566aaebfced5ba6c27777","amount":"1000000000","slippageBps":100}},"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","404":"Nothing at this identity (`NOT_FOUND`, `UNKNOWN_TOKEN`, `NO_ROUTE`).","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","502":"The routing engine or an upstream did not answer (`ENGINE_ERROR`, `ROUTE_ERROR`).","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"order":"object — `{ id, state, rail, chainIn, chainOut, tokenIn, tokenOut, amountIn, quotedOut, requestId, originTxHash?, destTxHash?, bridgedAmount?, destQuote?, claim?, note? }` — states: pending_origin · bridging · pending_dest · done · stuck_dest · failed_origin.","quote":{"chainIn":"integer","chainOut":"integer","tokenIn":"string — EVM address, hex, case-insensitive.","tokenOut":"string — EVM address, hex, case-insensitive.","amountIn":"string — Amount in the token's smallest unit, as a decimal string. Never a float.","amountOut":"string — Amount in the token's smallest unit, as a decimal string. Never a float.","legs":["…"],"timeEstimateSec":"number","rail":"string (relay|cctp)","railReason":"string — Why this rail.","fees":{"protocol":"object","bridge":"object","network":"object","totalUsd":"number"},"gas":{"origin":"string","dest":"string"},"minAnchorUnits":"string — Amount in the token's smallest unit, as a decimal string. Never a float.","bridge":"object — Rail-shaped: `{ rail, requestId, checkEndpoint, steps[], fees, details }` — sign `steps` in order on the origin chain (an `approval` item may be skipped when the allowance covers it)."},"requoteToleranceBps":"integer"},"example":null},"security":null},{"kind":"operation","operationId":"xswapOrderGet","method":"GET","path":"/v1/xswap/order","tag":"Bridge","summary":"Advance and read an order","description":"Asks the bridge where the money is and, once it landed, returns a fresh destination-leg quote (`destQuote`) to sign. Polling this is what moves the order.","url":"https://getchord.xyz/docs/api-reference/operations/xswaporderget/","parameters":[{"name":"id","in":"query","required":true,"type":"string","description":"Order id."}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","404":"Nothing at this identity (`NOT_FOUND`, `UNKNOWN_TOKEN`, `NO_ROUTE`).","502":"The routing engine or an upstream did not answer (`ENGINE_ERROR`, `ROUTE_ERROR`)."},"response":{"schema":{"order":"object","requoteToleranceBps":"integer"},"example":null},"security":null},{"kind":"operation","operationId":"xswapOrders","method":"GET","path":"/v1/xswap/orders","tag":"Bridge","summary":"A wallet's in-flight orders","description":"Newest first — how a client recovers cross-chain state it never held locally.","url":"https://getchord.xyz/docs/api-reference/operations/xswaporders/","parameters":[{"name":"user","in":"query","required":true,"type":"string","description":""}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","502":"The routing engine or an upstream did not answer (`ENGINE_ERROR`, `ROUTE_ERROR`)."},"response":{"schema":{"orders":["object"]},"example":null},"security":null},{"kind":"operation","operationId":"relayers","method":"GET","path":"/v1/relayers","tag":"Account and health","summary":"Relayer gas health","description":"For each chain Chord's relayer pays gas on (Monad gasless swaps, Robinhood Permit2 swaps, Arc CCTP mints): its address, native balance, current gas price and the estimated transactions that balance still covers. `ok` = above the floor; the cross-chain planner stops routing through a relayer that is not ok.","url":"https://getchord.xyz/docs/api-reference/operations/relayers/","parameters":[{"name":"force","in":"query","required":false,"type":"string","enum":["1"],"description":"Re-read now instead of the 60 s cache."}],"requestBody":null,"responses":{"200":""},"response":{"schema":{"minTx":"integer — The floor.","relayers":[{"chainId":"integer","name":"string","symbol":"string","role":"string","configured":"boolean","address":"string|null — EVM address, hex, case-insensitive.","balance":"string|null — Amount in the token's smallest unit, as a decimal string. Never a float.","gasPrice":"string|null — Amount in the token's smallest unit, as a decimal string. Never a float.","gasPerTx":"integer","txRemaining":"integer|null","ok":"boolean","checkedAt":"integer — Unix time, milliseconds — when the server built this answer.","error":"string"}],"updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":null},"security":null},{"kind":"operation","operationId":"crosschainConfig","method":"GET","path":"/v1/crosschain/config","tag":"Bridge","summary":"Bridge providers and chains","description":"Whether the provider is enabled, its app fee, the origin chains this deployment offers, and the destination chains with display names, native symbols, explorers and icons.","url":"https://getchord.xyz/docs/api-reference/operations/crosschainconfig/","parameters":[{"name":"provider","in":"query","required":false,"type":"string","enum":["lifi","relay"],"description":"Bridge provider. Chord uses `lifi`."},{"name":"origin","in":"query","required":false,"type":"integer","description":"Exclude this chain from the list."}],"requestBody":null,"responses":{"200":""},"response":{"schema":{"enabled":"boolean","provider":"string","appFeeBps":"number","origins":["integer"],"origin":"integer|null","chains":[{"id":"integer","name":"string","displayName":"string","nativeSymbol":"string","explorerUrl":"string","featured":"boolean","iconUrl":"string|null"}]},"example":{"enabled":true,"provider":"lifi","appFeeBps":5,"origins":[143,4663],"origin":null,"chains":[{"id":4663,"name":"out","displayName":"Robinhood Chain","nativeSymbol":"ETH","explorerUrl":"https://robin.etherscan.io","featured":true,"iconUrl":"https://raw.githubusercontent.com/lifinance/types/main/src/assets/icons/chains/robinhood.svg"},{"id":5042,"name":"arc","displayName":"Arc","nativeSymbol":"USDC","explorerUrl":"https://explorer.arc.io","featured":true,"iconUrl":"https://raw.githubusercontent.com/lifinance/types/main/src/assets/icons/chains/arc.svg"}]}},"security":null},{"kind":"operation","operationId":"crosschainCurrencies","method":"GET","path":"/v1/crosschain/currencies","tag":"Bridge","summary":"Bridgeable tokens on a chain","description":"Tokens the provider can move on a chain, filtered by a search term.","url":"https://getchord.xyz/docs/api-reference/operations/crosschaincurrencies/","parameters":[{"name":"chainId","in":"query","required":true,"type":"integer","description":""},{"name":"q","in":"query","required":false,"type":"string","description":"Symbol or name (≥ 2 characters)."},{"name":"provider","in":"query","required":false,"type":"string","enum":["lifi","relay"],"description":"Bridge provider. Chord uses `lifi`."}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chainId":"integer","provider":"string","currencies":["object — Token rows (address, symbol, name, decimals, logo)."]},"example":null},"security":null},{"kind":"operation","operationId":"crosschainQuote","method":"POST","path":"/v1/crosschain/quote","tag":"Bridge","summary":"Bridge quote","description":"A cross-chain quote from the provider: the steps, fees and the transactions to sign on the origin chain (an approve step is added when the origin token is an ERC-20). Poll `/crosschain/status` with the deposit hash.","url":"https://getchord.xyz/docs/api-reference/operations/crosschainquote/","parameters":[],"requestBody":{"schema":{"user":"string — EVM address, hex, case-insensitive.","originChainId":"integer","destinationChainId":"integer","originCurrency":"string — EVM address, hex, case-insensitive.","destinationCurrency":"string — EVM address, hex, case-insensitive.","amount":"string — Amount in the token's smallest unit, as a decimal string. Never a float.","slippageBps":"integer","recipient":"string — EVM address, hex, case-insensitive.","provider":"string (lifi|relay)","usePermit":"boolean — Relay only: a permit (signature) deposit instead of a transaction, for tokens that support it (native USDC on Arbitrum)."},"example":{"user":"0xb145400da27a2497d9fc2cd5621f2bfd37617af4","originChainId":8453,"destinationChainId":5042,"originCurrency":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","destinationCurrency":"0x3600000000000000000000000000000000000000","amount":"100000000","slippageBps":100,"provider":"lifi"}},"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","502":"The routing engine or an upstream did not answer (`ENGINE_ERROR`, `ROUTE_ERROR`).","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":"object — `{ provider, requestId, steps[], fees, details, checkEndpoint, txns[] }` — provider-shaped; sign `txns` in order.","example":null},"security":null},{"kind":"operation","operationId":"crosschainPermit","method":"POST","path":"/v1/crosschain/permit","tag":"Bridge","summary":"Submit a signed permit deposit","description":"Hands a signed `signature` step from a `usePermit` quote back to the provider (Relay only): send the step's `post.body` fields plus the EIP-712 signature. Then poll `/crosschain/status`.","url":"https://getchord.xyz/docs/api-reference/operations/crosschainpermit/","parameters":[],"requestBody":{"schema":{"requestId":"string","kind":"string — e.g. `eip3009`","api":"string — e.g. `swap`","signature":"string — 0x… EIP-712 signature"},"example":{"requestId":"0x17900816413eb4c1d4ec4b00d0be87c6b60872ed43d103eb87dc22a0b80ff325","kind":"eip3009","api":"swap","signature":"0x…"}},"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","502":"The routing engine or an upstream did not answer (`ENGINE_ERROR`, `ROUTE_ERROR`).","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":"object — Provider-shaped acknowledgement.","example":null},"security":null},{"kind":"operation","operationId":"crosschainStatus","method":"GET","path":"/v1/crosschain/status","tag":"Bridge","summary":"Bridge status","description":"Status of a bridge by its request id or deposit hash: `waiting` · `depositing` · `pending` · `submitted` · `success` · `delayed` · `refund` · `failure` · `unknown`.","url":"https://getchord.xyz/docs/api-reference/operations/crosschainstatus/","parameters":[{"name":"requestId","in":"query","required":true,"type":"string","description":"Request id (or the deposit tx hash on LI.FI)."},{"name":"provider","in":"query","required":false,"type":"string","enum":["lifi","relay"],"description":"Bridge provider. Chord uses `lifi`."},{"name":"fromChain","in":"query","required":false,"type":"integer","description":""},{"name":"toChain","in":"query","required":false,"type":"integer","description":""}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","502":"The routing engine or an upstream did not answer (`ENGINE_ERROR`, `ROUTE_ERROR`).","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"status":"string (waiting|depositing|pending|submitted|success|delayed|refund|failure|unknown)","substatus":"string","inTxHashes":["string"],"txHashes":["string"],"explorerLink":"string","updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":null},"security":null},{"kind":"operation","operationId":"rhStatus","method":"GET","path":"/v1/rh/status","tag":"Robinhood Chain data","summary":"Rollup freshness","description":"Chain 4663 only; takes no `chain` parameter. Served from Chord's rollup tables, never from a raw scan. `503 NOT_READY` until the rollup has run.","url":"https://getchord.xyz/docs/api-reference/operations/rhstatus/","parameters":[],"requestBody":null,"responses":{"200":"","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"integer","enabled":"boolean","recentAt":"integer|null — Unix time, seconds, UTC.","staleSec":"integer|null","floorHour":"integer|null","genesisHour":"integer|null","backfillComplete":"boolean","updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":{"chain":4663,"enabled":true,"recentAt":1789891427,"staleSec":441,"floorHour":1781197200,"genesisHour":1785974400,"backfillComplete":true,"updatedAt":1789891868582}},"security":null},{"kind":"operation","operationId":"rhOverview","method":"GET","path":"/v1/rh/overview","tag":"Robinhood Chain data","summary":"Chain totals","description":"Last 24 hours, venue share, 24 hourly buckets and up to 30 daily rows. Chain 4663 only; takes no `chain` parameter. Served from Chord's rollup tables, never from a raw scan. `503 NOT_READY` until the rollup has run.","url":"https://getchord.xyz/docs/api-reference/operations/rhoverview/","parameters":[],"requestBody":null,"responses":{"200":"","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"integer","last24h":{"volUsd":"number","swaps":"integer","tokens":"integer","sinceHour":"integer"},"venues24h":[{"dex":"string","volUsd":"number","trades":"integer","tokens":"integer","sharePct":"number"}],"hourly24":[{"hour":"integer","volUsd":"number","swaps":"integer"}],"daily":[{"day":"integer","swaps":"integer","volUsd":"number","tokens":"integer","wallets":"integer","venues":"integer"}],"coverage":{"recentAt":"integer|null — Unix time, seconds, UTC.","stale":"boolean — True when the most recent rolled-up hour is older than the lane's freshness bar.","floorHour":"integer|null — Oldest hour the rollup has reached so far.","genesisHour":"integer|null — The chain's first indexed hour.","backfillComplete":"boolean — True once the rollup reaches genesis — before that, long windows undercount."},"updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":{"chain":4663,"last24h":{"volUsd":550299744.1561619,"swaps":1079429,"tokens":1248,"sinceHour":1789808400},"venues24h":[{"dex":"uniswap_v3","volUsd":398446666.0763337,"trades":793745,"tokens":976,"sharePct":72.40538821025947},{"dex":"nadfun_dex","volUsd":86870804.38588408,"trades":94710,"tokens":205,"sharePct":15.786088456045553}],"hourly24":[{"hour":1789808400,"volUsd":20860178.787550393,"swaps":29122},{"hour":1789812000,"volUsd":16607559.066086678,"swaps":28538}],"daily":[{"day":1787356800,"swaps":706077,"volUsd":248035051.5861872,"tokens":1056,"wallets":32922,"venues":8},{"day":1787443200,"swaps":760930,"volUsd":261936195.3020307,"tokens":1065,"wallets":26961,"venues":9}],"coverage":{"recentAt":1789891427,"stale":false,"floorHour":1781197200,"genesisHour":1785974400,"backfillComplete":true},"updatedAt":1789891794537}},"security":null},{"kind":"operation","operationId":"rhVenues","method":"GET","path":"/v1/rh/venues","tag":"Robinhood Chain data","summary":"Venue share over a window","description":"Chain 4663 only; takes no `chain` parameter. Served from Chord's rollup tables, never from a raw scan. `503 NOT_READY` until the rollup has run.","url":"https://getchord.xyz/docs/api-reference/operations/rhvenues/","parameters":[{"name":"days","in":"query","required":false,"type":"integer","default":30,"description":""}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"integer","days":"integer","venues":[{"dex":"string","volUsd":"number","trades":"integer","sharePct":"number","series":"array"}],"totals":{"volUsd":"number","trades":"integer"}},"example":null},"security":null},{"kind":"operation","operationId":"rhTokens","method":"GET","path":"/v1/rh/tokens","tag":"Robinhood Chain data","summary":"Every token traded in the last 24 hours","description":"Price, change, volume split, trade counts and attributed traders. Unlisted tokens (no curated metadata or logo) are hidden unless asked for. Chain 4663 only; takes no `chain` parameter. Served from Chord's rollup tables, never from a raw scan. `503 NOT_READY` until the rollup has run.","url":"https://getchord.xyz/docs/api-reference/operations/rhtokens/","parameters":[{"name":"limit","in":"query","required":false,"type":"integer","default":100,"description":""},{"name":"sort","in":"query","required":false,"type":"string","enum":["volume","trades","traders","change"],"default":"volume","description":""},{"name":"includeUnlisted","in":"query","required":false,"type":"integer","enum":[0,1],"default":0,"description":""}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"integer","sinceHour":"integer","tradersSince":"integer","sort":"string","tokens":[{"address":"string — EVM address, hex, case-insensitive.","symbol":"string","name":"string","decimals":"integer","logoURI":"string|null","tags":"array","listed":"boolean","priceUsd":"number|null","change24hPct":"number|null","liquidityUsd":"number|null","volume24h":"number","buyVolume24h":"number","sellVolume24h":"number","trades24h":"integer","buys24h":"integer","sells24h":"integer","traders":"integer — Attributed wallets only.","lastTradeTs":"integer — Unix time, seconds, UTC."}],"total":"integer","updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":{"chain":4663,"sinceHour":1789808400,"tradersSince":1789776000,"sort":"volume","tokens":[{"address":"0x0Bd7D308f8E1639FAb988df18A8011f41EAcAD73","symbol":"WETH","name":"WETH","decimals":18,"logoURI":"https://assets.coingecko.com/coins/images/2518/small/weth.png?1696503332","tags":["bridged"],"listed":true,"priceUsd":2580.1259797979797,"change24hPct":-2.421961053968613,"liquidityUsd":null,"volume24h":305214685.46276,"buyVolume24h":150250793.83089906,"sellVolume24h":154963891.63186103,"trades24h":431734,"buys24h":221381,"sells24h":210353,"traders":19755,"lastTradeTs":1789891402},{"address":"0xd0601CE157Db5bdC3162BbaC2a2C8aF5320D9EEC","symbol":"NVDA","name":"NVIDIA • Robinhood Token","decimals":18,"logoURI":"https://cdn.robinhood.com/ncw_assets/logos/0xd0601ce157db5bdc3162bbac2a2c8af5320d9eec.png","tags":["stock"],"listed":true,"priceUsd":220.97693371148938,"change24hPct":-0.7107543259553206,"liquidityUsd":7508320,"volume24h":34504046.378991455,"buyVolume24h":16798001.15787153,"sellVolume24h":17706045.221119925,"trades24h":103172,"buys24h":52577,"sells24h":50595,"traders":5056,"lastTradeTs":1789891401}],"total":357,"updatedAt":1789891868895}},"security":null},{"kind":"operation","operationId":"rhToken","method":"GET","path":"/v1/rh/token/{address}","tag":"Robinhood Chain data","summary":"One token: hourly tape and venue split","description":"Chain 4663 only; takes no `chain` parameter. Served from Chord's rollup tables, never from a raw scan. `503 NOT_READY` until the rollup has run.","url":"https://getchord.xyz/docs/api-reference/operations/rhtoken/","parameters":[{"name":"address","in":"path","required":true,"type":"string","description":""},{"name":"hours","in":"query","required":false,"type":"integer","default":168,"description":""}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"token":{"address":"string — EVM address, hex, case-insensitive.","symbol":"string|null"},"series":[{"hour":"integer","volUsd":"number","buyUsd":"number","sellUsd":"number","trades":"integer","buys":"integer","sells":"integer","priceLast":"number|null"}],"byDex":[{"dex":"string","volUsd":"number","trades":"integer","sharePct":"number"}]},"example":null},"security":null},{"kind":"operation","operationId":"rhStocks","method":"GET","path":"/v1/rh/stocks","tag":"Robinhood Chain data","summary":"Tokenized stocks","description":"Every tokenized stock and ETF on chain 4663 with its 24-hour tape, NAV basis where the issuer publishes a rate, and the share of the last seven days that traded outside the NYSE session. Chain 4663 only; takes no `chain` parameter. Served from Chord's rollup tables, never from a raw scan. `503 NOT_READY` until the rollup has run.","url":"https://getchord.xyz/docs/api-reference/operations/rhstocks/","parameters":[],"requestBody":null,"responses":{"200":"","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"integer","sinceHour":"integer","tradersSince":"integer","stocks":[["object","object"]],"note":"string","updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":{"chain":4663,"sinceHour":1789808400,"tradersSince":1789776000,"stocks":[{"address":"0xd0601CE157Db5bdC3162BbaC2a2C8aF5320D9EEC","symbol":"NVDA","name":"NVIDIA • Robinhood Token","decimals":18,"logoURI":"https://cdn.robinhood.com/ncw_assets/logos/0xd0601ce157db5bdc3162bbac2a2c8af5320d9eec.png","tags":["stock"],"listed":true,"priceUsd":220.97693371148938,"change24hPct":-0.7107543259553206,"liquidityUsd":7508320,"volume24h":34504046.378991455,"buyVolume24h":16798001.15787153,"sellVolume24h":17706045.221119925,"trades24h":103172,"buys24h":52577,"sells24h":50595,"traders":5056,"lastTradeTs":1789891401,"navUsd":null,"basisPct":null,"offHours7d":{"volUsd":122712280.03735964,"trades":365579,"sharePct":57.75403042239189}},{"address":"0x4a0E65A3EcceC6dBe60AE065F2e7bb85Fae35eEa","symbol":"SPCX","name":"Space Exploration Technologies Corp • Robinhood Token","decimals":18,"logoURI":"https://cdn.robinhood.com/ncw_assets/logos/0x4a0e65a3eccec6dbe60ae065f2e7bb85fae35eea.png","tags":["stock"],"listed":true,"priceUsd":152.33158650694747,"change24hPct":-0.278639004753245,"liquidityUsd":4756081,"volume24h":14186052.186705315,"buyVolume24h":7064922.470980956,"sellVolume24h":7121129.715724356,"trades24h":41993,"buys24h":22090,"sells24h":19903,"traders":3138,"lastTradeTs":1789891402,"navUsd":null,"basisPct":null,"offHours7d":{"volUsd":75910449.80504468,"trades":277274,"sharePct":42.37032851899335}}],"note":"offHours7d = volume in hour buckets outside the NYSE regular session (09:30-16:00 New York, Mon-Fri, DST-aware; exchange holidays not modelled). navUsd = Blockscout exchange_rate at last catalogue refresh.","updatedAt":1789891849578}},"security":null},{"kind":"operation","operationId":"chainStatus","method":"GET","path":"/v1/chains/{chain}/status","tag":"Avalanche, Base, BNB Chain","summary":"Rollup freshness and coverage","description":"Is the chain's rollup fresh, how far back it reaches, whether the tape and the public flag are on, where the raw tape is cut, and the ingest floor. Answers 200 even before the first rollup pass (`recentAt` is then null). Check it before trusting a quiet number.\n\nChain-keyed data for Avalanche C-Chain, Base and BNB Chain, served from Chord's rollup tables for the chain (every swap summed by hour, token and venue). Only the trade tape, the prints ticker and the wallet read raw rows, scoped to one token or one wallet and bounded.\n\n- **Access.** No key needed while the chain is public (all three are today). A chain whose tape is off, or that is not public yet, answers `400 UNSUPPORTED_CHAIN` (\"chain N is not served yet\") unless the request carries an `X-API-Key`; those answers are sent `Cache-Control: private`.\n- **Ingest floor.** Every count, volume and print covers trades at or above the chain's floor, returned as `ingestFloor`. BNB Chain runs at $100 today; Avalanche and Base at 0.\n- **Readiness.** `503 NOT_READY` until the chain's rollup has run on this deployment; `503 CHAIN_DATA_UNAVAILABLE` when the store cannot be read. Never treat either as \"no trades\".","url":"https://getchord.xyz/docs/api-reference/operations/chainstatus/","parameters":[{"name":"chain","in":"path","required":true,"type":"string","enum":["avalanche","base","bnb","arbitrum","ethereum","43114","8453","56","42161","1"],"description":"The chain, by key or id: `avalanche` or `43114`, `base` or `8453`, `bnb` or `56`, `arbitrum` or `42161`, `ethereum` or `1` (case-insensitive). Arc, Robinhood Chain and Monad are refused with `400 UNSUPPORTED_CHAIN` and a pointer to their own routes."}],"requestBody":null,"responses":{"200":"","400":"`UNSUPPORTED_CHAIN` (unknown chain, a chain with its own routes, or a chain not served to this caller yet).","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","503":"`CHAIN_DATA_UNAVAILABLE`: the store could not be read. Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"integer — Registry id.","enabled":"boolean — The rollup and the tape both run.","tape":"boolean — The chain's trade tape runs.","public":"boolean — Served to callers without a key.","recentAt":"integer|null — Unix time, seconds, UTC.","staleSec":"integer|null — Seconds since the last rollup pass.","floorHour":"integer|null — Oldest hour the backfill has rolled.","genesisHour":"integer|null — The chain's first indexed hour, when this server knows it; often null.","backfillComplete":"boolean — True once the backfill has reached the first indexed hour.","retentionCutoffDay":"integer|null — UTC day start. Raw trades before it are retired from the database (about 3 days on BNB Chain and Base, 7 on Avalanche today); the hourly and daily rollups keep their history.","ingestFloor":{"minTradeUsd":"number — Trades under this USD value (at index time) are not in the index, so every count, volume and candle covers trades at or above it. 0 = every priced trade.","history":["object"]},"updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":{"chain":56,"enabled":true,"tape":true,"public":true,"recentAt":1791020996,"staleSec":460,"floorHour":1790787600,"genesisHour":null,"backfillComplete":true,"retentionCutoffDay":1790726400,"ingestFloor":{"minTradeUsd":100,"history":[{"usd":100,"fromTs":1790789196}]},"updatedAt":1791021456137}},"security":null},{"kind":"operation","operationId":"chainOverview","method":"GET","path":"/v1/chains/{chain}/overview","tag":"Avalanche, Base, BNB Chain","summary":"Chain totals","description":"Last 24 hours (volume, swaps, tokens, venues), distinct wallets per UTC day, venue share, 24 hourly buckets and up to 14 daily rows.\n\nChain-keyed data for Avalanche C-Chain, Base and BNB Chain, served from Chord's rollup tables for the chain (every swap summed by hour, token and venue). Only the trade tape, the prints ticker and the wallet read raw rows, scoped to one token or one wallet and bounded.\n\n- **Access.** No key needed while the chain is public (all three are today). A chain whose tape is off, or that is not public yet, answers `400 UNSUPPORTED_CHAIN` (\"chain N is not served yet\") unless the request carries an `X-API-Key`; those answers are sent `Cache-Control: private`.\n- **Ingest floor.** Every count, volume and print covers trades at or above the chain's floor, returned as `ingestFloor`. BNB Chain runs at $100 today; Avalanche and Base at 0.\n- **Readiness.** `503 NOT_READY` until the chain's rollup has run on this deployment; `503 CHAIN_DATA_UNAVAILABLE` when the store cannot be read. Never treat either as \"no trades\".","url":"https://getchord.xyz/docs/api-reference/operations/chainoverview/","parameters":[{"name":"chain","in":"path","required":true,"type":"string","enum":["avalanche","base","bnb","arbitrum","ethereum","43114","8453","56","42161","1"],"description":"The chain, by key or id: `avalanche` or `43114`, `base` or `8453`, `bnb` or `56`, `arbitrum` or `42161`, `ethereum` or `1` (case-insensitive). Arc, Robinhood Chain and Monad are refused with `400 UNSUPPORTED_CHAIN` and a pointer to their own routes."}],"requestBody":null,"responses":{"200":"","400":"`UNSUPPORTED_CHAIN` (unknown chain, a chain with its own routes, or a chain not served to this caller yet).","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","503":"`NOT_READY` (the chain's rollup has not run on this deployment yet) or `CHAIN_DATA_UNAVAILABLE` (the store could not be read). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"integer","last24h":{"volUsd":"number","swaps":"integer","tokens":"integer","venues":"integer","sinceHour":"integer — Start of the window."},"wallets":{"day":"integer — Unix time, seconds, UTC.","today":"integer|null — Distinct attributed wallets so far today (UTC); partial.","yesterday":"integer|null"},"venues24h":[{"dex":"string — Venue id.","volUsd":"number","trades":"integer","tokens":"integer","sharePct":"number"}],"hourly24":[{"hour":"integer","volUsd":"number","swaps":"integer"}],"daily":[{"day":"integer","swaps":"integer","volUsd":"number","tokens":"integer","wallets":"integer — Attributed wallets only.","venues":"integer"}],"coverage":{"recentAt":"integer — Unix time, seconds, UTC.","stale":"boolean — True when the last rollup pass is more than 30 minutes old."},"ingestFloor":{"minTradeUsd":"number — Trades under this USD value (at index time) are not in the index, so every count, volume and candle covers trades at or above it. 0 = every priced trade.","history":["object"]},"updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":{"chain":56,"last24h":{"volUsd":1014438316.7825807,"swaps":1725125,"tokens":4466,"venues":57,"sinceHour":1790935200},"wallets":{"day":1790985600,"today":52979,"yesterday":110488},"venues24h":[{"dex":"pancake_v3","volUsd":507002171.3116286,"trades":802437,"tokens":581,"sharePct":49.97861012581327},{"dex":"pancake_v2","volUsd":243172605.08525935,"trades":299915,"tokens":2950,"sharePct":23.971157345131836}],"hourly24":[{"hour":1790935200,"volUsd":32855754.23107098,"swaps":62895},{"hour":1790938800,"volUsd":37902743.56465449,"swaps":74862}],"daily":[{"day":1790726400,"swaps":352759,"volUsd":201620870.33918935,"tokens":1711,"wallets":24991,"venues":31},{"day":1790812800,"swaps":2017913,"volUsd":1025889560.5733465,"tokens":4523,"wallets":95849,"venues":55}],"coverage":{"recentAt":1791020331,"stale":false},"ingestFloor":{"minTradeUsd":100,"history":[{"usd":100,"fromTs":1790789196}]},"updatedAt":1791020818773}},"security":null},{"kind":"operation","operationId":"chainTokens","method":"GET","path":"/v1/chains/{chain}/tokens","tag":"Avalanche, Base, BNB Chain","summary":"Every token traded in the last 24 hours","description":"The chain's 24-hour board: price on the busiest venue, change, volume split, trade counts and the dominant venue for every token that traded, with symbol, name and decimals read from the contract. There is no curated list on these chains yet: rows carry no logo, no `listed` flag, no trader count and no wash or impostor flags, so check the address before trusting a symbol.\n\nChain-keyed data for Avalanche C-Chain, Base and BNB Chain, served from Chord's rollup tables for the chain (every swap summed by hour, token and venue). Only the trade tape, the prints ticker and the wallet read raw rows, scoped to one token or one wallet and bounded.\n\n- **Access.** No key needed while the chain is public (all three are today). A chain whose tape is off, or that is not public yet, answers `400 UNSUPPORTED_CHAIN` (\"chain N is not served yet\") unless the request carries an `X-API-Key`; those answers are sent `Cache-Control: private`.\n- **Ingest floor.** Every count, volume and print covers trades at or above the chain's floor, returned as `ingestFloor`. BNB Chain runs at $100 today; Avalanche and Base at 0.\n- **Readiness.** `503 NOT_READY` until the chain's rollup has run on this deployment; `503 CHAIN_DATA_UNAVAILABLE` when the store cannot be read. Never treat either as \"no trades\".","url":"https://getchord.xyz/docs/api-reference/operations/chaintokens/","parameters":[{"name":"chain","in":"path","required":true,"type":"string","enum":["avalanche","base","bnb","arbitrum","ethereum","43114","8453","56","42161","1"],"description":"The chain, by key or id: `avalanche` or `43114`, `base` or `8453`, `bnb` or `56`, `arbitrum` or `42161`, `ethereum` or `1` (case-insensitive). Arc, Robinhood Chain and Monad are refused with `400 UNSUPPORTED_CHAIN` and a pointer to their own routes."},{"name":"limit","in":"query","required":false,"type":"integer","default":100,"description":""},{"name":"sort","in":"query","required":false,"type":"string","enum":["volume","trades","change"],"default":"volume","description":"Descending."}],"requestBody":null,"responses":{"200":"","400":"`UNSUPPORTED_CHAIN` (unknown chain, a chain with its own routes, or a chain not served to this caller yet), or `BAD_LIMIT` / `BAD_SORT`.","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","503":"`NOT_READY` (the chain's rollup has not run on this deployment yet) or `CHAIN_DATA_UNAVAILABLE` (the store could not be read). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"integer","sinceHour":"integer","sort":"string","total":"integer — Tokens that traded in the window.","tokens":[{"address":"string — EVM address, hex, case-insensitive.","symbol":"string|null — Read from the contract. Null while unresolved.","name":"string|null","decimals":"integer|null","logoURI":"null — Always null on these chains for now.","priceUsd":"number|null — Last print on the token's busiest venue, USD.","change24hPct":"number|null","volume24h":"number — USD, every venue, trades at or above the ingest floor.","buyVolume24h":"number","sellVolume24h":"number","trades24h":"integer","buys24h":"integer","sells24h":"integer","dominantDex":"string|null — Venue id with the most 24-hour volume.","lastTradeTs":"integer — Unix time, seconds, UTC."}],"coverage":{"recentAt":"integer — Unix time, seconds, UTC.","stale":"boolean — True when the last rollup pass is more than 30 minutes old."},"ingestFloor":{"minTradeUsd":"number — Trades under this USD value (at index time) are not in the index, so every count, volume and candle covers trades at or above it. 0 = every priced trade.","history":["object"]},"updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":{"chain":56,"sinceHour":1790935200,"sort":"volume","total":4477,"tokens":[{"address":"0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c","symbol":"WBNB","name":"Wrapped BNB","decimals":18,"logoURI":null,"priceUsd":767.6455496451134,"change24hPct":-1.2492564760959057,"volume24h":166967025.3366614,"buyVolume24h":82320162.1387899,"sellVolume24h":84646863.19787142,"trades24h":249872,"buys24h":126268,"sells24h":123604,"dominantDex":"pancake_v3","lastTradeTs":1791020960},{"address":"0x4fa7c69a7b69f8bc48233024d546bc299d6b03bf","symbol":"quq","name":"quq","decimals":18,"logoURI":null,"priceUsd":0.0016094473421225778,"change24hPct":-0.02009274621601609,"volume24h":117639331.46884526,"buyVolume24h":58830955.6143909,"sellVolume24h":58808375.85445432,"trades24h":23746,"buys24h":11867,"sells24h":11879,"dominantDex":"pancake_v3","lastTradeTs":1791020960}],"coverage":{"recentAt":1791020996,"stale":false},"ingestFloor":{"minTradeUsd":100,"history":[{"usd":100,"fromTs":1790789196}]},"updatedAt":1791021450415}},"security":null},{"kind":"operation","operationId":"chainPrints","method":"GET","path":"/v1/chains/{chain}/prints","tag":"Avalanche, Base, BNB Chain","summary":"Latest prints across the chain","description":"The newest swaps of tokens on the chain's 24-hour board, newest first: a ticker, not a tape. It looks back ten minutes, skips trades under $1, keeps at most three prints a token so one busy pair does not fill it, and is shared for 10 seconds per chain. For one token's full tape use `/chains/{chain}/token/{address}/trades`.\n\nChain-keyed data for Avalanche C-Chain, Base and BNB Chain, served from Chord's rollup tables for the chain (every swap summed by hour, token and venue). Only the trade tape, the prints ticker and the wallet read raw rows, scoped to one token or one wallet and bounded.\n\n- **Access.** No key needed while the chain is public (all three are today). A chain whose tape is off, or that is not public yet, answers `400 UNSUPPORTED_CHAIN` (\"chain N is not served yet\") unless the request carries an `X-API-Key`; those answers are sent `Cache-Control: private`.\n- **Ingest floor.** Every count, volume and print covers trades at or above the chain's floor, returned as `ingestFloor`. BNB Chain runs at $100 today; Avalanche and Base at 0.\n- **Readiness.** `503 NOT_READY` until the chain's rollup has run on this deployment; `503 CHAIN_DATA_UNAVAILABLE` when the store cannot be read. Never treat either as \"no trades\".","url":"https://getchord.xyz/docs/api-reference/operations/chainprints/","parameters":[{"name":"chain","in":"path","required":true,"type":"string","enum":["avalanche","base","bnb","arbitrum","ethereum","43114","8453","56","42161","1"],"description":"The chain, by key or id: `avalanche` or `43114`, `base` or `8453`, `bnb` or `56`, `arbitrum` or `42161`, `ethereum` or `1` (case-insensitive). Arc, Robinhood Chain and Monad are refused with `400 UNSUPPORTED_CHAIN` and a pointer to their own routes."},{"name":"limit","in":"query","required":false,"type":"integer","default":20,"description":""}],"requestBody":null,"responses":{"200":"","400":"`UNSUPPORTED_CHAIN` (unknown chain, a chain with its own routes, or a chain not served to this caller yet), or `BAD_LIMIT`.","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","503":"`NOT_READY` (the chain's rollup has not run on this deployment yet) or `CHAIN_DATA_UNAVAILABLE` (the store could not be read). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"integer","prints":[{"tx":"string — Transaction hash.","logIndex":"integer","block":"integer","dex":"string","token":"string — EVM address, hex, case-insensitive.","side":"string (buy|sell)","usd":"number","priceUsd":"number","ts":"integer — Unix time, seconds, UTC.","symbol":"string — From the board."}],"updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":{"chain":56,"prints":[{"tx":"0xfd35e2957d9660bddbef974222d8f4cf0960aa00ffbb560b437eeda98921124d","logIndex":322,"block":125464252,"dex":"uniswap_v4","token":"0xca750ef65f295bbecd685abf54e82caf297bdb61","side":"sell","usd":374.6517520746725,"priceUsd":196.98795013758274,"ts":1791021448,"symbol":"SKHYB"},{"tx":"0x8eb8fb435526573f238417c155ebd7ad95ff73dae108eed0965db4bb7d84f7f3","logIndex":175,"block":125464252,"dex":"pancake_infinity_cl","token":"0x7ec43cf65f1663f820427c62a5780b8f2e25593a","side":"buy","usd":109.53620868310122,"priceUsd":0.052400254396345075,"ts":1791021448,"symbol":"LAB"}],"updatedAt":1791021450656}},"security":null},{"kind":"operation","operationId":"chainToken","method":"GET","path":"/v1/chains/{chain}/token/{address}","tag":"Avalanche, Base, BNB Chain","summary":"One token: hourly tape and venue split","description":"The token's identity (read from the contract), 24-hour stats, an hourly series (1–720 hours) and the venue split for the window. `404 UNKNOWN_TOKEN` when the chain's rollups have never seen the token trade; the same address on another chain is another token. For a price of a token Chord has not seen trade, `/ref-price` asks CoinGecko.\n\nChain-keyed data for Avalanche C-Chain, Base and BNB Chain, served from Chord's rollup tables for the chain (every swap summed by hour, token and venue). Only the trade tape, the prints ticker and the wallet read raw rows, scoped to one token or one wallet and bounded.\n\n- **Access.** No key needed while the chain is public (all three are today). A chain whose tape is off, or that is not public yet, answers `400 UNSUPPORTED_CHAIN` (\"chain N is not served yet\") unless the request carries an `X-API-Key`; those answers are sent `Cache-Control: private`.\n- **Ingest floor.** Every count, volume and print covers trades at or above the chain's floor, returned as `ingestFloor`. BNB Chain runs at $100 today; Avalanche and Base at 0.\n- **Readiness.** `503 NOT_READY` until the chain's rollup has run on this deployment; `503 CHAIN_DATA_UNAVAILABLE` when the store cannot be read. Never treat either as \"no trades\".","url":"https://getchord.xyz/docs/api-reference/operations/chaintoken/","parameters":[{"name":"chain","in":"path","required":true,"type":"string","enum":["avalanche","base","bnb","arbitrum","ethereum","43114","8453","56","42161","1"],"description":"The chain, by key or id: `avalanche` or `43114`, `base` or `8453`, `bnb` or `56`, `arbitrum` or `42161`, `ethereum` or `1` (case-insensitive). Arc, Robinhood Chain and Monad are refused with `400 UNSUPPORTED_CHAIN` and a pointer to their own routes."},{"name":"address","in":"path","required":true,"type":"string","description":"Token address. The zero address means the chain's wrapped native token (WAVAX, WETH, WBNB)."},{"name":"hours","in":"query","required":false,"type":"integer","default":168,"description":"Hourly buckets to return."}],"requestBody":null,"responses":{"200":"","400":"`UNSUPPORTED_CHAIN` (unknown chain, a chain with its own routes, or a chain not served to this caller yet), or `BAD_ADDRESS` / `BAD_HOURS`.","404":"`UNKNOWN_TOKEN`: no indexed trades for this token on this chain.","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","503":"`NOT_READY` (the chain's rollup has not run on this deployment yet) or `CHAIN_DATA_UNAVAILABLE` (the store could not be read). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"integer","token":{"address":"string — EVM address, hex, case-insensitive.","symbol":"string|null","name":"string|null","decimals":"integer|null","logoURI":"null"},"hours":"integer","stats24h":{"volUsd":"number","buyUsd":"number","sellUsd":"number","trades":"integer","buys":"integer","sells":"integer","lastTs":"integer — Unix time, seconds, UTC.","dominantDex":"string|null","priceUsd":"number|null — Last print on the dominant venue.","priceThen":"number|null — Price 24 hours ago, same rule.","change24hPct":"number|null","sinceHour":"integer"},"series":[{"hour":"integer","volUsd":"number","buyUsd":"number","sellUsd":"number","trades":"integer","buys":"integer","sells":"integer","priceLast":"number|null — The busiest venue's last print in the hour."}],"byDex":[{"dex":"string","volUsd":"number","trades":"integer","sharePct":"number"}],"coverage":{"recentAt":"integer — Unix time, seconds, UTC.","stale":"boolean — True when the last rollup pass is more than 30 minutes old."},"ingestFloor":{"minTradeUsd":"number — Trades under this USD value (at index time) are not in the index, so every count, volume and candle covers trades at or above it. 0 = every priced trade.","history":["object"]},"updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":{"chain":56,"token":{"address":"0x7130d2a12b9bcbfae4f2634d864a1ee1ce3ead9c","symbol":"BTCB","name":"BTCB Token","decimals":18,"logoURI":null},"hours":2,"stats24h":{"volUsd":60117802.11906611,"buyUsd":28027904.632707972,"sellUsd":32089897.486358132,"trades":43182,"buys":20811,"sells":22371,"lastTs":1791020918,"dominantDex":"pancake_v3","priceUsd":84842.07226361385,"priceThen":86518.97620817002,"change24hPct":-1.93819207999113,"sinceHour":1790935200},"series":[{"hour":1791014400,"volUsd":335885.749755259,"buyUsd":157624.90195060932,"sellUsd":178260.84780464956,"trades":500,"buys":259,"sells":241,"priceLast":84615.63679704415},{"hour":1791018000,"volUsd":499369.02600572666,"buyUsd":84656.32485821295,"sellUsd":414712.70114751335,"trades":636,"buys":166,"sells":470,"priceLast":84842.07226361385}],"byDex":[{"dex":"pancake_v3","volUsd":712878.8358403383,"trades":920,"sharePct":85.34866923578463},{"dex":"uniswap_v3","volUsd":100444.15196685962,"trades":98,"sharePct":12.025570506357985}],"coverage":{"recentAt":1791020996,"stale":false},"ingestFloor":{"minTradeUsd":100,"history":[{"usd":100,"fromTs":1790789196}]},"updatedAt":1791021450886}},"security":null},{"kind":"operation","operationId":"chainTokenRefPrice","method":"GET","path":"/v1/chains/{chain}/token/{address}/ref-price","tag":"Avalanche, Base, BNB Chain","summary":"Reference price from CoinGecko","description":"CoinGecko's price and 24-hour change for a token by contract address, for a token Chord's index has not seen trade (or to cross-check one it has). Not Chord's own data: the answer says so in `source`. Cached two minutes; `ageS` is the age of the cached CoinGecko answer.\n\nChain-keyed data for Avalanche C-Chain, Base and BNB Chain, served from Chord's rollup tables for the chain (every swap summed by hour, token and venue). Only the trade tape, the prints ticker and the wallet read raw rows, scoped to one token or one wallet and bounded.\n\n- **Access.** No key needed while the chain is public (all three are today). A chain whose tape is off, or that is not public yet, answers `400 UNSUPPORTED_CHAIN` (\"chain N is not served yet\") unless the request carries an `X-API-Key`; those answers are sent `Cache-Control: private`.\n- **Ingest floor.** Every count, volume and print covers trades at or above the chain's floor, returned as `ingestFloor`. BNB Chain runs at $100 today; Avalanche and Base at 0.\n- **Readiness.** `503 NOT_READY` until the chain's rollup has run on this deployment; `503 CHAIN_DATA_UNAVAILABLE` when the store cannot be read. Never treat either as \"no trades\".","url":"https://getchord.xyz/docs/api-reference/operations/chaintokenrefprice/","parameters":[{"name":"chain","in":"path","required":true,"type":"string","enum":["avalanche","base","bnb","arbitrum","ethereum","43114","8453","56","42161","1"],"description":"The chain, by key or id: `avalanche` or `43114`, `base` or `8453`, `bnb` or `56`, `arbitrum` or `42161`, `ethereum` or `1` (case-insensitive). Arc, Robinhood Chain and Monad are refused with `400 UNSUPPORTED_CHAIN` and a pointer to their own routes."},{"name":"address","in":"path","required":true,"type":"string","description":"Token address. The zero address means the chain's wrapped native token (WAVAX, WETH, WBNB)."}],"requestBody":null,"responses":{"200":"","400":"`UNSUPPORTED_CHAIN` (unknown chain, a chain with its own routes, or a chain not served to this caller yet), or `BAD_ADDRESS`.","404":"`NOT_LISTED`: CoinGecko does not list this token on this chain.","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","503":"`UNAVAILABLE`: CoinGecko did not answer. Retry later."},"response":{"schema":{"chain":"integer","address":"string — EVM address, hex, case-insensitive.","priceUsd":"number","change24hPct":"number|null","source":"string","ageS":"integer — Seconds since CoinGecko answered."},"example":{"chain":56,"address":"0x7130d2a12b9bcbfae4f2634d864a1ee1ce3ead9c","priceUsd":84397,"change24hPct":-2.11,"source":"coingecko","ageS":0}},"security":null},{"kind":"operation","operationId":"chainTokenTrades","method":"GET","path":"/v1/chains/{chain}/token/{address}/trades","tag":"Avalanche, Base, BNB Chain","summary":"Trade tape","description":"The token's swaps straight from the raw tape, newest first: venue, side, size, USD, price, block, wallet (`null` for a router or an unattributed trade, never a guess) and pool. Keyset-paged: pass `nextBefore` back as `before` for the next page; `nextBefore` is null on the last one. The raw tape is short on these chains (see `retentionCutoffDay` on `/status`), so paging stops there.\n\nChain-keyed data for Avalanche C-Chain, Base and BNB Chain, served from Chord's rollup tables for the chain (every swap summed by hour, token and venue). Only the trade tape, the prints ticker and the wallet read raw rows, scoped to one token or one wallet and bounded.\n\n- **Access.** No key needed while the chain is public (all three are today). A chain whose tape is off, or that is not public yet, answers `400 UNSUPPORTED_CHAIN` (\"chain N is not served yet\") unless the request carries an `X-API-Key`; those answers are sent `Cache-Control: private`.\n- **Ingest floor.** Every count, volume and print covers trades at or above the chain's floor, returned as `ingestFloor`. BNB Chain runs at $100 today; Avalanche and Base at 0.\n- **Readiness.** `503 NOT_READY` until the chain's rollup has run on this deployment; `503 CHAIN_DATA_UNAVAILABLE` when the store cannot be read. Never treat either as \"no trades\".","url":"https://getchord.xyz/docs/api-reference/operations/chaintokentrades/","parameters":[{"name":"chain","in":"path","required":true,"type":"string","enum":["avalanche","base","bnb","arbitrum","ethereum","43114","8453","56","42161","1"],"description":"The chain, by key or id: `avalanche` or `43114`, `base` or `8453`, `bnb` or `56`, `arbitrum` or `42161`, `ethereum` or `1` (case-insensitive). Arc, Robinhood Chain and Monad are refused with `400 UNSUPPORTED_CHAIN` and a pointer to their own routes."},{"name":"address","in":"path","required":true,"type":"string","description":"Token address. The zero address means the chain's wrapped native token (WAVAX, WETH, WBNB)."},{"name":"limit","in":"query","required":false,"type":"integer","default":50,"description":"Newest rows."},{"name":"before","in":"query","required":false,"type":"string","description":"Exclusive cursor: the previous page's `nextBefore` (`ts:block:logIndex`), or a Unix second."}],"requestBody":null,"responses":{"200":"","400":"`UNSUPPORTED_CHAIN` (unknown chain, a chain with its own routes, or a chain not served to this caller yet), or `BAD_ADDRESS` / `BAD_LIMIT` / `BAD_BEFORE`.","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","503":"`NOT_READY` (the chain's rollup has not run on this deployment yet) or `CHAIN_DATA_UNAVAILABLE` (the store could not be read). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"integer","token":"string — EVM address, hex, case-insensitive.","trades":[{"tx":"string — Transaction hash.","logIndex":"integer","block":"integer","dex":"string","side":"string (buy|sell)","tokenAmt":"number — Whole tokens.","usd":"number","priceUsd":"number","ts":"integer — Unix time, seconds, UTC.","wallet":"string|null — EVM address, hex, case-insensitive.","pool":"string — A pool: a 20-byte contract address (V2 / V3) or a 32-byte Uniswap V4 pool id."}],"nextBefore":"string|null — Cursor for the next page; null when this page is not full.","ingestFloor":{"minTradeUsd":"number — Trades under this USD value (at index time) are not in the index, so every count, volume and candle covers trades at or above it. 0 = every priced trade.","history":["object"]},"updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":{"chain":56,"token":"0x7130d2a12b9bcbfae4f2634d864a1ee1ce3ead9c","trades":[{"tx":"0x92fdb5120761de73892df232e459c1e93bd540160abf8123235d24b6a7544f65","logIndex":116,"block":125464201,"dex":"pancake_v3","side":"buy","tokenAmt":0.003505439793265937,"usd":296.55131688178034,"priceUsd":84597.46404758256,"ts":1791021425,"wallet":"0x7d63e553f87e560528ecd18e3d801ef4c7144313","pool":"0x247f51881d1e3ae0f759afb801413a6c948ef442"},{"tx":"0xbc749bf541475ff782ea186a076614a6634ace0abe6f855d1b4f6f7ff871055f","logIndex":138,"block":125464200,"dex":"pancake_v3","side":"sell","tokenAmt":0.001923013554163473,"usd":162.647334016205,"priceUsd":84579.40073488351,"ts":1791021425,"wallet":"0x939572264f180637d6a0f62aac7df9a4387146bd","pool":"0x247f51881d1e3ae0f759afb801413a6c948ef442"}],"nextBefore":"1791021425:125464200:138","ingestFloor":{"minTradeUsd":100,"history":[{"usd":100,"fromTs":1790789196}]},"updatedAt":1791021451693}},"security":null},{"kind":"operation","operationId":"chainVenues","method":"GET","path":"/v1/chains/{chain}/venues","tag":"Avalanche, Base, BNB Chain","summary":"Venue share over a window","description":"Per-venue volume, trades and share for 1–30 UTC days, with a daily series per venue. The first day of a young tape is partial.\n\nChain-keyed data for Avalanche C-Chain, Base and BNB Chain, served from Chord's rollup tables for the chain (every swap summed by hour, token and venue). Only the trade tape, the prints ticker and the wallet read raw rows, scoped to one token or one wallet and bounded.\n\n- **Access.** No key needed while the chain is public (all three are today). A chain whose tape is off, or that is not public yet, answers `400 UNSUPPORTED_CHAIN` (\"chain N is not served yet\") unless the request carries an `X-API-Key`; those answers are sent `Cache-Control: private`.\n- **Ingest floor.** Every count, volume and print covers trades at or above the chain's floor, returned as `ingestFloor`. BNB Chain runs at $100 today; Avalanche and Base at 0.\n- **Readiness.** `503 NOT_READY` until the chain's rollup has run on this deployment; `503 CHAIN_DATA_UNAVAILABLE` when the store cannot be read. Never treat either as \"no trades\".","url":"https://getchord.xyz/docs/api-reference/operations/chainvenues/","parameters":[{"name":"chain","in":"path","required":true,"type":"string","enum":["avalanche","base","bnb","arbitrum","ethereum","43114","8453","56","42161","1"],"description":"The chain, by key or id: `avalanche` or `43114`, `base` or `8453`, `bnb` or `56`, `arbitrum` or `42161`, `ethereum` or `1` (case-insensitive). Arc, Robinhood Chain and Monad are refused with `400 UNSUPPORTED_CHAIN` and a pointer to their own routes."},{"name":"days","in":"query","required":false,"type":"integer","default":30,"description":"Window length, in UTC days including today."}],"requestBody":null,"responses":{"200":"","400":"`UNSUPPORTED_CHAIN` (unknown chain, a chain with its own routes, or a chain not served to this caller yet), or `BAD_DAYS`.","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","503":"`NOT_READY` (the chain's rollup has not run on this deployment yet) or `CHAIN_DATA_UNAVAILABLE` (the store could not be read). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"integer","days":"integer","since":"integer — Unix time, seconds, UTC.","venues":[{"dex":"string","volUsd":"number","trades":"integer","sharePct":"number","series":"array"}],"totals":{"volUsd":"number","trades":"integer"},"updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":{"chain":56,"days":2,"since":1790899200,"venues":[{"dex":"pancake_v3","volUsd":736112650.6777563,"trades":1132649,"sharePct":48.37984424468907,"series":[{"day":1790899200,"volUsd":580832396.3483784,"trades":883596,"tokens":576},{"day":1790985600,"volUsd":155280254.32937792,"trades":249053,"tokens":430}]},{"dex":"pancake_infinity_cl","volUsd":315145928.03220856,"trades":871769,"sharePct":20.712469617942627,"series":[{"day":1790899200,"volUsd":249510270.7062881,"trades":732838,"tokens":166},{"day":1790985600,"volUsd":65635657.32592046,"trades":138931,"tokens":128}]}],"totals":{"volUsd":1521527533.1494346,"trades":2819913},"updatedAt":1791021451942}},"security":null},{"kind":"operation","operationId":"chainWalletTrades","method":"GET","path":"/v1/chains/{chain}/wallet/{address}/trades","tag":"Avalanche, Base, BNB Chain","summary":"A wallet's swaps","description":"The wallet's swaps on the chain, newest first, each with the token and its symbol. Keyset-paged: pass `nextBefore` back as `before` for the next page; `nextBefore` is null on the last one.\n\n**The list covers the raw tape only**: the last few days the database keeps on these chains (about 3 on BNB Chain and Base, 7 on Avalanche today). `window.fromTs` is where it starts. Older days are counted in the wallet route named by `olderHistory`, as totals per token, not as a list. Say how far back the list goes when you show it.\n\n- `wallet` on a trade is the address the tape attributed it to; a swap sent through a router that the tape could not attribute is not in the list.\n- Trades under the chain's ingest floor are not in the tape (BNB Chain: $100).\n\nChain-keyed data for Avalanche C-Chain, Base and BNB Chain, served from Chord's rollup tables for the chain (every swap summed by hour, token and venue). Only the trade tape, the prints ticker and the wallet read raw rows, scoped to one token or one wallet and bounded.\n\n- **Access.** No key needed while the chain is public (all three are today). A chain whose tape is off, or that is not public yet, answers `400 UNSUPPORTED_CHAIN` (\"chain N is not served yet\") unless the request carries an `X-API-Key`; those answers are sent `Cache-Control: private`.\n- **Ingest floor.** Every count, volume and print covers trades at or above the chain's floor, returned as `ingestFloor`. BNB Chain runs at $100 today; Avalanche and Base at 0.\n- **Readiness.** `503 NOT_READY` until the chain's rollup has run on this deployment; `503 CHAIN_DATA_UNAVAILABLE` when the store cannot be read. Never treat either as \"no trades\".","url":"https://getchord.xyz/docs/api-reference/operations/chainwallettrades/","parameters":[{"name":"chain","in":"path","required":true,"type":"string","enum":["avalanche","base","bnb","arbitrum","ethereum","43114","8453","56","42161","1"],"description":"The chain, by key or id: `avalanche` or `43114`, `base` or `8453`, `bnb` or `56`, `arbitrum` or `42161`, `ethereum` or `1` (case-insensitive). Arc, Robinhood Chain and Monad are refused with `400 UNSUPPORTED_CHAIN` and a pointer to their own routes."},{"name":"address","in":"path","required":true,"type":"string","description":"Wallet address."},{"name":"limit","in":"query","required":false,"type":"integer","default":50,"description":"Newest rows."},{"name":"before","in":"query","required":false,"type":"string","description":"Exclusive cursor: the previous page's `nextBefore` (`ts:block:logIndex`), or a Unix second."}],"requestBody":null,"responses":{"200":"","400":"`UNSUPPORTED_CHAIN` (unknown chain, a chain with its own routes, or a chain not served to this caller yet), or `BAD_ADDRESS` / `BAD_LIMIT` / `BAD_BEFORE`.","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","503":"`NOT_READY` (the chain's rollup has not run on this deployment yet) or `CHAIN_DATA_UNAVAILABLE` (the store could not be read). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"integer","wallet":"string — EVM address, hex, case-insensitive.","window":{"fromTs":"integer|null — Unix time, seconds, UTC.","toTs":"integer — Unix time, seconds, UTC."},"history":"string — Always `raw`: this list never reads the data lake.","trades":[{"ts":"integer — Unix time, seconds, UTC.","tx":"string — Transaction hash.","logIndex":"integer","block":"integer","token":"string — EVM address, hex, case-insensitive.","symbol":"string|null","side":"string (buy|sell)","tokenAmt":"number — Whole tokens.","usd":"number","priceUsd":"number","dex":"string"}],"nextBefore":"string|null — Cursor for the next page; null when this page is not full.","olderHistory":"string|null — Path of the wallet route that counts the days before `window.fromTs`.","ingestFloor":{"minTradeUsd":"number — Trades under this USD value (at index time) are not in the index, so every count, volume and candle covers trades at or above it. 0 = every priced trade.","history":["object"]}},"example":{"chain":56,"wallet":"0x2cf971cb78b7a3cdc0b2044a11abd7392b796c2d","window":{"fromTs":1791417600,"toTs":1791746566},"history":"raw","trades":[{"ts":1791746543,"tx":"0x330db50d0c397734e4d61fc2659b053527a9076f516b00050d4cceed47cf9c7e","logIndex":50,"block":127074619,"token":"0x4fa7c69a7b69f8bc48233024d546bc299d6b03bf","side":"sell","tokenAmt":950204.2671867504,"usd":1519.2258102727808,"priceUsd":0.0015988412836439056,"dex":"pancake_v3","symbol":"quq"},{"ts":1791746523,"tx":"0x4e1457e8bdc7d83db90ce6fed43a8092f71814c57834ecad38ec4746b47c11c1","logIndex":45,"block":127074574,"token":"0x4fa7c69a7b69f8bc48233024d546bc299d6b03bf","side":"buy","tokenAmt":855183.3425646495,"usd":1367.5757736974172,"priceUsd":0.0015991609116194076,"dex":"pancake_v3","symbol":"quq"}],"nextBefore":"1791746523:127074574:45","olderHistory":"/v1/chains/bnb/wallet/0x2cf971cb78b7a3cdc0b2044a11abd7392b796c2d","ingestFloor":{"minTradeUsd":100,"history":[{"usd":100,"fromTs":1790789196}]}}},"security":null},{"kind":"operation","operationId":"chainWallet","method":"GET","path":"/v1/chains/{chain}/wallet/{address}","tag":"Avalanche, Base, BNB Chain","summary":"One wallet's swaps and PnL","description":"A wallet's swaps on the chain and an average-cost PnL over them. **The window is short**: the database keeps the raw tape for a few days on these chains (about 3 on BNB Chain and Base, 7 on Avalanche today), and older days come from Chord's data lake only where its days run without a gap up to that window. `window` says how far back the numbers go and `history` where they came from (`raw`, `raw+lake`, or `raw (lake unavailable)`). Say so when you show the number.\n\n- A buy adds tokens and cost; a sell realizes proceeds minus the average cost of the part the window saw bought.\n- A sell with nothing bought in the window has no cost basis: it is counted in `soldWithoutBasisUsd`, never as profit.\n- `holdsTokens` is bought minus sold inside the window, priced at the token's last hourly print. It is not the on-chain balance (transfers are not swaps).\n- Trades under the chain's ingest floor are not in the tape (BNB Chain: $100).\n- Past 5,000 swaps in the window the newest 5,000 are kept and `truncated` is true (a bot or a router).\n\nChain-keyed data for Avalanche C-Chain, Base and BNB Chain, served from Chord's rollup tables for the chain (every swap summed by hour, token and venue). Only the trade tape, the prints ticker and the wallet read raw rows, scoped to one token or one wallet and bounded.\n\n- **Access.** No key needed while the chain is public (all three are today). A chain whose tape is off, or that is not public yet, answers `400 UNSUPPORTED_CHAIN` (\"chain N is not served yet\") unless the request carries an `X-API-Key`; those answers are sent `Cache-Control: private`.\n- **Ingest floor.** Every count, volume and print covers trades at or above the chain's floor, returned as `ingestFloor`. BNB Chain runs at $100 today; Avalanche and Base at 0.\n- **Readiness.** `503 NOT_READY` until the chain's rollup has run on this deployment; `503 CHAIN_DATA_UNAVAILABLE` when the store cannot be read. Never treat either as \"no trades\".","url":"https://getchord.xyz/docs/api-reference/operations/chainwallet/","parameters":[{"name":"chain","in":"path","required":true,"type":"string","enum":["avalanche","base","bnb","arbitrum","ethereum","43114","8453","56","42161","1"],"description":"The chain, by key or id: `avalanche` or `43114`, `base` or `8453`, `bnb` or `56`, `arbitrum` or `42161`, `ethereum` or `1` (case-insensitive). Arc, Robinhood Chain and Monad are refused with `400 UNSUPPORTED_CHAIN` and a pointer to their own routes."},{"name":"address","in":"path","required":true,"type":"string","description":"Wallet address."}],"requestBody":null,"responses":{"200":"","400":"`UNSUPPORTED_CHAIN` (unknown chain, a chain with its own routes, or a chain not served to this caller yet), or `BAD_ADDRESS`.","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","503":"`CHAIN_DATA_UNAVAILABLE`: the store could not be read. Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"integer","wallet":"string — EVM address, hex, case-insensitive.","window":{"fromTs":"integer|null — Unix time, seconds, UTC.","toTs":"integer — Unix time, seconds, UTC.","days":"integer|null"},"history":"string (raw|raw+lake|raw (lake unavailable)) — Where the window's rows came from.","trades":"integer — Swaps in the window.","truncated":"boolean — More than 5,000 swaps in the window: only the newest 5,000 are counted.","realizedUsd":"number","unrealizedUsd":"number","totalUsd":"number","volumeUsd":"number","soldWithoutBasisUsd":"number — Sell proceeds with no buy in the window to match. Not profit.","tokens":[{"token":"string — EVM address, hex, case-insensitive.","symbol":"string|null","buys":"integer","sells":"integer","boughtUsd":"number","soldUsd":"number","realizedUsd":"number","unrealizedUsd":"number","totalUsd":"number","holdsTokens":"number — Bought minus sold in the window, whole tokens.","holdsUsd":"number","avgCostUsd":"number|null — Average cost per token of what is still held.","lastPriceUsd":"number|null — Last hourly print within 7 days.","soldWithoutBasisUsd":"number"}],"recent":[{"ts":"integer — Unix time, seconds, UTC.","tx":"string — Transaction hash.","logIndex":"integer","token":"string — EVM address, hex, case-insensitive.","side":"string (buy|sell)","tokenAmt":"number","usd":"number","priceUsd":"number","dex":"string","symbol":"string|null"}],"ingestFloor":{"minTradeUsd":"number — Trades under this USD value (at index time) are not in the index, so every count, volume and candle covers trades at or above it. 0 = every priced trade.","history":["object"]},"updatedAt":"integer — Unix time, milliseconds — when the server built this answer."},"example":{"chain":56,"wallet":"0x34135a8b5cc02d1b579789fb09dd9cec4f8d7c13","window":{"fromTs":1790726400,"toTs":1791021452,"days":3},"history":"raw","trades":438,"truncated":false,"realizedUsd":-52.50256178614943,"unrealizedUsd":264.3511103300407,"totalUsd":211.84854854389124,"volumeUsd":1074760.992352269,"soldWithoutBasisUsd":142196.1744304485,"tokens":[{"token":"0x7130d2a12b9bcbfae4f2634d864a1ee1ce3ead9c","symbol":"BTCB","buys":82,"sells":88,"boughtUsd":232801.99929077973,"soldUsd":268637.2602480728,"realizedUsd":332.35056120683566,"unrealizedUsd":322.78762778211967,"totalUsd":655.1381889889553,"holdsTokens":0.48237177905003725,"holdsUsd":40925.42133609123,"avgCostUsd":84172.90453490094,"lastPriceUsd":84842.07226361385,"soldWithoutBasisUsd":76105.54410439507},{"token":"0x2170ed0880ac9a755fd29b2688956bd959f933f8","symbol":"ETH","buys":92,"sells":96,"boughtUsd":179038.3807585184,"soldUsd":167683.46997452437,"realizedUsd":-421.56179009490035,"unrealizedUsd":-58.43651745207899,"totalUsd":-479.99830754697933,"holdsTokens":14.799424875074559,"holdsUsd":39691.36613138376,"avgCostUsd":2685.901849860607,"lastPriceUsd":2681.9532830787653,"soldWithoutBasisUsd":28816.45365493667}],"recent":[{"ts":1791021243,"tx":"0xfacfd422253d675c6f886afffeb849d5a4f50c38cb0a3a5979b73473dd5b4273","logIndex":31,"token":"0x7130d2a12b9bcbfae4f2634d864a1ee1ce3ead9c","side":"buy","tokenAmt":0.007796979293366881,"usd":661.4196898072091,"priceUsd":84830.24834629204,"dex":"pancake_v3","symbol":"BTCB"},{"ts":1791016125,"tx":"0x06ac8ef3af4d007c08c7a9ca9e7ab666a724e1393c21865fe1d70d7c5825c19b","logIndex":76,"token":"0x2170ed0880ac9a755fd29b2688956bd959f933f8","side":"sell","tokenAmt":0.1525057769098823,"usd":408.73262726748277,"priceUsd":2680.1124229478096,"dex":"pancake_v3","symbol":"ETH"}],"ingestFloor":{"minTradeUsd":100,"history":[{"usd":100,"fromTs":1790789196}]},"updatedAt":1791021452229}},"security":null},{"kind":"operation","operationId":"solStatus","method":"GET","path":"/v1/chains/solana/status","tag":"Solana data","summary":"Is the tape following the chain","description":"The ingest's own health: the last slot written, how far behind the chain it is, the age of the newest block it has written, swaps per minute, and per-venue decode counters since the ingest started (`decode` is keyed by venue number: 1 pumpswap · 2 pumpfun · 3 meteora_dbc · 4 meteora_damm_v2 · 5 meteora_dlmm · 6 raydium_clmm · 7 orca · 8 raydium_cpmm · 9 raydium_v4 · 10 meteora_pools · 11 raydium_launchlab; the example shows two of the eleven). `ok: false` or a large `blockAgeS` means the numbers on the other routes are behind: say so when you show them. Never cached.\n\nChord's own Solana tape, read-only. No key needed.\n\n- **What it reads.** The swap events of 11 venues: PumpSwap, the pump.fun bonding curve, Meteora DBC, Meteora DAMM v2, Meteora DLMM, Meteora pools (dynamic AMM v1), Raydium CLMM, Raydium CPMM, Raydium AMM v4, Raydium LaunchLab and Orca Whirlpool. Each swap is checked against the pool vaults' balance changes in the same transaction.\n- **What it does not read.** Prop AMMs (SolFi, HumidiFi and the like) and order books. SOL/USDC and other major pairs therefore show far less volume than the whole market; the numbers are accurate for pump.fun, Meteora and Raydium style tokens. Transfers are not seen either: wallet PnL is average cost inside the window.\n- **History.** Live since 2026-10-03 12:01 UTC, plus a backfill of the days before. `coverageSince` on `/chains/solana/overview` says from when totals are complete: quote that field, not a date.\n- **Addresses** are base58 and **case-sensitive**. Never lower-case a mint or a wallet: a lower-cased mint is a different string, refused with `400 BAD_ADDRESS` when it stops being base58 (an `L` becomes `l`) and answered `404 TOKEN_NOT_FOUND` otherwise. Solana has no numeric chain id here: the path segment is the literal `solana`.\n- **Units.** Token amounts are whole tokens (decimals already applied), `quoteAmount` is whole units of the pool's quote (SOL, USDC, USDT or the other token), prices and `*Usd` fields are US dollars. Timestamps, `updatedAt` included, are Unix **seconds**.\n- **Names are untrusted.** `symbol`, `name` and `image` are whatever the token's creator wrote; many mints share a symbol and there are no wash or impostor flags. Identify a token by its mint.\n- **Errors.** `400 BAD_*` for a bad parameter; `400 UNSUPPORTED_CHAIN` if Solana is not public on the deployment and the request has no `X-API-Key`; `503 CHAIN_DATA_UNAVAILABLE` when the Solana store cannot be read in time and `503 CHAIN_NOT_ENABLED` when the lane is off: retry later, never read either as \"no trades\".","url":"https://getchord.xyz/docs/api-reference/operations/solstatus/","parameters":[],"requestBody":null,"responses":{"200":"","400":"`UNSUPPORTED_CHAIN` (Solana is not public on this deployment and the request has no `X-API-Key`).","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","503":"`CHAIN_DATA_UNAVAILABLE` (the Solana store did not answer in time) or `CHAIN_NOT_ENABLED` (the lane is off on this deployment). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"string","ok":"boolean — The ingest is healthy right now.","cursor":"integer — Last slot written.","genesisSlot":"integer — First slot of the live tape.","auditCursor":"integer — Last slot re-checked against `finalized` (orphaned slots removed, late ones written).","lagSlots":"integer|null — Slots between the chain head and `cursor`.","blockAgeS":"integer|null — Age of the newest block written, seconds.","slotsPerMin":"number|null","swapsPerMin":"number|null","startedAt":"integer|null — Unix time, seconds, UTC.","solUsd":"number|null — SOL price the tape is using (from its own SOL/stable swaps).","decode":{},"totals":{"slots":"integer","swaps":"integer","orphaned":"integer","late":"integer"},"venues":"string — What the tape reads, in words.","notCovered":"string — What it does not read, in words.","public":"boolean — Served to callers without a key.","gate":"object|null — The automatic public gate: `pass`, `liveHours`, `missing24h` (missing slots in 24 hours), `hourCheck` (rollup against raw for the last closed hour), `reasons`."},"example":{"chain":"solana","ok":false,"cursor":453384220,"genesisSlot":452927437,"auditCursor":453383708,"lagSlots":2065,"blockAgeS":15287,"slotsPerMin":273,"swapsPerMin":33344,"startedAt":1791163969,"solUsd":121.06980743427287,"decode":{"1":{"events":412502,"swaps":392156,"ok":392155,"bad":1,"unchecked":0,"noParent":0,"otherEvents":20346},"2":{"events":127002,"swaps":108165,"ok":108151,"bad":14,"unchecked":0,"noParent":0,"otherEvents":18837}},"totals":{"slots":5931,"swaps":740575,"orphaned":0,"late":0},"venues":"PumpSwap, pump.fun, Meteora (DAMM v2, DLMM, DBC, dynamic pools), Raydium (CLMM, CPMM, v4, LaunchLab) and Orca","notCovered":"prop AMMs such as SolFi / HumidiFi and order books such as Phoenix are not read, so SOL/USDC-style majors are understated","public":true,"gate":{"pass":false,"at":1791166182,"liveHours":38.1,"missing24h":0,"hourCheck":{"hour":497545,"hourlyDiff":0,"candleDiff":0},"reasons":["ingest not healthy right now"]}}},"security":null},{"kind":"operation","operationId":"solOverview","method":"GET","path":"/v1/chains/solana/overview","tag":"Solana data","summary":"Chain totals","description":"Last 24 hours on the venues the tape reads: volume, trades, buys, tokens traded, venue share and hourly buckets, plus `coverageSince`. The window never starts before `coverageSince`: `coverageHours` under 24 means a partial day. Cached 30 seconds.\n\nChord's own Solana tape, read-only. No key needed.\n\n- **What it reads.** The swap events of 11 venues: PumpSwap, the pump.fun bonding curve, Meteora DBC, Meteora DAMM v2, Meteora DLMM, Meteora pools (dynamic AMM v1), Raydium CLMM, Raydium CPMM, Raydium AMM v4, Raydium LaunchLab and Orca Whirlpool. Each swap is checked against the pool vaults' balance changes in the same transaction.\n- **What it does not read.** Prop AMMs (SolFi, HumidiFi and the like) and order books. SOL/USDC and other major pairs therefore show far less volume than the whole market; the numbers are accurate for pump.fun, Meteora and Raydium style tokens. Transfers are not seen either: wallet PnL is average cost inside the window.\n- **History.** Live since 2026-10-03 12:01 UTC, plus a backfill of the days before. `coverageSince` on `/chains/solana/overview` says from when totals are complete: quote that field, not a date.\n- **Addresses** are base58 and **case-sensitive**. Never lower-case a mint or a wallet: a lower-cased mint is a different string, refused with `400 BAD_ADDRESS` when it stops being base58 (an `L` becomes `l`) and answered `404 TOKEN_NOT_FOUND` otherwise. Solana has no numeric chain id here: the path segment is the literal `solana`.\n- **Units.** Token amounts are whole tokens (decimals already applied), `quoteAmount` is whole units of the pool's quote (SOL, USDC, USDT or the other token), prices and `*Usd` fields are US dollars. Timestamps, `updatedAt` included, are Unix **seconds**.\n- **Names are untrusted.** `symbol`, `name` and `image` are whatever the token's creator wrote; many mints share a symbol and there are no wash or impostor flags. Identify a token by its mint.\n- **Errors.** `400 BAD_*` for a bad parameter; `400 UNSUPPORTED_CHAIN` if Solana is not public on the deployment and the request has no `X-API-Key`; `503 CHAIN_DATA_UNAVAILABLE` when the Solana store cannot be read in time and `503 CHAIN_NOT_ENABLED` when the lane is off: retry later, never read either as \"no trades\".","url":"https://getchord.xyz/docs/api-reference/operations/soloverview/","parameters":[],"requestBody":null,"responses":{"200":"","400":"`UNSUPPORTED_CHAIN` (Solana is not public on this deployment and the request has no `X-API-Key`).","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","503":"`CHAIN_DATA_UNAVAILABLE` (the Solana store did not answer in time) or `CHAIN_NOT_ENABLED` (the lane is off on this deployment). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"string","windowHours":"integer","volumeUsd":"number","trades":"integer","buys":"integer","tokensTraded":"integer","venues":[{"dex":"string — Venue id: `pumpswap` · `pumpfun` (bonding curve) · `meteora_dbc` · `meteora_damm_v2` · `meteora_dlmm` · `meteora_pools` (dynamic AMM v1) · `raydium_clmm` · `raydium_cpmm` · `raydium_v4` · `raydium_launchlab` · `orca` (Whirlpool).","volumeUsd":"number","trades":"integer","share":"number — Fraction of the window's volume, 0–1 (not percent)."}],"hourly":[{"hour":"integer — Unix time, seconds, UTC.","volumeUsd":"number","trades":"integer"}],"coverageSince":"integer|null — Unix time, seconds, UTC.","coverageHours":"number — Hours of the 24-hour window the tape covers.","cursor":"integer — Last slot written.","updatedAt":"integer — Unix time, SECONDS, when the Solana box built this answer. Unlike the rest of the API (milliseconds).","botTapes":{"tokens":"integer","volumeUsd":"number","rule":"string"}},"example":{"chain":"solana","windowHours":24,"volumeUsd":3120445357.1785517,"trades":28259618,"buys":16493707,"tokensTraded":98530,"venues":[{"dex":"pumpswap","volumeUsd":1420441349.9695024,"trades":15748395,"share":0.45520468631241756},{"dex":"meteora_pools","volumeUsd":464739991.2308222,"trades":40125,"share":0.1489338661744846}],"hourly":[{"hour":1791082800,"volumeUsd":136078621.887329,"trades":1510518},{"hour":1791086400,"volumeUsd":110648628.7027686,"trades":1442682}],"coverageSince":1790611483,"coverageHours":24,"cursor":453384035,"updatedAt":1791166406}},"security":null},{"kind":"operation","operationId":"solTokens","method":"GET","path":"/v1/chains/solana/tokens","tag":"Solana data","summary":"Every token traded in the last 24 hours","description":"The 24-hour board. `volume` ranks the 600 most traded tokens and `trades` the 300 with the most trades; `change` (24-hour price change) and `new` (first seen in the last 24 hours, newest first) rank inside the 600 most traded tokens with at least $5,000 of volume, so a $40 pool moving 900 % is not a mover. Cached 20 seconds.\n\n**Volume-bot tapes and impostors are left out** (`screened` counts them, `all=1` keeps them in with their `screen`). Most of Solana's busiest tokens are wallets trading with themselves: on 13 and 14 October, 265 and 271 of the 400 most traded tokens had under 3 % of their volume from wallets that went one way, about 70 % of the board's volume (one of them printed $150M on $350k of liquidity, 78 wallets each buying and selling ~$1.56M). A token is left out when under 10 % of its 24-hour volume is one-way (`oneWayPct`) unless it is a deep market (at least $250k of SOL / stable liquidity turned over at most 10× in the window: majors whose Solana flow is arbitrage stay). Many tokens still share a symbol.\n\nChord's own Solana tape, read-only. No key needed.\n\n- **What it reads.** The swap events of 11 venues: PumpSwap, the pump.fun bonding curve, Meteora DBC, Meteora DAMM v2, Meteora DLMM, Meteora pools (dynamic AMM v1), Raydium CLMM, Raydium CPMM, Raydium AMM v4, Raydium LaunchLab and Orca Whirlpool. Each swap is checked against the pool vaults' balance changes in the same transaction.\n- **What it does not read.** Prop AMMs (SolFi, HumidiFi and the like) and order books. SOL/USDC and other major pairs therefore show far less volume than the whole market; the numbers are accurate for pump.fun, Meteora and Raydium style tokens. Transfers are not seen either: wallet PnL is average cost inside the window.\n- **History.** Live since 2026-10-03 12:01 UTC, plus a backfill of the days before. `coverageSince` on `/chains/solana/overview` says from when totals are complete: quote that field, not a date.\n- **Addresses** are base58 and **case-sensitive**. Never lower-case a mint or a wallet: a lower-cased mint is a different string, refused with `400 BAD_ADDRESS` when it stops being base58 (an `L` becomes `l`) and answered `404 TOKEN_NOT_FOUND` otherwise. Solana has no numeric chain id here: the path segment is the literal `solana`.\n- **Units.** Token amounts are whole tokens (decimals already applied), `quoteAmount` is whole units of the pool's quote (SOL, USDC, USDT or the other token), prices and `*Usd` fields are US dollars. Timestamps, `updatedAt` included, are Unix **seconds**.\n- **Names are untrusted.** `symbol`, `name` and `image` are whatever the token's creator wrote; many mints share a symbol and there are no wash or impostor flags. Identify a token by its mint.\n- **Errors.** `400 BAD_*` for a bad parameter; `400 UNSUPPORTED_CHAIN` if Solana is not public on the deployment and the request has no `X-API-Key`; `503 CHAIN_DATA_UNAVAILABLE` when the Solana store cannot be read in time and `503 CHAIN_NOT_ENABLED` when the lane is off: retry later, never read either as \"no trades\".","url":"https://getchord.xyz/docs/api-reference/operations/soltokens/","parameters":[{"name":"sort","in":"query","required":false,"type":"string","enum":["volume","trades","change","new"],"default":"volume","description":"Descending; `new` = newest first."},{"name":"limit","in":"query","required":false,"type":"integer","default":100,"description":""}],"requestBody":null,"responses":{"200":"","400":"`BAD_LIMIT` / `BAD_SORT`, or `UNSUPPORTED_CHAIN` (Solana is not public on this deployment and the request has no `X-API-Key`).","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","503":"`CHAIN_DATA_UNAVAILABLE` (the Solana store did not answer in time) or `CHAIN_NOT_ENABLED` (the lane is off on this deployment). Retry later; do not treat it as an empty answer."},"response":{"schema":{"sort":"string","windowHours":"integer","tokens":[{"token":"string — Solana address, base58, case-sensitive. Never lower-case it.","symbol":"string|null — Creator-chosen; null until the metadata worker has read it.","name":"string|null — Creator-chosen.","image":"string|null — Image URL from the token's metadata, as published by its creator.","decimals":"integer|null","priceUsd":"number|null — Last price on the token's main pool (traded in the last hour first, then the deepest).","change24hPct":"number|null — Price now against the main pool's close 24 hours ago.","volume24hUsd":"number — USD over the 24-hour window, every pool the tape reads.","trades24h":"integer","buys24h":"integer","buyVolume24hUsd":"number","liquidityUsd":"number|null — Main pool: twice its quote-side reserve in USD, from the last swap whose event carried the reserve. An estimate; null when unknown.","marketCapUsd":"number|null — Price × supply: fully diluted.","pool":"string|null — Solana address, base58, case-sensitive. Never lower-case it.","dex":"string|null — Venue id: `pumpswap` · `pumpfun` (bonding curve) · `meteora_dbc` · `meteora_damm_v2` · `meteora_dlmm` · `meteora_pools` (dynamic AMM v1) · `raydium_clmm` · `raydium_cpmm` · `raydium_v4` · `raydium_launchlab` · `orca` (Whirlpool).","firstSeen":"integer|null — Unix time, seconds, UTC.","oneWayPct":"number|null — Percent of the 24-hour dollar volume traded by wallets that went one way: each wallet's smaller side (bought or sold, in USD) under half its larger side. The rest is wallets buying and selling about the same amounts back and forth: arbitrage, market making or wash trading. Null when not measured.","screen":"string|null (volume bot|impostor) — Why the boards leave this token out, or null. `volume bot`: under 10 % of its 24-hour volume came from one-way wallets and it is not a deep market (at least $250k of SOL / stable liquidity turned over at most 10× in the window). `impostor`: the ticker of SOL, USDC or USDT, look-alike letters included, on another mint."}],"screened":{"tokens":"integer — Candidates of this board left out.","volumeUsd":"number — Their 24-hour volume.","byReason":"object — Count per `screen` value.","rule":"string — The rule, in words.","measured":"boolean — False when the volume screen did not run for this board (the tape's per-wallet rollup is missing or behind): rows are then unscreened for volume."},"updatedAt":"integer — Unix time, SECONDS, when the Solana box built this answer. Unlike the rest of the API (milliseconds)."},"example":{"sort":"trades","windowHours":24,"tokens":[{"token":"So11111111111111111111111111111111111111112","symbol":"SOL","name":"Solana","image":"https://raw.githubusercontent.com/solana-labs/token-list/main/assets/mainnet/So11111111111111111111111111111111111111112/logo.png","decimals":9,"priceUsd":120.98396092263611,"change24hPct":1.1310855236659645,"volume24hUsd":92343484.342816,"trades24h":668125,"buys24h":344626,"buyVolume24hUsd":47132735.284852006,"liquidityUsd":30496683.315842,"marketCapUsd":null,"pool":"58oQChx4yWmvKdwLLZzBi4ChoCc2fqCUWBkwMihLYQo2","dex":"raydium_v4","firstSeen":1791028889},{"token":"Xs3oZwbHvqis4NYcf4YKWmEia2eC84wSiVrcYcTqpH8","symbol":"SPCXx","name":"SpaceX xStock","image":"https://xstocks-metadata.backed.fi/logos/tokens/SPCXx.png","decimals":8,"priceUsd":163.10022589848552,"change24hPct":null,"volume24hUsd":37511133.496547684,"trades24h":476322,"buys24h":230903,"buyVolume24hUsd":18759541.58185133,"liquidityUsd":95373.03161138113,"marketCapUsd":91333037.55386804,"pool":"B7nYoGHqCGoFRiPB4AoT1NqbqrFWJDfiEkD3WNXxSCnt","dex":"raydium_cpmm","firstSeen":1791028946}],"updatedAt":1791166451}},"security":null},{"kind":"operation","operationId":"solSearch","method":"GET","path":"/v1/chains/solana/search","tag":"Solana data","summary":"Find a token by mint, symbol or name","description":"A mint returns that token (when the tape has seen it trade). Anything else is an exact, case-insensitive match on symbol or name among the tokens the tape has seen, up to 20, ordered by the volume of each token's deepest pool; a leading `$` is ignored. No prefix or substring search. Expect several mints per symbol: show the mint, and pick by liquidity and volume only when the user has not named one.\n\n`volumeUsd` is the main pool's volume since the tape first saw it for a symbol or name match, and the token's 24-hour volume for a mint: a ranking hint, not a window total. Use `/chains/solana/token/{address}` for the token's numbers.\n\nChord's own Solana tape, read-only. No key needed.\n\n- **What it reads.** The swap events of 11 venues: PumpSwap, the pump.fun bonding curve, Meteora DBC, Meteora DAMM v2, Meteora DLMM, Meteora pools (dynamic AMM v1), Raydium CLMM, Raydium CPMM, Raydium AMM v4, Raydium LaunchLab and Orca Whirlpool. Each swap is checked against the pool vaults' balance changes in the same transaction.\n- **What it does not read.** Prop AMMs (SolFi, HumidiFi and the like) and order books. SOL/USDC and other major pairs therefore show far less volume than the whole market; the numbers are accurate for pump.fun, Meteora and Raydium style tokens. Transfers are not seen either: wallet PnL is average cost inside the window.\n- **History.** Live since 2026-10-03 12:01 UTC, plus a backfill of the days before. `coverageSince` on `/chains/solana/overview` says from when totals are complete: quote that field, not a date.\n- **Addresses** are base58 and **case-sensitive**. Never lower-case a mint or a wallet: a lower-cased mint is a different string, refused with `400 BAD_ADDRESS` when it stops being base58 (an `L` becomes `l`) and answered `404 TOKEN_NOT_FOUND` otherwise. Solana has no numeric chain id here: the path segment is the literal `solana`.\n- **Units.** Token amounts are whole tokens (decimals already applied), `quoteAmount` is whole units of the pool's quote (SOL, USDC, USDT or the other token), prices and `*Usd` fields are US dollars. Timestamps, `updatedAt` included, are Unix **seconds**.\n- **Names are untrusted.** `symbol`, `name` and `image` are whatever the token's creator wrote; many mints share a symbol and there are no wash or impostor flags. Identify a token by its mint.\n- **Errors.** `400 BAD_*` for a bad parameter; `400 UNSUPPORTED_CHAIN` if Solana is not public on the deployment and the request has no `X-API-Key`; `503 CHAIN_DATA_UNAVAILABLE` when the Solana store cannot be read in time and `503 CHAIN_NOT_ENABLED` when the lane is off: retry later, never read either as \"no trades\".","url":"https://getchord.xyz/docs/api-reference/operations/solsearch/","parameters":[{"name":"q","in":"query","required":true,"type":"string","description":"A mint (base58), a symbol or a name."}],"requestBody":null,"responses":{"200":"Matches. An empty `tokens` is a real answer.","400":"`BAD_QUERY` (empty, or longer than 60 characters), or `UNSUPPORTED_CHAIN` (Solana is not public on this deployment and the request has no `X-API-Key`).","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","503":"`CHAIN_DATA_UNAVAILABLE` (the Solana store did not answer in time) or `CHAIN_NOT_ENABLED` (the lane is off on this deployment). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"string","query":"string","tokens":[{"token":"string — Solana address, base58, case-sensitive. Never lower-case it.","symbol":"string|null","name":"string|null","image":"string|null","priceUsd":"number|null","liquidityUsd":"number|null","volumeUsd":"number|null — See above.","screen":"string|null (volume bot|impostor) — Why the boards leave this token out, or null. `volume bot`: under 10 % of its 24-hour volume came from one-way wallets and it is not a deep market (at least $250k of SOL / stable liquidity turned over at most 10× in the window). `impostor`: the ticker of SOL, USDC or USDT, look-alike letters included, on another mint."}]},"example":{"chain":"solana","query":"Agency","tokens":[{"token":"PGXpPuXMe4jpcjHwC4FCvtu5oMn4izLVRJVkwe3AHaM","symbol":"Agency","name":"Agency","image":"https://pbs.twimg.com/profile_images/2105704660116144128/u2fzyGVC_400x400.jpg","priceUsd":0.000002688447447596337,"liquidityUsd":242806.21490618165,"volumeUsd":32772996.00219991},{"token":"7VertkgF9KLhxxJXHX6uaWuoYZTP9LdGj2bWmVXVpump","symbol":"Agency","name":"Agency","image":"https://ipfs.io/ipfs/bafybeicailrr3iobedoxprzs6evwq3nqxsezdhvxbhpseyhltfmufybxuq","priceUsd":0.012402169398382247,"liquidityUsd":490945.0136094359,"volumeUsd":30097665.520332042}]}},"security":null},{"kind":"operation","operationId":"solToken","method":"GET","path":"/v1/chains/solana/token/{address}","tag":"Solana data","summary":"One token: stats, pools and hourly tape","description":"Identity (from the token's metadata), price on the main pool with 1-hour and 24-hour change, fully diluted market cap, liquidity summed over the pools that traded in the last 24 hours, 24-hour volume and trade counts with the venue split, up to 20 pools, and an hourly series.\n\n**Pass `hours` of 24 or more**: the 24-hour totals are summed from the same hourly rows the series returns, so `hours=2` gives the totals of two hours. In `pools`, `volumeUsd` and `swaps` count since the tape first saw the pool, not 24 hours. Cached 10 seconds.\n\nChord's own Solana tape, read-only. No key needed.\n\n- **What it reads.** The swap events of 11 venues: PumpSwap, the pump.fun bonding curve, Meteora DBC, Meteora DAMM v2, Meteora DLMM, Meteora pools (dynamic AMM v1), Raydium CLMM, Raydium CPMM, Raydium AMM v4, Raydium LaunchLab and Orca Whirlpool. Each swap is checked against the pool vaults' balance changes in the same transaction.\n- **What it does not read.** Prop AMMs (SolFi, HumidiFi and the like) and order books. SOL/USDC and other major pairs therefore show far less volume than the whole market; the numbers are accurate for pump.fun, Meteora and Raydium style tokens. Transfers are not seen either: wallet PnL is average cost inside the window.\n- **History.** Live since 2026-10-03 12:01 UTC, plus a backfill of the days before. `coverageSince` on `/chains/solana/overview` says from when totals are complete: quote that field, not a date.\n- **Addresses** are base58 and **case-sensitive**. Never lower-case a mint or a wallet: a lower-cased mint is a different string, refused with `400 BAD_ADDRESS` when it stops being base58 (an `L` becomes `l`) and answered `404 TOKEN_NOT_FOUND` otherwise. Solana has no numeric chain id here: the path segment is the literal `solana`.\n- **Units.** Token amounts are whole tokens (decimals already applied), `quoteAmount` is whole units of the pool's quote (SOL, USDC, USDT or the other token), prices and `*Usd` fields are US dollars. Timestamps, `updatedAt` included, are Unix **seconds**.\n- **Names are untrusted.** `symbol`, `name` and `image` are whatever the token's creator wrote; many mints share a symbol and there are no wash or impostor flags. Identify a token by its mint.\n- **Errors.** `400 BAD_*` for a bad parameter; `400 UNSUPPORTED_CHAIN` if Solana is not public on the deployment and the request has no `X-API-Key`; `503 CHAIN_DATA_UNAVAILABLE` when the Solana store cannot be read in time and `503 CHAIN_NOT_ENABLED` when the lane is off: retry later, never read either as \"no trades\".","url":"https://getchord.xyz/docs/api-reference/operations/soltoken/","parameters":[{"name":"address","in":"path","required":true,"type":"string","description":"Token mint, base58, exactly as it appears on-chain."},{"name":"hours","in":"query","required":false,"type":"integer","default":168,"description":"Hourly buckets in `hourly`; also the span the 24-hour totals are read from (see above)."}],"requestBody":null,"responses":{"200":"","400":"`BAD_ADDRESS` / `BAD_HOURS`, or `UNSUPPORTED_CHAIN` (Solana is not public on this deployment and the request has no `X-API-Key`).","404":"`TOKEN_NOT_FOUND`: this mint has not traded on a venue the tape reads since the tape started.","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","503":"`CHAIN_DATA_UNAVAILABLE` (the Solana store did not answer in time) or `CHAIN_NOT_ENABLED` (the lane is off on this deployment). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"string","token":"string — Solana address, base58, case-sensitive. Never lower-case it.","symbol":"string|null","name":"string|null","image":"string|null","decimals":"integer|null","supply":"number|null — Whole tokens.","firstSeen":"integer|null — Unix time, seconds, UTC.","priceUsd":"number|null","change1hPct":"number|null","change24hPct":"number|null","marketCapUsd":"number|null — Price × supply.","liquidityUsd":"number|null — Sum over pools that traded in the last 24 hours.","volume24hUsd":"number","trades24h":"integer","buys24h":"integer","sells24h":"integer","buyVolume24hUsd":"number","sellVolume24hUsd":"number","venues":[{"dex":"string — Venue id: `pumpswap` · `pumpfun` (bonding curve) · `meteora_dbc` · `meteora_damm_v2` · `meteora_dlmm` · `meteora_pools` (dynamic AMM v1) · `raydium_clmm` · `raydium_cpmm` · `raydium_v4` · `raydium_launchlab` · `orca` (Whirlpool).","volumeUsd":"number","trades":"integer"}],"flow24h":{"oneWayPct":"number|null — As on the board row.","screen":"string|null (volume bot|impostor) — Why the boards leave this token out, or null. `volume bot`: under 10 % of its 24-hour volume came from one-way wallets and it is not a deep market (at least $250k of SOL / stable liquidity turned over at most 10× in the window). `impostor`: the ticker of SOL, USDC or USDT, look-alike letters included, on another mint.","wallets":"integer|null — Distinct wallets in the window.","volumeUsd":"number|null — The window's volume this was measured on.","rule":"string"},"pools":[{"pool":"string — Solana address, base58, case-sensitive. Never lower-case it.","dex":"string — Venue id: `pumpswap` · `pumpfun` (bonding curve) · `meteora_dbc` · `meteora_damm_v2` · `meteora_dlmm` · `meteora_pools` (dynamic AMM v1) · `raydium_clmm` · `raydium_cpmm` · `raydium_v4` · `raydium_launchlab` · `orca` (Whirlpool).","quote":"string — Solana address, base58, case-sensitive. Never lower-case it.","priceUsd":"number|null","liquidityUsd":"number|null","volumeUsd":"number — Since the tape first saw the pool.","swaps":"integer — Since the tape first saw the pool.","firstSeen":"integer|null — Unix time, seconds, UTC.","lastTrade":"integer|null — Unix time, seconds, UTC."}],"hourly":[{"hour":"integer — Unix time, seconds, UTC.","volumeUsd":"number","trades":"integer","buys":"integer"}],"updatedAt":"integer — Unix time, SECONDS, when the Solana box built this answer. Unlike the rest of the API (milliseconds)."},"example":{"chain":"solana","token":"7VertkgF9KLhxxJXHX6uaWuoYZTP9LdGj2bWmVXVpump","symbol":"Agency","name":"Agency","image":"https://ipfs.io/ipfs/bafybeicailrr3iobedoxprzs6evwq3nqxsezdhvxbhpseyhltfmufybxuq","decimals":6,"supply":966189741.871528,"firstSeen":1791028889,"priceUsd":0.012471350009671632,"change1hPct":0,"change24hPct":-33.59296229824511,"marketCapUsd":12049690.446634114,"liquidityUsd":492710.3227884476,"volume24hUsd":22300513.95510154,"trades24h":98644,"buys24h":50875,"sells24h":47769,"buyVolume24hUsd":10815371.994912628,"sellVolume24hUsd":11485141.96018891,"venues":[{"dex":"pumpswap","volumeUsd":12526132.33339345,"trades":59671},{"dex":"meteora_dlmm","volumeUsd":9716267.646647243,"trades":27864}],"pools":[{"pool":"CyJwKnLiiY4fmiwqMCSWFSHxo7T9Ubshgs2uRAuJCrk5","dex":"pumpswap","quote":"So11111111111111111111111111111111111111112","priceUsd":0.012471350009671632,"liquidityUsd":492426.2442871083,"volumeUsd":30096468.174518585,"swaps":152986,"firstSeen":1791028889,"lastTrade":1791151092},{"pool":"4MRafCAZEk9KLLDJ7YAQSuwAFFtxz3fVLUuyDKySU8Ep","dex":"meteora_damm_v2","quote":"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v","priceUsd":0.017382927320372235,"liquidityUsd":277.017254,"volumeUsd":1947.9255100000016,"swaps":3651,"firstSeen":1791067406,"lastTrade":1791124069}],"hourly":[{"hour":1791082800,"volumeUsd":634272.1321694182,"trades":3874,"buys":2057},{"hour":1791086400,"volumeUsd":1392924.1494347786,"trades":7064,"buys":3395}],"updatedAt":1791166385}},"security":null},{"kind":"operation","operationId":"solTokenTrades","method":"GET","path":"/v1/chains/solana/token/{address}/trades","tag":"Solana data","summary":"Trade tape","description":"The token's newest swaps across up to 30 of its pools, newest first: side, both amounts, USD, price, venue, pool, wallet and the transaction signature. Each page looks back at most two days from `before` (or from now): an empty page means no swap in that span. A mint the tape has never seen answers an empty list.\n\n- `side`: `buy` = the wallet bought the token, `sell` = it sold it.\n- `tokenAmount` and `quoteAmount` are what the wallet received or paid, fees included, in whole units; `priceUsd` is the pool's execution price.\n- `wallet` is the user account named in the swap instruction: often a bot or an arbitrage contract, sometimes on both sides of one transaction.\n\nChord's own Solana tape, read-only. No key needed.\n\n- **What it reads.** The swap events of 11 venues: PumpSwap, the pump.fun bonding curve, Meteora DBC, Meteora DAMM v2, Meteora DLMM, Meteora pools (dynamic AMM v1), Raydium CLMM, Raydium CPMM, Raydium AMM v4, Raydium LaunchLab and Orca Whirlpool. Each swap is checked against the pool vaults' balance changes in the same transaction.\n- **What it does not read.** Prop AMMs (SolFi, HumidiFi and the like) and order books. SOL/USDC and other major pairs therefore show far less volume than the whole market; the numbers are accurate for pump.fun, Meteora and Raydium style tokens. Transfers are not seen either: wallet PnL is average cost inside the window.\n- **History.** Live since 2026-10-03 12:01 UTC, plus a backfill of the days before. `coverageSince` on `/chains/solana/overview` says from when totals are complete: quote that field, not a date.\n- **Addresses** are base58 and **case-sensitive**. Never lower-case a mint or a wallet: a lower-cased mint is a different string, refused with `400 BAD_ADDRESS` when it stops being base58 (an `L` becomes `l`) and answered `404 TOKEN_NOT_FOUND` otherwise. Solana has no numeric chain id here: the path segment is the literal `solana`.\n- **Units.** Token amounts are whole tokens (decimals already applied), `quoteAmount` is whole units of the pool's quote (SOL, USDC, USDT or the other token), prices and `*Usd` fields are US dollars. Timestamps, `updatedAt` included, are Unix **seconds**.\n- **Names are untrusted.** `symbol`, `name` and `image` are whatever the token's creator wrote; many mints share a symbol and there are no wash or impostor flags. Identify a token by its mint.\n- **Errors.** `400 BAD_*` for a bad parameter; `400 UNSUPPORTED_CHAIN` if Solana is not public on the deployment and the request has no `X-API-Key`; `503 CHAIN_DATA_UNAVAILABLE` when the Solana store cannot be read in time and `503 CHAIN_NOT_ENABLED` when the lane is off: retry later, never read either as \"no trades\".","url":"https://getchord.xyz/docs/api-reference/operations/soltokentrades/","parameters":[{"name":"address","in":"path","required":true,"type":"string","description":"Token mint, base58, exactly as it appears on-chain."},{"name":"limit","in":"query","required":false,"type":"integer","default":50,"description":"Newest rows."},{"name":"before","in":"query","required":false,"type":"integer","description":"Exclusive cursor, Unix seconds: rows strictly older than it. Pass the last row's `ts` for the next page. Several swaps can share a second, so a page boundary can skip the rest of that second: overlap with `ts + 1` and drop rows whose `tx` you already have."}],"requestBody":null,"responses":{"200":"","400":"`BAD_ADDRESS` / `BAD_LIMIT` / `BAD_CURSOR`, or `UNSUPPORTED_CHAIN` (Solana is not public on this deployment and the request has no `X-API-Key`).","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","503":"`CHAIN_DATA_UNAVAILABLE` (the Solana store did not answer in time) or `CHAIN_NOT_ENABLED` (the lane is off on this deployment). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"string","token":"string — Solana address, base58, case-sensitive. Never lower-case it.","trades":[{"ts":"integer — Unix time, seconds, UTC.","slot":"integer","side":"string (buy|sell)","tokenAmount":"number — Whole tokens.","quoteAmount":"number — Whole units of the pool's quote.","usd":"number|null","priceUsd":"number|null","dex":"string — Venue id: `pumpswap` · `pumpfun` (bonding curve) · `meteora_dbc` · `meteora_damm_v2` · `meteora_dlmm` · `meteora_pools` (dynamic AMM v1) · `raydium_clmm` · `raydium_cpmm` · `raydium_v4` · `raydium_launchlab` · `orca` (Whirlpool).","pool":"string|null — Solana address, base58, case-sensitive. Never lower-case it.","wallet":"string|null — Solana address, base58, case-sensitive. Never lower-case it.","tx":"string — Transaction signature, base58."}],"updatedAt":"integer — Unix time, SECONDS, when the Solana box built this answer. Unlike the rest of the API (milliseconds)."},"example":{"chain":"solana","token":"7VertkgF9KLhxxJXHX6uaWuoYZTP9LdGj2bWmVXVpump","trades":[{"ts":1791151156,"slot":453384204,"side":"sell","tokenAmount":1581.186594,"quoteAmount":0.161487883,"usd":19.551313486445476,"priceUsd":0.012402169398382247,"dex":"pumpswap","pool":"CyJwKnLiiY4fmiwqMCSWFSHxo7T9Ubshgs2uRAuJCrk5","wallet":"ckdRDD9onSwL9yHgjEc5VdRx9BPmcsyVH9TjKGYygkY","tx":"5sT1cLSYjuD3BR4wNbGKTAcFgFLdY2FGxujWukJFQmgLm8i1qi37rQxdZS4EYyRdCuV35dU4Rn7GttkZmU4oe2op"},{"ts":1791151147,"slot":453384173,"side":"buy","tokenAmount":2879.134063,"quoteAmount":0.295798607,"usd":35.812234413351845,"priceUsd":0.012401339509037218,"dex":"pumpswap","pool":"CyJwKnLiiY4fmiwqMCSWFSHxo7T9Ubshgs2uRAuJCrk5","wallet":"3QZv9xcDELwLqB8SggDJHfVhMTn5YhKtXMCaKUucutm3","tx":"Vz2VPQCo2j82g6mowse5961MnUEM6koE7VSaVhtVHQKsvkCHZ9HGVMTgbw92vDSJw1ThSDiVGkwn16EucjAK6Ny"}],"updatedAt":1791166444}},"security":null},{"kind":"operation","operationId":"solTokenCandles","method":"GET","path":"/v1/chains/solana/token/{address}/candles","tag":"Solana data","summary":"Candles","description":"OHLCV of ONE pool of the token, in USD: the main pool (traded in the last hour first, then the deepest) unless `pool` names another. Not a volume-weighted blend of every pool: use `/chains/solana/token/{address}` for totals across pools. The window holds `limit` buckets ending with the open one; buckets without a trade are absent. A swap under $1 adds to the volume but does not move the open, high, low or close. Cached 5 seconds for `1m`, 20 seconds otherwise.\n\nChord's own Solana tape, read-only. No key needed.\n\n- **What it reads.** The swap events of 11 venues: PumpSwap, the pump.fun bonding curve, Meteora DBC, Meteora DAMM v2, Meteora DLMM, Meteora pools (dynamic AMM v1), Raydium CLMM, Raydium CPMM, Raydium AMM v4, Raydium LaunchLab and Orca Whirlpool. Each swap is checked against the pool vaults' balance changes in the same transaction.\n- **What it does not read.** Prop AMMs (SolFi, HumidiFi and the like) and order books. SOL/USDC and other major pairs therefore show far less volume than the whole market; the numbers are accurate for pump.fun, Meteora and Raydium style tokens. Transfers are not seen either: wallet PnL is average cost inside the window.\n- **History.** Live since 2026-10-03 12:01 UTC, plus a backfill of the days before. `coverageSince` on `/chains/solana/overview` says from when totals are complete: quote that field, not a date.\n- **Addresses** are base58 and **case-sensitive**. Never lower-case a mint or a wallet: a lower-cased mint is a different string, refused with `400 BAD_ADDRESS` when it stops being base58 (an `L` becomes `l`) and answered `404 TOKEN_NOT_FOUND` otherwise. Solana has no numeric chain id here: the path segment is the literal `solana`.\n- **Units.** Token amounts are whole tokens (decimals already applied), `quoteAmount` is whole units of the pool's quote (SOL, USDC, USDT or the other token), prices and `*Usd` fields are US dollars. Timestamps, `updatedAt` included, are Unix **seconds**.\n- **Names are untrusted.** `symbol`, `name` and `image` are whatever the token's creator wrote; many mints share a symbol and there are no wash or impostor flags. Identify a token by its mint.\n- **Errors.** `400 BAD_*` for a bad parameter; `400 UNSUPPORTED_CHAIN` if Solana is not public on the deployment and the request has no `X-API-Key`; `503 CHAIN_DATA_UNAVAILABLE` when the Solana store cannot be read in time and `503 CHAIN_NOT_ENABLED` when the lane is off: retry later, never read either as \"no trades\".","url":"https://getchord.xyz/docs/api-reference/operations/soltokencandles/","parameters":[{"name":"address","in":"path","required":true,"type":"string","description":"Token mint, base58, exactly as it appears on-chain."},{"name":"tf","in":"query","required":false,"type":"string","enum":["1m","5m","15m","1h","4h","1d"],"default":"5m","description":"Timeframe."},{"name":"limit","in":"query","required":false,"type":"integer","default":200,"description":"Buckets in the window."},{"name":"pool","in":"query","required":false,"type":"string","description":"A pool of this token (from `/chains/solana/token/{address}` `pools`). Default: the main pool."}],"requestBody":null,"responses":{"200":"`pool: null` with no candles = the tape has no priced pool for this mint.","400":"`BAD_ADDRESS` / `BAD_TIMEFRAME` / `BAD_LIMIT`, or `UNSUPPORTED_CHAIN` (Solana is not public on this deployment and the request has no `X-API-Key`).","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","503":"`CHAIN_DATA_UNAVAILABLE` (the Solana store did not answer in time) or `CHAIN_NOT_ENABLED` (the lane is off on this deployment). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"string","token":"string — Solana address, base58, case-sensitive. Never lower-case it.","pool":"string|null — Solana address, base58, case-sensitive. Never lower-case it.","timeframe":"string","candles":[{"t":"integer — Unix time, seconds, UTC.","o":"number","h":"number","l":"number","c":"number","volumeUsd":"number","trades":"integer"}],"updatedAt":"integer — Unix time, SECONDS, when the Solana box built this answer. Unlike the rest of the API (milliseconds)."},"example":{"chain":"solana","token":"7VertkgF9KLhxxJXHX6uaWuoYZTP9LdGj2bWmVXVpump","pool":"CyJwKnLiiY4fmiwqMCSWFSHxo7T9Ubshgs2uRAuJCrk5","timeframe":"1h","candles":[{"t":1791140400,"o":0.016581499823932228,"h":0.0167915473875269,"l":0.013856459444690225,"c":0.014365569915305174,"volumeUsd":336302.10729020054,"trades":2009},{"t":1791144000,"o":0.014362537896257067,"h":0.014962869347332729,"l":0.011578863188337602,"c":0.014393806600470372,"volumeUsd":495642.36503098987,"trades":2632}],"updatedAt":1791166459}},"security":null},{"kind":"operation","operationId":"solTokenTraders","method":"GET","path":"/v1/chains/solana/token/{address}/traders","tag":"Solana data","summary":"Who traded the token","description":"The wallets that traded the token over the window, biggest USD volume first (the top 100; `limit` slices them): bought, sold, net, trades, and an average-cost PnL over the window. The window is whole UTC hours: the current hour and the `hours` (1–48) before it, starting at `since`, so it covers a little more than `hours` × 3600 seconds. Closed hours come from an hourly (token, wallet) rollup and the current hour from the raw swaps; while the rollup has not reached back to `since` the whole window is read from raw, and the first read of a busy token can then take tens of seconds or answer `503`. The answer is cached on the Solana side: retry after a minute, or ask for fewer `hours`.\n\n- `heldAmount` is bought minus sold inside the window, not the wallet's balance.\n- `partial: true` = the wallet sold more than it bought in the window; those sells have no cost basis.\n\nChord's own Solana tape, read-only. No key needed.\n\n- **What it reads.** The swap events of 11 venues: PumpSwap, the pump.fun bonding curve, Meteora DBC, Meteora DAMM v2, Meteora DLMM, Meteora pools (dynamic AMM v1), Raydium CLMM, Raydium CPMM, Raydium AMM v4, Raydium LaunchLab and Orca Whirlpool. Each swap is checked against the pool vaults' balance changes in the same transaction.\n- **What it does not read.** Prop AMMs (SolFi, HumidiFi and the like) and order books. SOL/USDC and other major pairs therefore show far less volume than the whole market; the numbers are accurate for pump.fun, Meteora and Raydium style tokens. Transfers are not seen either: wallet PnL is average cost inside the window.\n- **History.** Live since 2026-10-03 12:01 UTC, plus a backfill of the days before. `coverageSince` on `/chains/solana/overview` says from when totals are complete: quote that field, not a date.\n- **Addresses** are base58 and **case-sensitive**. Never lower-case a mint or a wallet: a lower-cased mint is a different string, refused with `400 BAD_ADDRESS` when it stops being base58 (an `L` becomes `l`) and answered `404 TOKEN_NOT_FOUND` otherwise. Solana has no numeric chain id here: the path segment is the literal `solana`.\n- **Units.** Token amounts are whole tokens (decimals already applied), `quoteAmount` is whole units of the pool's quote (SOL, USDC, USDT or the other token), prices and `*Usd` fields are US dollars. Timestamps, `updatedAt` included, are Unix **seconds**.\n- **Names are untrusted.** `symbol`, `name` and `image` are whatever the token's creator wrote; many mints share a symbol and there are no wash or impostor flags. Identify a token by its mint.\n- **Errors.** `400 BAD_*` for a bad parameter; `400 UNSUPPORTED_CHAIN` if Solana is not public on the deployment and the request has no `X-API-Key`; `503 CHAIN_DATA_UNAVAILABLE` when the Solana store cannot be read in time and `503 CHAIN_NOT_ENABLED` when the lane is off: retry later, never read either as \"no trades\".","url":"https://getchord.xyz/docs/api-reference/operations/soltokentraders/","parameters":[{"name":"address","in":"path","required":true,"type":"string","description":"Token mint, base58, exactly as it appears on-chain."},{"name":"limit","in":"query","required":false,"type":"integer","default":30,"description":""},{"name":"hours","in":"query","required":false,"type":"integer","default":24,"description":"Whole UTC hours before the current one (see `since`)."}],"requestBody":null,"responses":{"200":"","400":"`BAD_ADDRESS` / `BAD_LIMIT` / `BAD_HOURS`, or `UNSUPPORTED_CHAIN` (Solana is not public on this deployment and the request has no `X-API-Key`).","404":"`TOKEN_NOT_FOUND`: this mint has not traded on a venue the tape reads since the tape started.","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","503":"`CHAIN_DATA_UNAVAILABLE` (the Solana store did not answer in time) or `CHAIN_NOT_ENABLED` (the lane is off on this deployment). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"string","token":"string — Solana address, base58, case-sensitive. Never lower-case it.","windowHours":"integer","since":"integer — Unix time, seconds, UTC.","priceUsd":"number|null","traders":[{"wallet":"string|null — Solana address, base58, case-sensitive. Never lower-case it.","boughtUsd":"number","soldUsd":"number","netUsd":"number — Bought minus sold, USD.","trades":"integer","lastTrade":"integer — Unix time, seconds, UTC.","heldAmount":"number — Whole tokens.","heldValueUsd":"number|null","realizedPnlUsd":"number|null","unrealizedPnlUsd":"number|null","partial":"boolean"}],"updatedAt":"integer — Unix time, SECONDS, when the Solana box built this answer. Unlike the rest of the API (milliseconds)."},"example":{"chain":"solana","token":"7VertkgF9KLhxxJXHX6uaWuoYZTP9LdGj2bWmVXVpump","windowHours":24,"since":1791079200,"priceUsd":0.01420426088276189,"traders":[{"wallet":"ARu4n5mFdZogZAravu7CcizaojWnS6oqka37gdLT5SZn","boughtUsd":2176754.8047437067,"soldUsd":1884286.4740241242,"netUsd":292468.3307195825,"trades":11466,"lastTrade":1791152541,"heldAmount":18044940.3278099,"heldValueUsd":256315.04003008266,"realizedPnlUsd":30691.394381958165,"unrealizedPnlUsd":-66844.68507145798,"partial":false},{"wallet":"MriyaNN8TMp6qRWjfr723PK7xgQK7yCt7Kg2v2PQu7X","boughtUsd":508194.52591024636,"soldUsd":519052.2068625818,"netUsd":-10857.680952335417,"trades":1436,"lastTrade":1791152211,"heldAmount":0,"heldValueUsd":0,"realizedPnlUsd":10307.184467280762,"unrealizedPnlUsd":0,"partial":true}],"updatedAt":1791167327}},"security":null},{"kind":"operation","operationId":"solTraders","method":"GET","path":"/v1/chains/solana/traders","tag":"Solana data","summary":"The day's traders","description":"Wallets ranked by realized PnL or by volume over today's UTC day (`days=2` adds yesterday), across every token the tape reads. Bots are left out by rule (`botRule`: above 3,000 trades or 300 tokens a day), and so are wallets under $1,000 of volume. Realized PnL per token = the matched amount × (average sell − average buy) inside the window, summed; `winRate` = the share of tokens with both buys and sells that sold above their average buy. Early in the UTC day the board is short, and empty until the day has rows. Cached 5 minutes; a cold `days=2` board can take longer than the API waits and answer `503`: retry later.\n\nChord's own Solana tape, read-only. No key needed.\n\n- **What it reads.** The swap events of 11 venues: PumpSwap, the pump.fun bonding curve, Meteora DBC, Meteora DAMM v2, Meteora DLMM, Meteora pools (dynamic AMM v1), Raydium CLMM, Raydium CPMM, Raydium AMM v4, Raydium LaunchLab and Orca Whirlpool. Each swap is checked against the pool vaults' balance changes in the same transaction.\n- **What it does not read.** Prop AMMs (SolFi, HumidiFi and the like) and order books. SOL/USDC and other major pairs therefore show far less volume than the whole market; the numbers are accurate for pump.fun, Meteora and Raydium style tokens. Transfers are not seen either: wallet PnL is average cost inside the window.\n- **History.** Live since 2026-10-03 12:01 UTC, plus a backfill of the days before. `coverageSince` on `/chains/solana/overview` says from when totals are complete: quote that field, not a date.\n- **Addresses** are base58 and **case-sensitive**. Never lower-case a mint or a wallet: a lower-cased mint is a different string, refused with `400 BAD_ADDRESS` when it stops being base58 (an `L` becomes `l`) and answered `404 TOKEN_NOT_FOUND` otherwise. Solana has no numeric chain id here: the path segment is the literal `solana`.\n- **Units.** Token amounts are whole tokens (decimals already applied), `quoteAmount` is whole units of the pool's quote (SOL, USDC, USDT or the other token), prices and `*Usd` fields are US dollars. Timestamps, `updatedAt` included, are Unix **seconds**.\n- **Names are untrusted.** `symbol`, `name` and `image` are whatever the token's creator wrote; many mints share a symbol and there are no wash or impostor flags. Identify a token by its mint.\n- **Errors.** `400 BAD_*` for a bad parameter; `400 UNSUPPORTED_CHAIN` if Solana is not public on the deployment and the request has no `X-API-Key`; `503 CHAIN_DATA_UNAVAILABLE` when the Solana store cannot be read in time and `503 CHAIN_NOT_ENABLED` when the lane is off: retry later, never read either as \"no trades\".","url":"https://getchord.xyz/docs/api-reference/operations/soltraders/","parameters":[{"name":"sort","in":"query","required":false,"type":"string","enum":["pnl","volume"],"default":"pnl","description":"Descending."},{"name":"limit","in":"query","required":false,"type":"integer","default":50,"description":""},{"name":"days","in":"query","required":false,"type":"integer","default":1,"description":"1 = today (UTC), 2 = today and yesterday."}],"requestBody":null,"responses":{"200":"","400":"`BAD_LIMIT` / `BAD_DAYS` / `BAD_SORT`, or `UNSUPPORTED_CHAIN` (Solana is not public on this deployment and the request has no `X-API-Key`).","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","503":"`CHAIN_DATA_UNAVAILABLE` (the Solana store did not answer in time) or `CHAIN_NOT_ENABLED` (the lane is off on this deployment). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"string","sort":"string","windowDays":"integer","botRule":"string — The rule that removed bots, in words.","traders":[{"wallet":"string|null — Solana address, base58, case-sensitive. Never lower-case it.","realizedPnlUsd":"number","volumeUsd":"number","trades":"integer","tokens":"integer — Tokens traded.","winRate":"number|null — 0–1."}],"updatedAt":"integer — Unix time, SECONDS, when the Solana box built this answer. Unlike the rest of the API (milliseconds)."},"example":{"chain":"solana","sort":"pnl","windowDays":1,"botRule":"wallets above 3000 trades or 300 tokens a day are left out","traders":[],"updatedAt":1791166631}},"security":null},{"kind":"operation","operationId":"solSmartTraders","method":"GET","path":"/v1/chains/solana/smart-traders","tag":"Solana data","summary":"Smart traders","description":"The wallets that made repeated, verifiable profit over the last 1, 3 or 7 UTC days (today included): bots, launch wallets and lucky one-offs removed by named rules, then ranked by a luck-corrected `score`. Rebuilt every 10 minutes on the Solana side (`computedAt`); the request never computes, so it answers in milliseconds, and `503` for a few minutes after a deploy until the first build.\n\nHow a wallet gets on the board:\n\n- **Profit you can stand behind.** Realized PnL at average cost over the whole window (a position bought on day 1 and sold on day 3 counts), from swaps in pools quoted in SOL, USDC or USDT only. A position with more than 10 % of its amount traded through pools quoted in another token is left out (`unpricedTokens`), and so is one returning over 1,000× its cost or selling more than the token's deepest pool could pay (`suspectTokens`).\n- **A person, not a machine.** Removed by name (`checked.flags`): `cadence` (over 500 swaps on a day), `sniper` (over 150 tokens on a day), `burst` (8+ transactions inside a minute, in more minutes than the wallet has active days), `sameslot` (sells within 2 s of buying, 5+ and 5 %+ of its sells), `arb` (transactions that buy and sell one token), `scalp` (median hold under 60 s: gone before anyone could follow), `launch` (most closed positions first bought within 2 s of that pool's first swap: creator and bundle wallets).\n- **One operator, one row.** Wallets that made their first buy of the same 3+ tokens within 2 s of each other are one operator: the best score stays and carries `siblings`; a follower 30 s behind is not grouped.\n- **Not luck.** At least 5 tokens bought and sold, 10 swaps, $2,000 of volume, $1,000 realized and a 30 % win rate.\n- **Score** = realized × (0.35 + 0.65 × win rate shrunk toward 50 % with 20 phantom positions) × (0.5 + 0.5 × profitable days / active days) × (0.5 when one token made over 80 % of the profit, 0.75 over 60 %) × exp(−hours since the last trade / 48). `rules` repeats every threshold in words.\n\nCandidates are the top 250 wallets by realized PnL in the window, so `sort=roi` and `sort=winrate` reorder that verified set rather than search every wallet; `roi` only ranks wallets that put at least $1,000 to work. `from` is where the window really starts: never before `coverageSince`. Unrealized PnL (`unrealizedPnlUsd`, held amount marked at most at the deepest pool's liquidity) is shown, not ranked. Past profit over a few days is not a forecast.\n\nChord's own Solana tape, read-only. No key needed.\n\n- **What it reads.** The swap events of 11 venues: PumpSwap, the pump.fun bonding curve, Meteora DBC, Meteora DAMM v2, Meteora DLMM, Meteora pools (dynamic AMM v1), Raydium CLMM, Raydium CPMM, Raydium AMM v4, Raydium LaunchLab and Orca Whirlpool. Each swap is checked against the pool vaults' balance changes in the same transaction.\n- **What it does not read.** Prop AMMs (SolFi, HumidiFi and the like) and order books. SOL/USDC and other major pairs therefore show far less volume than the whole market; the numbers are accurate for pump.fun, Meteora and Raydium style tokens. Transfers are not seen either: wallet PnL is average cost inside the window.\n- **History.** Live since 2026-10-03 12:01 UTC, plus a backfill of the days before. `coverageSince` on `/chains/solana/overview` says from when totals are complete: quote that field, not a date.\n- **Addresses** are base58 and **case-sensitive**. Never lower-case a mint or a wallet: a lower-cased mint is a different string, refused with `400 BAD_ADDRESS` when it stops being base58 (an `L` becomes `l`) and answered `404 TOKEN_NOT_FOUND` otherwise. Solana has no numeric chain id here: the path segment is the literal `solana`.\n- **Units.** Token amounts are whole tokens (decimals already applied), `quoteAmount` is whole units of the pool's quote (SOL, USDC, USDT or the other token), prices and `*Usd` fields are US dollars. Timestamps, `updatedAt` included, are Unix **seconds**.\n- **Names are untrusted.** `symbol`, `name` and `image` are whatever the token's creator wrote; many mints share a symbol and there are no wash or impostor flags. Identify a token by its mint.\n- **Errors.** `400 BAD_*` for a bad parameter; `400 UNSUPPORTED_CHAIN` if Solana is not public on the deployment and the request has no `X-API-Key`; `503 CHAIN_DATA_UNAVAILABLE` when the Solana store cannot be read in time and `503 CHAIN_NOT_ENABLED` when the lane is off: retry later, never read either as \"no trades\".","url":"https://getchord.xyz/docs/api-reference/operations/solsmarttraders/","parameters":[{"name":"days","in":"query","required":false,"type":"integer","enum":[1,3,7],"default":7,"description":"Window in UTC days, today included."},{"name":"sort","in":"query","required":false,"type":"string","enum":["score","pnl","roi","winrate"],"default":"score","description":"Descending."},{"name":"limit","in":"query","required":false,"type":"integer","default":50,"description":""}],"requestBody":null,"responses":{"200":"","400":"`BAD_DAYS` / `BAD_SORT` / `BAD_LIMIT`, or `UNSUPPORTED_CHAIN` (Solana is not public on this deployment and the request has no `X-API-Key`).","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","503":"`CHAIN_DATA_UNAVAILABLE` (the Solana store did not answer in time) or `CHAIN_NOT_ENABLED` (the lane is off on this deployment). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"string","windowDays":"integer — 1, 3 or 7.","sort":"string","from":"integer — Unix time, seconds, UTC.","coverageSince":"integer|null — Unix time, seconds, UTC.","computedAt":"integer — Unix time, seconds, UTC.","tookMs":"integer — How long the last build of this window took on the Solana side.","population":{"profitable":"integer — Wallets over the floors with realized PnL in the window.","cadence":"integer — Of those, removed for over 500 swaps on a day.","sniper":"integer — Removed for over 150 tokens on a day."},"checked":{"candidates":"integer — Wallets read swap by swap.","kept":"integer — On the board.","flags":{},"suspect":"integer — Removed because most of the profit came from left-out positions.","ineligible":"integer — Under a floor once read exactly.","readErrors":"integer — Candidates whose swaps could not be read this cycle (back next cycle).","clustered":"integer — Wallets dropped as a second wallet of an operator already on the board (see `siblings`)."},"rules":{},"traders":[{"wallet":"string — Solana address, base58, case-sensitive. Never lower-case it.","score":"number — Luck-corrected, recency-weighted realized profit; the default order.","realizedPnlUsd":"number","roi":"number|null — Realized ÷ cost of the sold amount; 0.5 = +50 %.","winRate":"number|null — Share of closed tokens sold above their average buy, 0–1.","winRateAdj":"number — Win rate shrunk toward 0.5.","closedTokens":"integer — Tokens bought and sold in the window.","winningTokens":"integer","tokens":"integer","trades":"integer","volumeUsd":"number","activeDays":"integer","profitableDays":"integer — Days whose closed positions (by last sell) netted a profit.","medianHoldS":"number|null — Median seconds between average buy and average sell, closed tokens.","unrealizedPnlUsd":"number — Held amount at the current price (capped at the deepest pool's liquidity) minus its average cost. Not ranked.","heldValueUsd":"number","costSoldUsd":"number — Cost of the sold amount at the average buy.","bestToken":["object","null"],"bestShare":"number|null — The best token's share of realized PnL.","unpricedTokens":"integer","suspectTokens":"integer","launchTokens":"integer — Closed tokens first bought within 2 s of the pool's first swap.","siblings":"integer — Other wallets of the same operator left off the board: they made their first buy of the same 3+ tokens within 2 s of this one.","lastTrade":"integer — Unix time, seconds, UTC."}]},"example":{"chain":"solana","windowDays":7,"from":1790726400,"coverageSince":1790419777,"computedAt":1791304962,"tookMs":11141,"population":{"profitable":16007,"cadence":3755,"sniper":86},"checked":{"candidates":250,"kept":25,"flags":{"cadence":0,"sniper":0,"burst":92,"sameslot":125,"arb":8,"scalp":101,"launch":27},"suspect":0,"ineligible":69,"readErrors":0,"clustered":0},"rules":{"pricing":"PnL counts only swaps in pools quoted in SOL, USDC or USDT (direct USD); a position with more than 10 % of its amount traded through pools quoted in another token is left out (unpriced)","averageCost":"realized = sold amount (up to what was bought in the window) × (average sell − average buy); tokens bought before the window are not priced","suspect":"a position returning more than 1000× its cost, or one sell above $1,000,000 into a token whose deepest pool now holds less than 1/20 of it, is left out; a wallet whose profit came mostly from such positions is left out","cadence":"more than 500 swaps on any day","sniper":"more than 150 tokens on any day","burst":"8+ transactions inside one minute, in 3+ different minutes","sameslot":"5+ sells within 2 s of buying the same token (sandwich / bundle / launch sniper)","arb":"10+ transactions (and 20 %+ of all) that buy and sell the same token","cluster":"wallets that made their first buy of the same 3+ tokens within 2 s of each other are one operator: only the best score stays (siblings on its row, checked.clustered)","scalp":"median hold under 60 s over 5+ closed positions (sold before anyone could follow)","launch":"3+ closed positions, and at least half of them, first bought within 2 s of that pool's first swap (creator / bundle wallet)","eligibility":"volume ≥ $2000, ≥ 5 tokens bought and sold, ≥ 10 swaps, realized ≥ $1000, win rate ≥ 30 %","score":"realized × (0.35 + 0.65 × win rate shrunk toward 50 % with 20 phantom positions) × (0.5 + 0.5 × profitable days / active days) × (0.5 when one token made > 80 % of the profit, 0.75 when > 60 %) × exp(−hours since last trade / 48)"},"traders":[{"wallet":"9LXWa7V3AE15VfBupcx5gDts2ix3Y9NzbcKZKjkkq6hV","score":37132.17771163606,"realizedPnlUsd":43978.0170266694,"roi":0.4170270878884252,"winRate":0.7761627906976745,"winRateAdj":0.760989010989011,"closedTokens":344,"winningTokens":267,"tokens":459,"trades":1356,"volumeUsd":314916.44803633285,"activeDays":7,"profitableDays":7,"medianHoldS":177.9890558719635,"unrealizedPnlUsd":-61.60543642516731,"heldValueUsd":2038.5111692911005,"costSoldUsd":105456.02025361871,"bestToken":{"token":"Am6SB1xhuwyv6hENfR2uHj2fvKeo87KN8vVw28RcrmEa","symbol":"Cassie","name":"Cassie The Chimpanzee","image":"https://metadata.j7tracker.io/images/1c2700b89272443f","realizedPnlUsd":7868.563813198551},"bestShare":0.17892038671108912,"unpricedTokens":62,"suspectTokens":0,"launchTokens":20,"siblings":0,"lastTrade":1791304899},{"wallet":"cATq48AALCiD2hECKZDgKHp3VoSHbXc4aDxSzgQLbc3","score":32503.036821818743,"realizedPnlUsd":63356.15881453157,"roi":0.5491717745407618,"winRate":0.6666666666666666,"winRateAdj":0.5853658536585366,"closedTokens":21,"winningTokens":14,"tokens":25,"trades":100,"volumeUsd":308927.798739281,"activeDays":7,"profitableDays":4,"medianHoldS":1102.3087236881256,"unrealizedPnlUsd":0,"heldValueUsd":0,"costSoldUsd":115366.74270543561,"bestToken":{"token":"9m4Swt3D8aTzzeDEaA5xmCA8Sjd5uvWrhvMKTocjpump","symbol":"GTA6 Coin","name":"GTA6 Coin","image":"https://gateway.pinata.cloud/ipfs/bafkreibbdrekbfek6cbxrzi4meqbxzjnxzaycvlfnghnde3kr2rrz3vxne","realizedPnlUsd":19491.505347944916},"bestShare":0.3076497330749522,"unpricedTokens":0,"suspectTokens":0,"launchTokens":7,"siblings":0,"lastTrade":1791285568}],"sort":"score"}},"security":null},{"kind":"operation","operationId":"solWallet","method":"GET","path":"/v1/chains/solana/wallet/{address}","tag":"Solana data","summary":"One wallet's tokens and PnL","description":"What a wallet bought and sold per token over the last `days` UTC days (today included), with an average-cost PnL: realized on the sold part, unrealized on what is still held at the current price. Up to 200 tokens, biggest first. Say how far back the numbers go when you show them.\n\n- Transfers are not seen: a token that arrived by transfer and was then sold counts as a sell without a buy. Such rows carry `partial: true` (counted in `partialTokens`) and their sells have no realized PnL.\n- `heldAmount` and `heldValueUsd` are bought minus sold inside the window, not the on-chain balance.\n- `likelyBot` = more than 3,000 trades or 300 tokens a day.\n\nChord's own Solana tape, read-only. No key needed.\n\n- **What it reads.** The swap events of 11 venues: PumpSwap, the pump.fun bonding curve, Meteora DBC, Meteora DAMM v2, Meteora DLMM, Meteora pools (dynamic AMM v1), Raydium CLMM, Raydium CPMM, Raydium AMM v4, Raydium LaunchLab and Orca Whirlpool. Each swap is checked against the pool vaults' balance changes in the same transaction.\n- **What it does not read.** Prop AMMs (SolFi, HumidiFi and the like) and order books. SOL/USDC and other major pairs therefore show far less volume than the whole market; the numbers are accurate for pump.fun, Meteora and Raydium style tokens. Transfers are not seen either: wallet PnL is average cost inside the window.\n- **History.** Live since 2026-10-03 12:01 UTC, plus a backfill of the days before. `coverageSince` on `/chains/solana/overview` says from when totals are complete: quote that field, not a date.\n- **Addresses** are base58 and **case-sensitive**. Never lower-case a mint or a wallet: a lower-cased mint is a different string, refused with `400 BAD_ADDRESS` when it stops being base58 (an `L` becomes `l`) and answered `404 TOKEN_NOT_FOUND` otherwise. Solana has no numeric chain id here: the path segment is the literal `solana`.\n- **Units.** Token amounts are whole tokens (decimals already applied), `quoteAmount` is whole units of the pool's quote (SOL, USDC, USDT or the other token), prices and `*Usd` fields are US dollars. Timestamps, `updatedAt` included, are Unix **seconds**.\n- **Names are untrusted.** `symbol`, `name` and `image` are whatever the token's creator wrote; many mints share a symbol and there are no wash or impostor flags. Identify a token by its mint.\n- **Errors.** `400 BAD_*` for a bad parameter; `400 UNSUPPORTED_CHAIN` if Solana is not public on the deployment and the request has no `X-API-Key`; `503 CHAIN_DATA_UNAVAILABLE` when the Solana store cannot be read in time and `503 CHAIN_NOT_ENABLED` when the lane is off: retry later, never read either as \"no trades\".","url":"https://getchord.xyz/docs/api-reference/operations/solwallet/","parameters":[{"name":"address","in":"path","required":true,"type":"string","description":"Wallet address, base58, exactly as it appears on-chain."},{"name":"days","in":"query","required":false,"type":"integer","default":7,"description":"Window in UTC days, today included."}],"requestBody":null,"responses":{"200":"A wallet the tape has never seen answers zeros and an empty `positions`.","400":"`BAD_ADDRESS` / `BAD_DAYS`, or `UNSUPPORTED_CHAIN` (Solana is not public on this deployment and the request has no `X-API-Key`).","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","503":"`CHAIN_DATA_UNAVAILABLE` (the Solana store did not answer in time) or `CHAIN_NOT_ENABLED` (the lane is off on this deployment). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"string","wallet":"string — Solana address, base58, case-sensitive. Never lower-case it.","windowDays":"integer","tokens":"integer","trades":"integer","volumeUsd":"number","boughtUsd":"number","soldUsd":"number","realizedPnlUsd":"number","unrealizedPnlUsd":"number","heldValueUsd":"number","winRate":"number|null — Share of tokens with sells that closed in profit, 0–1.","partialTokens":"integer — Tokens with `partial: true`.","likelyBot":"boolean","positions":[{"token":"string — Solana address, base58, case-sensitive. Never lower-case it.","symbol":"string|null","name":"string|null","image":"string|null","priceUsd":"number|null — Current price on the main pool.","boughtUsd":"number","soldUsd":"number","boughtAmount":"number — Whole tokens.","soldAmount":"number — Whole tokens.","buys":"integer","sells":"integer","heldAmount":"number — Bought minus sold inside the window, whole tokens (never below 0). Not the on-chain balance.","heldValueUsd":"number|null","realizedPnlUsd":"number|null — Matched amount × (average sell − average buy). Null when the window has sells but no buys.","unrealizedPnlUsd":"number|null — Held amount × (price − average buy).","partial":"boolean — Sold more than it bought inside the window: part of the position was bought before the window (or arrived by transfer), so those sells carry no cost basis.","lastDay":"integer — Unix time, seconds, UTC."}],"updatedAt":"integer — Unix time, SECONDS, when the Solana box built this answer. Unlike the rest of the API (milliseconds)."},"example":{"chain":"solana","wallet":"3QZv9xcDELwLqB8SggDJHfVhMTn5YhKtXMCaKUucutm3","windowDays":7,"tokens":3,"trades":10,"volumeUsd":249.92409078731498,"boughtUsd":157.82642149850838,"soldUsd":92.09766928880659,"realizedPnlUsd":10.89172430885074,"unrealizedPnlUsd":-13.521686548756673,"heldValueUsd":92.65951096979586,"winRate":1,"partialTokens":1,"likelyBot":false,"positions":[{"token":"7VertkgF9KLhxxJXHX6uaWuoYZTP9LdGj2bWmVXVpump","symbol":"Agency","name":"Agency","image":"https://ipfs.io/ipfs/bafybeicailrr3iobedoxprzs6evwq3nqxsezdhvxbhpseyhltfmufybxuq","priceUsd":0.012298957291368744,"boughtUsd":139.35060978011185,"soldUsd":62.536948288806585,"boughtAmount":9685.829453,"soldAmount":3589.699624,"buys":5,"sells":2,"heldAmount":6096.129829,"heldValueUsd":74.97604040951005,"realizedPnlUsd":10.89172430885074,"unrealizedPnlUsd":-12.72934539064596,"partial":false,"lastDay":1791072000},{"token":"So11111111111111111111111111111111111111112","symbol":"SOL","name":"Solana","image":"https://raw.githubusercontent.com/solana-labs/token-list/main/assets/mainnet/So11111111111111111111111111111111111111112/logo.png","priceUsd":120.9862,"boughtUsd":0,"soldUsd":29.560721,"boughtAmount":0,"soldAmount":0.247089203,"buys":0,"sells":1,"heldAmount":0,"heldValueUsd":0,"realizedPnlUsd":null,"unrealizedPnlUsd":0,"partial":true,"lastDay":1790985600}],"updatedAt":1791166532}},"security":null},{"kind":"operation","operationId":"solWalletTrades","method":"GET","path":"/v1/chains/solana/wallet/{address}/trades","tag":"Solana data","summary":"A wallet's swaps","description":"The wallet's newest swaps on the venues the tape reads, newest first, with the token and its symbol. Each page looks back at most seven days from `before` (or from now).\n\nChord's own Solana tape, read-only. No key needed.\n\n- **What it reads.** The swap events of 11 venues: PumpSwap, the pump.fun bonding curve, Meteora DBC, Meteora DAMM v2, Meteora DLMM, Meteora pools (dynamic AMM v1), Raydium CLMM, Raydium CPMM, Raydium AMM v4, Raydium LaunchLab and Orca Whirlpool. Each swap is checked against the pool vaults' balance changes in the same transaction.\n- **What it does not read.** Prop AMMs (SolFi, HumidiFi and the like) and order books. SOL/USDC and other major pairs therefore show far less volume than the whole market; the numbers are accurate for pump.fun, Meteora and Raydium style tokens. Transfers are not seen either: wallet PnL is average cost inside the window.\n- **History.** Live since 2026-10-03 12:01 UTC, plus a backfill of the days before. `coverageSince` on `/chains/solana/overview` says from when totals are complete: quote that field, not a date.\n- **Addresses** are base58 and **case-sensitive**. Never lower-case a mint or a wallet: a lower-cased mint is a different string, refused with `400 BAD_ADDRESS` when it stops being base58 (an `L` becomes `l`) and answered `404 TOKEN_NOT_FOUND` otherwise. Solana has no numeric chain id here: the path segment is the literal `solana`.\n- **Units.** Token amounts are whole tokens (decimals already applied), `quoteAmount` is whole units of the pool's quote (SOL, USDC, USDT or the other token), prices and `*Usd` fields are US dollars. Timestamps, `updatedAt` included, are Unix **seconds**.\n- **Names are untrusted.** `symbol`, `name` and `image` are whatever the token's creator wrote; many mints share a symbol and there are no wash or impostor flags. Identify a token by its mint.\n- **Errors.** `400 BAD_*` for a bad parameter; `400 UNSUPPORTED_CHAIN` if Solana is not public on the deployment and the request has no `X-API-Key`; `503 CHAIN_DATA_UNAVAILABLE` when the Solana store cannot be read in time and `503 CHAIN_NOT_ENABLED` when the lane is off: retry later, never read either as \"no trades\".","url":"https://getchord.xyz/docs/api-reference/operations/solwallettrades/","parameters":[{"name":"address","in":"path","required":true,"type":"string","description":"Wallet address, base58, exactly as it appears on-chain."},{"name":"limit","in":"query","required":false,"type":"integer","default":50,"description":"Newest rows."},{"name":"before","in":"query","required":false,"type":"integer","description":"Exclusive cursor, Unix seconds: rows strictly older than it. Pass the last row's `ts` for the next page. Several swaps can share a second, so a page boundary can skip the rest of that second: overlap with `ts + 1` and drop rows whose `tx` you already have."}],"requestBody":null,"responses":{"200":"","400":"`BAD_ADDRESS` / `BAD_LIMIT` / `BAD_CURSOR`, or `UNSUPPORTED_CHAIN` (Solana is not public on this deployment and the request has no `X-API-Key`).","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","503":"`CHAIN_DATA_UNAVAILABLE` (the Solana store did not answer in time) or `CHAIN_NOT_ENABLED` (the lane is off on this deployment). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"string","wallet":"string — Solana address, base58, case-sensitive. Never lower-case it.","trades":[{"ts":"integer — Unix time, seconds, UTC.","slot":"integer","side":"string (buy|sell)","token":"string — Solana address, base58, case-sensitive. Never lower-case it.","symbol":"string|null","name":"string|null","tokenAmount":"number — Whole tokens.","quoteAmount":"number — Whole units of the pool's quote.","usd":"number|null","priceUsd":"number|null","dex":"string — Venue id: `pumpswap` · `pumpfun` (bonding curve) · `meteora_dbc` · `meteora_damm_v2` · `meteora_dlmm` · `meteora_pools` (dynamic AMM v1) · `raydium_clmm` · `raydium_cpmm` · `raydium_v4` · `raydium_launchlab` · `orca` (Whirlpool).","pool":"string|null — Solana address, base58, case-sensitive. Never lower-case it.","tx":"string — Transaction signature, base58."}],"updatedAt":"integer — Unix time, SECONDS, when the Solana box built this answer. Unlike the rest of the API (milliseconds)."},"example":{"chain":"solana","wallet":"3QZv9xcDELwLqB8SggDJHfVhMTn5YhKtXMCaKUucutm3","trades":[{"ts":1791151147,"slot":453384173,"side":"buy","token":"7VertkgF9KLhxxJXHX6uaWuoYZTP9LdGj2bWmVXVpump","symbol":"Agency","name":"Agency","tokenAmount":2879.134063,"quoteAmount":0.295798607,"usd":35.812234413351845,"priceUsd":0.012401339509037218,"dex":"pumpswap","pool":"CyJwKnLiiY4fmiwqMCSWFSHxo7T9Ubshgs2uRAuJCrk5","tx":"Vz2VPQCo2j82g6mowse5961MnUEM6koE7VSaVhtVHQKsvkCHZ9HGVMTgbw92vDSJw1ThSDiVGkwn16EucjAK6Ny"},{"ts":1791141717,"slot":453349000,"side":"buy","token":"DoVAVzViX8Bjy3r15nwikSaSbzE6dV4ovd28aWpJpump","symbol":"HIGGS","name":"Higgspad","tokenAmount":2231.366315,"quoteAmount":0.040323739,"usd":4.90003471839652,"priceUsd":0.0021763918544292736,"dex":"pumpswap","pool":"BFrSZakeqNzVtM3EFhroo4eRhagmmWN8BRntiQKFH6Ru","tx":"5yzFpQRh11MNX9dVWZsNGkHN4nD1XW7KQqWXD931tsYnc2rYggjaNkzZ4bCvddXoEama9pz1hqo2DH1f8i9UBVTr"}],"updatedAt":1791166571}},"security":null},{"kind":"operation","operationId":"solLpPools","method":"GET","path":"/v1/chains/solana/lp/pools","tag":"Solana data","summary":"Liquidity pools by LP activity","description":"Every pool where liquidity moved in the window, ranked: `fees` (claimed fees, default), `deposits`, `withdrawals`, `net` (net inflow), `lps` (distinct LPs), `tvl` or `fee_tvl` (fees claimed in the window per dollar of liquidity now). Each row has the pool's TVL estimate and swap volume from the swap tape (TVL is null until the pool has had a verified swap), deposits, withdrawals, claimed fees, counts and open positions. Cached 60 seconds.\n\n`feeTvlPct` is fees **claimed**, not fees accrued: the tape cannot see fees that sit unclaimed in a position, so it is not an APR. `sort=fee_tvl` starts from a $10,000 TVL floor (one claim on a thin pool would top the list); pass `minTvl=0` for no floor. `q` takes a ticker (any case, part of it is enough) or one pool or mint address (exact, case-sensitive).\n\nLiquidity on Solana from Chord's own tape: adds, removes, fee claims, position opens and closes, decoded from the same blocks as the swaps. No key needed.\n\n- **Venues.** Meteora DLMM, Meteora DAMM v2, Raydium CLMM and PumpSwap. Orca Whirlpools, Raydium CPMM / v4 and Meteora dynamic pools are not read yet.\n- **Since.** `since` is when LP decoding started (2026-10-06 15:53 UTC); windows never start before it. A position opened earlier is `partial: true` and carries no PnL.\n- **Fees are claimed fees.** An LP's fees appear when it claims them, so a window's fees understate what the pool earned, and one claim can hold days of fees.\n- **Positions.** One row per position account (DLMM / DAMM v2 position, Raydium CLMM position NFT, PumpSwap LP token account), rebuilt from all its events. `lower` / `upper` are DLMM bin ids or Raydium CLMM ticks; null = full range. Realized PnL = withdrawn + fees claimed − deposited, only for a position seen from its open to its close with every amount priced. An open position's current value is not in the events: none is given.\n- **Amounts** are whole tokens in the pool's own order (`mintA` / `mintB`); USD is valued when the event happened. Each add / remove / claim is checked against the pool vaults' balance changes in the same transaction (`verified`).\n- **Addresses** are base58 and case-sensitive, as on the other Solana routes.","url":"https://getchord.xyz/docs/api-reference/operations/sollppools/","parameters":[{"name":"sort","in":"query","required":false,"type":"string","enum":["fees","deposits","withdrawals","net","lps","tvl","fee_tvl"],"default":"fees","description":""},{"name":"limit","in":"query","required":false,"type":"integer","default":50,"description":""},{"name":"hours","in":"query","required":false,"type":"integer","default":24,"description":"Window in hours, never before `since`."},{"name":"minTvl","in":"query","required":false,"type":"integer","description":"Leave out pools under this TVL in US dollars, and pools whose TVL is unknown. Default 0, or 10000 with `sort=fee_tvl`."},{"name":"q","in":"query","required":false,"type":"string","description":"A ticker, or one pool or mint address."},{"name":"dex","in":"query","required":false,"type":"string","enum":["meteora_dlmm","meteora_damm_v2","raydium_clmm","pumpswap"],"description":"One venue."}],"requestBody":null,"responses":{"200":"","400":"`BAD_LIMIT` / `BAD_HOURS` / `BAD_SORT` / `BAD_MIN_TVL` / `BAD_QUERY` / `BAD_DEX`, or `UNSUPPORTED_CHAIN` (Solana is not public on this deployment and the request has no `X-API-Key`).","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","503":"`CHAIN_DATA_UNAVAILABLE` (the Solana store did not answer in time) or `CHAIN_NOT_ENABLED` (the lane is off on this deployment). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"string","sort":"string","windowHours":"integer","since":"integer — Unix time, seconds, UTC.","pools":"integer — Pools with activity in the window.","total":"integer — Pools left after `minTvl`, `q` and `dex`.","minTvl":"number — The floor applied.","rows":[{"pool":"string — Solana address, base58, case-sensitive. Never lower-case it.","dex":"string — `meteora_dlmm` · `meteora_damm_v2` · `raydium_clmm` · `pumpswap`.","mintA":"string|null — Solana address, base58, case-sensitive. Never lower-case it.","symbolA":"string|null — Creator-chosen.","mintB":"string|null — Solana address, base58, case-sensitive. Never lower-case it.","symbolB":"string|null — Creator-chosen.","tvlUsd":"number|null","priceUsd":"number|null","token":"string|null — Solana address, base58, case-sensitive. Never lower-case it.","swapVolumeUsd":"number|null","depositsUsd":"number","withdrawalsUsd":"number","netFlowUsd":"number","feesClaimedUsd":"number","adds":"integer","removes":"integer","claims":"integer","opens":"integer","closes":"integer","lps":"integer","openPositions":"integer|null","feeTvlPct":"number|null — Fees claimed in the window as a percent of `tvlUsd`. null when the TVL is unknown.","firstLpEvent":"integer|null — Unix time, seconds, UTC.","imageA":"string|null — Token image as its creator set it. Untrusted.","imageB":"string|null"}],"updatedAt":"integer — Unix time, SECONDS, when the Solana box built this answer. Unlike the rest of the API (milliseconds)."},"example":{"chain":"solana","sort":"fees","windowHours":24,"since":1791301995,"pools":862,"rows":[{"pool":"7fDzFPYhdtNm5NbqvZYRcjB879DxH4dRjmMhbHSYqM5J","dex":"meteora_damm_v2","mintA":"TfLEzpE2rvwng5WPDP7XqsMoNLfgk2mKXNxJUvQs8c1","symbolA":"LOCAL","mintB":"So11111111111111111111111111111111111111112","symbolB":"SOL","tvlUsd":27625.24059411423,"priceUsd":0.00007144600292746474,"token":"TfLEzpE2rvwng5WPDP7XqsMoNLfgk2mKXNxJUvQs8c1","swapVolumeUsd":4454.320941113588,"depositsUsd":0,"withdrawalsUsd":0,"netFlowUsd":0,"feesClaimedUsd":4161.145469719044,"adds":0,"removes":0,"claims":2,"opens":0,"closes":0,"lps":1,"openPositions":1},{"pool":"HbjYfcWZBjCBYTJpZkLGxqArVmZVu3mQcRudb6Wg1sVh","dex":"meteora_dlmm","mintA":"pumpCmXqMfrsAkQ5r49WcJnRayYRqmXz6ae8H7H9Dfn","symbolA":"PUMP","mintB":"So11111111111111111111111111111111111111112","symbolB":"SOL","tvlUsd":null,"priceUsd":0.006306820783643733,"token":"pumpCmXqMfrsAkQ5r49WcJnRayYRqmXz6ae8H7H9Dfn","swapVolumeUsd":19055.704227499944,"depositsUsd":7769.8327865424735,"withdrawalsUsd":41.92886719122702,"netFlowUsd":7727.903919351246,"feesClaimedUsd":3075.699010802388,"adds":11,"removes":1,"claims":10,"opens":0,"closes":0,"lps":7,"openPositions":7}],"updatedAt":1791303661}},"security":null},{"kind":"operation","operationId":"solLpTop","method":"GET","path":"/v1/chains/solana/lp/top","tag":"Solana data","summary":"LP wallets","description":"Wallets ranked over the LP positions active in the window: `fees` (claimed, default), `deposits` or `pnl` (realized). Many leaders are vaults and rebalancing bots; a short window is not a track record. Cached 60 seconds.\n\nThe board is **fee-checked**: a wallet whose realized profit is positive while the fees it claimed are under a tenth of that profit earned on the token's price (in practice one-sided liquidity on a token it launched) and is left out; `hidden` counts them. A launchpad account (500 or more positions with a pool of its own for at least every second one: the liquidity of what a launchpad launched) is left out with them; `operators` counts those. `all=1` keeps both in.\n\nLiquidity on Solana from Chord's own tape: adds, removes, fee claims, position opens and closes, decoded from the same blocks as the swaps. No key needed.\n\n- **Venues.** Meteora DLMM, Meteora DAMM v2, Raydium CLMM and PumpSwap. Orca Whirlpools, Raydium CPMM / v4 and Meteora dynamic pools are not read yet.\n- **Since.** `since` is when LP decoding started (2026-10-06 15:53 UTC); windows never start before it. A position opened earlier is `partial: true` and carries no PnL.\n- **Fees are claimed fees.** An LP's fees appear when it claims them, so a window's fees understate what the pool earned, and one claim can hold days of fees.\n- **Positions.** One row per position account (DLMM / DAMM v2 position, Raydium CLMM position NFT, PumpSwap LP token account), rebuilt from all its events. `lower` / `upper` are DLMM bin ids or Raydium CLMM ticks; null = full range. Realized PnL = withdrawn + fees claimed − deposited, only for a position seen from its open to its close with every amount priced. An open position's current value is not in the events: none is given.\n- **Amounts** are whole tokens in the pool's own order (`mintA` / `mintB`); USD is valued when the event happened. Each add / remove / claim is checked against the pool vaults' balance changes in the same transaction (`verified`).\n- **Addresses** are base58 and case-sensitive, as on the other Solana routes.","url":"https://getchord.xyz/docs/api-reference/operations/sollptop/","parameters":[{"name":"sort","in":"query","required":false,"type":"string","enum":["fees","deposits","pnl","win_rate","ev","positions","avg_age","last_activity"],"default":"fees","description":""},{"name":"unit","in":"query","required":false,"type":"string","enum":["usd","native"],"default":"usd","description":"`native` = the money fields of the answer in SOL: every deposit, withdrawal and claimed fee converted at the SOL price of its own minute, so a wallet that put SOL in and took the same SOL out reads flat whatever SOL did in dollars (win rate and expected value follow the unit). The fields keep their `…Usd` names; `unit` and `unitSymbol` in the answer say what they carry. `503 UNIT_NOT_READY` while positions are being folded again; another value is `400 BAD_UNIT`."},{"name":"limit","in":"query","required":false,"type":"integer","default":50,"description":""},{"name":"hours","in":"query","required":false,"type":"integer","default":24,"description":"Window in hours, never before `since`."},{"name":"all","in":"query","required":false,"type":"string","enum":["0","1"],"description":"1 = keep the wallets the fee check and the launchpad rule leave out."}],"requestBody":null,"responses":{"200":"","400":"`BAD_LIMIT` / `BAD_HOURS` / `BAD_SORT` / `BAD_ALL`, or `UNSUPPORTED_CHAIN` (Solana is not public on this deployment and the request has no `X-API-Key`).","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","503":"`CHAIN_DATA_UNAVAILABLE` (the Solana store did not answer in time) or `CHAIN_NOT_ENABLED` (the lane is off on this deployment). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"string","sort":"string","windowHours":"integer","since":"integer — Unix time, seconds, UTC.","feeChecked":"boolean — The fee check was applied.","hidden":"integer — Wallets of the window the fee check left out.","operators":"integer — Launchpad accounts of the window left out.","rows":[{"wallet":"string|null — Solana address, base58, case-sensitive. Never lower-case it.","positions":"integer","open":"integer","pools":"integer","depositedUsd":"number","withdrawnUsd":"number","feesClaimedUsd":"number","realizedPnlUsd":"number|null","realizedPositions":"integer","winRate":"number|null — 0–1.","evUsd":"number|null — Mean result of a realized position; null with none.","avgAgeHours":"number|null — Hours a position stays open, open ones counted to now.","avgDepositUsd":"number|null","firstTs":"integer|null — Unix time, seconds, UTC.","lastTs":"integer|null — Unix time, seconds, UTC."}],"updatedAt":"integer — Unix time, SECONDS, when the Solana box built this answer. Unlike the rest of the API (milliseconds)."},"example":{"chain":"solana","sort":"fees","windowHours":24,"since":1791750117,"feeChecked":true,"hidden":235,"operators":2,"rows":[{"wallet":"6sWm5C5E25mZD98z7RAZZCqetT3rjWuLXRZsmimg6KEK","positions":1,"open":1,"pools":1,"depositedUsd":0,"withdrawnUsd":0,"feesClaimedUsd":225969.36547100003,"realizedPnlUsd":null,"realizedPositions":0,"winRate":null,"evUsd":null,"avgAgeHours":74.6913888888889,"avgDepositUsd":null,"firstTs":1791567628,"lastTs":1791818882},{"wallet":"9SgR9w7ii7ZofZ5kgyb7hUwRVAkqRApdTZWcx4gsssCb","positions":2,"open":2,"pools":1,"depositedUsd":0,"withdrawnUsd":0,"feesClaimedUsd":94307.16837727133,"realizedPnlUsd":null,"realizedPositions":0,"winRate":null,"evUsd":null,"avgAgeHours":null,"avgDepositUsd":null,"firstTs":1791429320,"lastTs":1791791319}],"updatedAt":1791836517}},"security":null},{"kind":"operation","operationId":"solLpPool","method":"GET","path":"/v1/chains/solana/lp/pool/{address}","tag":"Solana data","summary":"One pool's liquidity","description":"Deposits, withdrawals, net flow and claimed fees over the window, and by hour; open positions and their owners; the pair with decimals, TVL estimate and swap volume. Cached 20 seconds.\n\nLiquidity on Solana from Chord's own tape: adds, removes, fee claims, position opens and closes, decoded from the same blocks as the swaps. No key needed.\n\n- **Venues.** Meteora DLMM, Meteora DAMM v2, Raydium CLMM and PumpSwap. Orca Whirlpools, Raydium CPMM / v4 and Meteora dynamic pools are not read yet.\n- **Since.** `since` is when LP decoding started (2026-10-06 15:53 UTC); windows never start before it. A position opened earlier is `partial: true` and carries no PnL.\n- **Fees are claimed fees.** An LP's fees appear when it claims them, so a window's fees understate what the pool earned, and one claim can hold days of fees.\n- **Positions.** One row per position account (DLMM / DAMM v2 position, Raydium CLMM position NFT, PumpSwap LP token account), rebuilt from all its events. `lower` / `upper` are DLMM bin ids or Raydium CLMM ticks; null = full range. Realized PnL = withdrawn + fees claimed − deposited, only for a position seen from its open to its close with every amount priced. An open position's current value is not in the events: none is given.\n- **Amounts** are whole tokens in the pool's own order (`mintA` / `mintB`); USD is valued when the event happened. Each add / remove / claim is checked against the pool vaults' balance changes in the same transaction (`verified`).\n- **Addresses** are base58 and case-sensitive, as on the other Solana routes.","url":"https://getchord.xyz/docs/api-reference/operations/sollppool/","parameters":[{"name":"address","in":"path","required":true,"type":"string","description":"Pool address, base58."},{"name":"hours","in":"query","required":false,"type":"integer","default":24,"description":"Window in hours, never before `since`."}],"requestBody":null,"responses":{"200":"","400":"`BAD_ADDRESS` / `BAD_HOURS`, or `UNSUPPORTED_CHAIN` (Solana is not public on this deployment and the request has no `X-API-Key`).","404":"`POOL_NOT_FOUND`: no liquidity event in this pool since LP decoding started, or its venue is not read.","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","503":"`CHAIN_DATA_UNAVAILABLE` (the Solana store did not answer in time) or `CHAIN_NOT_ENABLED` (the lane is off on this deployment). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"string","pool":"string — Solana address, base58, case-sensitive. Never lower-case it.","dex":"string — `meteora_dlmm` · `meteora_damm_v2` · `raydium_clmm` · `pumpswap`.","windowHours":"integer","since":"integer — Unix time, seconds, UTC.","mintA":"string|null — Solana address, base58, case-sensitive. Never lower-case it.","symbolA":"string|null — Creator-chosen.","mintB":"string|null — Solana address, base58, case-sensitive. Never lower-case it.","symbolB":"string|null — Creator-chosen.","decimalsA":"integer","decimalsB":"integer","tvlUsd":"number|null","priceUsd":"number|null","token":"string|null — Solana address, base58, case-sensitive. Never lower-case it.","firstLpEvent":"integer — Unix time, seconds, UTC.","swapVolumeUsd":"number|null","depositsUsd":"number","withdrawalsUsd":"number","netFlowUsd":"number","feesClaimedUsd":"number","openPositions":"integer","openOwners":"integer","hourly":[{"hour":"integer — Unix time, seconds, UTC.","depositsUsd":"number","withdrawalsUsd":"number","feesClaimedUsd":"number","adds":"integer","removes":"integer","claims":"integer","opens":"integer","closes":"integer","lps":"integer"}],"updatedAt":"integer — Unix time, SECONDS, when the Solana box built this answer. Unlike the rest of the API (milliseconds)."},"example":{"chain":"solana","pool":"HTvjzsfX3yU6BUodCjZ5vZkUrAxMDTrBs3CJaq43ashR","dex":"meteora_dlmm","windowHours":24,"since":1791301995,"mintA":"So11111111111111111111111111111111111111112","symbolA":"SOL","decimalsA":9,"mintB":"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v","symbolB":"USDC","decimalsB":6,"tvlUsd":null,"priceUsd":120.90833585378545,"token":"So11111111111111111111111111111111111111112","firstLpEvent":1791302002,"swapVolumeUsd":657350.330032,"depositsUsd":46262.672679370095,"withdrawalsUsd":12314.010901404514,"netFlowUsd":33948.66177796558,"feesClaimedUsd":25.931564176688006,"openPositions":22,"openOwners":17,"hourly":[{"hour":1791298800,"depositsUsd":30397.05064594894,"withdrawalsUsd":7196.542626796252,"feesClaimedUsd":0.370617802409548,"adds":52,"removes":28,"claims":30,"opens":24,"closes":0,"lps":10},{"hour":1791302400,"depositsUsd":15865.622033421156,"withdrawalsUsd":5117.468274608262,"feesClaimedUsd":25.56094637427846,"adds":56,"removes":35,"claims":36,"opens":27,"closes":0,"lps":15}],"updatedAt":1791303661}},"security":null},{"kind":"operation","operationId":"solLpPoolPositions","method":"GET","path":"/v1/chains/solana/lp/pool/{address}/positions","tag":"Solana data","summary":"A pool's positions","description":"The pool's positions, most recently active first. Cached 20 seconds.\n\nLiquidity on Solana from Chord's own tape: adds, removes, fee claims, position opens and closes, decoded from the same blocks as the swaps. No key needed.\n\n- **Venues.** Meteora DLMM, Meteora DAMM v2, Raydium CLMM and PumpSwap. Orca Whirlpools, Raydium CPMM / v4 and Meteora dynamic pools are not read yet.\n- **Since.** `since` is when LP decoding started (2026-10-06 15:53 UTC); windows never start before it. A position opened earlier is `partial: true` and carries no PnL.\n- **Fees are claimed fees.** An LP's fees appear when it claims them, so a window's fees understate what the pool earned, and one claim can hold days of fees.\n- **Positions.** One row per position account (DLMM / DAMM v2 position, Raydium CLMM position NFT, PumpSwap LP token account), rebuilt from all its events. `lower` / `upper` are DLMM bin ids or Raydium CLMM ticks; null = full range. Realized PnL = withdrawn + fees claimed − deposited, only for a position seen from its open to its close with every amount priced. An open position's current value is not in the events: none is given.\n- **Amounts** are whole tokens in the pool's own order (`mintA` / `mintB`); USD is valued when the event happened. Each add / remove / claim is checked against the pool vaults' balance changes in the same transaction (`verified`).\n- **Addresses** are base58 and case-sensitive, as on the other Solana routes.","url":"https://getchord.xyz/docs/api-reference/operations/sollppoolpositions/","parameters":[{"name":"address","in":"path","required":true,"type":"string","description":"Pool address, base58."},{"name":"status","in":"query","required":false,"type":"string","enum":["open","closed","all"],"default":"all","description":"Which positions."},{"name":"limit","in":"query","required":false,"type":"integer","default":50,"description":""}],"requestBody":null,"responses":{"200":"","400":"`BAD_ADDRESS` / `BAD_STATUS` / `BAD_LIMIT`, or `UNSUPPORTED_CHAIN` (Solana is not public on this deployment and the request has no `X-API-Key`).","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","503":"`CHAIN_DATA_UNAVAILABLE` (the Solana store did not answer in time) or `CHAIN_NOT_ENABLED` (the lane is off on this deployment). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"string","pool":"string — Solana address, base58, case-sensitive. Never lower-case it.","status":"string","since":"integer|null — Unix time, seconds, UTC.","positions":[{"position":"string|null — Solana address, base58, case-sensitive. Never lower-case it.","dex":"string — `meteora_dlmm` · `meteora_damm_v2` · `raydium_clmm` · `pumpswap`.","pool":"string|null — Solana address, base58, case-sensitive. Never lower-case it.","owner":"string|null — Solana address, base58, case-sensitive. Never lower-case it.","mintA":"string|null — Solana address, base58, case-sensitive. Never lower-case it.","symbolA":"string|null — Creator-chosen.","mintB":"string|null — Solana address, base58, case-sensitive. Never lower-case it.","symbolB":"string|null — Creator-chosen.","lower":"integer|null — DLMM bin id or CLMM tick.","upper":"integer|null","status":"string (open|closed)","openedAt":"integer|null — Unix time, seconds, UTC.","closedAt":"integer|null — Unix time, seconds, UTC.","firstEvent":"integer — Unix time, seconds, UTC.","lastEvent":"integer — Unix time, seconds, UTC.","events":"integer","depositedA":"number|null — Whole tokens.","depositedB":"number|null","withdrawnA":"number|null","withdrawnB":"number|null","feesA":"number|null — Claimed.","feesB":"number|null — Claimed.","depositedUsd":"number","withdrawnUsd":"number","feesClaimedUsd":"number","realizedPnlUsd":"number|null — Withdrawn + fees − deposited; null unless closed, not partial and fully priced.","partial":"boolean — The tape did not see the open (opened before `since`); PumpSwap: more came out than the tape saw going in.","unpricedEvents":"integer — Value events without a USD price."}],"updatedAt":"integer — Unix time, SECONDS, when the Solana box built this answer. Unlike the rest of the API (milliseconds)."},"example":{"chain":"solana","pool":"HTvjzsfX3yU6BUodCjZ5vZkUrAxMDTrBs3CJaq43ashR","status":"open","since":1791301995,"positions":[{"position":"6gDiPzm69sdQMAAMUjSwY8n1ruPXYpy6Yx5tTt3PBgPv","dex":"meteora_dlmm","pool":"HTvjzsfX3yU6BUodCjZ5vZkUrAxMDTrBs3CJaq43ashR","owner":"GDzKV9YibjzWNtFCeGSAXntzv8e2tU1UcLPV1hoXxXJM","mintA":"So11111111111111111111111111111111111111112","symbolA":"SOL","mintB":"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v","symbolB":"USDC","lower":-21194,"upper":-21170,"status":"open","openedAt":1791303634,"closedAt":null,"firstEvent":1791303634,"lastEvent":1791303634,"events":2,"depositedA":0,"depositedB":65.188341,"withdrawnA":0,"withdrawnB":0,"feesA":0,"feesB":0,"depositedUsd":65.188341,"withdrawnUsd":0,"feesClaimedUsd":0,"realizedPnlUsd":null,"partial":false,"unpricedEvents":0},{"position":"G8LWKkSM58cGfty8Huw7PAsaRz86LqyaysUhMLL8HdD3","dex":"meteora_dlmm","pool":"HTvjzsfX3yU6BUodCjZ5vZkUrAxMDTrBs3CJaq43ashR","owner":"zmpMLRAH2Nt5ZDaax1jXH9QdmVRzw7rHm84sKpZa6wy","mintA":"So11111111111111111111111111111111111111112","symbolA":"SOL","mintB":"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v","symbolB":"USDC","lower":-21167,"upper":-21091,"status":"open","openedAt":1791302020,"closedAt":null,"firstEvent":1791302020,"lastEvent":1791303567,"events":25,"depositedA":22.506085353,"depositedB":1668.168769,"withdrawnA":16.697187434,"withdrawnB":1367.959384,"feesA":0.001835888,"feesB":0.267907,"depositedUsd":4385.0568295447565,"withdrawnUsd":3383.4942419848394,"feesClaimedUsd":0.48990795627555367,"realizedPnlUsd":null,"partial":false,"unpricedEvents":0}],"updatedAt":1791303662}},"security":null},{"kind":"operation","operationId":"solLpWallet","method":"GET","path":"/v1/chains/solana/lp/wallet/{address}","tag":"Solana data","summary":"A wallet's LP positions","description":"The wallet's positions as owner (DLMM: the position's owner, not an operator acting for it), most recently active first, with totals over every position of the `status` asked: deposited, withdrawn, claimed fees, realized PnL and win rate over positions seen open to close. Cached 15 seconds.\n\nLiquidity on Solana from Chord's own tape: adds, removes, fee claims, position opens and closes, decoded from the same blocks as the swaps. No key needed.\n\n- **Venues.** Meteora DLMM, Meteora DAMM v2, Raydium CLMM and PumpSwap. Orca Whirlpools, Raydium CPMM / v4 and Meteora dynamic pools are not read yet.\n- **Since.** `since` is when LP decoding started (2026-10-06 15:53 UTC); windows never start before it. A position opened earlier is `partial: true` and carries no PnL.\n- **Fees are claimed fees.** An LP's fees appear when it claims them, so a window's fees understate what the pool earned, and one claim can hold days of fees.\n- **Positions.** One row per position account (DLMM / DAMM v2 position, Raydium CLMM position NFT, PumpSwap LP token account), rebuilt from all its events. `lower` / `upper` are DLMM bin ids or Raydium CLMM ticks; null = full range. Realized PnL = withdrawn + fees claimed − deposited, only for a position seen from its open to its close with every amount priced. An open position's current value is not in the events: none is given.\n- **Amounts** are whole tokens in the pool's own order (`mintA` / `mintB`); USD is valued when the event happened. Each add / remove / claim is checked against the pool vaults' balance changes in the same transaction (`verified`).\n- **Addresses** are base58 and case-sensitive, as on the other Solana routes.","url":"https://getchord.xyz/docs/api-reference/operations/sollpwallet/","parameters":[{"name":"address","in":"path","required":true,"type":"string","description":"Wallet address, base58, exactly as it appears on-chain."},{"name":"status","in":"query","required":false,"type":"string","enum":["open","closed","all"],"default":"all","description":"Which positions."},{"name":"unit","in":"query","required":false,"type":"string","enum":["usd","native"],"default":"usd","description":"`native` = the money fields of the answer in SOL: every deposit, withdrawal and claimed fee converted at the SOL price of its own minute, so a wallet that put SOL in and took the same SOL out reads flat whatever SOL did in dollars (win rate and expected value follow the unit). The fields keep their `…Usd` names; `unit` and `unitSymbol` in the answer say what they carry. `503 UNIT_NOT_READY` while positions are being folded again; another value is `400 BAD_UNIT`."},{"name":"limit","in":"query","required":false,"type":"integer","default":100,"description":"Rows; totals cover every position."}],"requestBody":null,"responses":{"200":"","400":"`BAD_ADDRESS` / `BAD_STATUS` / `BAD_LIMIT`, or `UNSUPPORTED_CHAIN` (Solana is not public on this deployment and the request has no `X-API-Key`).","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","503":"`CHAIN_DATA_UNAVAILABLE` (the Solana store did not answer in time) or `CHAIN_NOT_ENABLED` (the lane is off on this deployment). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"string","wallet":"string — Solana address, base58, case-sensitive. Never lower-case it.","status":"string","since":"integer|null — Unix time, seconds, UTC.","positions":"integer","open":"integer","closed":"integer","pools":"integer","depositedUsd":"number","withdrawnUsd":"number","feesClaimedUsd":"number","realizedPnlUsd":"number|null","realizedPositions":"integer","winRate":"number|null — 0–1.","evUsd":"number|null — Mean result of a realized position.","avgAgeHours":"number|null","avgDepositUsd":"number|null","firstTs":"integer|null — Unix time, seconds, UTC.","lastTs":"integer|null — Unix time, seconds, UTC.","history":[{"day":"string — YYYY-MM-DD, UTC","profitUsd":"number — Result of the realized positions that ended on the day.","feesUsd":"number — Fees claimed by the positions that ended, or were last touched, on the day.","positions":"integer"}],"rows":[{"position":"string|null — Solana address, base58, case-sensitive. Never lower-case it.","dex":"string — `meteora_dlmm` · `meteora_damm_v2` · `raydium_clmm` · `pumpswap`.","pool":"string|null — Solana address, base58, case-sensitive. Never lower-case it.","owner":"string|null — Solana address, base58, case-sensitive. Never lower-case it.","mintA":"string|null — Solana address, base58, case-sensitive. Never lower-case it.","symbolA":"string|null — Creator-chosen.","mintB":"string|null — Solana address, base58, case-sensitive. Never lower-case it.","symbolB":"string|null — Creator-chosen.","lower":"integer|null — DLMM bin id or CLMM tick.","upper":"integer|null","status":"string (open|closed)","openedAt":"integer|null — Unix time, seconds, UTC.","closedAt":"integer|null — Unix time, seconds, UTC.","firstEvent":"integer — Unix time, seconds, UTC.","lastEvent":"integer — Unix time, seconds, UTC.","events":"integer","depositedA":"number|null — Whole tokens.","depositedB":"number|null","withdrawnA":"number|null","withdrawnB":"number|null","feesA":"number|null — Claimed.","feesB":"number|null — Claimed.","depositedUsd":"number","withdrawnUsd":"number","feesClaimedUsd":"number","realizedPnlUsd":"number|null — Withdrawn + fees − deposited; null unless closed, not partial and fully priced.","partial":"boolean — The tape did not see the open (opened before `since`); PumpSwap: more came out than the tape saw going in.","unpricedEvents":"integer — Value events without a USD price."}],"updatedAt":"integer — Unix time, SECONDS, when the Solana box built this answer. Unlike the rest of the API (milliseconds)."},"example":{"chain":"solana","wallet":"GwBsj9GJdFrATQs1k9EYUyfaatKZDiViy8tkU9JP3TUL","status":"all","since":1791301995,"positions":750,"open":10,"closed":740,"pools":26,"depositedUsd":2649179.5405913335,"withdrawnUsd":2647817.6755300546,"feesClaimedUsd":18015.87641073856,"realizedPnlUsd":3345.1307860846005,"realizedPositions":722,"winRate":0.5512465373961218,"evUsd":4.633145133081164,"avgAgeHours":2.460573222071869,"avgDepositUsd":3575.1410804201532,"firstTs":1790774387,"lastTs":1791825711,"history":[{"day":"2026-09-30","profitUsd":0,"feesUsd":71.65268316036983,"positions":2},{"day":"2026-10-01","profitUsd":0,"feesUsd":7.083795820757369,"positions":2},{"day":"2026-10-04","profitUsd":0,"feesUsd":38.751457795784674,"positions":2}],"rows":[{"position":"69v9s6gQje3Rk8u3vwn8kSEAxX1BNciUJEhG5Vb2fcPA","dex":"meteora_dlmm","pool":"GgoFghiA6Ca7YNmG6dRxwKQWkZhRK8ND47EREz46arot","owner":"GwBsj9GJdFrATQs1k9EYUyfaatKZDiViy8tkU9JP3TUL","mintA":"WXMRyRZhsa19ety5erZhHg4N3xj3EVN92u94422teJp","symbolA":"XMR","mintB":"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v","symbolB":"USDC","lower":-7544,"upper":-7544,"status":"closed","openedAt":1791825038,"closedAt":1791825711,"firstEvent":1791825038,"lastEvent":1791825711,"events":5,"depositedA":0,"depositedB":9871.870653,"withdrawnA":15.009532666305,"withdrawnB":1897.560215,"feesA":0.017992659416,"feesB":2.482098,"depositedUsd":9871.870653,"withdrawnUsd":9879.734769314513,"feesClaimedUsd":12.050720244798956,"realizedPnlUsd":19.91483655931188,"partial":false,"unpricedEvents":0},{"position":"BpHs9ZbEoCTrM2P5JKY3cgxWhUTeMMUMa41jWiUjwQ9w","dex":"meteora_dlmm","pool":"GgoFghiA6Ca7YNmG6dRxwKQWkZhRK8ND47EREz46arot","owner":"GwBsj9GJdFrATQs1k9EYUyfaatKZDiViy8tkU9JP3TUL","mintA":"WXMRyRZhsa19ety5erZhHg4N3xj3EVN92u94422teJp","symbolA":"XMR","mintB":"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v","symbolB":"USDC","lower":-7545,"upper":-7545,"status":"closed","openedAt":1791824988,"closedAt":1791825034,"firstEvent":1791824988,"lastEvent":1791825034,"events":5,"depositedA":0,"depositedB":9871.839615,"withdrawnA":0,"withdrawnB":9871.405961,"feesA":0.000141564492,"feesB":0.464692,"depositedUsd":9871.839615,"withdrawnUsd":9871.405961,"feesClaimedUsd":0.5398261385532628,"realizedPnlUsd":0.10617213855221053,"partial":false,"unpricedEvents":0}],"updatedAt":1791836517}},"security":null},{"kind":"operation","operationId":"solLpPoolEvents","method":"GET","path":"/v1/chains/solana/lp/pool/{address}/events","tag":"Solana data","summary":"A pool's liquidity events","description":"Adds, removes, fee claims, opens and closes, newest first. A close row of a DLMM `close_position2` or a Raydium CLMM position has no `pool`: the instruction does not carry it.\n\nLiquidity on Solana from Chord's own tape: adds, removes, fee claims, position opens and closes, decoded from the same blocks as the swaps. No key needed.\n\n- **Venues.** Meteora DLMM, Meteora DAMM v2, Raydium CLMM and PumpSwap. Orca Whirlpools, Raydium CPMM / v4 and Meteora dynamic pools are not read yet.\n- **Since.** `since` is when LP decoding started (2026-10-06 15:53 UTC); windows never start before it. A position opened earlier is `partial: true` and carries no PnL.\n- **Fees are claimed fees.** An LP's fees appear when it claims them, so a window's fees understate what the pool earned, and one claim can hold days of fees.\n- **Positions.** One row per position account (DLMM / DAMM v2 position, Raydium CLMM position NFT, PumpSwap LP token account), rebuilt from all its events. `lower` / `upper` are DLMM bin ids or Raydium CLMM ticks; null = full range. Realized PnL = withdrawn + fees claimed − deposited, only for a position seen from its open to its close with every amount priced. An open position's current value is not in the events: none is given.\n- **Amounts** are whole tokens in the pool's own order (`mintA` / `mintB`); USD is valued when the event happened. Each add / remove / claim is checked against the pool vaults' balance changes in the same transaction (`verified`).\n- **Addresses** are base58 and case-sensitive, as on the other Solana routes.","url":"https://getchord.xyz/docs/api-reference/operations/sollppoolevents/","parameters":[{"name":"address","in":"path","required":true,"type":"string","description":"Pool address, base58."},{"name":"limit","in":"query","required":false,"type":"integer","default":50,"description":""},{"name":"before","in":"query","required":false,"type":"integer","description":"Exclusive cursor, Unix seconds: rows strictly older than it. Pass the last row's `ts` for the next page. Several swaps can share a second, so a page boundary can skip the rest of that second: overlap with `ts + 1` and drop rows whose `tx` you already have."}],"requestBody":null,"responses":{"200":"","400":"`BAD_ADDRESS` / `BAD_LIMIT` / `BAD_CURSOR`, or `UNSUPPORTED_CHAIN` (Solana is not public on this deployment and the request has no `X-API-Key`).","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","503":"`CHAIN_DATA_UNAVAILABLE` (the Solana store did not answer in time) or `CHAIN_NOT_ENABLED` (the lane is off on this deployment). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"string","pool":"string — Solana address, base58, case-sensitive. Never lower-case it.","events":[{"ts":"integer — Unix time, seconds, UTC.","slot":"integer","signature":"string|null — Transaction signature, base58.","dex":"string — `meteora_dlmm` · `meteora_damm_v2` · `raydium_clmm` · `pumpswap`.","kind":"string (add|remove|fee|open|close)","pool":"string|null — Solana address, base58, case-sensitive. Never lower-case it.","position":"string|null — Solana address, base58, case-sensitive. Never lower-case it.","owner":"string|null — Solana address, base58, case-sensitive. Never lower-case it.","amountA":"number|null — Whole tokens.","amountB":"number|null","usd":"number|null","lower":"integer|null","upper":"integer|null","verified":"boolean|null — true = matches the vault balance changes; null = could not be checked (shared vault, first deposit of a new pool)"}],"nextBefore":"integer|null — Unix time, seconds, UTC."},"example":{"chain":"solana","pool":"HTvjzsfX3yU6BUodCjZ5vZkUrAxMDTrBs3CJaq43ashR","events":[{"ts":1791303634,"slot":453953506,"signature":"5bPcr5RdHzhoYFECwNaxp6FFwiv1xCcMxkGhLfrzZJaHos6UWJdnCey9FgUhfUC8kZqLgsrBy2ifzw8b9oQsyajc","dex":"meteora_dlmm","kind":"add","pool":"HTvjzsfX3yU6BUodCjZ5vZkUrAxMDTrBs3CJaq43ashR","position":"6gDiPzm69sdQMAAMUjSwY8n1ruPXYpy6Yx5tTt3PBgPv","owner":"GDzKV9YibjzWNtFCeGSAXntzv8e2tU1UcLPV1hoXxXJM","amountA":0,"amountB":65.188341,"usd":65.188341,"lower":null,"upper":null,"verified":true},{"ts":1791303634,"slot":453953506,"signature":"5bPcr5RdHzhoYFECwNaxp6FFwiv1xCcMxkGhLfrzZJaHos6UWJdnCey9FgUhfUC8kZqLgsrBy2ifzw8b9oQsyajc","dex":"meteora_dlmm","kind":"open","pool":"HTvjzsfX3yU6BUodCjZ5vZkUrAxMDTrBs3CJaq43ashR","position":"6gDiPzm69sdQMAAMUjSwY8n1ruPXYpy6Yx5tTt3PBgPv","owner":"GDzKV9YibjzWNtFCeGSAXntzv8e2tU1UcLPV1hoXxXJM","amountA":0,"amountB":0,"usd":null,"lower":-21194,"upper":-21170,"verified":null}],"nextBefore":1791303634}},"security":null},{"kind":"operation","operationId":"solLpWalletEvents","method":"GET","path":"/v1/chains/solana/lp/wallet/{address}/events","tag":"Solana data","summary":"A wallet's liquidity events","description":"Adds, removes, fee claims, opens and closes, newest first (the wallet as the position's owner). A close row of a DLMM `close_position2` or a Raydium CLMM position has no `pool`: the instruction does not carry it.\n\nLiquidity on Solana from Chord's own tape: adds, removes, fee claims, position opens and closes, decoded from the same blocks as the swaps. No key needed.\n\n- **Venues.** Meteora DLMM, Meteora DAMM v2, Raydium CLMM and PumpSwap. Orca Whirlpools, Raydium CPMM / v4 and Meteora dynamic pools are not read yet.\n- **Since.** `since` is when LP decoding started (2026-10-06 15:53 UTC); windows never start before it. A position opened earlier is `partial: true` and carries no PnL.\n- **Fees are claimed fees.** An LP's fees appear when it claims them, so a window's fees understate what the pool earned, and one claim can hold days of fees.\n- **Positions.** One row per position account (DLMM / DAMM v2 position, Raydium CLMM position NFT, PumpSwap LP token account), rebuilt from all its events. `lower` / `upper` are DLMM bin ids or Raydium CLMM ticks; null = full range. Realized PnL = withdrawn + fees claimed − deposited, only for a position seen from its open to its close with every amount priced. An open position's current value is not in the events: none is given.\n- **Amounts** are whole tokens in the pool's own order (`mintA` / `mintB`); USD is valued when the event happened. Each add / remove / claim is checked against the pool vaults' balance changes in the same transaction (`verified`).\n- **Addresses** are base58 and case-sensitive, as on the other Solana routes.","url":"https://getchord.xyz/docs/api-reference/operations/sollpwalletevents/","parameters":[{"name":"address","in":"path","required":true,"type":"string","description":"Wallet address, base58."},{"name":"limit","in":"query","required":false,"type":"integer","default":50,"description":""},{"name":"before","in":"query","required":false,"type":"integer","description":"Exclusive cursor, Unix seconds: rows strictly older than it. Pass the last row's `ts` for the next page. Several swaps can share a second, so a page boundary can skip the rest of that second: overlap with `ts + 1` and drop rows whose `tx` you already have."}],"requestBody":null,"responses":{"200":"","400":"`BAD_ADDRESS` / `BAD_LIMIT` / `BAD_CURSOR`, or `UNSUPPORTED_CHAIN` (Solana is not public on this deployment and the request has no `X-API-Key`).","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","503":"`CHAIN_DATA_UNAVAILABLE` (the Solana store did not answer in time) or `CHAIN_NOT_ENABLED` (the lane is off on this deployment). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"string","owner":"string — Solana address, base58, case-sensitive. Never lower-case it.","events":[{"ts":"integer — Unix time, seconds, UTC.","slot":"integer","signature":"string|null — Transaction signature, base58.","dex":"string — `meteora_dlmm` · `meteora_damm_v2` · `raydium_clmm` · `pumpswap`.","kind":"string (add|remove|fee|open|close)","pool":"string|null — Solana address, base58, case-sensitive. Never lower-case it.","position":"string|null — Solana address, base58, case-sensitive. Never lower-case it.","owner":"string|null — Solana address, base58, case-sensitive. Never lower-case it.","amountA":"number|null — Whole tokens.","amountB":"number|null","usd":"number|null","lower":"integer|null","upper":"integer|null","verified":"boolean|null — true = matches the vault balance changes; null = could not be checked (shared vault, first deposit of a new pool)"}],"nextBefore":"integer|null — Unix time, seconds, UTC."},"example":{"chain":"solana","owner":"GwBsj9GJdFrATQs1k9EYUyfaatKZDiViy8tkU9JP3TUL","events":[{"ts":1791303527,"slot":453953116,"signature":"843tuGhTxg7i7CEFuJsFfJPhxhRMcL4mr2gDaHifmm8d9Gfzd7AKgHXXj6gCzNgos9tyjcSLCVXrvwWKodsTq5u","dex":"meteora_dlmm","kind":"add","pool":"5whNk71ua6aRtNKazDqEeAimmfzuX9epJcjh4isQKprn","position":"9FSWX8ctaKQKYsTpxuuXEMWVXYm3NGm9cDCLYvs6zhE7","owner":"GwBsj9GJdFrATQs1k9EYUyfaatKZDiViy8tkU9JP3TUL","amountA":87.25797003,"amountB":0,"usd":15125.346891374138,"lower":null,"upper":null,"verified":true},{"ts":1791303527,"slot":453953116,"signature":"843tuGhTxg7i7CEFuJsFfJPhxhRMcL4mr2gDaHifmm8d9Gfzd7AKgHXXj6gCzNgos9tyjcSLCVXrvwWKodsTq5u","dex":"meteora_dlmm","kind":"open","pool":"5whNk71ua6aRtNKazDqEeAimmfzuX9epJcjh4isQKprn","position":"9FSWX8ctaKQKYsTpxuuXEMWVXYm3NGm9cDCLYvs6zhE7","owner":"GwBsj9GJdFrATQs1k9EYUyfaatKZDiViy8tkU9JP3TUL","amountA":0,"amountB":0,"usd":null,"lower":688,"upper":693,"verified":null}],"nextBefore":1791303527}},"security":null},{"kind":"operation","operationId":"solLpPositionEvents","method":"GET","path":"/v1/chains/solana/lp/position/{address}/events","tag":"Solana data","summary":"One position's events","description":"Adds, removes, fee claims, opens and closes, newest first. A close row of a DLMM `close_position2` or a Raydium CLMM position has no `pool`: the instruction does not carry it.\n\nLiquidity on Solana from Chord's own tape: adds, removes, fee claims, position opens and closes, decoded from the same blocks as the swaps. No key needed.\n\n- **Venues.** Meteora DLMM, Meteora DAMM v2, Raydium CLMM and PumpSwap. Orca Whirlpools, Raydium CPMM / v4 and Meteora dynamic pools are not read yet.\n- **Since.** `since` is when LP decoding started (2026-10-06 15:53 UTC); windows never start before it. A position opened earlier is `partial: true` and carries no PnL.\n- **Fees are claimed fees.** An LP's fees appear when it claims them, so a window's fees understate what the pool earned, and one claim can hold days of fees.\n- **Positions.** One row per position account (DLMM / DAMM v2 position, Raydium CLMM position NFT, PumpSwap LP token account), rebuilt from all its events. `lower` / `upper` are DLMM bin ids or Raydium CLMM ticks; null = full range. Realized PnL = withdrawn + fees claimed − deposited, only for a position seen from its open to its close with every amount priced. An open position's current value is not in the events: none is given.\n- **Amounts** are whole tokens in the pool's own order (`mintA` / `mintB`); USD is valued when the event happened. Each add / remove / claim is checked against the pool vaults' balance changes in the same transaction (`verified`).\n- **Addresses** are base58 and case-sensitive, as on the other Solana routes.","url":"https://getchord.xyz/docs/api-reference/operations/sollppositionevents/","parameters":[{"name":"address","in":"path","required":true,"type":"string","description":"Position address, base58."},{"name":"limit","in":"query","required":false,"type":"integer","default":50,"description":""},{"name":"before","in":"query","required":false,"type":"integer","description":"Exclusive cursor, Unix seconds: rows strictly older than it. Pass the last row's `ts` for the next page. Several swaps can share a second, so a page boundary can skip the rest of that second: overlap with `ts + 1` and drop rows whose `tx` you already have."}],"requestBody":null,"responses":{"200":"","400":"`BAD_ADDRESS` / `BAD_LIMIT` / `BAD_CURSOR`, or `UNSUPPORTED_CHAIN` (Solana is not public on this deployment and the request has no `X-API-Key`).","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","503":"`CHAIN_DATA_UNAVAILABLE` (the Solana store did not answer in time) or `CHAIN_NOT_ENABLED` (the lane is off on this deployment). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"string","position":"string — Solana address, base58, case-sensitive. Never lower-case it.","events":[{"ts":"integer — Unix time, seconds, UTC.","slot":"integer","signature":"string|null — Transaction signature, base58.","dex":"string — `meteora_dlmm` · `meteora_damm_v2` · `raydium_clmm` · `pumpswap`.","kind":"string (add|remove|fee|open|close)","pool":"string|null — Solana address, base58, case-sensitive. Never lower-case it.","position":"string|null — Solana address, base58, case-sensitive. Never lower-case it.","owner":"string|null — Solana address, base58, case-sensitive. Never lower-case it.","amountA":"number|null — Whole tokens.","amountB":"number|null","usd":"number|null","lower":"integer|null","upper":"integer|null","verified":"boolean|null — true = matches the vault balance changes; null = could not be checked (shared vault, first deposit of a new pool)"}],"nextBefore":"integer|null — Unix time, seconds, UTC."},"example":{"chain":"solana","position":"BJMyRCurUG45Lst2tZf2RMVbxwCopyWzxzHjgQz5ET6m","events":[{"ts":1791303523,"slot":453953100,"signature":"2e9A11ocj5EURDZJj7DYtFPQN7D62Xjdg1sW9aAyN8RJ4RmFBf9N73D29G11zJnJGc8HUnzQQ1WkH1KWduaggb5p","dex":"meteora_dlmm","kind":"close","pool":null,"position":"BJMyRCurUG45Lst2tZf2RMVbxwCopyWzxzHjgQz5ET6m","owner":"GwBsj9GJdFrATQs1k9EYUyfaatKZDiViy8tkU9JP3TUL","amountA":null,"amountB":null,"usd":null,"lower":null,"upper":null,"verified":null},{"ts":1791303523,"slot":453953100,"signature":"2e9A11ocj5EURDZJj7DYtFPQN7D62Xjdg1sW9aAyN8RJ4RmFBf9N73D29G11zJnJGc8HUnzQQ1WkH1KWduaggb5p","dex":"meteora_dlmm","kind":"fee","pool":"5whNk71ua6aRtNKazDqEeAimmfzuX9epJcjh4isQKprn","position":"BJMyRCurUG45Lst2tZf2RMVbxwCopyWzxzHjgQz5ET6m","owner":"GwBsj9GJdFrATQs1k9EYUyfaatKZDiViy8tkU9JP3TUL","amountA":0.03680336,"amountB":0,"usd":6.379515665752227,"lower":null,"upper":null,"verified":true}],"nextBefore":1791303523}},"security":null},{"kind":"operation","operationId":"solTradeConfig","method":"GET","path":"/v1/sol/trade/config","tag":"Solana swaps","summary":"May this caller trade","description":"`enabled` = the lane is on in this deployment, `open` = open to everyone, `allowed` = open to the caller who asks (a beta account, or everyone once `open`). Never gated, never cached.\n\n**Open to everyone** since 2026-10-15, no key needed (an `X-API-Key` raises the rate limit). `/sol/trade/config` says whether the lane is on for the caller; when it is off the other routes answer `503 TRADE_NOT_ENABLED`.\n\nA quote is SOL against one token, bought or sold. For every quote Chord builds, for **your wallet**, the transaction of each route — `direct` (Chord's own router: Raydium AMM v4 / CPMM / CLMM, Orca Whirlpool, Meteora DLMM / DAMM v2, Meteora DBC, Raydium LaunchLab, pump.fun, PumpSwap; up to two pools), `jupiter` (Jupiter's swap API, no Jupiter fee) and `jupiter_meta` (Jupiter's order: Metis, its RFQ market makers, DFlow, OKX; Jupiter's fee inside the amount) — simulates each on the chain and returns the one that leaves the wallet with the most: tokens for a buy, SOL for a sell, after every fee. Ties go to `direct`, then `jupiter`. A route handing back under half of the input's market value is refused.\n\nAmounts are base units as decimal strings: lamports for SOL, the token's smallest unit otherwise. Addresses are base58, case-sensitive. Chord takes no fee on Solana today. Nothing is signed by Chord: you sign `quote.tx` unchanged and send it back.","url":"https://getchord.xyz/docs/api-reference/operations/soltradeconfig/","parameters":[],"requestBody":null,"responses":{"200":""},"response":{"schema":{"enabled":"boolean","open":"boolean","allowed":"boolean"},"example":{"enabled":true,"open":false,"allowed":false}},"security":null},{"kind":"operation","operationId":"solTradeQuote","method":"GET","path":"/v1/sol/trade/quote","tag":"Solana swaps","summary":"Best quote: Chord's route or Jupiter's","description":"The quote of the route that leaves the wallet with the most, its unsigned transaction, and what every route offered (`compared`). `ok: false` with `quote: null` and a `reason` is an answer (no route for this token, size or wallet), not an error.\n\n**Open to everyone** since 2026-10-15, no key needed (an `X-API-Key` raises the rate limit). `/sol/trade/config` says whether the lane is on for the caller; when it is off the other routes answer `503 TRADE_NOT_ENABLED`.\n\nA quote is SOL against one token, bought or sold. For every quote Chord builds, for **your wallet**, the transaction of each route — `direct` (Chord's own router: Raydium AMM v4 / CPMM / CLMM, Orca Whirlpool, Meteora DLMM / DAMM v2, Meteora DBC, Raydium LaunchLab, pump.fun, PumpSwap; up to two pools), `jupiter` (Jupiter's swap API, no Jupiter fee) and `jupiter_meta` (Jupiter's order: Metis, its RFQ market makers, DFlow, OKX; Jupiter's fee inside the amount) — simulates each on the chain and returns the one that leaves the wallet with the most: tokens for a buy, SOL for a sell, after every fee. Ties go to `direct`, then `jupiter`. A route handing back under half of the input's market value is refused.\n\nAmounts are base units as decimal strings: lamports for SOL, the token's smallest unit otherwise. Addresses are base58, case-sensitive. Chord takes no fee on Solana today. Nothing is signed by Chord: you sign `quote.tx` unchanged and send it back.","url":"https://getchord.xyz/docs/api-reference/operations/soltradequote/","parameters":[{"name":"mint","in":"query","required":true,"type":"string","description":"The token."},{"name":"side","in":"query","required":true,"type":"string","enum":["buy","sell"],"description":"`buy` = SOL in, token out · `sell` = token in, SOL out."},{"name":"amount","in":"query","required":true,"type":"string","description":"Input in base units: lamports for a buy, the token's smallest unit for a sell."},{"name":"wallet","in":"query","required":true,"type":"string","description":"The wallet that will sign: every route is simulated for it, so it must hold the input (and SOL for fees)."},{"name":"slippageBps","in":"query","required":false,"type":"integer","default":100,"description":"Tolerance that sets `minOut`."}],"requestBody":null,"responses":{"200":"","400":"`BAD_ADDRESS` / `BAD_SIDE` / `BAD_AMOUNT` / `BAD_SLIPPAGE`.","502":"`TRADE_BAD_ANSWER`: the Solana box answered something that is not the quote asked for (another mint, side, amount, tolerance or fee payer, or an unknown shape). Nothing is forwarded.","503":"`TRADE_NOT_ENABLED` (the lane is off on this deployment, or not open to this caller yet) or `TRADE_UNAVAILABLE` (the Solana box did not answer). Retry later; do not read it as \"no route\"."},"response":{"schema":{"ok":"boolean","quote":{"ok":"boolean","route":"string (direct|jupiter|jupiter_meta) — `direct` = Chord's own route (pump pools or Chord's router) · `jupiter` = Jupiter's swap API · `jupiter_meta` = Jupiter's order (RFQ makers, DFlow, OKX).","mint":"string — Solana address, base58, case-sensitive. Never lower-case it.","side":"string (buy|sell)","inAmount":"string — What the wallet puts in: lamports for a buy, the token's smallest unit for a sell.","outAmount":"string — What the simulation of `tx` delivered to the wallet: tokens for a buy, lamports for a sell (wSOL counted as SOL), after every fee.","minOut":"string — The least the transaction accepts before it fails, from `slippageBps`.","slippageBps":"integer","feeLamports":"string — Chord's fee. 0 today.","feeBps":"integer — Chord's fee rate. 0 today.","networkFeeLamports":"integer — Base + priority fee the wallet pays; 0 when Jupiter or a market maker pays (`gasless`).","units":"integer — Compute units of the simulation.","walletLamportsDelta":"string — The wallet's whole SOL change in the simulation, network fee and rent of new accounts included.","tx":"string — The unsigned v0 transaction, base64 — exactly what was simulated. Sign it unchanged and POST it to `/sol/trade/send`.","txBytes":"integer","blockhash":"string","lastValidBlockHeight":"integer — After this block height the transaction can no longer land.","simulatedSlot":"integer","ms":"number","venue":"string — `direct` only: where it trades (the largest leg when the order is split): `pumpswap`, `pumpfun`, `raydium_v4`, `raydium_cpmm`, `raydium_clmm`, `orca`, `meteora_dlmm`, `meteora_damm_v2`, `meteora_dbc`, `raydium_launchlab`.","layout":"string — `direct` on a pump pool: the instruction layout copied.","solBased":"boolean — A PumpSwap pool whose base is SOL.","pool":"string — Solana address, base58, case-sensitive. Never lower-case it.","partial":"boolean — A pump.fun curve had fewer tokens left than the input buys: the quote takes all it has, for at most `inAmount`.","hops":["object"],"router":"string — `jupiter_meta`: which router won Jupiter's auction (`metis`, `jupiterz`, `dflow`, `okx`).","gasless":"boolean — `jupiter_meta`: Jupiter or the market maker pays the network fee; the wallet is a second signer.","expireAt":"integer — `jupiter_meta` RFQ quotes: Unix seconds the market maker's price lives to. Ask again when under ten seconds are left."},"reason":"string (not_a_token|bad_request|no_pool|no_template|no_route|wallet_cannot|pool_limit|no_output|simulation_failed|too_large|error|off) — Why a route has no quote. `wallet_cannot` (no funds, or no token account), `pool_limit` (a size the pool refuses, or under half the market value) and `no_output` are about the request; `no_pool` = the route does not cover this token; `simulation_failed`, `too_large`, `error` = the route failed; `off` = not asked or switched off.","detail":"string","compared":{"direct":"…","jupiter":"…","jupiterMeta":"…"},"ms":"number"},"example":{"ok":true,"quote":{"ok":true,"route":"direct","mint":"98sMhvDwXj1RQi5c5Mndm3vPe9cBqPrbLaufMXFNMh5g","side":"buy","inAmount":"1000000000","outAmount":"1291169314","minOut":"1278257620","slippageBps":100,"feeLamports":"0","feeBps":0,"networkFeeLamports":13462,"units":53847,"walletLamportsDelta":"-1001501902","tx":"AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQAJF36MCIdgv94d3c8ywX8gm4JC7lKq8TH6zYjQ6ixtCwbybQ/ffN89KMzS1moKr3xD+eaLjFLD93Uu7/6fCChoRW+33r5/N5kXzVmVKDnDCPuAkyP2Gtb/z4vZXn9rJrNgnlYtVRIeQFP9RCTKJ4QcFXTmTFrjug4KMZNwxfvPi59T3FuLdqms3IWcwYxorNprzTnpS/UIS8cr22A9a0z5hMQguKAAE9blFXzMeY2Ul+aVjNz5CWJMPZFyDxSfYLteeLFBAdK4u9M26/E24V6FVw6ivZ7F6IKKhmtyA8AUTfymAHzJZSEoI1LREgsRMMb+c3W9Pk5HT+Ci3aCI/WgF+bbdWqpQ+Iq9Y9M30s68O5hGfLeLdlEbgXgDuUWpI64G0UeeEGWqwXbkX0swI7SX5eIdaHc3Qyw0ilOG3FwaVKK3wRwJ7Hd/cQIYGczxT34DxoMVJNeXfeJLQyrGn/5CRYApa3YIBFLBUkXofOcSUKM6WFvxPe9wsqWKl3DHs4sghgHyPnPlSprtPOAV8DiJLgrp8nHRCYh08HSC9eHtCKRKNckuzi1T27nDcSwt5D+6EBI+n21RbgNj47MiJk7XsmsDBkZv5SEXMv/srbpyw5vnvIzlu8X3EmssQ5s6QAAAAIyXJY9OJInxuz0QKRSODYMLWhOZ2v8QhASOe9jb6fhZBpuIV/6rgYT7aH9jRhjANdrEOdwa6ztVmKDwAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbd9uHXZaGT2cvhRs7reawctIXtX1s3kTqM9YV+/wCpeOF/+c+e8osV49WDJ0Hs54BOB9XJf0LvM+1fBZx0kl8E6eEvvIToJskyzOniZAzOFVkMHGJzsJJXCLo7hSCwvAVKU1qZKSEGTSTocWDaOHx8NbXdvJK7geQfqEBBBUSNsnDWf6mMUc8CEwUTWJYrrzV0K+1ZydlEXpwNDIXHzZF54KJrKMEZBlNIu3jg6xTnaDFVOdmUnu4hys0zsh+wiAgOAAUCiUoBAA4ACQOghgEAAAAAAA8GAAEAEBESAQEPBgACABMREgEBEQIAAQwCAAAAAMqaOwAAAAASAQEBERQWAwQFBgECEBMHFAASEhUWFAgJCgsMDRxBSz9M61tbiADKmjsAAAAA1KkwTAAAAAAAAAAAEgMBAAABCQA=","txBytes":962,"blockhash":"9CkzxZDnrGUqa6v7wWKq3jMxYFkLvqE1c8ogo7DURJjq","lastValidBlockHeight":435407004,"simulatedSlot":457371000,"ms":269,"venue":"meteora_dlmm","pool":"6oQ9wVex4mKZti2GsGCfD8FWTMMC9PLQkztRU5cd6MK8","hops":[{"label":"Meteora DLMM","pool":"6oQ9wVex4mKZti2GsGCfD8FWTMMC9PLQkztRU5cd6MK8","percent":100}]},"compared":{"direct":{"ok":true,"outAmount":"1291169314","measured":"simulated","networkFeeLamports":13462,"units":53847,"ms":269},"jupiter":{"ok":true,"outAmount":"1291041752","measured":"simulated","networkFeeLamports":23574,"units":149660,"ms":128},"jupiterMeta":{"ok":true,"outAmount":"1289637269","measured":"simulated","networkFeeLamports":0,"units":25294,"ms":350}},"ms":392}},"security":null},{"kind":"operation","operationId":"solTradeSend","method":"POST","path":"/v1/sol/trade/send","tag":"Solana swaps","summary":"Send the signed quote","description":"Relays a transaction Chord quoted in the last three minutes, signed by the wallet it was quoted for — anything else is refused. Chord sends it to several RPC providers and again every 2 seconds until it lands or its blockhash expires; a `jupiter_meta` order goes through Jupiter's execute endpoint instead (Jupiter or the market maker adds its signature). Then poll `/sol/trade/tx/{signature}`.\n\n**Open to everyone** since 2026-10-15, no key needed (an `X-API-Key` raises the rate limit). `/sol/trade/config` says whether the lane is on for the caller; when it is off the other routes answer `503 TRADE_NOT_ENABLED`.\n\nA quote is SOL against one token, bought or sold. For every quote Chord builds, for **your wallet**, the transaction of each route — `direct` (Chord's own router: Raydium AMM v4 / CPMM / CLMM, Orca Whirlpool, Meteora DLMM / DAMM v2, Meteora DBC, Raydium LaunchLab, pump.fun, PumpSwap; up to two pools), `jupiter` (Jupiter's swap API, no Jupiter fee) and `jupiter_meta` (Jupiter's order: Metis, its RFQ market makers, DFlow, OKX; Jupiter's fee inside the amount) — simulates each on the chain and returns the one that leaves the wallet with the most: tokens for a buy, SOL for a sell, after every fee. Ties go to `direct`, then `jupiter`. A route handing back under half of the input's market value is refused.\n\nAmounts are base units as decimal strings: lamports for SOL, the token's smallest unit otherwise. Addresses are base58, case-sensitive. Chord takes no fee on Solana today. Nothing is signed by Chord: you sign `quote.tx` unchanged and send it back.","url":"https://getchord.xyz/docs/api-reference/operations/soltradesend/","parameters":[],"requestBody":{"schema":{"tx":"string — `quote.tx` signed by the wallet, base64. Do not change the message."},"example":{"tx":"<base64 signed transaction>"}},"responses":{"200":"","400":"`BAD_TRANSACTION` (not a transaction, or not base64) · `UNKNOWN_TRANSACTION` (not one a quote handed out in the last three minutes, or changed before signing — ask for a new quote) · `NOT_SIGNED` / `BAD_SIGNATURE` (not signed by the quoted wallet).","502":"`SEND_FAILED`: no RPC accepted the transaction.","503":"`TRADE_NOT_ENABLED` (the lane is off on this deployment, or not open to this caller yet) or `TRADE_UNAVAILABLE` (the Solana box did not answer). Retry later; do not read it as \"no route\"."},"response":{"schema":{"ok":"boolean","signature":"string — Transaction signature, base58.","status":{"signature":"string — Transaction signature, base58.","status":"string (pending|confirmed|finalized|failed|expired)","route":"string (direct|jupiter|jupiter_meta) — `direct` = Chord's own route (pump pools or Chord's router) · `jupiter` = Jupiter's swap API · `jupiter_meta` = Jupiter's order (RFQ makers, DFlow, OKX).","mint":"string — Solana address, base58, case-sensitive. Never lower-case it.","side":"string (buy|sell)","wallet":"string — Solana address, base58, case-sensitive. Never lower-case it.","sentAt":"integer — Unix seconds.","sends":"integer — How many times Chord sent it (every 2 seconds until it lands or its blockhash expires).","slot":"integer|null","error":"string|null","quotedOut":"string — Base units as a decimal string (lamports for SOL).","receivedOut":"string|null — What the wallet really got, read from the landed transaction with the quote's measure.","confirmedAt":"integer|null — Unix seconds."},"error":"string","message":"string"},"example":null},"security":null},{"kind":"operation","operationId":"solTradeTx","method":"GET","path":"/v1/sol/trade/tx/{signature}","tag":"Solana swaps","summary":"Status of a sent swap","description":"`pending` until the transaction is in a block, then `confirmed` / `finalized` with `receivedOut`, or `failed` / `expired` (its blockhash ran out; an RFQ order unseen for two minutes). Only transactions sent through `/sol/trade/send`.\n\n**Open to everyone** since 2026-10-15, no key needed (an `X-API-Key` raises the rate limit). `/sol/trade/config` says whether the lane is on for the caller; when it is off the other routes answer `503 TRADE_NOT_ENABLED`.\n\nA quote is SOL against one token, bought or sold. For every quote Chord builds, for **your wallet**, the transaction of each route — `direct` (Chord's own router: Raydium AMM v4 / CPMM / CLMM, Orca Whirlpool, Meteora DLMM / DAMM v2, Meteora DBC, Raydium LaunchLab, pump.fun, PumpSwap; up to two pools), `jupiter` (Jupiter's swap API, no Jupiter fee) and `jupiter_meta` (Jupiter's order: Metis, its RFQ market makers, DFlow, OKX; Jupiter's fee inside the amount) — simulates each on the chain and returns the one that leaves the wallet with the most: tokens for a buy, SOL for a sell, after every fee. Ties go to `direct`, then `jupiter`. A route handing back under half of the input's market value is refused.\n\nAmounts are base units as decimal strings: lamports for SOL, the token's smallest unit otherwise. Addresses are base58, case-sensitive. Chord takes no fee on Solana today. Nothing is signed by Chord: you sign `quote.tx` unchanged and send it back.","url":"https://getchord.xyz/docs/api-reference/operations/soltradetx/","parameters":[{"name":"signature","in":"path","required":true,"type":"string","description":"From `/sol/trade/send`."}],"requestBody":null,"responses":{"200":"","400":"`BAD_SIGNATURE`.","404":"`TX_NOT_FOUND`: not a transaction sent through this API, or done more than 15 minutes ago.","503":"`TRADE_NOT_ENABLED` (the lane is off on this deployment, or not open to this caller yet) or `TRADE_UNAVAILABLE` (the Solana box did not answer). Retry later; do not read it as \"no route\"."},"response":{"schema":{"signature":"string — Transaction signature, base58.","status":"string (pending|confirmed|finalized|failed|expired)","route":"string (direct|jupiter|jupiter_meta) — `direct` = Chord's own route (pump pools or Chord's router) · `jupiter` = Jupiter's swap API · `jupiter_meta` = Jupiter's order (RFQ makers, DFlow, OKX).","mint":"string — Solana address, base58, case-sensitive. Never lower-case it.","side":"string (buy|sell)","wallet":"string — Solana address, base58, case-sensitive. Never lower-case it.","sentAt":"integer — Unix seconds.","sends":"integer — How many times Chord sent it (every 2 seconds until it lands or its blockhash expires).","slot":"integer|null","error":"string|null","quotedOut":"string — Base units as a decimal string (lamports for SOL).","receivedOut":"string|null — What the wallet really got, read from the landed transaction with the quote's measure.","confirmedAt":"integer|null — Unix seconds."},"example":null},"security":null},{"kind":"operation","operationId":"solTradeBalances","method":"GET","path":"/v1/sol/trade/balances","tag":"Solana swaps","summary":"A wallet's SOL and one token","description":"For a swap form: lamports, and the token in the wallet's associated account (`amount`, what a sell spends) and in all its accounts of that mint (`total`).\n\n**Open to everyone** since 2026-10-15, no key needed (an `X-API-Key` raises the rate limit). `/sol/trade/config` says whether the lane is on for the caller; when it is off the other routes answer `503 TRADE_NOT_ENABLED`.\n\nA quote is SOL against one token, bought or sold. For every quote Chord builds, for **your wallet**, the transaction of each route — `direct` (Chord's own router: Raydium AMM v4 / CPMM / CLMM, Orca Whirlpool, Meteora DLMM / DAMM v2, Meteora DBC, Raydium LaunchLab, pump.fun, PumpSwap; up to two pools), `jupiter` (Jupiter's swap API, no Jupiter fee) and `jupiter_meta` (Jupiter's order: Metis, its RFQ market makers, DFlow, OKX; Jupiter's fee inside the amount) — simulates each on the chain and returns the one that leaves the wallet with the most: tokens for a buy, SOL for a sell, after every fee. Ties go to `direct`, then `jupiter`. A route handing back under half of the input's market value is refused.\n\nAmounts are base units as decimal strings: lamports for SOL, the token's smallest unit otherwise. Addresses are base58, case-sensitive. Chord takes no fee on Solana today. Nothing is signed by Chord: you sign `quote.tx` unchanged and send it back.","url":"https://getchord.xyz/docs/api-reference/operations/soltradebalances/","parameters":[{"name":"wallet","in":"query","required":true,"type":"string","description":""},{"name":"mint","in":"query","required":true,"type":"string","description":""}],"requestBody":null,"responses":{"200":"","400":"`BAD_ADDRESS`.","503":"`TRADE_NOT_ENABLED` (the lane is off on this deployment, or not open to this caller yet) or `TRADE_UNAVAILABLE` (the Solana box did not answer). Retry later; do not read it as \"no route\"."},"response":{"schema":{"wallet":"string — Solana address, base58, case-sensitive. Never lower-case it.","mint":"string — Solana address, base58, case-sensitive. Never lower-case it.","lamports":"string — Base units as a decimal string (lamports for SOL).","token":{"amount":"string — Base units as a decimal string (lamports for SOL).","total":"string — Base units as a decimal string (lamports for SOL).","decimals":"integer|null"},"slot":"integer"},"example":{"wallet":"9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM","mint":"98sMhvDwXj1RQi5c5Mndm3vPe9cBqPrbLaufMXFNMh5g","lamports":"11175972108683952","token":{"amount":"0","total":"0","decimals":9},"slot":457371001}},"security":null},{"kind":"operation","operationId":"solTradeHoldings","method":"GET","path":"/v1/sol/trade/holdings","tag":"Solana swaps","summary":"A wallet's SOL and tokens","description":"SOL and every token the wallet holds (both token programs, accounts summed), at most 50 by value; `more` = left out. Name, image and price from Chord's tape (null for a token it never saw).\n\n**Open to everyone** since 2026-10-15, no key needed (an `X-API-Key` raises the rate limit). `/sol/trade/config` says whether the lane is on for the caller; when it is off the other routes answer `503 TRADE_NOT_ENABLED`.\n\nA quote is SOL against one token, bought or sold. For every quote Chord builds, for **your wallet**, the transaction of each route — `direct` (Chord's own router: Raydium AMM v4 / CPMM / CLMM, Orca Whirlpool, Meteora DLMM / DAMM v2, Meteora DBC, Raydium LaunchLab, pump.fun, PumpSwap; up to two pools), `jupiter` (Jupiter's swap API, no Jupiter fee) and `jupiter_meta` (Jupiter's order: Metis, its RFQ market makers, DFlow, OKX; Jupiter's fee inside the amount) — simulates each on the chain and returns the one that leaves the wallet with the most: tokens for a buy, SOL for a sell, after every fee. Ties go to `direct`, then `jupiter`. A route handing back under half of the input's market value is refused.\n\nAmounts are base units as decimal strings: lamports for SOL, the token's smallest unit otherwise. Addresses are base58, case-sensitive. Chord takes no fee on Solana today. Nothing is signed by Chord: you sign `quote.tx` unchanged and send it back.","url":"https://getchord.xyz/docs/api-reference/operations/soltradeholdings/","parameters":[{"name":"wallet","in":"query","required":true,"type":"string","description":""}],"requestBody":null,"responses":{"200":"","400":"`BAD_ADDRESS`.","503":"`TRADE_NOT_ENABLED` (the lane is off on this deployment, or not open to this caller yet) or `TRADE_UNAVAILABLE` (the Solana box did not answer). Retry later; do not read it as \"no route\"."},"response":{"schema":{"wallet":"string — Solana address, base58, case-sensitive. Never lower-case it.","lamports":"string — Base units as a decimal string (lamports for SOL).","slot":"integer","more":"integer","tokens":[{"mint":"string — Solana address, base58, case-sensitive. Never lower-case it.","amount":"string — Base units as a decimal string (lamports for SOL).","decimals":"integer|null","symbol":"string|null","name":"string|null","image":"string|null","priceUsd":"number|null","valueUsd":"number|null"}]},"example":{"wallet":"9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM","lamports":"11175972108683952","slot":457371002,"more":3059,"tokens":[{"mint":"BZLbGTNCSFfoth2GYDtwr7e4imWzpR5jqcUuGEwr646K","amount":"9110839995100000","decimals":8,"symbol":"IO","name":"IO","image":"https://bafkreicnqsbhpzxiasdm5esr7fqi3vcjvcbfefo4sq4y3ff747rfqf7w7i.ipfs.nftstorage.link","priceUsd":0.16689062068413946,"valueUsd":15205137.417361211},{"mint":"2qEHjDLDLbuBgRYvsxhc5D6uDWAivNFZGan56P1tpump","amount":"305126997000000","decimals":6,"symbol":"Pnut","name":"Peanut the Squirrel","image":"https://ipfs.io/ipfs/QmNdTtJauw39u4DzGyTaZ35rRx4VgAxqb91wE89zjyHWd2","priceUsd":0.04610248419139405,"valueUsd":14067112.555560041}]}},"security":null},{"kind":"operation","operationId":"streamMarket","method":"GET","path":"/v1/stream/market","tag":"Streaming","summary":"Server-sent events: prices","description":"One `text/event-stream` feed, no key, EventSource-friendly with automatic reconnect. Events: `rh-ticker` (fresh prices for chain 4663, about every 10 s, only addresses whose price moved), `ticker` / `whales` / `defi` (Monad), `ping` every 5 s. Capacity 500 clients (`503` beyond). Arc and Robinhood Chain boards stream faster over the WebSocket `prices` channel — see Concepts → Streaming.","url":"https://getchord.xyz/docs/api-reference/operations/streammarket/","parameters":[],"requestBody":null,"responses":{"200":"`text/event-stream`","503":"At capacity."},"response":null,"security":null},{"kind":"operation","operationId":"wsLive","method":"GET","path":"/v1/ws/live","tag":"Streaming","summary":"WebSocket: live candles, trades and board feeds","description":"Upgrade to a WebSocket. No key needed, rate-limit exempt, up to 8 channels per connection. With an API key (`X-API-Key`, or `?apiKey=` from a browser) the connection joins a separate pool: up to 64 channels per connection and 20 connections per key (`429` beyond). Subscribe with `{op:\"sub\", channel:\"candles\", token, tf}`, `{op:\"sub\", channel:\"trades\", token}` or `{op:\"sub\", channel:\"prices\", chain}` (chain `5042`, `4663` or `143`); the server pushes `candle`, `trades` and `prices` frames (every print within ~400 ms; on 5042 / 4663 each item also carries the token's live 24h volume and trade counts), `new` frames for tokens trading for the first time (5042 / 4663), `ping` every 25 s, and `error` with a code (`bad_op` · `bad_token` · `bad_tf` · `bad_chain` · `channel_cap`). Full protocol under Concepts → Streaming.","url":"https://getchord.xyz/docs/api-reference/operations/wslive/","parameters":[],"requestBody":null,"responses":{"101":"Switching protocols.","429":"This API key already holds its maximum of live connections.","503":"`WS_LIVE_DISABLED` or at capacity."},"response":null,"security":null},{"kind":"operation","operationId":"backtest","method":"GET","path":"/v1/backtest","tag":"Backtests","summary":"Backtest a strategy","description":"One bar-close strategy replayed over stored candles of a Hyperliquid perp or an FX pair / metal. Simulated: nothing is traded.\n\n**Model** (the same text comes back in `assumptions`):\n- A signal is computed on a CLOSED bar and filled at the NEXT bar's open.\n- One position at a time, all-in (equity × `leverage`), long, short or both.\n- `feeBps` is charged per side on notional. Default 4.5 for Hyperliquid, 1 for FX.\n- `stopPct` / `takePct` are checked inside each bar against its high and low. When both could hit in the same bar the stop is taken first; a bar that opens beyond the level fills at its open.\n- A position still open at the last bar is closed at that bar's close (`reason: \"end\"`). Equity at or below zero ends the run.\n- No funding, no spread beyond the fee, no slippage. FX uses Dukascopy BID prices.\n\n**Strategies and their parameters** (pass only the ones you want to change):\n\n| `strategy` | Rule | Parameters (default) |\n| --- | --- | --- |\n| `supertrend` | Long while the Supertrend direction is up, short while it is down. | `atr` (10), `mult` (3) |\n| `ema_cross` | Long while EMA(`fast`) is above EMA(`slow`), short while below. | `fast` (20), `slow` (50) |\n| `rsi` | Long when RSI falls below `lower`, short when it rises above `upper`, flat again when RSI crosses back through 50. | `length` (14), `lower` (30), `upper` (70) |\n| `donchian` | Long on a close above the highest high of the previous `length` bars, short on a close below their lowest low; held until the opposite breakout. | `length` (20) |\n| `buy_hold` | Always long. | none |\n\n**Symbols**: any Hyperliquid perp by its coin id, matched without case (`BTC`, `eth`, `kPEPE`); a leading `$` and a trailing `USDT` / `USD` / `-PERP` are dropped. FX and metals: `EURUSD`, `GBPUSD`, `USDJPY`, `USDCHF`, `AUDUSD`, `USDCAD`, `USDSEK`, `NZDUSD`, `EURJPY`, `GBPJPY`, `EURGBP`, `XAUUSD` (also `gold`), `XAGUSD` (also `silver`).\n\n**How much history there is**: the window is the last `days` ending now, cut to what the store holds. Hyperliquid candles start from what its API served when the store was built (1m a few days, 15m about seven weeks, 1h about seven months, 4h and 1d years) and grow from there; FX has 1h bars since 2016 and 1m bars for about the last 400 days (`/fx/lake` shows how far each symbol is filled). Fewer than 50 bars in the window is a `400` whose message says what the store keeps. Read `from`, `to` and `bars` in the answer for the window that was really tested.","url":"https://getchord.xyz/docs/api-reference/operations/backtest/","parameters":[{"name":"symbol","in":"query","required":false,"type":"string","default":"BTC","description":"A Hyperliquid perp coin id or an FX / metal symbol (list above)."},{"name":"interval","in":"query","required":false,"type":"string","enum":["1m","5m","15m","30m","1h","4h","1d"],"default":"1h","description":"Bar size. 5m and 30m are resampled from finer stored bars."},{"name":"strategy","in":"query","required":false,"type":"string","enum":["supertrend","ema_cross","rsi","donchian","buy_hold"],"default":"supertrend","description":""},{"name":"days","in":"query","required":false,"type":"integer","default":365,"description":"Length of the window, ending now."},{"name":"side","in":"query","required":false,"type":"string","enum":["long","short","both"],"default":"both","description":"Which signals are traded."},{"name":"atr","in":"query","required":false,"type":"number","default":10,"description":"`supertrend`: ATR length."},{"name":"mult","in":"query","required":false,"type":"number","default":3,"description":"`supertrend`: band width in ATRs."},{"name":"fast","in":"query","required":false,"type":"number","default":20,"description":"`ema_cross`: fast EMA length."},{"name":"slow","in":"query","required":false,"type":"number","default":50,"description":"`ema_cross`: slow EMA length."},{"name":"length","in":"query","required":false,"type":"number","description":"`rsi`: RSI length (default 14). `donchian`: channel length in bars (default 20)."},{"name":"lower","in":"query","required":false,"type":"number","default":30,"description":"`rsi`: go long below this."},{"name":"upper","in":"query","required":false,"type":"number","default":70,"description":"`rsi`: go short above this."},{"name":"feeBps","in":"query","required":false,"type":"number","description":"Fee per side in basis points of notional. Default 4.5 (Hyperliquid) or 1 (FX)."},{"name":"stopPct","in":"query","required":false,"type":"number","description":"Stop-loss, percent from entry. Omitted = none."},{"name":"takePct","in":"query","required":false,"type":"number","description":"Take-profit, percent from entry. Omitted = none."},{"name":"leverage","in":"query","required":false,"type":"number","default":1,"description":"Position size as a multiple of equity. Values outside 0.1–20 are clamped."}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"strategy":"string (supertrend|ema_cross|rsi|donchian|buy_hold)","params":"object — The parameters the run used, defaults filled in.","side":"string — long, short or both.","metrics":{"totalReturnPct":"number — Return of the strategy over the window, after fees.","buyHoldPct":"number — Return of holding the asset over the same bars.","cagrPct":"number|null — Annualised return. Null when the tested window is shorter than three months, or equity ended at zero.","maxDrawdownPct":"number — Largest peak-to-trough fall of equity, as a positive number.","sharpe":"number|null — Mean over standard deviation of per-bar returns, annualised by the bar size. Null when equity never moved.","trades":"integer — Closed trades in the window.","winRatePct":"number|null — Share of trades that made money. Null with no trades.","profitFactor":"number|null — Sum of winning returns over sum of losing returns. Null when nothing lost.","avgWinPct":"number|null — Null with no winning trade.","avgLossPct":"number|null — Negative. Null with no losing trade.","exposurePct":"number — Share of bars spent in a position.","feesPaidPct":"number — Sum of the fees charged (each side of each trade, times leverage), in percent."},"equity":[{"t":"integer — Unix time in MILLISECONDS (every time field of this endpoint is; the rest of the API uses seconds).","equity":"number — Strategy equity, starting at 1.","hold":"number — Buy-and-hold equity, starting at 1."}],"trades":[{"side":"string (long|short)","entryT":"integer — Unix time in MILLISECONDS (every time field of this endpoint is; the rest of the API uses seconds).","entry":"number — Fill price: the open of the bar after the signal.","exitT":"integer — Unix time in MILLISECONDS (every time field of this endpoint is; the rest of the API uses seconds).","exit":"number","retPct":"number — Return of the trade after both fees, leverage applied.","reason":"string (signal|stop|take|end) — `end` = still open at the last bar, closed there.","bars":"integer — Bars held."}],"symbol":"string — The symbol as resolved: the Hyperliquid coin id or the FX symbol.","source":"string (hyperliquid|dukascopy)","interval":"string (1m|5m|15m|30m|1h|4h|1d)","from":"integer — Unix time in MILLISECONDS (every time field of this endpoint is; the rest of the API uses seconds).","to":"integer — Unix time in MILLISECONDS (every time field of this endpoint is; the rest of the API uses seconds).","bars":"integer — Bars the run used. `from` and `to` are the first and last of them.","assumptions":"string — The model of this run in one sentence: fill rule, fee, leverage, price source."},"example":{"strategy":"supertrend","params":{"atr":10,"mult":3},"side":"both","metrics":{"totalReturnPct":-29.7396335093976,"buyHoldPct":-24.840856481481477,"cagrPct":-29.77364346765159,"maxDrawdownPct":43.938798730789316,"sharpe":-0.67928989324471,"trades":58,"winRatePct":37.93103448275862,"profitFactor":0.7686488016790433,"avgWinPct":4.190301346373836,"avgLossPct":-3.3314820839884187,"exposurePct":99.58847736625515,"feesPaidPct":5.2199999999999935},"equity":[{"t":1760227200000,"equity":1,"hold":1.000244140625},{"t":1760342400000,"equity":1,"hold":1.0321994357638888}],"trades":[{"side":"long","entryT":1760356800000,"entry":114153,"exitT":1760601600000,"exit":110526,"retPct":-3.267314656645025,"reason":"signal","bars":17},{"side":"short","entryT":1760601600000,"entry":110526,"exitT":1760947200000,"exit":111160,"retPct":-0.6636206865353033,"reason":"signal","bars":24}],"symbol":"BTC","source":"hyperliquid","interval":"4h","from":1760212800000,"to":1791705600000,"bars":2188,"assumptions":"Signal on bar close, fill at next open; 4.5 bps fee per side; Hyperliquid perp candles, no funding; no slippage."}},"security":null},{"kind":"operation","operationId":"fxLake","method":"GET","path":"/v1/fx/lake","tag":"Backtests","summary":"FX store coverage","description":"How far the FX / metal candle store behind `/backtest` is filled, per symbol: the last month of 1h bars and the last day of 1m bars. `state` is `running` while a fill pass is in progress.","url":"https://getchord.xyz/docs/api-reference/operations/fxlake/","parameters":[],"requestBody":null,"responses":{"200":"","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"state":"string (off|running|idle)","lastError":"string|null","lastAt":"integer — Unix ms of the last fill pass, 0 when none ran in this process.","files":"integer — Files written by the last pass.","snapshotAt":"integer — Unix time, milliseconds — when the server built this answer.","from":"string — First month of the 1h store, `YYYY-MM`.","minuteDays":"integer — How many days back the 1m store reaches.","symbols":"object — Keyed by symbol."},"example":{"state":"idle","lastError":null,"lastAt":0,"files":0,"snapshotAt":1791737879748,"from":"2016-01","minuteDays":400,"symbols":{"EURUSD":{"hourThrough":"2026-09","minuteThrough":"2026-10-10"},"GBPUSD":{"hourThrough":"2026-09","minuteThrough":"2026-10-10"},"USDJPY":{"hourThrough":"2026-09","minuteThrough":"2026-10-10"},"USDCHF":{"hourThrough":"2026-09","minuteThrough":"2026-10-10"},"AUDUSD":{"hourThrough":"2026-09","minuteThrough":"2026-10-10"},"USDCAD":{"hourThrough":"2026-09","minuteThrough":"2026-10-10"},"USDSEK":{"hourThrough":"2026-09","minuteThrough":"2026-10-10"},"NZDUSD":{"hourThrough":"2026-09","minuteThrough":"2026-10-10"},"EURJPY":{"hourThrough":"2026-09","minuteThrough":"2026-10-10"},"GBPJPY":{"hourThrough":"2026-09","minuteThrough":"2026-10-10"},"EURGBP":{"hourThrough":"2026-09","minuteThrough":"2026-10-10"},"XAUUSD":{"hourThrough":"2026-09","minuteThrough":"2026-10-10"},"XAGUSD":{"hourThrough":"2026-09","minuteThrough":"2026-10-10"}}}},"security":null},{"kind":"operation","operationId":"me","method":"GET","path":"/v1/me","tag":"Account and health","summary":"Your key's plan and usage","description":"The tier, limits and usage (today, this month) behind an API key. Keys are created on getchord.xyz/developer after a Google sign-in.","url":"https://getchord.xyz/docs/api-reference/operations/me/","parameters":[],"requestBody":null,"responses":{"200":"","401":"Missing or unknown credential (`UNAUTHORIZED`)."},"response":{"schema":{"email":"string|null","tier":"string (free|builder|pro)","limits":{"rpm":"integer","monthly":"integer","priceUsd":"number","label":"string"},"usage":{"today":"integer","month":"integer"}},"example":{"email":"you@example.com","tier":"free","limits":{"rpm":60,"monthly":100000,"priceUsd":0,"label":"Free"},"usage":{"today":41,"month":1209}}},"security":[{"ApiKey":[]}]},{"kind":"operation","operationId":"chainsDirectory","method":"GET","path":"/v1/chains","tag":"Agents and status","summary":"Every chain and the route of each capability","description":"The directory an agent starts from. One entry per chain Chord serves, with its constants (native asset, wrapped native, dollar anchors with real decimals, explorer) and, for each capability, the route that serves it on that chain. A capability the chain does not have is `null`: the data routes grew chain by chain, so this is the one place that says where to read what. Solana is listed with `id: null` and base58, case-sensitive addresses; its `quote` and `swap` are `/sol/trade/quote` and `/sol/trade/send` while its trade lane is open to everyone. A chain that is not public yet appears only for a caller with an API key.","url":"https://getchord.xyz/docs/api-reference/operations/chainsdirectory/","parameters":[],"requestBody":null,"responses":{"200":"","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off."},"response":{"schema":{"chains":[{"key":"string (monad|robinhood|arc|avalanche|base|bnb|arbitrum|ethereum|solana) — Chain key, the value every `chain` parameter accepts.","id":"integer|null — EVM chain id; null for Solana.","name":"string","short":"string — Short label.","addressFormat":"string (evm|base58) — `evm` (0x, case-insensitive) or `base58` (case-sensitive).","native":"object","wrappedNative":"string — The token the native asset is stored under.","anchors":"array","explorer":"string","blockTimeSec":"number — Measured average.","capabilities":"object","mcp":"string — The hosted MCP endpoint pinned to this chain."}],"capabilities":["string"],"updatedAt":"string — ISO time."},"example":{"chains":[{"key":"arc","id":5042,"name":"Arc","short":"Arc","addressFormat":"evm","native":{"symbol":"USDC","decimals":18},"wrappedNative":"0x3600000000000000000000000000000000000000","anchors":[{"symbol":"USDC","address":"0x3600000000000000000000000000000000000000","decimals":6,"stableUsd":1}],"explorer":"https://explorer.arc.io","blockTimeSec":0.5,"capabilities":{"search":{"method":"GET","path":"/v1/tokens/search","query":{"chain":"5042","q":"{q}"}},"candles":{"method":"GET","path":"/v1/candles","query":{"chain":"5042","token":"{address}"}},"wallet":{"method":"GET","path":"/v1/portfolio/{wallet}/pnl","query":{"chain":"5042"}},"walletTrades":{"method":"GET","path":"/v1/portfolio/{wallet}/trades","query":{"chain":"5042"}},"lpPools":{"method":"GET","path":"/v1/lp/pools","query":{"chain":"5042"}},"lpPositions":{"method":"GET","path":"/v1/lp/positions","query":{"chain":"5042","owner":"{wallet}"}},"overview":{"method":"GET","path":"/v1/arc/overview"},"tokens":{"method":"GET","path":"/v1/arc/tokens"},"token":{"method":"GET","path":"/v1/arc/token/{address}"},"trades":{"method":"GET","path":"/v1/arc/token/{address}/trades"},"smartMoney":{"method":"GET","path":"/v1/smart-money/top","query":{"chain":"5042","source":"onchain"}},"holders":{"method":"GET","path":"/v1/arc/token/{address}/holders"},"quote":{"method":"GET","path":"/v1/meta/quote","query":{"chain":"5042"}},"swap":{"method":"POST","path":"/v1/meta/swap"}},"mcp":"https://api.getchord.xyz/v1/mcp?chain=arc"},{"key":"base","id":8453,"name":"Base","short":"Base","addressFormat":"evm","native":{"symbol":"ETH","decimals":18},"wrappedNative":"0x4200000000000000000000000000000000000006","anchors":[{"symbol":"WETH","address":"0x4200000000000000000000000000000000000006","decimals":18,"stableUsd":null},{"symbol":"USDC","address":"0x833589fcd6edb6e08f4c7c32d4f71b54bda02913","decimals":6,"stableUsd":1}],"explorer":"https://basescan.org","blockTimeSec":2,"capabilities":{"overview":{"method":"GET","path":"/v1/chains/base/overview"},"tokens":{"method":"GET","path":"/v1/chains/base/tokens"},"search":{"method":"GET","path":"/v1/tokens/search","query":{"chain":"8453","q":"{q}"}},"token":{"method":"GET","path":"/v1/chains/base/token/{address}"},"trades":{"method":"GET","path":"/v1/chains/base/token/{address}/trades"},"candles":{"method":"GET","path":"/v1/candles","query":{"chain":"8453","token":"{address}"}},"wallet":{"method":"GET","path":"/v1/chains/base/wallet/{wallet}"},"walletTrades":null,"smartMoney":null,"holders":null,"lpPools":null,"lpPositions":null,"quote":{"method":"GET","path":"/v1/meta/quote","query":{"chain":"8453"}},"swap":{"method":"POST","path":"/v1/meta/swap"}},"mcp":"https://api.getchord.xyz/v1/mcp?chain=base"}],"capabilities":["overview","tokens","search","token","trades","candles","wallet","walletTrades","smartMoney","holders","lpPools","lpPositions","quote","swap"],"updatedAt":"2026-10-11T17:33:08.447Z"}},"security":null},{"kind":"operation","operationId":"chainHealth","method":"GET","path":"/v1/health/chains","tag":"Agents and status","summary":"Health of every chain, one generic row each","description":"What the status page is built from, readable directly. `quotes.engine` is the routing engine's own state (`ok`, `starting` after a deploy, `stale` when its pool sync stopped, `down`); `quotes.canary` is the small quote the status probe sends. `data.ageSec` is how old the newest indexed trade is and `data.maxAgeSec` the age past which the chain's data counts as delayed. `quotes` is null where Chord does not route (Solana), `data` is null where no tape runs. Answers from a 15-second memo.","url":"https://getchord.xyz/docs/api-reference/operations/chainhealth/","parameters":[],"requestBody":null,"responses":{"200":"","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off."},"response":{"schema":{"at":"string — ISO time the rows were read.","chains":[{"key":"string (monad|robinhood|arc|avalanche|base|bnb|arbitrum|ethereum|solana)","id":"integer|null","name":"string","quotes":["object","null"],"data":["object","null"]}]},"example":{"at":"2026-10-11T17:33:02.088Z","chains":[{"key":"monad","id":143,"name":"Monad","quotes":{"engine":"ok","latencyMs":4,"lastSyncBlock":112529162,"canary":{"inputMint":"0x754704bc059f8c67012fed69bc8a327a5aafb603","outputMint":"0x3bd359c1119da7da1d913d1c4d2b7c461115433a","amount":"10000000"}},"data":{"ageSec":10,"maxAgeSec":600}},{"key":"robinhood","id":4663,"name":"Robinhood Chain","quotes":{"engine":"ok","latencyMs":5,"lastSyncBlock":86010669,"canary":{"inputMint":"0x5fc5360d0400a0fd4f2af552add042d716f1d168","outputMint":"0x0bd7d308f8e1639fab988df18a8011f41eacad73","amount":"10000000"}},"data":{"ageSec":4,"maxAgeSec":2700}}]}},"security":null},{"kind":"operation","operationId":"statusSummary","method":"GET","path":"/v1/status","tag":"Agents and status","summary":"Uptime history, measured from outside Chord's servers","description":"Served by Cloudflare, not by the API's own servers, so it answers while they do not. A probe runs every minute: it reads `GET /health/chains` and requests one small quote per chain down the public path. Components are `api`, `quotes:<chain>` and `data:<chain>`. Uptime is the share of SAMPLED minutes that were not down; `sampledMin` says how many minutes each window really holds, and a day with no samples has `level: null`: it is never counted as up. An incident opens on the second bad check in a row and closes on the second good one. The same data as a page: https://getchord.xyz/status","url":"https://getchord.xyz/docs/api-reference/operations/statussummary/","parameters":[],"requestBody":null,"responses":{"200":"","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"at":"string — ISO time.","overall":"string (operational|degraded|outage|unknown)","lastProbeAgeSec":"integer|null — Seconds since the last probe. Above about 180 every status reads `unknown`.","since":"string|null — First UTC day with a sample.","probe":{"from":"string","everySec":"integer","openAfterMin":"integer"},"components":[{"id":"string — `api`, `quotes:<chain>` or `data:<chain>`.","group":"string (api|quotes|data)","chain":"string|null","name":"string","status":"string (operational|degraded|down|unknown)","note":"string|null — Why it is not operational.","ms":"integer|null — Last probe: the API call, or the canary quote, in milliseconds. Null for data components.","ageSec":"integer|null — Data components: seconds behind the chain.","uptime":"object","sampledMin":"object","avgMs30d":"integer|null","days":"array"}],"incidents":[{"id":"string — Component id.","name":"string","group":"string","start":"string — ISO.","end":"string|null — ISO; null while open.","minutes":"integer","worst":"string","note":"string|null"}]},"example":{"at":"2026-10-11T17:33:09.133Z","overall":"operational","lastProbeAgeSec":9,"since":"2026-10-11","probe":{"from":"Cloudflare edge","everySec":60,"openAfterMin":2},"incidents":[],"components":[{"id":"api","group":"api","chain":null,"name":"API","status":"operational","note":null,"ms":58,"ageSec":null,"uptime":{"h24":100,"d7":100,"d30":100,"d90":100},"sampledMin":{"h24":9,"d7":9,"d30":9,"d90":9},"avgMs30d":119,"days":[{"day":"2026-07-14","level":null,"downMin":0,"degMin":0,"sampled":0},{"day":"2026-07-15","level":null,"downMin":0,"degMin":0,"sampled":0}]},{"id":"quotes:arc","group":"quotes","chain":"arc","name":"Arc","status":"operational","note":null,"ms":697,"ageSec":null,"uptime":{"h24":100,"d7":100,"d30":100,"d90":100},"sampledMin":{"h24":9,"d7":9,"d30":9,"d90":9},"avgMs30d":683,"days":[{"day":"2026-07-14","level":null,"downMin":0,"degMin":0,"sampled":0},{"day":"2026-07-15","level":null,"downMin":0,"degMin":0,"sampled":0}]},{"id":"data:arc","group":"data","chain":"arc","name":"Arc","status":"operational","note":null,"ms":null,"ageSec":2,"uptime":{"h24":100,"d7":100,"d30":100,"d90":100},"sampledMin":{"h24":9,"d7":9,"d30":9,"d90":9},"avgMs30d":null,"days":[{"day":"2026-07-14","level":null,"downMin":0,"degMin":0,"sampled":0},{"day":"2026-07-15","level":null,"downMin":0,"degMin":0,"sampled":0}]}]}},"security":null},{"kind":"operation","operationId":"agentStats","method":"GET","path":"/v1/agent/stats","tag":"Agents and status","summary":"Agent traffic per chain","description":"How much programmatic traffic a chain sees through Chord, by the surface it came through: `mcp` (the hosted MCP), `api` (an API key), `x402` and `wallet` (not live yet), `anon` (keyless scripts), and `web` (people in Chord's own app; their board reads are not counted). `agents` adds up everything that is not `web`. Counts are requests answered 2xx; `swapTx` is swap transactions BUILT; what executed is under `onchain`, read from the router's events on each chain. `callers` is distinct callers over the window. `since` is the first day with any count: the counters started on 2026-10-11, earlier days are unknown, not zero.","url":"https://getchord.xyz/docs/api-reference/operations/agentstats/","parameters":[{"name":"chain","in":"query","required":false,"type":"string","enum":["all","monad","robinhood","arc","avalanche","base","bnb","arbitrum","ethereum","solana"],"description":"A chain key or id, or `all` (every chain plus chain-free calls such as Ask). Default `all`."},{"name":"days","in":"query","required":false,"type":"integer","default":30,"description":"Window in UTC days, today included."}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"chain":"string","days":"integer","from":"string — UTC day.","to":"string — UTC day.","agents":{"calls":"integer — Requests answered 2xx.","reads":"integer","quotes":"integer","swapTx":"integer — Swap transactions built, not executed.","asks":"integer — Questions to the analyst.","callers":"integer — Distinct callers in the window."},"web":{"calls":"integer — Requests answered 2xx.","reads":"integer","quotes":"integer","swapTx":"integer — Swap transactions built, not executed.","asks":"integer — Questions to the analyst.","callers":"integer — Distinct callers in the window."},"bySource":{"mcp":{"calls":"integer — Requests answered 2xx.","reads":"integer","quotes":"integer","swapTx":"integer — Swap transactions built, not executed.","asks":"integer — Questions to the analyst.","callers":"integer — Distinct callers in the window."},"x402":{"calls":"integer — Requests answered 2xx.","reads":"integer","quotes":"integer","swapTx":"integer — Swap transactions built, not executed.","asks":"integer — Questions to the analyst.","callers":"integer — Distinct callers in the window."},"wallet":{"calls":"integer — Requests answered 2xx.","reads":"integer","quotes":"integer","swapTx":"integer — Swap transactions built, not executed.","asks":"integer — Questions to the analyst.","callers":"integer — Distinct callers in the window."},"api":{"calls":"integer — Requests answered 2xx.","reads":"integer","quotes":"integer","swapTx":"integer — Swap transactions built, not executed.","asks":"integer — Questions to the analyst.","callers":"integer — Distinct callers in the window."},"anon":{"calls":"integer — Requests answered 2xx.","reads":"integer","quotes":"integer","swapTx":"integer — Swap transactions built, not executed.","asks":"integer — Questions to the analyst.","callers":"integer — Distinct callers in the window."},"web":{"calls":"integer — Requests answered 2xx.","reads":"integer","quotes":"integer","swapTx":"integer — Swap transactions built, not executed.","asks":"integer — Questions to the analyst.","callers":"integer — Distinct callers in the window."}},"daily":[{"day":"string","calls":"integer","reads":"integer","quotes":"integer","swapTx":"integer","asks":"integer"}],"since":"string|null","onchain":{"swaps":"integer — Swaps executed through Chord's router in the window, from the router's own `Swap` events.","wallets":"integer — Distinct `sender` addresses. A swap relayed by another contract has that contract as sender.","volumeUsd":"number — USD of the swaps that have a dollar-stable leg (that leg's own amount).","unpriced":"integer — Swaps with no stable leg: counted in `swaps`, not in `volumeUsd`. Never estimated.","bySource":"object — Swaps whose transaction was built through a known surface in the two hours before it landed, by surface. The rest are unlabelled.","daily":["object"],"coverage":["object"]},"updatedAt":"string — ISO time."},"example":{"chain":"arc","days":7,"from":"2026-10-05","to":"2026-10-11","agents":{"calls":9,"reads":7,"quotes":2,"swapTx":0,"asks":0,"callers":2},"web":{"calls":0,"reads":0,"quotes":0,"swapTx":0,"asks":0,"callers":0},"bySource":{"mcp":{"calls":6,"reads":6,"quotes":0,"swapTx":0,"asks":0,"callers":1},"x402":{"calls":0,"reads":0,"quotes":0,"swapTx":0,"asks":0,"callers":0},"wallet":{"calls":0,"reads":0,"quotes":0,"swapTx":0,"asks":0,"callers":0},"api":{"calls":1,"reads":1,"quotes":0,"swapTx":0,"asks":0,"callers":1},"anon":{"calls":2,"reads":0,"quotes":2,"swapTx":0,"asks":0,"callers":1},"web":{"calls":0,"reads":0,"quotes":0,"swapTx":0,"asks":0,"callers":0}},"daily":[{"day":"2026-10-05","calls":0,"reads":0,"quotes":0,"swapTx":0,"asks":0},{"day":"2026-10-06","calls":0,"reads":0,"quotes":0,"swapTx":0,"asks":0}],"since":"2026-10-11","onchain":{"swaps":1,"wallets":1,"volumeUsd":190,"unpriced":0,"bySource":{},"daily":[{"day":"2026-10-05","swaps":0,"volumeUsd":0},{"day":"2026-10-06","swaps":0,"volumeUsd":0}],"coverage":[{"chain":5042,"fromBlock":20268312,"cursor":25453341}]},"updatedAt":"2026-10-11T18:22:55.946Z"}},"security":null},{"kind":"operation","operationId":"agentRouterWallet","method":"GET","path":"/v1/agent/router/wallet/{address}","tag":"Agents and status","summary":"One wallet's swaps through Chord's router","description":"What one address swapped through Chord's router contract in the last `days` × 24 h (rolling), read from the router's own `Swap` events: count and USD volume, in total and per chain. A swap with a dollar-stable leg is worth that leg; one with the chain's own coin (native or wrapped) on a leg is worth that amount at CoinGecko's price now; anything else is `unpriced` and counts for $0. MoltNode (moltnode.ag/quest) sizes RPC keys from `volumeUsd`. Public: router events are public chain data. Cached 60 s.","url":"https://getchord.xyz/docs/api-reference/operations/agentrouterwallet/","parameters":[{"name":"address","in":"path","required":true,"type":"string","description":"The `sender` of the router swap (the wallet that called the router)."},{"name":"days","in":"query","required":false,"type":"integer","default":30,"description":"Window in days of 24 h, ending now."}],"requestBody":null,"responses":{"200":"","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …).","429":"Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"wallet":"string — EVM address, hex, case-insensitive.","days":"integer","since":"integer — Unix seconds: the start of the window.","swaps":"integer — Swaps through the router in the window.","volumeUsd":"number — USD of the priced swaps.","pricedBy":{"stable":"integer — Valued by a dollar-stable leg.","coin":"integer — Valued by the chain coin's leg at today's price."},"unpriced":"integer — Swaps with neither leg: counted in `swaps`, worth $0 here.","lastSwapAt":"integer|null — Unix seconds of the latest swap.","byChain":[{"chain":"integer","key":"string","swaps":"integer","volumeUsd":"number"}]},"example":{"wallet":"0x0f1171209dad379af0e486f2c77d275d6e0a4f79","days":30,"since":1789587369,"swaps":297,"volumeUsd":974.44,"pricedBy":{"stable":279,"coin":18},"unpriced":0,"lastSwapAt":1792094831,"byChain":[{"chain":1,"key":"ethereum","swaps":58,"volumeUsd":284.1},{"chain":42161,"key":"arbitrum","swaps":51,"volumeUsd":156.87},{"chain":56,"key":"bnb","swaps":40,"volumeUsd":144.68},{"chain":4663,"key":"robinhood","swaps":15,"volumeUsd":104.93},{"chain":8453,"key":"base","swaps":30,"volumeUsd":100.98},{"chain":143,"key":"monad","swaps":23,"volumeUsd":65.9},{"chain":43114,"key":"avalanche","swaps":53,"volumeUsd":63.45},{"chain":5042,"key":"arc","swaps":27,"volumeUsd":53.52}]}},"security":null},{"kind":"operation","operationId":"mcp","method":"POST","path":"/v1/mcp","tag":"Agents and status","summary":"Hosted MCP server","description":"Model Context Protocol over stateless Streamable HTTP: POST one JSON-RPC message (or a batch of up to 20), get JSON back. Methods: `initialize`, `ping`, `tools/list`, `tools/call`. 17 tools; every data tool takes a `chain`. `?chain=<key>` pins a default chain and names the server `chord-<key>`. The handshake and the tool list need no credentials and are not metered; a tool call is an ordinary request to this API made as the caller, so it is limited and metered exactly like the REST call it wraps. Send a key as `X-API-Key`, `Authorization: Bearer`, or `?apiKey=`. A tool-level failure is a normal result with `isError: true` and a sentence the model can act on. Guide: https://getchord.xyz/docs/agents/mcp/","url":"https://getchord.xyz/docs/api-reference/operations/mcp/","parameters":[{"name":"chain","in":"query","required":false,"type":"string","enum":["monad","robinhood","arc","avalanche","base","bnb","arbitrum","ethereum","solana"],"description":"Default chain for this endpoint."},{"name":"apiKey","in":"query","required":false,"type":"string","description":"Your key, for connectors that cannot set a header."}],"requestBody":{"schema":"object — A JSON-RPC 2.0 message, or an array of them.","example":{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"chord_search","arguments":{"query":"EURC"}}}},"responses":{"200":"The JSON-RPC response. A tool result carries one text block: `{chain, route, data}` as JSON.","202":"A notification: nothing to answer.","400":"Invalid parameters — `error` names the check that failed (`INVALID_PARAMS`, `BAD_ADDRESS`, `BAD_LIMIT`, `BAD_HOURS`, …)."},"response":{"schema":"object — JSON-RPC 2.0 response.","example":{"jsonrpc":"2.0","id":1,"result":{"content":[{"type":"text","text":"{\"chain\":\"arc\",\"route\":\"GET /v1/tokens/search\",\"data\":{\"chain\":5042,\"q\":\"EURC\",\"tokens\":[{\"address\":\"0xbef5f6d51cb62b58e6a8f77868681825c6fe21c1\",\"symbol\":\"EURC\",\"name\":\"Euro Coin\",\"decimals\":6,\"logoURI\":\"https://assets.coingecko.com/coins/images/26045/small/euro.png\",\"verified\":true}]}}"}]}}},"security":null},{"kind":"operation","operationId":"mcpTools","method":"GET","path":"/v1/mcp/tools.json","tag":"Agents and status","summary":"The MCP tools as a function-calling manifest","description":"The same tool list as OpenAI-style function definitions, for frameworks that take a manifest instead of speaking MCP. Always current: it is printed from the list the MCP server serves.","url":"https://getchord.xyz/docs/api-reference/operations/mcptools/","parameters":[],"requestBody":null,"responses":{"200":""},"response":{"schema":{"name":"string","version":"string","base_url":"string","mcp":"string — The hosted MCP endpoint.","auth":{"header":"string","required":"boolean"},"tools":[{"type":"string","function":"object"}]},"example":{"name":"chord","version":"1.0.0","base_url":"https://api.getchord.xyz","mcp":"https://api.getchord.xyz/v1/mcp","auth":{"header":"X-API-Key","required":false},"tools":[{"type":"function","function":{"name":"chord_chains","description":"The chains Chord serves, with their native asset, anchors and which capabilities each one has (overview, tokens, trades, candles, wallet PnL, smart money, holders, LP, quote, swap). Call this first when unsure what a chain supports.","parameters":{"type":"object","properties":{}}}},{"type":"function","function":{"name":"chord_status","description":"Live health of every chain: routing engine state, how old the newest indexed trade is, and the public status page link.","parameters":{"type":"object","properties":{}}}}]}},"security":null},{"kind":"operation","operationId":"health","method":"GET","path":"/v1/health","tag":"Account and health","summary":"Service health","description":"Engine, cache and pool-sync state. `503` when the routing engine is unreachable.","url":"https://getchord.xyz/docs/api-reference/operations/health/","parameters":[],"requestBody":null,"responses":{"200":"","503":"The lane behind this endpoint is not ready or not enabled here (`NOT_READY`, `CHAIN_NOT_ENABLED`, `NOT_ENABLED`, `*_UNAVAILABLE`). Retry later; do not treat it as an empty answer."},"response":{"schema":{"status":"string","version":"string","uptime":"number — Seconds.","engine":{"status":"string","latencyMs":"integer"},"redis":{"status":"string"},"poolCount":"integer","lastSyncBlock":"integer"},"example":{"status":"ok","version":"0.1.0","uptime":494.311362193,"engine":{"status":"ok","latencyMs":1},"redis":{"status":"ok"},"poolCount":1649,"lastSyncBlock":106412042}},"security":null}]}