# Crius documentation (full text) > Every page of the Crius API documentation (https://crius.sh/docs/) in one Markdown file, in navigation order. Index: https://crius.sh/llms.txt # Crius API documentation > The Crius API serves real-time and historical Robinhood Chain data (token prices, candles, trades, holders, pools, launchpads, security checks) over REST and WebSocket from our own archive nodes. Source: https://crius.sh/docs/ The **Crius API** is a data API for **Robinhood Chain** (chain id 4663). It gives you prices, OHLCV candles, trades, holders, pools, launchpad lifecycles, security checks and wallet analytics for every token on the chain, in real time and back to block one, from one REST API and one WebSocket. Every response is plain JSON with a `meta` block that says exactly which block the data comes from and how far behind the chain head it is. ```bash curl "https://api.crius.sh/v1/robinhood/token/0x0bd7d308f8e1639fab988df18a8011f41eacad73/price" ``` That request works without a key (anonymous calls are rate-limited per IP). [Get a free API key](https://dashboard.crius.sh/signup) for 1,000,000 credits a month and the full set of endpoints. - [Quickstart](/docs/quickstart/): From sign-up to your first request in under five minutes. - [API playground](/docs/playground/): Call any endpoint from your browser and copy the code. - [API reference](/docs/reference/tokens/): Every endpoint with parameters, examples and real responses. - [Chart example](/docs/examples/chart/): Live candles with TradingView Lightweight Charts in 40 lines. ## Base URLs | What | URL | |---|---| | Data API (REST) | `https://api.crius.sh/v1/robinhood/…` | | WebSocket stream | `wss://api.crius.sh/v1/robinhood/stream` | | Account API (keys, usage, billing) | `https://account.crius.sh/v1/account/…` | | OpenAPI 3 document | [`https://api.crius.sh/openapi.json`](https://api.crius.sh/openapi.json) | | Service status | [`status.crius.sh`](https://status.crius.sh) | **Test the connection** (no key needed): `curl https://api.crius.sh/v1/status` returns the node and chain status, and `curl https://api.crius.sh/v1/robinhood` returns an index of the main endpoints. A first data call: `curl https://api.crius.sh/v1/robinhood/stats`. `{chain}` in every path is the chain slug `robinhood` or the chain id `4663`. ## What you can build **Trading bots.** Prices a block behind the head, the live trade tape, new launches and graduations over WebSocket, and realized buy/sell tax before you trade. **Charts & dashboards.** Candles from 1 second to 1 day, market cap history, chain-wide volume, TVL and launchpad stats. **Wallets & portfolio apps.** Holdings, PnL, wallet trade history, token profiles with logos and socials, and security checks. **Research & AI agents.** Holder snapshots at any block or market cap, diamond-hand cohorts, bundles, snipers and bubble maps, as clean JSON an agent can reason about. ## What's covered - **Every ERC-20** on Robinhood Chain: profiles, supply, holders, transfers. - **Uniswap v2, v3 and v4**: every pool and fee tier, v4 hooks with decoded permissions. - **Launchpads**: Pons, Flap.sh, Bankr, Long.xyz, King of the Markets and more, from bonding curve to graduation. - **Tokenized stocks** priced from on-chain pools. - **LP lockers**: Pons, UNCX, Team Finance, TitanLocker, HoodLock. > **Using an AI assistant?:** > Every docs page has a Markdown version (add `.md` to the URL, or use **Copy page** at the top), and the whole > documentation is available as one file at [`/llms-full.txt`](https://crius.sh/llms-full.txt). See [For AI agents](https://crius.sh/docs/ai/). --- # Quickstart > Create a free Crius account, get an API key and make your first Robinhood Chain API request with cURL, JavaScript or Python in under five minutes. Source: https://crius.sh/docs/quickstart/ 1. **Create an account.** Go to [dashboard.crius.sh](https://dashboard.crius.sh/signup), enter your email and the one-time code we send you. The free plan needs no card and includes 1,000,000 credits a month. 2. **Create an API key.** In the dashboard, open **API keys** and create a key. Copy the secret straight away: it is shown once, and only a hash of it is stored. Keys look like `crs_live_AbCd1234_…`. 3. **Store the key in an environment variable.** Never put it in front-end code or commit it to git. ```bash export CRIUS_API_KEY="crs_live_…" ``` 4. **Make your first request.** Get the price of Charge AI (CHARGE), a token that launched on Pons and graduated to a Uniswap v4 pool: **cURL** ```bash curl "https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/price" \ -H "x-api-key: $CRIUS_API_KEY" ``` **JavaScript** ```js const res = await fetch( "https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/price", { headers: { "x-api-key": process.env.CRIUS_API_KEY } }, ); const { data, meta } = await res.json(); console.log(`${data.symbol} = $${data.usd} (block ${meta.block})`); ``` **Python** ```python import os, requests r = requests.get( "https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/price", headers={"x-api-key": os.environ["CRIUS_API_KEY"]}, ) body = r.json() print(body["data"]["symbol"], body["data"]["usd"], "at block", body["meta"]["block"]) ``` 5. **Read the response.** Data is in `data`; `meta` tells you the block it was read at and how fresh it is. ```json { "data": { "symbol": "CHARGE", "token": "0x7b8892cea949bc60d494681d1bc3ea96071ab0b8", "usd": 0.00000576413, "eth": 0.0000000024199, "dex": "uniswap_v4", "liquidity_usd": 6861.07, "confidence": "medium", "thin_liquidity": false }, "meta": { "chain": "robinhood", "block": 95503718, "block_age_ms": 1050, "lag_ms": 37 } } ``` The response headers tell you your limits: `x-ratelimit-remaining`, `x-credits-cost` and `x-quota-remaining`. ## Next steps - Browse the [API reference](https://crius.sh/docs/reference/tokens/), or try endpoints live in the [playground](https://crius.sh/docs/playground/). - Draw a live chart with the [chart example](https://crius.sh/docs/examples/chart/). - Stream trades and new launches with the [WebSocket stream](https://crius.sh/docs/reference/stream/). - Learn how [credits and rate limits](https://crius.sh/docs/plans-and-limits/) work. > **Keep keys server-side:** > An API key in a web page can be copied by anyone. For browser use, create a key restricted to your site's origin > (it becomes read-only) or proxy requests through your own backend. See [Authentication](https://crius.sh/docs/authentication/). --- # Authentication & API keys > How to authenticate Crius API requests with the x-api-key header, key scopes, IP allow-lists, browser origins, expiry, rotation with a grace period, and dashboard sessions. Source: https://crius.sh/docs/authentication/ Send your API key in the **`x-api-key`** header on every request: ```bash curl "https://api.crius.sh/v1/robinhood/stats" -H "x-api-key: $CRIUS_API_KEY" ``` WebSocket clients that can't set headers may pass it as a query parameter instead: `wss://api.crius.sh/v1/robinhood/stream?api_key=…`. Requests **without a key** are allowed for the core endpoints (prices, tokens, pools, trades, candles, search, stats) under the anonymous plan: 2 requests per second per client IP, read-only. Everything else needs a key. ## Key format Keys look like `crs_live_AbCd1234_`: - `crs` identifies a Crius key (handy for secret scanners); - `live` or `test` is the key's environment label; - `AbCd1234` is the public **prefix** shown in your dashboard and in emails; - the rest is the secret. It is shown **once** when the key is created. We store only a salted SHA-256 hash, so a lost key can't be recovered: rotate it. An account can have up to **20 active keys**. Credits and plan limits belong to the account and are shared by all its keys. ## Scopes | Scope | Allows | |---|---| | `read` | All REST data endpoints your plan includes | | `stream` | The WebSocket stream (also implies `read`) | | `simulate` | Fresh on-demand security simulations (`/security?fresh=1`) | | `export` | Bulk exports (reserved) | The key issued when you sign up has `read`, `stream` and `simulate`; keys you create get `read` and `stream` unless you choose otherwise. Account management (keys, wallets, billing) is never possible with an API key: it needs a signed-in dashboard session, so a leaked key can read data but can't take over your account. ## Restricting a key Every key can be narrowed in the dashboard or through the [Account API](https://crius.sh/docs/reference/account/): - **IP allow-list**: one or more IPs or CIDR ranges (`203.0.113.7`, `10.0.0.0/8`, IPv6 too). Requests from anywhere else get `403 ip_not_allowed`. - **Allowed origins**: browser origins such as `https://app.example.com`. A key with origins becomes **read-only** and only works from those pages (`403 origin_not_allowed` otherwise). Use this for keys that must live in front-end code. - **Rate limit**: a per-key requests-per-second cap below your plan's limit, so one service can't starve another. - **Expiry**: the key stops working after a number of days (`401 key_expired`). ## Rotating a key Rotation issues a new secret and keeps the old one working for a **grace period** (1 hour by default, up to 7 days) so you can deploy the new key without downtime. After the grace period the old key returns `401 key_rotated`. Revoking a key stops it immediately (`401 key_revoked`), on every region within seconds. ## Dashboard sessions Signing in at [dashboard.crius.sh](https://dashboard.crius.sh) (email code or a linked wallet) creates a **session key** that lasts 7 days. Session keys can only call the Account API; using one on a data endpoint returns `403 session_not_api_key`. API keys calling account-management endpoints get `403 session_required`. ## Failed authentication Invalid keys get `401 invalid_key`. After 20 failed attempts in a minute from one IP, that IP is blocked for 60 seconds (`429 auth_banned`). > **Caution:** > Treat keys like passwords. Don't put an unrestricted key in browser code, mobile apps or public repositories. If a > key leaks, revoke or rotate it in the dashboard; we also email you whenever a key is created, rotated or revoked. --- # Plans, limits & credits > Crius API plans (Free, Starter, Pro, Business, Enterprise), monthly credits, requests per second, WebSocket limits, credit cost per endpoint and the rate-limit response headers. Source: https://crius.sh/docs/plans-and-limits/ Every plan has a **rate limit** (requests per second, with a burst of twice that), a **monthly credit quota**, WebSocket limits and a set of endpoints. Each request costs a number of **credits** depending on the endpoint; cheap calls such as prices cost 1. ## Plans | Plan | Price | Credits / month | Requests / s | WebSockets | Subscriptions | |---|---|---|---|---|---| | Anonymous (no key) | free | n/a, per IP | 2 | none | none | | **Free** | $0 | 1,000,000 | 10 | 1 | 10 | | **Starter** | $19 / month | 10,000,000 | 25 | 3 | 100 | | **Pro** | $79 / month | 50,000,000 | 75 | 10 | 1,000 | | **Business** | $249 / month | 200,000,000 | 200 | 50 | 10,000 | | **Enterprise** | custom | custom | custom | custom | custom | Paying for 6 months gives 10% off, and 12 months 20% off. Plans are paid on-chain on Robinhood Chain in USDG, ETH or WETH; see [Billing & payments](https://crius.sh/docs/reference/billing/). Credits reset at the start of each UTC month and are shared by all of an account's keys. ## Endpoints by plan | Plan needed | Endpoints | Credits per call | |---|---|---| | Anonymous | token profile, price, batch prices, batch profiles, pools, pool, token lists, search, stats, volume, launchpads, security (cached), status, chains | 1 | | Anonymous | trades, candles | 2 | | Free | holders, launch, activity feed, hooks, hook detail | 2 | | Free | holder snapshot, top traders, liquidity & locks, developer profile | 5 | | Free | WebSocket stream (per connection) | 1 | | Starter | wallet profile, wallet trades, fees & claims | 5 | | Starter | holder cohort, holder history, bundles, bubble map, wallet connections | 10 | | Starter | fresh security simulation (`/security?fresh=1`) | 20 | | Enterprise | `firehose:trades` stream channel (every trade on chain) | | Each endpoint page in the [API reference](https://crius.sh/docs/reference/tokens/) shows its plan and cost. Calls to the Account API (`/v1/account/*`) are **free** and don't count against your credits. ## Rate-limit headers Every data response carries: | Header | Meaning | |---|---| | `x-ratelimit-limit` | Your requests-per-second limit for this key | | `x-ratelimit-remaining` | Requests left in the current burst | | `x-ratelimit-reset` | Milliseconds until the bucket refills (1000) | | `x-credits-cost` | Credits this request cost | | `x-quota-remaining` | Credits left this month (after this request) | When you go over the rate limit you get **`429 rate_limited`** with a `retry-after` header (seconds). When the month's credits run out you get **`429 quota_exceeded`** until the next month, or until you upgrade. ## Handling 429 well ```js async function crius(path, tries = 4) { for (let i = 0; i < tries; i++) { const res = await fetch(`https://api.crius.sh${path}`, { headers: { "x-api-key": process.env.CRIUS_API_KEY }, }); if (res.status !== 429) return res.json(); const body = await res.json(); if (body.error?.code === "quota_exceeded") throw new Error("monthly credits used up"); const wait = Number(res.headers.get("retry-after") ?? 1) * 1000; await new Promise((r) => setTimeout(r, wait + Math.random() * 250)); } throw new Error("still rate limited"); } ``` > **Save credits:** > Use batch endpoints (`/prices` and `/tokens/batch` take up to 100 tokens per call), use the WebSocket stream instead > of polling, and cache responses for the time you can tolerate: `meta.block` tells you whether anything changed. ## Usage and alerts The dashboard shows usage per day and per endpoint, and `GET /v1/account/usage` returns the same data. We email you when you reach 50%, 80%, 90% and 100% of your monthly credits. --- # Responses & conventions > The Crius API response envelope, meta block, number and amount formats, timestamps, addresses, pagination, finality levels and liquidity and market-cap definitions. Source: https://crius.sh/docs/conventions/ ## The envelope Every successful response is a JSON object with `data` and `meta`: ```json { "data": { "symbol": "WETH", "usd": 2381.97 }, "meta": { "chain": "robinhood", "block": 95503718, "block_ts": 1792712926000, "block_age_ms": 1050, "lag_ms": 37, "safe_block": 95497061, "finalized_block": 95493649 } } ``` | `meta` field | Meaning | |---|---| | `block` | The latest L2 block the data reflects | | `block_ts` | That block's timestamp (unix ms) | | `block_age_ms` | How old that block is | | `lag_ms` | How long ago our index applied it | | `safe_block` | Latest block whose batch is posted to Ethereum | | `finalized_block` | Latest block finalized on Ethereum | | `next_cursor` | On paginated lists: pass it as `?cursor=` for the next page | Errors use `{"error": {"code": "…", "message": "…"}}` with a matching HTTP status. See [Errors](https://crius.sh/docs/errors/). ## Numbers and amounts - **USD values, prices and ratios** are JSON numbers, always in **plain decimal notation** (`0.00000576413`, never `5.76e-6`), rounded to 6 significant digits. - **Token amounts** are in human units (already divided by the token's decimals). - **Percentages** are 0–100 (`12.5` means 12.5%). - `liquidity_usd` is **2 × the quote side** of a pool (the convention DEX screeners use). `quote_liquidity_usd` is the real quote amount sellers could withdraw. For bonding curves only the real quote raised counts. - `market_cap_usd` = price × (total supply − tokens burned at `0x0` or `0x…dEaD`), with unsold bonding-curve tokens included. `fdv_usd` = price × total supply. ## Time - Every `*_ts` field is **unix milliseconds** (UTC). - Stats windows: `1s`, `30s`, `1m`, `5m`, `1h`, `4h`, `6h`, `24h`, plus `all_time` totals. - Candle intervals: `1s`, `30s`, `1m`, `5m`, `15m`, `1h`, `4h`, `6h`, `1d`. - Robinhood Chain produces a block roughly every 100 ms. Inside contracts, `block.number` is the **Ethereum L1** block (about 12 s), which is why per-block contract rules (anti-snipe, sell throttles) act on L1 blocks; responses expose both `block` and `l1_block` where it matters. ## Addresses Addresses are accepted in any case and always returned **lowercase**. Native ETH is `0x0000000000000000000000000000000000000000` with symbol `ETH`. Uniswap v4 pools are identified by their 32-byte pool id. ## Pagination Lists take `limit` (each endpoint documents its maximum, usually 500) and return `meta.next_cursor` when there is more. Pass it back as `cursor`; cursors are opaque and stable. ## Finality Every event (trade, transfer, liquidity change) carries a `finality` level: | Level | Meaning | |---|---| | `latest` | Confirmed by the Robinhood Chain sequencer (sub-second) | | `safe` | Its batch has been posted to Ethereum | | `finalized` | Finalized on Ethereum | Most apps can use `latest`. If you need settled data only, filter by finality where an endpoint supports it, or subscribe to the stream with `"finality": "safe"`. See [Finality & reorgs](https://crius.sh/docs/concepts/finality/). ## History Fields marked `history: "partial"` or `since_index_start` cover data from when our index started for that item; they become complete once the history backfill reaches it. Profiles show `history: "complete"` once everything is indexed. --- # Errors > Crius API error format, HTTP status codes and every error code with its meaning and what to do about it. Source: https://crius.sh/docs/errors/ Errors return a non-2xx HTTP status and a JSON body: ```json { "error": { "code": "plan_required", "message": "this endpoint needs the free plan or higher" } } ``` Match on `error.code` (stable, machine-readable); `message` is for humans and may change. ## Authentication and access | Status | Code | Meaning | What to do | |---|---|---|---| | 401 | `key_required` | This endpoint needs a key and none was sent | Send `x-api-key` | | 401 | `invalid_key` | The key doesn't exist or the secret is wrong | Check for typos or a truncated key | | 401 | `key_rotated` | The key was rotated and its grace period ended | Use the new key | | 401 | `key_revoked` | The key was revoked | Create a new key | | 401 | `key_expired` | The key passed its expiry date | Create a new key | | 403 | `account_suspended` | The account is suspended | Contact support@crius.sh | | 403 | `plan_required` | Your plan doesn't include this endpoint | Upgrade, see [plans](https://crius.sh/docs/plans-and-limits/) | | 403 | `scope_required` | The key lacks the scope (`stream`, `simulate`) | Edit the key's scopes | | 403 | `ip_not_allowed` | The client IP isn't in the key's allow-list | Update the allow-list | | 403 | `origin_not_allowed` | The browser origin isn't allowed for this key | Add the origin to the key | | 403 | `session_required` | Account management needs a dashboard session | Use the dashboard | | 403 | `session_not_api_key` | A dashboard session was used on a data endpoint | Use an API key | ## Limits | Status | Code | Meaning | What to do | |---|---|---|---| | 429 | `rate_limited` | Over your requests-per-second limit | Wait `retry-after` seconds, then retry | | 429 | `quota_exceeded` | Monthly credits used up | Upgrade or wait for the next month | | 429 | `auth_banned` | Too many failed authentications from this IP | Wait 60 s and fix the key | | 503 | `busy` | Too many heavy analytics requests in flight | Retry shortly with backoff | ## Requests | Status | Code | Meaning | |---|---|---| | 400 | `invalid_address` | Not a valid `0x` address | | 400 | `invalid_pool` | Not a valid pool address or v4 pool id | | 400 | `invalid_interval` | Unsupported candle interval | | 400 | `invalid_window` | Unsupported stats window | | 400 | `invalid_cursor` | The cursor is malformed or from another list | | 400 | `invalid_at` | The point in time (`at`, `from`, `to`) couldn't be parsed | | 400 | `invalid_list`, `invalid_sort`, `invalid_tz` | An unsupported option | | 400 | `too_many_tokens` | More than 100 tokens in a batch | | 400 | `window_too_large` | The requested time window is too large for this endpoint | | 400 | `token_too_active` | The token has too much history for this query (holder history) | | 400 | `invalid_request` | Malformed query string or body | | 413 | `payload_too_large` | Request body over 256 KB | ## Not found | Status | Code | Meaning | |---|---|---| | 404 | `chain_not_found` | Unknown chain slug or id | | 404 | `token_not_found` | We have no token at this address | | 404 | `pool_not_found` | No such pool | | 404 | `wallet_not_found`, `dev_not_found` | No activity for this address | | 404 | `hook_not_found`, `launch_not_found`, `launchpad_not_found` | No such hook, launch or launchpad | | 404 | `point_not_found` | The point in time (`mcap:`, `graduation`…) never happened for this token | | 404 | `not_ready` | The data is still being indexed; retry shortly | | 404 | `stream_unavailable` | The stream isn't enabled on this node | ## Server | Status | Code | Meaning | |---|---|---| | 500 | `internal` | Something broke on our side; it is logged. Retry, and contact support if it persists | | 504 | `timeout` | The request took longer than 10 seconds | Check [status.crius.sh](https://status.crius.sh) for ongoing incidents. --- # API playground > Try every Crius API endpoint from your browser - pick an endpoint, fill in parameters, send a live request to api.crius.sh and copy ready-made cURL, JavaScript and Python code. Source: https://crius.sh/docs/playground/ Pick an endpoint, adjust its parameters and press **Send request**. Requests go straight from your browser to `https://api.crius.sh`. Endpoints marked “No key needed” work anonymously (2 requests per second per IP); for the rest, paste an API key from your [dashboard](https://dashboard.crius.sh). Your key stays in this tab and is only sent to the API. *(Interactive playground: open https://crius.sh/docs/playground/ in a browser. Endpoints are listed in https://crius.sh/llms.txt and https://api.crius.sh/openapi.json.)* Every request shows its status, timing, credit cost and remaining rate limit, and the **cURL**, **JavaScript** and **Python** tabs give you the same call as code. --- # Chart example > Draw a live candlestick and volume chart for any Robinhood Chain token with the Crius candles endpoint and TradingView Lightweight Charts, with full source code. Source: https://crius.sh/docs/examples/chart/ A live candlestick chart with volume for any Robinhood Chain token (here Tesla's tokenized stock, TSLA), built on [`/candles`](https://crius.sh/docs/reference/trades/#ohlcv-candles) and [TradingView Lightweight Charts](https://github.com/tradingview/lightweight-charts). Paste any token address or pick an interval; it refreshes every 15 seconds. *(Live chart: open https://crius.sh/docs/examples/chart/ in a browser.)* ## The code The candles endpoint returns **columnar** arrays (`t`, `o`, `h`, `l`, `c`, `v`), which map straight onto chart series: ```html
``` ## Make it real-time Polling works, but the [WebSocket stream](https://crius.sh/docs/reference/stream/) pushes the live candle as trades happen. Subscribe to `candles::` and update the last bar: ```js // Run this where your key is safe (your backend, a desktop app), never in a public page. const ws = new WebSocket(`wss://api.crius.sh/v1/robinhood/stream?api_key=${KEY}`); ws.onopen = () => ws.send(JSON.stringify({ op: "subscribe", channels: [`candles:${token}:15m`] })); ws.onmessage = (e) => { const m = JSON.parse(e.data); if (!m.ch.startsWith("candles:")) return; const c = m.data; candles.update({ time: c.t / 1000, open: c.o, high: c.h, low: c.l, close: c.c }); volume.update({ time: c.t / 1000, value: c.v }); }; ``` > **Tip:** > Meme tokens trade at tiny prices. Set the series' `priceFormat.precision` from the last close (for example 10 > decimals for $0.0000057) so the axis stays readable. Use `currency=quote` to chart in the pool's quote token (ETH) > instead of USD. --- # Real-time stream example > A complete reconnecting WebSocket client for the Crius stream in Node.js - subscribe to new launches, trades and prices on Robinhood Chain, resume after disconnects and handle reorgs. Source: https://crius.sh/docs/examples/stream/ This client subscribes to every new launch and graduation plus the trades of one token, reconnects with backoff, resumes the messages it missed, and undoes reorged events. It runs on Node.js 22+ (built-in `WebSocket`) with a key that has the `stream` scope. ```js // stream.mjs: node stream.mjs const KEY = process.env.CRIUS_API_KEY; const TOKEN = "0x7b8892cea949bc60d494681d1bc3ea96071ab0b8"; const CHANNELS = ["launches:all", "graduations:all", `trades:${TOKEN}`, `price:${TOKEN}`]; const lastSeq = {}; // channel -> last seq seen, for resuming let backoff = 1000; function connect() { const ws = new WebSocket(`wss://api.crius.sh/v1/robinhood/stream?api_key=${KEY}`); let idle; const touch = () => { clearTimeout(idle); idle = setTimeout(() => ws.close(), 45_000); // heartbeats come every 15 s }; ws.onopen = () => { backoff = 1000; touch(); ws.send(JSON.stringify({ op: "subscribe", channels: CHANNELS })); if (Object.keys(lastSeq).length) ws.send(JSON.stringify({ op: "resume", seqs: lastSeq })); }; ws.onmessage = (e) => { touch(); const m = JSON.parse(e.data); if (m.seq) lastSeq[m.ch] = m.seq; switch (true) { case m.ch === "reorg": console.warn(`reorg: blocks ${m.data.removed_blocks.join(", ")} replaced`); break; case m.data?.removed: console.warn(`undo ${m.ch} ${m.data.id}`); // reverse whatever you did for this event id break; case m.ch.startsWith("launches:"): console.log(`new ${m.data.launchpad} token ${m.data.address} by ${m.data.creator}`); break; case m.ch.startsWith("graduations:"): console.log(`graduated ${m.data.token} → pool ${m.data.pool}`); break; case m.ch.startsWith("trades:"): console.log(`${m.data.type} $${m.data.value_usd} by ${m.data.trader}`); break; case m.ch.startsWith("price:"): console.log(`price $${m.data.usd}`); break; case m.ch === "error": console.error(m.data); break; } }; ws.onclose = () => { clearTimeout(idle); setTimeout(connect, backoff + Math.random() * 500); backoff = Math.min(backoff * 2, 30_000); }; ws.onerror = () => ws.close(); } connect(); ``` > **Note:** > The replay buffer holds 60 seconds of messages. After a longer outage, re-sync from REST (for example > [`/trades`](https://crius.sh/docs/reference/trades/#trade-tape) since your last `ts`) before relying on the stream again. ## Browser version Browsers can't set headers on WebSockets, so the key would have to go in the URL (`?api_key=`), where anyone can read it from your page. Connect from your backend instead and forward the events to your page (for example over Server-Sent Events). Keys restricted to browser origins are read-only and can't open the stream. --- # Tokens & prices > Token profiles, live USD prices, batch prices, sparse batch profiles and every market a token trades in on Robinhood Chain. Source: https://crius.sh/docs/reference/tokens/ Everything about one token, or many at once. The **token profile** is the richest call (metadata, socials, supply, launch, market, holders summary, liquidity locks, security summary, rolling stats). The **price** call is the smallest and fastest: use it in hot loops. For many tokens, use **batch prices** (up to 100 per call) or **batch profiles** with a field list. Prices are derived on-chain: token → its deepest pool's quote (ETH, WETH, USDG or another token) → USD through the deepest ETH/USDG pool. Tokenized stocks follow the same path, using on-chain pools only. `confidence` and `thin_liquidity` tell you how much to trust a price. | Endpoint | Method | Plan | Credits | |---|---|---|---| | [Token profile](#token-profile) | `GET /v1/{chain}/token/{address}` | Anonymous | 1 | | [Token price](#token-price) | `GET /v1/{chain}/token/{address}/price` | Anonymous | 1 | | [Batch prices](#batch-prices) | `GET /v1/{chain}/prices` | Anonymous | 1 | | [Batch prices (POST)](#batch-prices-post) | `POST /v1/{chain}/prices` | Anonymous | 1 | | [Batch token profiles](#batch-token-profiles) | `POST /v1/{chain}/tokens/batch` | Anonymous | 1 | | [Token markets](#token-markets) | `GET /v1/{chain}/token/{address}/pools` | Anonymous | 1 | ## Token profile **GET** `/v1/{chain}/token/{address}` **Plan:** Anonymous and above (no key needed) · **Cost:** 1 credit per call Full profile of any ERC-20 on the chain: name, symbol, decimals, supply (total, burned, locked, circulating), creation and launchpad lifecycle, metadata and socials (with their source), price with change per window and all-time high, market (market cap, FDV, liquidity), holder summary (count, top-10 share, dev holding), liquidity lock status, contract verification and rolling trade stats. Heavier sections link to their own endpoints (`security.see`, `bundles.see`) so the profile stays fast. > Identity, supply, metadata & socials, creation, verification, launch, price + change + ATH, market (FDV, market cap, liquidity), stats per window, holders summary, liquidity summary, dexscreener (dex paid, community takeover, boosts; confirmed against DexScreener orders). ### Parameters | Name | In | Type | Default | Description | |---|---|---|---|---| | `chain` | path, required | string | | Chain slug (`robinhood`) or chain id (`4663`). | | `address` | path, required | string | | Contract or wallet address, any case (`0x…`, 20 bytes). | ### Request **cURL** ```bash curl "https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8" \ -H "x-api-key: $CRIUS_API_KEY" ``` **JavaScript** ```js const res = await fetch("https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8", { headers: { "x-api-key": process.env.CRIUS_API_KEY }, }); const { data, meta } = await res.json(); ``` **Python** ```python import os, requests r = requests.get( "https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8", headers={"x-api-key": os.environ["CRIUS_API_KEY"]}, ) body = r.json() print(body["data"]) ``` [Try it in the playground →](https://crius.sh/docs/playground/?op=GET%20%2Fv1%2F%7Bchain%7D%2Ftoken%2F%7Baddress%7D) ### Key response fields - `price.usd`, `price.change_pct` (per window), `price.ath_usd`, `price.confidence` - `market.market_cap_usd`, `market.fdv_usd`, `market.liquidity_usd`, `market.quote_liquidity_usd`, `market.pools_count` - `holders.count`, `holders.top10_pct`, `holders.dev_pct`, `holders.burned_pct`, `holders.locked_pct` - `launch`: launchpad id and name, creator, curve, `status` (`bonding` / `graduated`), `progress_pct`, launch and graduation blocks - `liquidity`: lock status, lockers, next unlock time - `stats`: trades, buys, sells, traders, volume per window plus `all_time` - `metadata`: description, logo, socials, and where they came from ### Example response Real response captured from the API (arrays trimmed to three items). ```json { "data": { "address": "0x7b8892cea949bc60d494681d1bc3ea96071ab0b8", "admin_flags": null, "bundles": { "see": "/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/bundles" }, "burned": 29840058.774195638068253872, "chain_id": 4663, "circulating_supply": 970159941.225804361931746128, "creation": { "attribution": "known_launchpad", "block": 88385886, "deployed_via": "pons_v2", "deployer": "0x3ac82d45ff9e4963cefbc3f74dbe293f34c927ca", "factory": "0x7ed598bcef8bd9edd8c97a195c6d13f40801ec7e", "launchpad_name": "Pons", "tx": "0x4d9536e81ce418070e93b72f46f1d91afdd6a9ed34141b8e3773926b0d863747" }, "decimals": 18, "dexscreener": { "boosts": { "active_amount": null, "active_seen_ts": null, "count": 0, "last_ts": null, "total_amount": 0 }, "checked_ts": 1792712926595, "community_takeover": false, "community_takeover_ts": null, "confirmed": true, "dex_paid": true, "dex_paid_ts": 1791988981764, "orders": [ { "payment_ts": 1791988981764, "status": "approved", "type": "tokenProfile" } ], "profile": { "description": null, "header": null, "icon": null, "links": [] }, "url": "https://dexscreener.com/robinhood/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8" }, "first_seen_block": 88385886, "history": "complete", "holders": { "burned_pct": 2.98401, "count": 201, "dev_holding": false, "dev_pct": 0, "locked_pct": 8.16327, "top10_pct": 88.5277 }, "launch": { "creator": "0x3ac82d45ff9e4963cefbc3f74dbe293f34c927ca", "creator_label": null, "curve": "0x2b0943bf947b54df526047b6fec8183a4fdeb3c3", "curve_state": null, "graduated_block": 88461321, "graduation_threshold": 4.2, "launched_block": 88385886, "launchpad": "pons", "launchpad_name": "Pons", "pair_token": "0x0000000000000000000000000000000000000000", "progress_pct": 100, "raised": null, "status": "graduated" }, "liquidity": { "locked_pct": 100, "lockers": [ "pons_v2_launch_locker" ], "next_unlock_ts": null, "permanent": true, "status": "locked" }, "locked": 81632653.061224486519511236, "market": { "fdv_usd": 5764.13, "liquidity_usd": 6869.4, "market_cap_usd": 5592.13, "pools_count": 10, "quote_liquidity_usd": 3434.7 }, "metadata": { "description": "hf:charge-ai/charge-30b@9ff2ef1e98ea4d9745a70b33ea02b80dba26c582", "logo": "https://api.surplusllm.com/api/launchpad/logos/bb4315cb9506ef872830b1dab25ffdb6694df1b8b8e32cc2c8d083208f26baab.png", "socials": { "discord": null, "farcaster": null, "github": null, "telegram": null, "twitter": { "source": "pons_launch", "url": "https://x.com/chargeairh" }, "website": { "source": "pons_launch", "url": "https://chargeai.bid/" } }, "source": "pons_launch" }, "name": "Charge AI", "price": { "ath_market_cap_usd": 68295.9, "ath_scope": "all_time", "ath_ts": 1792055700000, "ath_usd": 0.0000703965, "change_pct": { "1h": -0.109425, "1m": -0.109425, "1s": -0.109425, "24h": -3.67324, "30s": -0.109425, "4h": -1.31288, "5m": -0.109425, "6h": -1.31288 }, "confidence": "medium", "dex": "uniswap_v4", "eth": 0.0000000024199, "liquidity_usd": 6861.07, "quote": "0x0000000000000000000000000000000000000000", "quote_liquidity_usd": 3430.53, "source_pool": "0x871b166182fd708d5d16a4daa9a42f05a653fa51ee2b195097f425e0d9ca4913", "thin_liquidity": false, "usd": 0.00000576413 }, "security": { "see": "/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/security" }, "standard": "erc20", "stats": { "all_time": { "buy_volume_usd": 142708, "buys": 2880, "first_trade_ts": 1791982835000, "sell_volume_usd": 136694, "sells": 2210, "since": "chain_start", "trades": 5090, "volume_usd": 279402 }, "avg_trade_usd": { "1h": null, "1m": null, "1s": null, "24h": 30.7463, "30s": null, "4h": 11.3632, "5m": null, "6h": 11.3632 }, "buy_volume_usd": { "1h": 0, "1m": 0, "1s": 0, "24h": 238.251, "30s": 0, "4h": 7.40995, "5m": 0, "6h": 7.40995 }, "buyers": { "1h": 0, "1m": 0, "1s": 0, "24h": 5, "30s": 0, "4h": 1, "5m": 0, "6h": 1 }, "buys": { "1h": 0, "1m": 0, "1s": 0, "24h": 9, "30s": 0, "4h": 1, "5m": 0, "6h": 1 }, "last_trade_ts": 1792705534000, "sell_volume_usd": { "1h": 0, "1m": 0, "1s": 0, "24h": 222.943, "30s": 0, "4h": 15.3164, "5m": 0, "6h": 15.3164 }, "sellers": { "1h": 0, "1m": 0, "1s": 0, "24h": 6, "30s": 0, "4h": 1, "5m": 0, "6h": 1 }, "sells": { "1h": 0, "1m": 0, "1s": 0, "24h": 6, "30s": 0, "4h": 1, "5m": 0, "6h": 1 }, "traders": { "1h": 0, "1m": 0, "1s": 0, "24h": 10, "30s": 0, "4h": 2, "5m": 0, "6h": 2 }, "trades": { "1h": 0, "1m": 0, "1s": 0, "24h": 15, "30s": 0, "4h": 2, "5m": 0, "6h": 2 }, "txns": { "1h": 0, "1m": 0, "1s": 0, "24h": 15, "30s": 0, "4h": 2, "5m": 0, "6h": 2 }, "volume_eth": { "1h": 0, "1m": 0, "1s": 0, "24h": 0.189336, "30s": 0, "4h": 0.00954709, "5m": 0, "6h": 0.00954709 }, "volume_usd": { "1h": 0, "1m": 0, "1s": 0, "24h": 461.194, "30s": 0, "4h": 22.7263, "5m": 0, "6h": 22.7263 } }, "symbol": "CHARGE", "total_supply": 1000000000, "type": "launchpad", "ui_multiplier": null, "verification": { "compiler": null, "contract_name": null, "implementation": null, "is_proxy": null, "sourcify": null } }, "meta": { "block": 95504341, "block_age_ms": 373, "block_ts": 1792712990000, "chain": "robinhood", "finalized_block": 95493649, "lag_ms": 97, "pending": [], "safe_block": 95497061 } } ``` ## Token price **GET** `/v1/{chain}/token/{address}/price` **Plan:** Anonymous and above (no key needed) · **Cost:** 1 credit per call The fastest call: USD and ETH price, the pool it came from, that pool's liquidity and a confidence level. Ideal for bots, widgets and portfolio valuation. > Deepest pool against ETH / WETH / USDG (real reserves), ETH/USD from the deepest ETH/USDG pool. ### Parameters | Name | In | Type | Default | Description | |---|---|---|---|---| | `chain` | path, required | string | | Chain slug (`robinhood`) or chain id (`4663`). | | `address` | path, required | string | | Contract or wallet address, any case (`0x…`, 20 bytes). | ### Request **cURL** ```bash curl "https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/price" \ -H "x-api-key: $CRIUS_API_KEY" ``` **JavaScript** ```js const res = await fetch("https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/price", { headers: { "x-api-key": process.env.CRIUS_API_KEY }, }); const { data, meta } = await res.json(); ``` **Python** ```python import os, requests r = requests.get( "https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/price", headers={"x-api-key": os.environ["CRIUS_API_KEY"]}, ) body = r.json() print(body["data"]) ``` [Try it in the playground →](https://crius.sh/docs/playground/?op=GET%20%2Fv1%2F%7Bchain%7D%2Ftoken%2F%7Baddress%7D%2Fprice) ### Key response fields - `usd`, `eth`: price per whole token - `source_pool`, `dex`, `quote`: where the price comes from - `liquidity_usd` (2 × the quote side, DEX-screener convention) and `quote_liquidity_usd` (the real quote side) - `confidence` (`high` / `medium` / `low`) and `thin_liquidity` ### Example response Real response captured from the API (arrays trimmed to three items). ```json { "data": { "confidence": "medium", "dex": "uniswap_v4", "eth": 0.0000000024199, "eth_usd": 2381.97, "liquidity_usd": 6861.07, "quote": "0x0000000000000000000000000000000000000000", "quote_liquidity_usd": 3430.53, "source_pool": "0x871b166182fd708d5d16a4daa9a42f05a653fa51ee2b195097f425e0d9ca4913", "symbol": "CHARGE", "thin_liquidity": false, "token": "0x7b8892cea949bc60d494681d1bc3ea96071ab0b8", "usd": 0.00000576413 }, "meta": { "block": 95504348, "block_age_ms": 1075, "block_ts": 1792712990000, "chain": "robinhood", "finalized_block": 95493649, "lag_ms": 114, "safe_block": 95497061 } } ``` ## Batch prices **GET** `/v1/{chain}/prices` **Plan:** Anonymous and above (no key needed) · **Cost:** 1 credit per call Prices for up to **100 tokens** in one call. Pass a comma-separated list in `tokens`. Unknown addresses are listed in `meta.missing` instead of failing the request. > Also POST with {"tokens": [...]}. ### Parameters | Name | In | Type | Default | Description | |---|---|---|---|---| | `chain` | path, required | string | | Chain slug (`robinhood`) or chain id (`4663`). | | `tokens` | query | string | `0x8ac48210be19378229f12060d499c3b0eae5e14e,0x7b8892cea949bc60d494681d1bc3ea96071ab0b8` | Comma-separated token addresses (up to 100). | ### Request **cURL** ```bash curl "https://api.crius.sh/v1/robinhood/prices?tokens=0x7b8892cea949bc60d494681d1bc3ea96071ab0b8%2C0x0bd7d308f8e1639fab988df18a8011f41eacad73" \ -H "x-api-key: $CRIUS_API_KEY" ``` **JavaScript** ```js const res = await fetch("https://api.crius.sh/v1/robinhood/prices?tokens=0x7b8892cea949bc60d494681d1bc3ea96071ab0b8%2C0x0bd7d308f8e1639fab988df18a8011f41eacad73", { headers: { "x-api-key": process.env.CRIUS_API_KEY }, }); const { data, meta } = await res.json(); ``` **Python** ```python import os, requests r = requests.get( "https://api.crius.sh/v1/robinhood/prices?tokens=0x7b8892cea949bc60d494681d1bc3ea96071ab0b8%2C0x0bd7d308f8e1639fab988df18a8011f41eacad73", headers={"x-api-key": os.environ["CRIUS_API_KEY"]}, ) body = r.json() print(body["data"]) ``` [Try it in the playground →](https://crius.sh/docs/playground/?op=GET%20%2Fv1%2F%7Bchain%7D%2Fprices) ### Example response Real response captured from the API (arrays trimmed to three items). ```json { "data": { "0x0bd7d308f8e1639fab988df18a8011f41eacad73": { "change_24h_pct": -3.51169, "confidence": "high", "eth": 1, "liquidity_usd": 6101152, "source_pool": "0xbac3aa3b91584a53a579b3c999a56756e954e59247e497bad1d25a4334bde551", "symbol": "WETH", "usd": 2381.97 }, "0x7b8892cea949bc60d494681d1bc3ea96071ab0b8": { "change_24h_pct": -3.67324, "confidence": "medium", "eth": 0.0000000024199, "liquidity_usd": 6861.07, "source_pool": "0x871b166182fd708d5d16a4daa9a42f05a653fa51ee2b195097f425e0d9ca4913", "symbol": "CHARGE", "usd": 0.00000576413 } }, "meta": { "block": 95504355, "block_age_ms": 777, "block_ts": 1792712991000, "chain": "robinhood", "finalized_block": 95493649, "lag_ms": 5, "missing": [], "safe_block": 95497061 } } ``` ## Batch prices (POST) **POST** `/v1/{chain}/prices` **Plan:** Anonymous and above (no key needed) · **Cost:** 1 credit per call Same as the GET form, with the list in a JSON body. Use it when the list would make the URL too long. ### Parameters | Name | In | Type | Default | Description | |---|---|---|---|---| | `chain` | path, required | string | | Chain slug (`robinhood`) or chain id (`4663`). | ### Body ```json { "tokens": [ "0x7b8892cea949bc60d494681d1bc3ea96071ab0b8", "0x0bd7d308f8e1639fab988df18a8011f41eacad73" ] } ``` ### Request **cURL** ```bash curl -X POST "https://api.crius.sh/v1/robinhood/prices" \ -H "x-api-key: $CRIUS_API_KEY" \ -H "content-type: application/json" \ -d '{"tokens":["0x7b8892cea949bc60d494681d1bc3ea96071ab0b8","0x0bd7d308f8e1639fab988df18a8011f41eacad73"]}' ``` **JavaScript** ```js const res = await fetch("https://api.crius.sh/v1/robinhood/prices", { method: "POST", headers: { "x-api-key": process.env.CRIUS_API_KEY, "content-type": "application/json", }, body: JSON.stringify({ "tokens": [ "0x7b8892cea949bc60d494681d1bc3ea96071ab0b8", "0x0bd7d308f8e1639fab988df18a8011f41eacad73" ] }), }); const { data, meta } = await res.json(); ``` **Python** ```python import os, requests r = requests.post( "https://api.crius.sh/v1/robinhood/prices", headers={"x-api-key": os.environ["CRIUS_API_KEY"]}, json={"tokens":["0x7b8892cea949bc60d494681d1bc3ea96071ab0b8","0x0bd7d308f8e1639fab988df18a8011f41eacad73"]}, ) body = r.json() print(body["data"]) ``` [Try it in the playground →](https://crius.sh/docs/playground/?op=POST%20%2Fv1%2F%7Bchain%7D%2Fprices) ### Example response Real response captured from the API (arrays trimmed to three items). ```json { "data": { "0x0bd7d308f8e1639fab988df18a8011f41eacad73": { "change_24h_pct": -3.50483, "confidence": "high", "eth": 1, "liquidity_usd": 6101152, "source_pool": "0xbac3aa3b91584a53a579b3c999a56756e954e59247e497bad1d25a4334bde551", "symbol": "WETH", "usd": 2381.97 }, "0x7b8892cea949bc60d494681d1bc3ea96071ab0b8": { "change_24h_pct": -3.67324, "confidence": "medium", "eth": 0.0000000024199, "liquidity_usd": 6861.07, "source_pool": "0x871b166182fd708d5d16a4daa9a42f05a653fa51ee2b195097f425e0d9ca4913", "symbol": "CHARGE", "usd": 0.00000576413 } }, "meta": { "block": 95504362, "block_age_ms": 481, "block_ts": 1792712992000, "chain": "robinhood", "finalized_block": 95493649, "lag_ms": 15, "missing": [], "safe_block": 95497061 } } ``` ## Batch token profiles **POST** `/v1/{chain}/tokens/batch` **Plan:** Anonymous and above (no key needed) · **Cost:** 1 credit per call Token profiles for up to **100 tokens**, trimmed to the fields you ask for. `fields` takes dot paths into the profile above (`price.usd`, `market.market_cap_usd`, `holders.count`…); an empty list returns full profiles. > fields: dotted paths of the token profile. ### Parameters | Name | In | Type | Default | Description | |---|---|---|---|---| | `chain` | path, required | string | | Chain slug (`robinhood`) or chain id (`4663`). | ### Body ```json { "tokens": [ "0x7b8892cea949bc60d494681d1bc3ea96071ab0b8", "0x0bd7d308f8e1639fab988df18a8011f41eacad73" ], "fields": [ "symbol", "price.usd", "price.change_pct.24h", "market.market_cap_usd", "market.liquidity_usd" ] } ``` ### Request **cURL** ```bash curl -X POST "https://api.crius.sh/v1/robinhood/tokens/batch" \ -H "x-api-key: $CRIUS_API_KEY" \ -H "content-type: application/json" \ -d '{"tokens":["0x7b8892cea949bc60d494681d1bc3ea96071ab0b8","0x0bd7d308f8e1639fab988df18a8011f41eacad73"],"fields":["symbol","price.usd","price.change_pct.24h","market.market_cap_usd","market.liquidity_usd"]}' ``` **JavaScript** ```js const res = await fetch("https://api.crius.sh/v1/robinhood/tokens/batch", { method: "POST", headers: { "x-api-key": process.env.CRIUS_API_KEY, "content-type": "application/json", }, body: JSON.stringify({ "tokens": [ "0x7b8892cea949bc60d494681d1bc3ea96071ab0b8", "0x0bd7d308f8e1639fab988df18a8011f41eacad73" ], "fields": [ "symbol", "price.usd", "price.change_pct.24h", "market.market_cap_usd", "market.liquidity_usd" ] }), }); const { data, meta } = await res.json(); ``` **Python** ```python import os, requests r = requests.post( "https://api.crius.sh/v1/robinhood/tokens/batch", headers={"x-api-key": os.environ["CRIUS_API_KEY"]}, json={"tokens":["0x7b8892cea949bc60d494681d1bc3ea96071ab0b8","0x0bd7d308f8e1639fab988df18a8011f41eacad73"],"fields":["symbol","price.usd","price.change_pct.24h","market.market_cap_usd","market.liquidity_usd"]}, ) body = r.json() print(body["data"]) ``` [Try it in the playground →](https://crius.sh/docs/playground/?op=POST%20%2Fv1%2F%7Bchain%7D%2Ftokens%2Fbatch) ### Example response Real response captured from the API (arrays trimmed to three items). ```json { "data": { "0x0bd7d308f8e1639fab988df18a8011f41eacad73": { "market": { "liquidity_usd": 71541592, "market_cap_usd": 98288648 }, "price": { "change_pct": { "24h": -3.50483 }, "usd": 2381.97 }, "symbol": "WETH" }, "0x7b8892cea949bc60d494681d1bc3ea96071ab0b8": { "market": { "liquidity_usd": 6869.4, "market_cap_usd": 5592.13 }, "price": { "change_pct": { "24h": -3.67324 }, "usd": 0.00000576413 }, "symbol": "CHARGE" } }, "meta": { "block": 95504430, "block_age_ms": 406, "block_ts": 1792712999000, "chain": "robinhood", "finalized_block": 95493649, "lag_ms": 178, "missing": [], "safe_block": 95497061 } } ``` ## Token markets **GET** `/v1/{chain}/token/{address}/pools` **Plan:** Anonymous and above (no key needed) · **Cost:** 1 credit per call Every market the token trades in: Uniswap v2 pairs, v3 pools (all fee tiers), v4 pools (with their hook) and launchpad bonding curves, with liquidity and 24h activity. Paginate with `cursor`. > Uniswap V2/V3/V4, Pons and launchpad curves, ranked by USD liquidity (2 x quote side, from each pool's own state). is_price_pool marks the market the token price comes from. meta.total = all pools. ### Parameters | Name | In | Type | Default | Description | |---|---|---|---|---| | `chain` | path, required | string | | Chain slug (`robinhood`) or chain id (`4663`). | | `address` | path, required | string | | Contract or wallet address, any case (`0x…`, 20 bytes). | | `limit` | query | integer | `50` | Maximum number of items to return. Up to 200. | | `cursor` | query | string | | Pagination cursor from the previous response's `meta.next_cursor`. | ### Request **cURL** ```bash curl "https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/pools?limit=3" \ -H "x-api-key: $CRIUS_API_KEY" ``` **JavaScript** ```js const res = await fetch("https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/pools?limit=3", { headers: { "x-api-key": process.env.CRIUS_API_KEY }, }); const { data, meta } = await res.json(); ``` **Python** ```python import os, requests r = requests.get( "https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/pools?limit=3", headers={"x-api-key": os.environ["CRIUS_API_KEY"]}, ) body = r.json() print(body["data"]) ``` [Try it in the playground →](https://crius.sh/docs/playground/?op=GET%20%2Fv1%2F%7Bchain%7D%2Ftoken%2F%7Baddress%7D%2Fpools) ### Example response Real response captured from the API (arrays trimmed to three items). ```json { "data": [ { "amounts": { "token0": 1.44021, "token1": 595151991 }, "base": { "address": "0x7b8892cea949bc60d494681d1bc3ea96071ab0b8", "symbol": "CHARGE" }, "created_block": 88461321, "dex": "uniswap_v4", "dynamic_fee": false, "fee": 0, "hook": { "address": "0xe5e702641ea86f4ae6cc3cdaed2b886f976be044", "name": "pons_v2_meme_hook" }, "is_price_pool": true, "liquidity_usd": 6861.07, "pool": "0x871b166182fd708d5d16a4daa9a42f05a653fa51ee2b195097f425e0d9ca4913", "price_usd": 0.00000576413, "quote": { "address": "0x0000000000000000000000000000000000000000", "symbol": "ETH" }, "quote_liquidity_usd": 3430.53, "state": { "liquidity": 29277002188455996438188, "reserve0": 0, "reserve1": 0, "sqrt_price_x96": 1610574686881614931072228111579696, "tick": 198405 }, "swaps_indexed": 383, "tick_spacing": 200 }, { "amounts": { "token0": 3.66104, "token1": 98899.9 }, "base": { "address": "0x7b8892cea949bc60d494681d1bc3ea96071ab0b8", "symbol": "CHARGE" }, "created_block": 88461495, "dex": "uniswap_v4", "dynamic_fee": false, "fee": 850000, "hook": null, "is_price_pool": false, "liquidity_usd": 7.32208, "pool": "0xe928234e515b0c000dd6aa1c60cf5a009082367cda4775a5b63b4ff0c83dcdd3", "price_usd": 0.0000370176, "quote": { "address": "0x5fc5360d0400a0fd4f2af552add042d716f1d168", "symbol": "USDG" }, "quote_liquidity_usd": 3.66104, "state": { "liquidity": 601728037770030, "reserve0": 0, "reserve1": 0, "sqrt_price_x96": 13021930043213842984890107533469941760, "tick": 378370 }, "swaps_indexed": 0, "tick_spacing": 60 }, { "amounts": { "token0": 0.365039, "token1": 32233.4 }, "base": { "address": "0x7b8892cea949bc60d494681d1bc3ea96071ab0b8", "symbol": "CHARGE" }, "created_block": 88466617, "dex": "uniswap_v4", "dynamic_fee": false, "fee": 450000, "hook": null, "is_price_pool": false, "liquidity_usd": 0.730077, "pool": "0x1a184f0aa1978e7b543ee944a30df88dd34fcb667aa5a9142bb399ef582481b8", "price_usd": 0.0000113249, "quote": { "address": "0x5fc5360d0400a0fd4f2af552add042d716f1d168", "symbol": "USDG" }, "quote_liquidity_usd": 0.365039, "state": { "liquidity": 108473206521826, "reserve0": 0, "reserve1": 0, "sqrt_price_x96": 23543071597340630825735724748883305548, "tick": 390214 }, "swaps_indexed": 3, "tick_spacing": 4500 } ], "meta": { "block": 95504370, "block_age_ms": 1196, "block_ts": 1792712992000, "chain": "robinhood", "finalized_block": 95493649, "lag_ms": 0, "next_cursor": "3", "safe_block": 95497061, "total": 10 } } ``` --- # Trades & candles > Trade tape with real-trader attribution, OHLCV candles from 1 second to 1 day, and a unified activity feed for any Robinhood Chain token. Source: https://crius.sh/docs/reference/trades/ The trade tape, candles and the full activity feed of a token. **Who actually traded.** On-chain, `tx.from` and the swap's sender are often infrastructure: routers, aggregators, Relay solvers, ERC-4337 bundlers, launchpad helpers, bot contracts. Every trade is attributed to the address whose balance actually changed (the **trader**), and the infrastructure that sent it is reported separately as `executor` and `signer`. One transaction can contain several trades. | Endpoint | Method | Plan | Credits | |---|---|---|---| | [Trade tape](#trade-tape) | `GET /v1/{chain}/token/{address}/trades` | Anonymous | 2 | | [OHLCV candles](#ohlcv-candles) | `GET /v1/{chain}/token/{address}/candles` | Anonymous | 2 | | [Activity feed](#activity-feed) | `GET /v1/{chain}/token/{address}/transactions` | Free | 2 | ## Trade tape **GET** `/v1/{chain}/token/{address}/trades` **Plan:** Anonymous and above (no key needed) · **Cost:** 2 credits per call Newest first. Each trade carries side, amounts in human units, USD and ETH value, the price, pool and DEX, the attributed trader, gas and token tax, and its `finality` (`latest` → `safe` → `finalized`). Filter by `side`, `trader`, `min_usd` and a time range; paginate with `cursor`. > Real trader attribution, USD at trade time, realized tax, gas (L2 + L1). ### Parameters | Name | In | Type | Default | Description | |---|---|---|---|---| | `chain` | path, required | string | | Chain slug (`robinhood`) or chain id (`4663`). | | `address` | path, required | string | | Contract or wallet address, any case (`0x…`, 20 bytes). | | `limit` | query | integer | `50` | Maximum number of items to return. Up to 500. | | `cursor` | query | string | | Pagination cursor from the previous response's `meta.next_cursor`. | | `side` | query | string | | `buy` or `sell`. | | `trader` | query | string | | Only trades by this trader address. | | `min_usd` | query | number | | Only items worth at least this many USD. | | `from_ts` | query | integer | | Start of the time range, unix milliseconds (inclusive). | | `to_ts` | query | integer | | End of the time range, unix milliseconds (inclusive). | ### Request **cURL** ```bash curl "https://api.crius.sh/v1/robinhood/token/0x0bd7d308f8e1639fab988df18a8011f41eacad73/trades?limit=3" \ -H "x-api-key: $CRIUS_API_KEY" ``` **JavaScript** ```js const res = await fetch("https://api.crius.sh/v1/robinhood/token/0x0bd7d308f8e1639fab988df18a8011f41eacad73/trades?limit=3", { headers: { "x-api-key": process.env.CRIUS_API_KEY }, }); const { data, meta } = await res.json(); ``` **Python** ```python import os, requests r = requests.get( "https://api.crius.sh/v1/robinhood/token/0x0bd7d308f8e1639fab988df18a8011f41eacad73/trades?limit=3", headers={"x-api-key": os.environ["CRIUS_API_KEY"]}, ) body = r.json() print(body["data"]) ``` [Try it in the playground →](https://crius.sh/docs/playground/?op=GET%20%2Fv1%2F%7Bchain%7D%2Ftoken%2F%7Baddress%7D%2Ftrades) ### Example response Real response captured from the API (arrays trimmed to three items). ```json { "data": [ { "amount_base": 0.0007766108202848, "amount_quote": 1.851107, "block": 95504366, "dex": "uniswap_v3", "eth_usd_at_trade": 2383.18, "executor": null, "fees": { "gas": { "gas_price_gwei": 0.02021, "gas_used": 325451, "gas_used_l1": 0, "l1_eth": 0, "l2_eth": 0.00000657736, "total_eth": 0.00000657736, "usd": 0.0156671 }, "token_tax": { "pct": null } }, "finality": "latest", "id": "95504366-2-6", "market_cap_usd_at_trade": 98354693, "pool": "0x52e65b17fb6e5ba00ed806f37afcd2daa50271ca", "price_eth": 1.00016, "price_usd": 2383.57, "quote": "0x5fc5360d0400a0fd4f2af552add042d716f1d168", "quote_symbol": "USDG", "signer": "0xafa54e6945803ec0025bb5adf7dea1e50c32bb41", "trader": "0xafa54e6945803ec0025bb5adf7dea1e50c32bb41", "ts": 1792712992000, "tx": "0x413b63acc6148916f503f8ec69cf084dd245a3306c35f813256b4236f0f46fd8", "tx_index": 2, "type": "buy", "value_eth": 0.000776738, "value_usd": 1.85111, "via": [] }, { "amount_base": 0.004912218011682397, "amount_quote": 11.706273, "block": 95504363, "dex": "uniswap_v3", "eth_usd_at_trade": 2383.18, "executor": null, "fees": { "gas": { "gas_price_gwei": 0.02004, "gas_used": 545154, "gas_used_l1": 0, "l1_eth": 0, "l2_eth": 0.0000109249, "total_eth": 0.0000109249, "usd": 0.0260228 }, "token_tax": { "pct": null } }, "finality": "latest", "id": "95504363-24-9", "market_cap_usd_at_trade": 98334976, "pool": "0x52e65b17fb6e5ba00ed806f37afcd2daa50271ca", "price_eth": 0.999964, "price_usd": 2383.09, "quote": "0x5fc5360d0400a0fd4f2af552add042d716f1d168", "quote_symbol": "USDG", "signer": "0xa635592405b43dd06c8e801e61310ba64287856a", "trader": "0xa635592405b43dd06c8e801e61310ba64287856a", "ts": 1792712992000, "tx": "0x7125a0df6c354f157facaa6b0133caca6a15b37eccd28050a6fd431efb06d290", "tx_index": 24, "type": "sell", "value_eth": 0.00491204, "value_usd": 11.7063, "via": [ "okx_dex_router" ] }, { "amount_base": 0.015072639336010453, "amount_quote": 35.926685, "block": 95504354, "dex": "uniswap_v3", "eth_usd_at_trade": 2383.18, "executor": null, "fees": { "gas": { "gas_price_gwei": 0.02007, "gas_used": 425441, "gas_used_l1": 0, "l1_eth": 0, "l2_eth": 0.0000085386, "total_eth": 0.0000085386, "usd": 0.0203387 }, "token_tax": { "pct": null } }, "finality": "latest", "id": "95504354-24-11", "market_cap_usd_at_trade": 98354637, "pool": "0x52e65b17fb6e5ba00ed806f37afcd2daa50271ca", "price_eth": 1.00016, "price_usd": 2383.57, "quote": "0x5fc5360d0400a0fd4f2af552add042d716f1d168", "quote_symbol": "USDG", "signer": "0x97c18ecd26897974a003fce7dbb18306da4fcb54", "trader": "0x97c18ecd26897974a003fce7dbb18306da4fcb54", "ts": 1792712991000, "tx": "0xc6a0696a05853a04dee75c0abd0ff42cacbf440949e67245fd0f302b2dc2eef9", "tx_index": 24, "type": "buy", "value_eth": 0.0150751, "value_usd": 35.9267, "via": [] } ], "meta": { "block": 95504399, "block_age_ms": 1155, "block_ts": 1792712995000, "chain": "robinhood", "finalized_block": 95493649, "lag_ms": 7, "next_cursor": "95504354-11", "safe_block": 95497061 } } ``` ## OHLCV candles **GET** `/v1/{chain}/token/{address}/candles` **Plan:** Anonymous and above (no key needed) · **Cost:** 2 credits per call Candles in **columnar** form (one array per field, aligned by index), which is compact and maps straight onto charting libraries. Intervals: `1s`, `30s`, `1m`, `5m`, `15m`, `1h`, `4h`, `6h`, `1d`. Up to 1,500 candles per call; buckets without trades are omitted. By default (USD) candles merge the token's real markets: every pool with at least $1k or 2% of its liquidity, plus its launch curve for launchpad tokens. Thin side pools stay out, so a $1 trade there can't draw a wick. `pool=main` charts the main market only (the default with `currency=quote`, prices in the pool's quote token), `pool=` one pool, `pool=all` every pool. Each candle opens at the previous close (`continuous=false` for first-trade opens), and `fill=true` adds flat candles for buckets without trades so the time axis is evenly spaced. Dust trades (under 10,000 raw units on either side) never set a price. See the [chart example](https://crius.sh/docs/examples/chart/) for a complete TradingView Lightweight Charts integration. > Default (usd): the token's real markets merged (pools with >= $1k or >= 2% of its liquidity) plus its launch curve; ?pool=main its main market only; ?pool=all every pool. Candles open at the previous close. ### Parameters | Name | In | Type | Default | Description | |---|---|---|---|---| | `chain` | path, required | string | | Chain slug (`robinhood`) or chain id (`4663`). | | `address` | path, required | string | | Contract or wallet address, any case (`0x…`, 20 bytes). | | `interval` | query | string | `1m` | Bucket size. One of `1s`, `30s`, `1m`, `5m`, `15m`, `1h`, `4h`, `6h`, `1d`. | | `limit` | query | integer | `500` | Maximum number of items to return. | | `from_ts` | query | integer | | Start of the time range, unix milliseconds (inclusive). | | `to_ts` | query | integer | | End of the time range, unix milliseconds (inclusive). | | `currency` | query | string | `usd` | Price unit. One of `usd`, `quote`. | | `pool` | query | string | | Pool address (Uniswap v2/v3) or 32-byte pool id (Uniswap v4). Markets (default for usd) \| main (default for quote) \| all \| a pool id. | | `continuous` | query | boolean | `true` | `true`: the holder must stay above the threshold for the whole window. Open = previous close. | | `fill` | query | boolean | `false` | Flat candles for buckets without trades. | ### Request **cURL** ```bash curl "https://api.crius.sh/v1/robinhood/token/0x0bd7d308f8e1639fab988df18a8011f41eacad73/candles?interval=1h&limit=3" \ -H "x-api-key: $CRIUS_API_KEY" ``` **JavaScript** ```js const res = await fetch("https://api.crius.sh/v1/robinhood/token/0x0bd7d308f8e1639fab988df18a8011f41eacad73/candles?interval=1h&limit=3", { headers: { "x-api-key": process.env.CRIUS_API_KEY }, }); const { data, meta } = await res.json(); ``` **Python** ```python import os, requests r = requests.get( "https://api.crius.sh/v1/robinhood/token/0x0bd7d308f8e1639fab988df18a8011f41eacad73/candles?interval=1h&limit=3", headers={"x-api-key": os.environ["CRIUS_API_KEY"]}, ) body = r.json() print(body["data"]) ``` [Try it in the playground →](https://crius.sh/docs/playground/?op=GET%20%2Fv1%2F%7Bchain%7D%2Ftoken%2F%7Baddress%7D%2Fcandles) ### Key response fields - `t`: bucket start (unix ms) · `o` `h` `l` `c`: open, high, low, close - `v`: USD volume · `bv`: buy volume (sell volume = `v − bv`) · `n`: number of trades · `mc`: market cap at close ### Example response Real response captured from the API (arrays trimmed to three items). ```json { "data": { "bv": [ 2691794, 1743314, 1039396 ], "c": [ 2390.77, 2382.33, 2383.09 ], "currency": "usd", "h": [ 2473.01, 2395.33, 2457.6 ], "interval": "1h", "l": [ 1416.96, 2176.09, 2377.71 ], "mc": [ 98652729, 98304422, 98335812 ], "n": [ 5776, 4388, 2734 ], "o": [ 2379.84, 2390.81, 2381.85 ], "t": [ 1792702800000, 1792706400000, 1792710000000 ], "v": [ 5065109, 3747088, 2040556 ] }, "meta": { "block": 95504408, "block_age_ms": 994, "block_ts": 1792712996000, "chain": "robinhood", "finalized_block": 95493649, "from_ts": 1792702800000, "lag_ms": 2, "note": "buckets without trades are omitted; default = the token's main market (its pricing pool) plus its launch curve for launchpad tokens; ?pool=markets merges its real markets, ?pool= one pool, ?pool=all every pool", "pools": [ "0x52e65b17fb6e5ba00ed806f37afcd2daa50271ca" ], "safe_block": 95497061, "to_ts": 1792712996000 } } ``` ## Activity feed **GET** `/v1/{chain}/token/{address}/transactions` **Plan:** Free and above · **Cost:** 2 credits per call One chronological feed of everything that happened to the token: buys and sells, liquidity adds and removes, plain transfers, mints and burns, LP lock events, fee claims, owner actions on the contract (`renounceOwnership`, `openTrading`, setters, upgrades) and launchpad lifecycle events. Filter with `type` (comma list), `wallet`, `min_usd`, `from`/`to` and `finality`. > Trades, liquidity adds/removes, transfers, mints/burns, owner actions (decoded), locks, fee claims, launch / graduation. ### Parameters | Name | In | Type | Default | Description | |---|---|---|---|---| | `chain` | path, required | string | | Chain slug (`robinhood`) or chain id (`4663`). | | `address` | path, required | string | | Contract or wallet address, any case (`0x…`, 20 bytes). | | `type` | query | string | | Filter by item type. Comma list of `buy`, `sell`, `add_liquidity`, `remove_liquidity`, `transfer`, `mint`, `burn`, `owner_action`, `lock`, `fee_claim`, `launch`, `graduation`. | | `wallet` | query | string | | Only events involving this wallet. | | `min_usd` | query | number | | Only items worth at least this many USD. | | `from` | query | string | | Start of the window (`block:`, `ts:`, `mcap:` or a label). One of `block:N`, `ts:MS`, `mcap:USD`, `launch`, `trading_open`, `graduation`, `ath`. | | `to` | query | string | | End of the window (same forms as `from`). | | `finality` | query | string | | Only rows at or below this finality level. One of `latest`, `safe`, `finalized`. | | `limit` | query | integer | `50` | Maximum number of items to return. | | `cursor` | query | string | | Pagination cursor from the previous response's `meta.next_cursor`. | ### Request **cURL** ```bash curl "https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/transactions?limit=20" \ -H "x-api-key: $CRIUS_API_KEY" ``` **JavaScript** ```js const res = await fetch("https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/transactions?limit=20", { headers: { "x-api-key": process.env.CRIUS_API_KEY }, }); const { data, meta } = await res.json(); ``` **Python** ```python import os, requests r = requests.get( "https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/transactions?limit=20", headers={"x-api-key": os.environ["CRIUS_API_KEY"]}, ) body = r.json() print(body["data"]) ``` --- # Holders & traders > Live holder lists, holder snapshots at any past block, time or market cap, diamond-hand cohorts, holder count history and top traders with PnL. Source: https://crius.sh/docs/reference/holders/ Holder data for every ERC-20 on the chain, live and historical. Points in time (`at`, `from`, `to`) accept several forms: | Form | Meaning | |---|---| | `block:95000000` | an exact L2 block | | `ts:1792000000000` | the last block at or before that time (unix ms) | | `mcap:50000` | the block where market cap first crossed $50k (`mcap_crossing=first\|last\|ath`) | | `launch`, `graduation`, `ath`, `now` | lifecycle labels | | Endpoint | Method | Plan | Credits | |---|---|---|---| | [Live holders](#live-holders) | `GET /v1/{chain}/token/{address}/holders` | Free | 2 | | [Holder snapshot](#holder-snapshot) | `GET /v1/{chain}/token/{address}/holders/snapshot` | Free | 5 | | [Holder cohort](#holder-cohort) | `GET /v1/{chain}/token/{address}/holders/cohort` | Starter | 10 | | [Holder count history](#holder-count-history) | `GET /v1/{chain}/token/{address}/holders/history` | Starter | 10 | | [Top traders](#top-traders) | `GET /v1/{chain}/token/{address}/traders` | Free | 5 | ## Live holders **GET** `/v1/{chain}/token/{address}/holders` **Plan:** Free and above · **Cost:** 2 credits per call The current holder list, ranked by balance, with each holder's share of supply, USD value and labels (pools, lockers, burn addresses, the dev). Also returns the holder count and top-10 concentration. ### Parameters | Name | In | Type | Default | Description | |---|---|---|---|---| | `chain` | path, required | string | | Chain slug (`robinhood`) or chain id (`4663`). | | `address` | path, required | string | | Contract or wallet address, any case (`0x…`, 20 bytes). | | `limit` | query | integer | `100` | Maximum number of items to return. Up to 500. | ### Request **cURL** ```bash curl "https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/holders?limit=20" \ -H "x-api-key: $CRIUS_API_KEY" ``` **JavaScript** ```js const res = await fetch("https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/holders?limit=20", { headers: { "x-api-key": process.env.CRIUS_API_KEY }, }); const { data, meta } = await res.json(); ``` **Python** ```python import os, requests r = requests.get( "https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/holders?limit=20", headers={"x-api-key": os.environ["CRIUS_API_KEY"]}, ) body = r.json() print(body["data"]) ``` ### Key response fields - `count`, `top10_pct` - `holders[]`: `rank`, `address`, `balance`, `pct`, `value_usd`, `value_eth`, `label` ## Holder snapshot **GET** `/v1/{chain}/token/{address}/holders/snapshot` **Plan:** Free and above · **Cost:** 5 credits per call Holders **as they were at a past point**, valued at that moment's price. `compare_to=now` adds each holder's balance change since then, which answers "who bought before $50k market cap, and are they still holding?". > Valued at that moment's price; compare_to=now adds change per holder. ### Parameters | Name | In | Type | Default | Description | |---|---|---|---|---| | `chain` | path, required | string | | Chain slug (`robinhood`) or chain id (`4663`). | | `address` | path, required | string | | Contract or wallet address, any case (`0x…`, 20 bytes). | | `at` | query | string | `trading_open` | The point in time to look at (see the forms above). One of `block:N`, `ts:MS`, `mcap:USD`, `launch`, `trading_open`, `graduation`, `ath`, `now`. | | `mcap_crossing` | query | string | `first` | Which crossing of the market cap level to use. One of `first`, `last`. | | `compare_to` | query | string | `now` | Add each holder's change since another point (`now` or any `at` form). | | `exclude` | query | string | | Comma list of holder classes to leave out, such as `infra` (pools, lockers, burn) or `bots`. | | `min_usd` | query | number | | Only items worth at least this many USD. | | `min_pct` | query | number | | Minimum share of supply, in percent. | | `tag` | query | string | | Only wallets with this tag (`sniper`, `bot`, `whale`, `fresh`, `dev`, `insider`, `bundler`, `top_trader`). | | `limit` | query | integer | `100` | Maximum number of items to return. | | `cursor` | query | string | | Pagination cursor from the previous response's `meta.next_cursor`. | ### Request **cURL** ```bash curl "https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/holders/snapshot?at=mcap%3A50000&compare_to=now&exclude=infra" \ -H "x-api-key: $CRIUS_API_KEY" ``` **JavaScript** ```js const res = await fetch("https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/holders/snapshot?at=mcap%3A50000&compare_to=now&exclude=infra", { headers: { "x-api-key": process.env.CRIUS_API_KEY }, }); const { data, meta } = await res.json(); ``` **Python** ```python import os, requests r = requests.get( "https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/holders/snapshot?at=mcap%3A50000&compare_to=now&exclude=infra", headers={"x-api-key": os.environ["CRIUS_API_KEY"]}, ) body = r.json() print(body["data"]) ``` ## Holder cohort **GET** `/v1/{chain}/token/{address}/holders/cohort` **Plan:** Starter and above · **Cost:** 10 credits per call Wallets that held through a window. A holder qualifies when it stayed above a size threshold (`min_usd`, `min_balance` or `min_pct`); with `continuous=true` it must hold for the whole window, and `reset_on` decides what breaks continuity (`sell` by default). `entered_before=mcap:20000` keeps only wallets that first qualified before that point. Sort by hold time, balance, entry market cap or PnL. > Continuity with reset on sell / decrease / below threshold. ### Parameters | Name | In | Type | Default | Description | |---|---|---|---|---| | `chain` | path, required | string | | Chain slug (`robinhood`) or chain id (`4663`). | | `address` | path, required | string | | Contract or wallet address, any case (`0x…`, 20 bytes). | | `from` | query | string | `trading_open` | Start of the window (`block:`, `ts:`, `mcap:` or a label). | | `to` | query | string | `now` | End of the window (same forms as `from`). | | `min_usd` | query | number | `50` | Only items worth at least this many USD. | | `min_balance` | query | number | | Minimum balance in token units. | | `min_pct` | query | number | | Minimum share of supply, in percent. | | `continuous` | query | boolean | `false` | `true`: the holder must stay above the threshold for the whole window. | | `reset_on` | query | string | `sell` | One of `sell`, `any_decrease`, `below_threshold`, `none`. | | `min_hold_s` | query | integer | | Minimum continuous hold time inside the window, in seconds. | | `entered_before` | query | string | | Only holders that first qualified before this point (e.g. `mcap:20000`). | | `exclude` | query | string | | Comma list of holder classes to leave out, such as `infra` (pools, lockers, burn) or `bots`. Comma list of `infra`, `dev`, `snipers`. | | `sort` | query | string | `hold_time` | Sort order. One of `hold_time`, `balance`, `entry_mcap`. | | `limit` | query | integer | `100` | Maximum number of items to return. | ### Request **cURL** ```bash curl "https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/holders/cohort?from=mcap%3A10000&to=now&min_usd=50&continuous=true&reset_on=sell&exclude=infra" \ -H "x-api-key: $CRIUS_API_KEY" ``` **JavaScript** ```js const res = await fetch("https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/holders/cohort?from=mcap%3A10000&to=now&min_usd=50&continuous=true&reset_on=sell&exclude=infra", { headers: { "x-api-key": process.env.CRIUS_API_KEY }, }); const { data, meta } = await res.json(); ``` **Python** ```python import os, requests r = requests.get( "https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/holders/cohort?from=mcap%3A10000&to=now&min_usd=50&continuous=true&reset_on=sell&exclude=infra", headers={"x-api-key": os.environ["CRIUS_API_KEY"]}, ) body = r.json() print(body["data"]) ``` ## Holder count history **GET** `/v1/{chain}/token/{address}/holders/history` **Plan:** Starter and above · **Cost:** 10 credits per call Holder count over time at a chosen interval, with your own definition of a holder (`min_balance` or `min_usd`). Answers "what was the minimum and maximum number of holders during a period". > min / max / new / exited per interval. ### Parameters | Name | In | Type | Default | Description | |---|---|---|---|---| | `chain` | path, required | string | | Chain slug (`robinhood`) or chain id (`4663`). | | `address` | path, required | string | | Contract or wallet address, any case (`0x…`, 20 bytes). | | `interval` | query | string | `1h` | Bucket size. One of `1m`, `5m`, `15m`, `1h`, `4h`, `1d`. | | `from` | query | string | | Start of the window (`block:`, `ts:`, `mcap:` or a label). | | `to` | query | string | | End of the window (same forms as `from`). | | `min_balance` | query | number | | Minimum balance in token units. | | `min_usd` | query | number | | Only items worth at least this many USD. | | `exclude` | query | string | | Comma list of holder classes to leave out, such as `infra` (pools, lockers, burn) or `bots`. | ### Request **cURL** ```bash curl "https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/holders/history?interval=1h&from=launch&to=now" \ -H "x-api-key: $CRIUS_API_KEY" ``` **JavaScript** ```js const res = await fetch("https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/holders/history?interval=1h&from=launch&to=now", { headers: { "x-api-key": process.env.CRIUS_API_KEY }, }); const { data, meta } = await res.json(); ``` **Python** ```python import os, requests r = requests.get( "https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/holders/history?interval=1h&from=launch&to=now", headers={"x-api-key": os.environ["CRIUS_API_KEY"]}, ) body = r.json() print(body["data"]) ``` ## Top traders **GET** `/v1/{chain}/token/{address}/traders` **Plan:** Free and above · **Cost:** 5 credits per call Traders of the token ranked by PnL, realized PnL, volume, buys or ROI over a window (`1h`, `24h`, `7d`, `all`), with wallet tags (`sniper`, `bot`, `whale`, `dev`…). > Average cost; USD at trade time; unrealized at current price. ### Parameters | Name | In | Type | Default | Description | |---|---|---|---|---| | `chain` | path, required | string | | Chain slug (`robinhood`) or chain id (`4663`). | | `address` | path, required | string | | Contract or wallet address, any case (`0x…`, 20 bytes). | | `sort` | query | string | `pnl` | Sort order. One of `pnl`, `realized_pnl`, `volume`, `buys`, `roi`. | | `window` | query | string | `all` | Stats window. One of `1h`, `24h`, `7d`, `all`. | | `tag` | query | string | | Only wallets with this tag (`sniper`, `bot`, `whale`, `fresh`, `dev`, `insider`, `bundler`, `top_trader`). | | `limit` | query | integer | `50` | Maximum number of items to return. | | `cursor` | query | string | | Pagination cursor from the previous response's `meta.next_cursor`. | ### Request **cURL** ```bash curl "https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/traders?sort=pnl&window=all&limit=20" \ -H "x-api-key: $CRIUS_API_KEY" ``` **JavaScript** ```js const res = await fetch("https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/traders?sort=pnl&window=all&limit=20", { headers: { "x-api-key": process.env.CRIUS_API_KEY }, }); const { data, meta } = await res.json(); ``` **Python** ```python import os, requests r = requests.get( "https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/traders?sort=pnl&window=all&limit=20", headers={"x-api-key": os.environ["CRIUS_API_KEY"]}, ) body = r.json() print(body["data"]) ``` --- # Security & liquidity > Realized buy and sell tax, simulated honeypot checks, contract flags and LP lock status for any Robinhood Chain token. Source: https://crius.sh/docs/reference/security/ Is the token safe to trade, and can its liquidity be pulled? Tax is measured from **real trades** (what the pool sent versus what the wallet received, which also catches Uniswap v4 hook taxes), backed by **simulation** of a real buy → transfer → sell sequence at the head block, and **static** checks of the contract. A fresh simulation on demand (`fresh=1`) costs 20 credits and needs the Starter plan or higher. | Endpoint | Method | Plan | Credits | |---|---|---|---| | [Security checks](#security-checks) | `GET /v1/{chain}/token/{address}/security` | Anonymous | 1 | | [Liquidity & locks](#liquidity-locks) | `GET /v1/{chain}/token/{address}/liquidity` | Free | 5 | ## Security checks **GET** `/v1/{chain}/token/{address}/security` **Plan:** Anonymous and above (no key needed) · **Cost:** 1 credit per call Contract checks (ownership, mint, pause, blacklist, proxy, limits), realized and simulated buy/sell tax, honeypot verdict and, for v4 tokens, the pool hook's permissions and risk. `amount_usd` sets the simulated trade size (default 100). > Realized tax (30 d), eth_simulateV1 buy → transfer → sell for V2-routed tokens, owner / proxy / capabilities / limits, hook risk, LP status, flags, score. ### Parameters | Name | In | Type | Default | Description | |---|---|---|---|---| | `chain` | path, required | string | | Chain slug (`robinhood`) or chain id (`4663`). | | `address` | path, required | string | | Contract or wallet address, any case (`0x…`, 20 bytes). | | `amount_usd` | query | number | `100` | Simulated trade size in USD. | | `fresh` | query | integer | | `1` runs a new simulation now (Starter plan and up, 20 credits). | ### Request **cURL** ```bash curl "https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/security" \ -H "x-api-key: $CRIUS_API_KEY" ``` **JavaScript** ```js const res = await fetch("https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/security", { headers: { "x-api-key": process.env.CRIUS_API_KEY }, }); const { data, meta } = await res.json(); ``` **Python** ```python import os, requests r = requests.get( "https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/security", headers={"x-api-key": os.environ["CRIUS_API_KEY"]}, ) body = r.json() print(body["data"]) ``` [Try it in the playground →](https://crius.sh/docs/playground/?op=GET%20%2Fv1%2F%7Bchain%7D%2Ftoken%2F%7Baddress%7D%2Fsecurity) ### Key response fields - `risk` (`low` / `medium` / `high`) and `score` (0–100), plus `flags` - `honeypot.is_honeypot`, `honeypot.selective` (only some wallets can sell), `honeypot.reason` - `tax.buy_pct`, `tax.sell_pct` and their `source`; `tax.realized` (from real trades, with sample counts and the highest sell tax seen) and `tax.simulated` - `tax_history`: every tax change with the block it took effect - `contract`: ownership, mintable, pausable, blacklist, proxy / upgradeable, can change tax or limits - `hook`: the v4 pool hook's name, permissions, capabilities and risk - `liquidity.summary`: locked, burned and unlocked shares of LP ### Example response Real response captured from the API (arrays trimmed to three items). ```json { "data": { "contract": { "blacklist": false, "can_change_limits": false, "can_change_tax": false, "cooldown": false, "implementation": null, "is_proxy": false, "mintable": false, "owner": null, "ownership": "none", "pausable": false, "proxy_kind": null, "self_destruct": false, "trading_switch": false, "upgradeable": false, "verified": null }, "flags": [ "unverified" ], "honeypot": { "is_honeypot": false, "reason": null, "selective": false }, "hook": { "address": "0xe5e702641ea86f4ae6cc3cdaed2b886f976be044", "capabilities": { "can_block_swaps": false, "can_gate_liquidity": false, "can_modify_liquidity_amounts": false, "can_modify_swap_amounts": true }, "name": "PonsV2MemeHook", "permissions": [ "beforeInitialize", "afterSwap", "afterSwapReturnDelta" ], "risk": [ "can_modify_swap_amounts" ] }, "known_asset": false, "limits": {}, "liquidity": { "status": "partially_locked", "summary": { "burned_pct": 0, "locked_pct": 99.8934, "next_unlock_ts": null, "protocol_fee_pct": 0, "unlocked_in_wallets_pct": 0.106605, "weighting": "by pool liquidity_usd" } }, "primary_dex": "uniswap_v4", "risk": "low", "score": 95, "tax": { "buy_pct": 2.99, "confidence": "high", "realized": { "buy_pct": 2.99, "by_wallet_class": { "dev_sell_pct": null, "others_sell_pct": 0 }, "last_sample_ts": 1792705534000, "max_sell_pct_seen": 96.64, "samples": { "buys": 2529, "sells": 1840 }, "sell_pct": 0, "window": "30d" }, "sell_pct": 0, "simulated": null, "source": "realized", "transfer_pct": null }, "tax_history": [ { "from_block": 88385895, "pct": 0, "side": "buy" }, { "from_block": 88387118, "pct": 0, "side": "sell" }, { "from_block": 88461329, "pct": 3, "side": "buy" } ], "tax_history_total": 29, "tax_mode": "dynamic", "token": "0x7b8892cea949bc60d494681d1bc3ea96071ab0b8" }, "meta": { "block": 95504416, "block_age_ms": 890, "block_ts": 1792712997000, "chain": "robinhood", "finalized_block": 95493649, "lag_ms": 24, "safe_block": 95497061, "simulation": "no V2 WETH pair: realized tax only" } } ``` ## Liquidity & locks **GET** `/v1/{chain}/token/{address}/liquidity` **Plan:** Free and above · **Cost:** 5 credits per call Who owns the token's liquidity, per pool: burned, locked (which locker, until when, who can withdraw) or held by wallets. After an unlock the LP keeps being followed: withdrawn → to whom → removed or still held. Supported lockers include the Pons launch locker, UNCX v2/v3/v4, Team Finance, TitanLocker and HoodLock. > V2 LP-token holders, V3/V4 position NFT owners, decoded locker events (UNCX, Team Finance, Titan, HoodLock, Pons). ### Parameters | Name | In | Type | Default | Description | |---|---|---|---|---| | `chain` | path, required | string | | Chain slug (`robinhood`) or chain id (`4663`). | | `address` | path, required | string | | Contract or wallet address, any case (`0x…`, 20 bytes). | ### Request **cURL** ```bash curl "https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/liquidity" \ -H "x-api-key: $CRIUS_API_KEY" ``` **JavaScript** ```js const res = await fetch("https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/liquidity", { headers: { "x-api-key": process.env.CRIUS_API_KEY }, }); const { data, meta } = await res.json(); ``` **Python** ```python import os, requests r = requests.get( "https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/liquidity", headers={"x-api-key": os.environ["CRIUS_API_KEY"]}, ) body = r.json() print(body["data"]) ``` --- # Launchpads & fees > Launchpad lifecycle (bonding curve progress, graduation), live launchpad stats, and fees, claims and receivers for Robinhood Chain tokens. Source: https://crius.sh/docs/reference/launchpads/ Robinhood Chain launchpads such as **Pons**, **Flap.sh**, **Bankr**, **Long.xyz** and **King of the Markets** are attributed automatically. Every response that mentions a launchpad carries a stable id (`launchpad`, use it in filters) and a display name (`launchpad_name`). | Endpoint | Method | Plan | Credits | |---|---|---|---| | [Launchpads](#launchpads) | `GET /v1/{chain}/launchpads` | Anonymous | 1 | | [Launch lifecycle](#launch-lifecycle) | `GET /v1/{chain}/token/{address}/launch` | Free | 2 | | [Fees & claims](#fees-claims) | `GET /v1/{chain}/token/{address}/fees` | Starter | 5 | ## Launchpads **GET** `/v1/{chain}/launchpads` **Plan:** Anonymous and above (no key needed) · **Cost:** 1 credit per call Every supported launchpad with its live stats: launches, graduations and volume. ### Parameters | Name | In | Type | Default | Description | |---|---|---|---|---| | `chain` | path, required | string | | Chain slug (`robinhood`) or chain id (`4663`). | ### Request **cURL** ```bash curl "https://api.crius.sh/v1/robinhood/launchpads" \ -H "x-api-key: $CRIUS_API_KEY" ``` **JavaScript** ```js const res = await fetch("https://api.crius.sh/v1/robinhood/launchpads", { headers: { "x-api-key": process.env.CRIUS_API_KEY }, }); const { data, meta } = await res.json(); ``` **Python** ```python import os, requests r = requests.get( "https://api.crius.sh/v1/robinhood/launchpads", headers={"x-api-key": os.environ["CRIUS_API_KEY"]}, ) body = r.json() print(body["data"]) ``` [Try it in the playground →](https://crius.sh/docs/playground/?op=GET%20%2Fv1%2F%7Bchain%7D%2Flaunchpads) ### Example response Real response captured from the API (arrays trimmed to three items). ```json { "data": [ { "contracts": { "buyback_vault": "0x42df2a798f82289e177311362e8f5ccc45c1219c", "factory": "0x7ed598bcef8bd9edd8c97a195c6d13f40801ec7e", "fee_escrow": "0xd3afeb2a57f70ef218aa82451c51b2fb0416ac9e", "hook": "0xe5e702641ea86f4ae6cc3cdaed2b886f976be044", "launch_and_buy": "0xe33e9e479df8802cb0866d5d05258bec4cf62948", "lp_locker": "0x267444d099b10fb5ed7c3cc7b7c767adca574952" }, "id": "pons", "name": "Pons", "since_block": 27027321, "stats": { "graduated": 10411, "graduated_24h": 23, "graduation_rate_pct": 1.47015, "launches_24h": 1591, "median_blocks_to_graduate": 2469, "tokens_launched": 708157, "volume_usd_24h": 22460562 }, "type": "bonding_curve_to_v4", "website": null }, { "contracts": { "launch_contracts": [ "0x26605f322f7ff986f381bb9a6e3f5dab0beaeb09" ] }, "id": "flap", "name": "Flap.sh", "since_block": 4227932, "stats": { "graduated": 337, "graduated_24h": 0, "graduation_rate_pct": 0.0885423, "launches_24h": 1374, "median_blocks_to_graduate": 8048, "tokens_launched": 380609, "volume_usd_24h": 378086 }, "type": "config_driven", "website": "https://flap.sh" }, { "contracts": { "launch_contracts": [ "0xeb7c034704ef8dcd2d32324c1545f62fb4ad0862" ] }, "id": "bankr", "name": "Bankr", "since_block": 1565844, "stats": { "graduated": 0, "graduated_24h": 0, "graduation_rate_pct": 0, "launches_24h": 54, "median_blocks_to_graduate": null, "tokens_launched": 98503, "volume_usd_24h": 296276 }, "type": "config_driven", "website": "https://bankr.bot" } ], "meta": { "block": 95504452, "block_age_ms": 603, "block_ts": 1792713001000, "chain": "robinhood", "finalized_block": 95493649, "lag_ms": 160, "safe_block": 95497061 } } ``` ## Launch lifecycle **GET** `/v1/{chain}/token/{address}/launch` **Plan:** Free and above · **Cost:** 2 credits per call A launchpad token's lifecycle: creator, curve, bonding progress, raised amount, graduation block and the pool it graduated into. Tokens from unattributed factories return `data: null` with `meta.attribution = "unattributed_factory"`. > Pons config & fees read live from the chain, graduation details. ### Parameters | Name | In | Type | Default | Description | |---|---|---|---|---| | `chain` | path, required | string | | Chain slug (`robinhood`) or chain id (`4663`). | | `address` | path, required | string | | Contract or wallet address, any case (`0x…`, 20 bytes). | ### Request **cURL** ```bash curl "https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/launch" \ -H "x-api-key: $CRIUS_API_KEY" ``` **JavaScript** ```js const res = await fetch("https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/launch", { headers: { "x-api-key": process.env.CRIUS_API_KEY }, }); const { data, meta } = await res.json(); ``` **Python** ```python import os, requests r = requests.get( "https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/launch", headers={"x-api-key": os.environ["CRIUS_API_KEY"]}, ) body = r.json() print(body["data"]) ``` ## Fees & claims **GET** `/v1/{chain}/token/{address}/fees` **Plan:** Starter and above · **Cost:** 5 credits per call Fees paid around a token over a window: gas (L2 and L1), LP fees, Uniswap protocol fees, hook fees and taxes, launchpad and creator fees and token tax, plus who claimed them and where they went. > Gas, LP fees, hook fees, creator tax, bonding-curve fees, token tax; Pons sweeps. ### Parameters | Name | In | Type | Default | Description | |---|---|---|---|---| | `chain` | path, required | string | | Chain slug (`robinhood`) or chain id (`4663`). | | `address` | path, required | string | | Contract or wallet address, any case (`0x…`, 20 bytes). | | `window` | query | string | `24h` | Stats window. One of `1h`, `24h`, `7d`, `all`. | ### Request **cURL** ```bash curl "https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/fees?window=7d" \ -H "x-api-key: $CRIUS_API_KEY" ``` **JavaScript** ```js const res = await fetch("https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/fees?window=7d", { headers: { "x-api-key": process.env.CRIUS_API_KEY }, }); const { data, meta } = await res.json(); ``` **Python** ```python import os, requests r = requests.get( "https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/fees?window=7d", headers={"x-api-key": os.environ["CRIUS_API_KEY"]}, ) body = r.json() print(body["data"]) ``` --- # Pools & hooks > Pool details for Uniswap v2, v3 and v4 on Robinhood Chain, and Uniswap v4 hooks with decoded permissions and risk flags. Source: https://crius.sh/docs/reference/pools/ Pools are addressed by their pair/pool address (Uniswap v2 and v3) or their 32-byte pool id (Uniswap v4). v4 **hook** permissions are decoded from the hook address itself (its low 14 bits, as in Uniswap's `Hooks.sol`), and turned into plain risk flags such as `can_block_or_reprice_swaps` or `can_gate_liquidity_removal`. | Endpoint | Method | Plan | Credits | |---|---|---|---| | [Pool detail](#pool-detail) | `GET /v1/{chain}/pool/{pool}` | Anonymous | 1 | | [Uniswap v4 hooks](#uniswap-v4-hooks) | `GET /v1/{chain}/hooks` | Free | 2 | | [Hook detail](#hook-detail) | `GET /v1/{chain}/hook/{address}` | Free | 2 | ## Pool detail **GET** `/v1/{chain}/pool/{pool}` **Plan:** Anonymous and above (no key needed) · **Cost:** 1 credit per call Tokens, reserves and in-range liquidity, fee tier (dynamic fee for v4), hook, price, TVL and recent activity of one pool. > Real reserves, prices both ways, TVL, stats per window, hook, LP status. ### Parameters | Name | In | Type | Default | Description | |---|---|---|---|---| | `chain` | path, required | string | | Chain slug (`robinhood`) or chain id (`4663`). | | `pool` | path, required | string | | Pool address (Uniswap v2/v3) or 32-byte pool id (Uniswap v4). | ### Request **cURL** ```bash curl "https://api.crius.sh/v1/robinhood/pool/0x871b166182fd708d5d16a4daa9a42f05a653fa51ee2b195097f425e0d9ca4913" \ -H "x-api-key: $CRIUS_API_KEY" ``` **JavaScript** ```js const res = await fetch("https://api.crius.sh/v1/robinhood/pool/0x871b166182fd708d5d16a4daa9a42f05a653fa51ee2b195097f425e0d9ca4913", { headers: { "x-api-key": process.env.CRIUS_API_KEY }, }); const { data, meta } = await res.json(); ``` **Python** ```python import os, requests r = requests.get( "https://api.crius.sh/v1/robinhood/pool/0x871b166182fd708d5d16a4daa9a42f05a653fa51ee2b195097f425e0d9ca4913", headers={"x-api-key": os.environ["CRIUS_API_KEY"]}, ) body = r.json() print(body["data"]) ``` [Try it in the playground →](https://crius.sh/docs/playground/?op=GET%20%2Fv1%2F%7Bchain%7D%2Fpool%2F%7Bpool%7D) ### Example response Real response captured from the API (arrays trimmed to three items). ```json { "data": { "created_block": 88461321, "created_ts": 1791990423100, "currency0": { "address": "0x0000000000000000000000000000000000000000", "decimals": 18, "price_usd": 2381.97, "symbol": "ETH" }, "currency1": { "address": "0x7b8892cea949bc60d494681d1bc3ea96071ab0b8", "decimals": 18, "price_usd": 0.00000576413, "symbol": "CHARGE" }, "dex": "uniswap_v4", "dynamic_fee": false, "factory": "0x8366a39cc670b4001a1121b8f6a443a643e40951", "fee": 0, "fee_bps": 0, "hook": { "address": "0xe5e702641ea86f4ae6cc3cdaed2b886f976be044", "name": "PonsV2MemeHook", "permissions": [ "beforeInitialize", "afterSwap", "afterSwapReturnDelta" ], "risk": [ "can_modify_swap_amounts" ] }, "lp": { "locked_pct": 100, "locker": "pons_v2_launch_locker", "permanent": true, "status": "locked" }, "pool": "0x871b166182fd708d5d16a4daa9a42f05a653fa51ee2b195097f425e0d9ca4913", "pool_manager": "0x8366a39cc670b4001a1121b8f6a443a643e40951", "state": { "initialized_ticks": 2, "last_block": 95433009, "liquidity": 29277002188455996438188, "price_0_in_1": 413240207, "price_1_in_0": 0.0000000024199, "real_quote_raised": null, "reserve0": 0, "reserve1": 0, "reserves": { "currency0": 1.44021, "currency1": 595151991, "kind": "real" }, "sqrt_price_x96": 1610574686881614931072228111579696, "tick": 198405 }, "stats": { "all_time": { "buy_volume_usd": 107362, "buys": 2146, "first_trade_ts": 1791990423000, "sell_volume_usd": 113977, "sells": 1731, "since": "chain_start", "trades": 3877, "volume_usd": 221339 }, "avg_trade_usd": { "1h": null, "1m": null, "1s": null, "24h": 30.7463, "30s": null, "4h": 11.3632, "5m": null, "6h": 11.3632 }, "buy_volume_usd": { "1h": 0, "1m": 0, "1s": 0, "24h": 238.251, "30s": 0, "4h": 7.40995, "5m": 0, "6h": 7.40995 }, "buyers": { "1h": 0, "1m": 0, "1s": 0, "24h": 5, "30s": 0, "4h": 1, "5m": 0, "6h": 1 }, "buys": { "1h": 0, "1m": 0, "1s": 0, "24h": 9, "30s": 0, "4h": 1, "5m": 0, "6h": 1 }, "last_trade_ts": 1792705534000, "sell_volume_usd": { "1h": 0, "1m": 0, "1s": 0, "24h": 222.943, "30s": 0, "4h": 15.3164, "5m": 0, "6h": 15.3164 }, "sellers": { "1h": 0, "1m": 0, "1s": 0, "24h": 6, "30s": 0, "4h": 1, "5m": 0, "6h": 1 }, "sells": { "1h": 0, "1m": 0, "1s": 0, "24h": 6, "30s": 0, "4h": 1, "5m": 0, "6h": 1 }, "traders": { "1h": 0, "1m": 0, "1s": 0, "24h": 10, "30s": 0, "4h": 2, "5m": 0, "6h": 2 }, "trades": { "1h": 0, "1m": 0, "1s": 0, "24h": 15, "30s": 0, "4h": 2, "5m": 0, "6h": 2 }, "txns": { "1h": 0, "1m": 0, "1s": 0, "24h": 15, "30s": 0, "4h": 2, "5m": 0, "6h": 2 }, "volume_eth": { "1h": 0, "1m": 0, "1s": 0, "24h": 0.189336, "30s": 0, "4h": 0.00954709, "5m": 0, "6h": 0.00954709 }, "volume_usd": { "1h": 0, "1m": 0, "1s": 0, "24h": 461.194, "30s": 0, "4h": 22.7263, "5m": 0, "6h": 22.7263 } }, "swaps_indexed": 383, "tick_spacing": 200, "tvl_usd": 6861.07 }, "meta": { "block": 95504392, "block_age_ms": 419, "block_ts": 1792712995000, "chain": "robinhood", "finalized_block": 95493649, "lag_ms": 2, "safe_block": 95497061 } } ``` ## Uniswap v4 hooks **GET** `/v1/{chain}/hooks` **Plan:** Free and above · **Cost:** 2 credits per call Every v4 hook seen on chain, with pool count, volume and fees, verification status and risk. Filter by `verified`, `risk` or `launchpad`. > Permissions decoded from the hook address; live pool counts. ### Parameters | Name | In | Type | Default | Description | |---|---|---|---|---| | `chain` | path, required | string | | Chain slug (`robinhood`) or chain id (`4663`). | | `sort` | query | string | `pools` | Sort order. One of `pools`, `volume_24h`. | | `verified` | query | boolean | | `true` or `false`: only verified (or unverified) hooks. | | `risk` | query | string | | Only hooks with this risk flag. | | `launchpad` | query | string | | Launchpad id, such as `pons` or `flap` (see /launchpads). | | `limit` | query | integer | `50` | Maximum number of items to return. | ### Request **cURL** ```bash curl "https://api.crius.sh/v1/robinhood/hooks?sort=pools&limit=20" \ -H "x-api-key: $CRIUS_API_KEY" ``` **JavaScript** ```js const res = await fetch("https://api.crius.sh/v1/robinhood/hooks?sort=pools&limit=20", { headers: { "x-api-key": process.env.CRIUS_API_KEY }, }); const { data, meta } = await res.json(); ``` **Python** ```python import os, requests r = requests.get( "https://api.crius.sh/v1/robinhood/hooks?sort=pools&limit=20", headers={"x-api-key": os.environ["CRIUS_API_KEY"]}, ) body = r.json() print(body["data"]) ``` ## Hook detail **GET** `/v1/{chain}/hook/{address}` **Plan:** Free and above · **Cost:** 2 credits per call One hook: its decoded permissions, risk flags, verification, the events it emits and the pools that use it. ### Parameters | Name | In | Type | Default | Description | |---|---|---|---|---| | `chain` | path, required | string | | Chain slug (`robinhood`) or chain id (`4663`). | | `address` | path, required | string | | Contract or wallet address, any case (`0x…`, 20 bytes). | ### Request **cURL** ```bash curl "https://api.crius.sh/v1/robinhood/hook/0x4e3468951d49f2eea976ed0d6e75ffcb44a9a544" \ -H "x-api-key: $CRIUS_API_KEY" ``` **JavaScript** ```js const res = await fetch("https://api.crius.sh/v1/robinhood/hook/0x4e3468951d49f2eea976ed0d6e75ffcb44a9a544", { headers: { "x-api-key": process.env.CRIUS_API_KEY }, }); const { data, meta } = await res.json(); ``` **Python** ```python import os, requests r = requests.get( "https://api.crius.sh/v1/robinhood/hook/0x4e3468951d49f2eea976ed0d6e75ffcb44a9a544", headers={"x-api-key": os.environ["CRIUS_API_KEY"]}, ) body = r.json() print(body["data"]) ``` --- # Wallets & devs > Wallet profiles with holdings and PnL, wallet trade history, funding connections and token developer profiles on Robinhood Chain. Source: https://crius.sh/docs/reference/wallets/ Wallet-level data: what a wallet holds and earned, every trade it made, who funded it, and for token creators, every token they launched and how those did. | Endpoint | Method | Plan | Credits | |---|---|---|---| | [Wallet profile](#wallet-profile) | `GET /v1/{chain}/wallet/{address}` | Starter | 5 | | [Wallet trades](#wallet-trades) | `GET /v1/{chain}/wallet/{address}/trades` | Starter | 5 | | [Wallet connections](#wallet-connections) | `GET /v1/{chain}/wallet/{address}/connections` | Starter | 10 | | [Developer profile](#developer-profile) | `GET /v1/{chain}/dev/{address}` | Free | 5 | ## Wallet profile **GET** `/v1/{chain}/wallet/{address}` **Plan:** Starter and above · **Cost:** 5 credits per call Holdings with USD value, realized and unrealized PnL over a window (`1d`, `7d`, `30d`, `all`), win rate and wallet tags. `min_value_usd` hides dust. ### Parameters | Name | In | Type | Default | Description | |---|---|---|---|---| | `chain` | path, required | string | | Chain slug (`robinhood`) or chain id (`4663`). | | `address` | path, required | string | | Contract or wallet address, any case (`0x…`, 20 bytes). | | `window` | query | string | `30d` | Stats window. One of `1d`, `7d`, `30d`, `all`. | | `min_value_usd` | query | number | | Hide holdings worth less than this many USD. | ### Request **cURL** ```bash curl "https://api.crius.sh/v1/robinhood/wallet/0x3ac82d45ff9e4963cefbc3f74dbe293f34c927ca?window=30d" \ -H "x-api-key: $CRIUS_API_KEY" ``` **JavaScript** ```js const res = await fetch("https://api.crius.sh/v1/robinhood/wallet/0x3ac82d45ff9e4963cefbc3f74dbe293f34c927ca?window=30d", { headers: { "x-api-key": process.env.CRIUS_API_KEY }, }); const { data, meta } = await res.json(); ``` **Python** ```python import os, requests r = requests.get( "https://api.crius.sh/v1/robinhood/wallet/0x3ac82d45ff9e4963cefbc3f74dbe293f34c927ca?window=30d", headers={"x-api-key": os.environ["CRIUS_API_KEY"]}, ) body = r.json() print(body["data"]) ``` ## Wallet trades **GET** `/v1/{chain}/wallet/{address}/trades` **Plan:** Starter and above · **Cost:** 5 credits per call Every trade the wallet made across all tokens, newest first, in the same shape as the trade tape plus the token. Filter by `token`, `side`, `min_usd` and time. ### Parameters | Name | In | Type | Default | Description | |---|---|---|---|---| | `chain` | path, required | string | | Chain slug (`robinhood`) or chain id (`4663`). | | `address` | path, required | string | | Contract or wallet address, any case (`0x…`, 20 bytes). | | `token` | query | string | | Only trades of this token. | | `side` | query | string | | `buy` or `sell`. | | `min_usd` | query | number | | Only items worth at least this many USD. | | `from_ts` | query | integer | | Start of the time range, unix milliseconds (inclusive). | | `to_ts` | query | integer | | End of the time range, unix milliseconds (inclusive). | | `limit` | query | integer | `50` | Maximum number of items to return. | | `cursor` | query | string | | Pagination cursor from the previous response's `meta.next_cursor`. | ### Request **cURL** ```bash curl "https://api.crius.sh/v1/robinhood/wallet/0x3ac82d45ff9e4963cefbc3f74dbe293f34c927ca/trades?limit=20" \ -H "x-api-key: $CRIUS_API_KEY" ``` **JavaScript** ```js const res = await fetch("https://api.crius.sh/v1/robinhood/wallet/0x3ac82d45ff9e4963cefbc3f74dbe293f34c927ca/trades?limit=20", { headers: { "x-api-key": process.env.CRIUS_API_KEY }, }); const { data, meta } = await res.json(); ``` **Python** ```python import os, requests r = requests.get( "https://api.crius.sh/v1/robinhood/wallet/0x3ac82d45ff9e4963cefbc3f74dbe293f34c927ca/trades?limit=20", headers={"x-api-key": os.environ["CRIUS_API_KEY"]}, ) body = r.json() print(body["data"]) ``` ## Wallet connections **GET** `/v1/{chain}/wallet/{address}/connections` **Plan:** Starter and above · **Cost:** 10 credits per call Wallets connected to this one through funding and transfers: who funded it, who it funded, and wallets sharing a funder. ### Parameters | Name | In | Type | Default | Description | |---|---|---|---|---| | `chain` | path, required | string | | Chain slug (`robinhood`) or chain id (`4663`). | | `address` | path, required | string | | Contract or wallet address, any case (`0x…`, 20 bytes). | | `limit` | query | integer | `25` | Maximum number of items to return. | ### Request **cURL** ```bash curl "https://api.crius.sh/v1/robinhood/wallet/0x3ac82d45ff9e4963cefbc3f74dbe293f34c927ca/connections" \ -H "x-api-key: $CRIUS_API_KEY" ``` **JavaScript** ```js const res = await fetch("https://api.crius.sh/v1/robinhood/wallet/0x3ac82d45ff9e4963cefbc3f74dbe293f34c927ca/connections", { headers: { "x-api-key": process.env.CRIUS_API_KEY }, }); const { data, meta } = await res.json(); ``` **Python** ```python import os, requests r = requests.get( "https://api.crius.sh/v1/robinhood/wallet/0x3ac82d45ff9e4963cefbc3f74dbe293f34c927ca/connections", headers={"x-api-key": os.environ["CRIUS_API_KEY"]}, ) body = r.json() print(body["data"]) ``` ## Developer profile **GET** `/v1/{chain}/dev/{address}` **Plan:** Free and above · **Cost:** 5 credits per call A token creator's track record: every token they deployed or launched, with peak market cap, current state and outcomes. > Tokens created (launchpad + direct deployments), outcomes, funding. ### Parameters | Name | In | Type | Default | Description | |---|---|---|---|---| | `chain` | path, required | string | | Chain slug (`robinhood`) or chain id (`4663`). | | `address` | path, required | string | | Contract or wallet address, any case (`0x…`, 20 bytes). | | `sort` | query | string | `created` | Sort order. One of `created`, `ath`, `market_cap`. | | `limit` | query | integer | `50` | Maximum number of items to return. | ### Request **cURL** ```bash curl "https://api.crius.sh/v1/robinhood/dev/0x3ac82d45ff9e4963cefbc3f74dbe293f34c927ca?sort=created" \ -H "x-api-key: $CRIUS_API_KEY" ``` **JavaScript** ```js const res = await fetch("https://api.crius.sh/v1/robinhood/dev/0x3ac82d45ff9e4963cefbc3f74dbe293f34c927ca?sort=created", { headers: { "x-api-key": process.env.CRIUS_API_KEY }, }); const { data, meta } = await res.json(); ``` **Python** ```python import os, requests r = requests.get( "https://api.crius.sh/v1/robinhood/dev/0x3ac82d45ff9e4963cefbc3f74dbe293f34c927ca?sort=created", headers={"x-api-key": os.environ["CRIUS_API_KEY"]}, ) body = r.json() print(body["data"]) ``` --- # Bundles & bubble maps > Sniper, bundle and cluster detection and holder bubble-map graphs for Robinhood Chain tokens. Source: https://crius.sh/docs/reference/wallet-graph/ Graph analytics over holders. A **bundle** is one transaction buying for several recipients, a launch transaction that also buys, two or more wallets buying in the same block that share a funder, or wallets forwarding tokens to a common wallet. | Endpoint | Method | Plan | Credits | |---|---|---|---| | [Snipers, bundles & clusters](#snipers-bundles-clusters) | `GET /v1/{chain}/token/{address}/bundles` | Starter | 10 | | [Bubble map](#bubble-map) | `GET /v1/{chain}/token/{address}/bubblemap` | Starter | 10 | ## Snipers, bundles & clusters **GET** `/v1/{chain}/token/{address}/bundles` **Plan:** Starter and above · **Cost:** 10 credits per call Snipers (bought within the first blocks after trading opened), bundles, funding clusters and the share of supply they hold. `window_blocks` sets the sniper window (default 10 blocks). > First 300 blocks of trading. ### Parameters | Name | In | Type | Default | Description | |---|---|---|---|---| | `chain` | path, required | string | | Chain slug (`robinhood`) or chain id (`4663`). | | `address` | path, required | string | | Contract or wallet address, any case (`0x…`, 20 bytes). | | `window_blocks` | query | integer | `10` | Sniper window after trading opened, in blocks. | ### Request **cURL** ```bash curl "https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/bundles" \ -H "x-api-key: $CRIUS_API_KEY" ``` **JavaScript** ```js const res = await fetch("https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/bundles", { headers: { "x-api-key": process.env.CRIUS_API_KEY }, }); const { data, meta } = await res.json(); ``` **Python** ```python import os, requests r = requests.get( "https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/bundles", headers={"x-api-key": os.environ["CRIUS_API_KEY"]}, ) body = r.json() print(body["data"]) ``` ## Bubble map **GET** `/v1/{chain}/token/{address}/bubblemap` **Plan:** Starter and above · **Cost:** 10 credits per call The top holders (`top`, up to 500) as nodes and the links between them as edges: funding, transfers, common funders and same-block buys. Pass `block` for a historical map. Ready to render with any force-directed graph library. > Nodes = holders (+ external funders), edges = funding / transfers. ### Parameters | Name | In | Type | Default | Description | |---|---|---|---|---| | `chain` | path, required | string | | Chain slug (`robinhood`) or chain id (`4663`). | | `address` | path, required | string | | Contract or wallet address, any case (`0x…`, 20 bytes). | | `top` | query | integer | `100` | Number of top holders to include as nodes. Up to 500. | | `edges` | query | string | `funding,transfers,common_funder` | Which links to include between holders. | | `exclude` | query | string | `infra` | Comma list of holder classes to leave out, such as `infra` (pools, lockers, burn) or `bots`. | | `block` | query | integer | | Build the map as of this block (historical). | ### Request **cURL** ```bash curl "https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/bubblemap?top=100" \ -H "x-api-key: $CRIUS_API_KEY" ``` **JavaScript** ```js const res = await fetch("https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/bubblemap?top=100", { headers: { "x-api-key": process.env.CRIUS_API_KEY }, }); const { data, meta } = await res.json(); ``` **Python** ```python import os, requests r = requests.get( "https://api.crius.sh/v1/robinhood/token/0x7b8892cea949bc60d494681d1bc3ea96071ab0b8/bubblemap?top=100", headers={"x-api-key": os.environ["CRIUS_API_KEY"]}, ) body = r.json() print(body["data"]) ``` --- # Discovery & search > Token lists (new, bonding, graduating, trending, top gainers and losers) and search across tokens, pools, wallets and hooks on Robinhood Chain. Source: https://crius.sh/docs/reference/discovery/ Find tokens: curated lists with filters, and a fast search box backend. | Endpoint | Method | Plan | Credits | |---|---|---|---| | [Token lists](#token-lists) | `GET /v1/{chain}/tokens` | Anonymous | 1 | | [Search](#search) | `GET /v1/{chain}/search` | Anonymous | 1 | ## Token lists **GET** `/v1/{chain}/tokens` **Plan:** Anonymous and above (no key needed) · **Cost:** 1 credit per call Lists: `new`, `bonding`, `graduating`, `graduated`, `trending`, `top_volume`, `top_gainers`, `top_losers`. Filter by `launchpad`, `quote`, `min_liquidity_usd`, `min_volume_usd` and `created_after_ts`; `window` picks the stats window. Up to 100 per page. ### Parameters | Name | In | Type | Default | Description | |---|---|---|---|---| | `chain` | path, required | string | | Chain slug (`robinhood`) or chain id (`4663`). | | `list` | query | string | `trending` | Which list to return. One of `new`, `bonding`, `graduating`, `graduated`, `trending`, `top_volume`, `top_gainers`, `top_losers`. | | `window` | query | string | | Stats window. From `1s` to `24h`. | | `launchpad` | query | string | | Launchpad id, such as `pons` or `flap` (see /launchpads). | | `quote` | query | string | | Quote asset of the token's main pool. One of `eth`, `usdg`. | | `min_liquidity_usd` | query | number | | Only tokens with at least this much liquidity (USD). | | `min_volume_usd` | query | number | | Only tokens with at least this much volume in the window (USD). | | `created_after_ts` | query | integer | | Only tokens created after this time (unix ms). | | `limit` | query | integer | `50` | Maximum number of items to return. | | `cursor` | query | string | | Pagination cursor from the previous response's `meta.next_cursor`. | ### Request **cURL** ```bash curl "https://api.crius.sh/v1/robinhood/tokens?list=trending&window=24h&limit=3" \ -H "x-api-key: $CRIUS_API_KEY" ``` **JavaScript** ```js const res = await fetch("https://api.crius.sh/v1/robinhood/tokens?list=trending&window=24h&limit=3", { headers: { "x-api-key": process.env.CRIUS_API_KEY }, }); const { data, meta } = await res.json(); ``` **Python** ```python import os, requests r = requests.get( "https://api.crius.sh/v1/robinhood/tokens?list=trending&window=24h&limit=3", headers={"x-api-key": os.environ["CRIUS_API_KEY"]}, ) body = r.json() print(body["data"]) ``` [Try it in the playground →](https://crius.sh/docs/playground/?op=GET%20%2Fv1%2F%7Bchain%7D%2Ftokens) ### Example response Real response captured from the API (arrays trimmed to three items). ```json { "data": [ { "address": "0xc9675fe679c7d4e1b94416f66d61c96127eb964a", "buy_volume_usd": { "1h": 21463, "24h": 653991, "5m": 2331.27, "6h": 164734 }, "buyers": { "1h": 212, "24h": 4198, "5m": 33, "6h": 1218 }, "buys": { "1h": 368, "24h": 10533, "5m": 39, "6h": 2645 }, "change_pct": { "1h": -4.93203, "24h": -1.36741, "5m": -0.638032, "6h": -15.1299 }, "created_block": 84352016, "created_ts": 1791568845600, "decimals": 18, "fdv_usd": 1722014, "holders": 9446, "launchpad": null, "launchpad_name": null, "liquidity_usd": 160074, "logo": null, "market_cap_usd": 1722014, "name": "Giga Tenev", "price_eth": 0.000000722937, "price_usd": 0.00172201, "progress_pct": null, "quote": "ETH", "sell_volume_usd": { "1h": 23253.1, "24h": 653071, "5m": 2526.45, "6h": 172651 }, "sellers": { "1h": 228, "24h": 4433, "5m": 37, "6h": 1267 }, "sells": { "1h": 367, "24h": 10333, "5m": 38, "6h": 2570 }, "status": null, "symbol": "GIGATENEV", "traders": { "1h": 379, "24h": 5706, "5m": 57, "6h": 1701 }, "txns": { "1h": 655, "24h": 17735, "5m": 72, "6h": 4563 }, "volume_usd": { "1h": 44716.1, "24h": 1307062, "5m": 4857.72, "6h": 337384 } }, { "address": "0x30de7ae4c9578d110a97367ede9f7765cdce06ea", "buy_volume_usd": { "1h": 38569.1, "24h": 1745868, "5m": 1171.1, "6h": 300413 }, "buyers": { "1h": 106, "24h": 3033, "5m": 8, "6h": 679 }, "buys": { "1h": 275, "24h": 11949, "5m": 9, "6h": 1945 }, "change_pct": { "1h": -10.4998, "24h": -53.1886, "5m": 0.790503, "6h": -23.8595 }, "created_block": 94425334, "created_ts": 1792600484400, "decimals": 9, "fdv_usd": 2011643, "holders": 2456, "launchpad": null, "launchpad_name": null, "liquidity_usd": 272118, "logo": "https://ipfs.filebase.io/ipfs/QmeR3Yytm2RLS7NPbkzzz543DJfM6sk3DaQGZHA6mEWwsF", "market_cap_usd": 1995511, "name": "Pangea", "price_eth": 0.00000052634, "price_usd": 0.00125373, "progress_pct": null, "quote": "USDG", "sell_volume_usd": { "1h": 51816.8, "24h": 1854001, "5m": 2142.84, "6h": 324890 }, "sellers": { "1h": 131, "24h": 3361, "5m": 7, "6h": 824 }, "sells": { "1h": 244, "24h": 11434, "5m": 10, "6h": 2091 }, "status": null, "symbol": "PANGEA", "traders": { "1h": 184, "24h": 4181, "5m": 14, "6h": 1070 }, "txns": { "1h": 339, "24h": 15288, "5m": 15, "6h": 2674 }, "volume_usd": { "1h": 90385.9, "24h": 3599869, "5m": 3313.94, "6h": 625304 } }, { "address": "0xe01ada02fb4d1951cdb8cbb761d509db2ff02c94", "buy_volume_usd": { "1h": 436789, "24h": 7590722, "5m": 43478.8, "6h": 2177300 }, "buyers": { "1h": 646, "24h": 3504, "5m": 83, "6h": 2140 }, "buys": { "1h": 1256, "24h": 27801, "5m": 106, "6h": 7492 }, "change_pct": { "1h": 46.1081, "24h": 27.7039, "5m": 1.75704, "6h": 79.8324 }, "created_block": 92609286, "created_ts": 1792412328600, "decimals": 18, "fdv_usd": 35959968, "holders": 8208, "launchpad": null, "launchpad_name": null, "liquidity_usd": 590655, "logo": "https://ipfs.filebase.io/ipfs/bafkreid54stiiy2eguahowkokprffrvyfcuxpgumm37kwg7b375weqtgmq", "market_cap_usd": 35959968, "name": "Universal High Income", "price_eth": 0.0000150967, "price_usd": 0.03596, "progress_pct": null, "quote": "ETH", "sell_volume_usd": { "1h": 385373, "24h": 7552732, "5m": 41177.2, "6h": 2101469 }, "sellers": { "1h": 308, "24h": 3132, "5m": 39, "6h": 1487 }, "sells": { "1h": 736, "24h": 20732, "5m": 57, "6h": 5269 }, "status": null, "symbol": "UHI", "traders": { "1h": 796, "24h": 3607, "5m": 104, "6h": 2530 }, "txns": { "1h": 1890, "24h": 47165, "5m": 163, "6h": 12389 }, "volume_usd": { "1h": 822162, "24h": 15143454, "5m": 84656, "6h": 4278769 } } ], "meta": { "block": 95504424, "block_age_ms": 687, "block_ts": 1792712998000, "chain": "robinhood", "finalized_block": 95493649, "lag_ms": 61, "list": "trending", "next_cursor": "3", "safe_block": 95497061, "stats_since": "chain_start", "window": "24h" } } ``` ## Search **GET** `/v1/{chain}/search` **Plan:** Anonymous and above (no key needed) · **Cost:** 1 credit per call Prefix search over token names and symbols, and exact match on token, pool, wallet and hook addresses and v4 pool ids. `type` narrows the result kind; up to 20 results. > Prefix on name / symbol, exact on address / pool id. ### Parameters | Name | In | Type | Default | Description | |---|---|---|---|---| | `chain` | path, required | string | | Chain slug (`robinhood`) or chain id (`4663`). | | `q` | query | string | `shoot` | Search text: a name or symbol prefix, or an exact address / pool id. | | `type` | query | string | | Filter by item type. Comma list of `token`, `pool`, `wallet`, `hook`. | | `limit` | query | integer | `10` | Maximum number of items to return. Up to 20. | ### Request **cURL** ```bash curl "https://api.crius.sh/v1/robinhood/search?q=charge&limit=3" \ -H "x-api-key: $CRIUS_API_KEY" ``` **JavaScript** ```js const res = await fetch("https://api.crius.sh/v1/robinhood/search?q=charge&limit=3", { headers: { "x-api-key": process.env.CRIUS_API_KEY }, }); const { data, meta } = await res.json(); ``` **Python** ```python import os, requests r = requests.get( "https://api.crius.sh/v1/robinhood/search?q=charge&limit=3", headers={"x-api-key": os.environ["CRIUS_API_KEY"]}, ) body = r.json() print(body["data"]) ``` [Try it in the playground →](https://crius.sh/docs/playground/?op=GET%20%2Fv1%2F%7Bchain%7D%2Fsearch) ### Example response Real response captured from the API (arrays trimmed to three items). ```json { "data": [ { "address": "0x7b8892cea949bc60d494681d1bc3ea96071ab0b8", "label": null, "launchpad": "pons", "launchpad_name": "Pons", "liquidity_usd": 6869.4, "logo": "https://api.surplusllm.com/api/launchpad/logos/bb4315cb9506ef872830b1dab25ffdb6694df1b8b8e32cc2c8d083208f26baab.png", "name": "Charge AI", "price_usd": 0.00000576413, "symbol": "CHARGE", "type": "token" }, { "address": "0x202e72dcbc815ca222f1a0674dd08755545b1329", "label": null, "launchpad": "pons", "launchpad_name": "Pons", "liquidity_usd": 4928.79, "logo": "https://chargeit.fun/assets/charge-token.png", "name": "CHARGE", "price_usd": 0.00000297461, "symbol": "CHARGE", "type": "token" }, { "address": "0xc15f9324d2742387f98e2dba6b3745e5390113ec", "label": null, "launchpad": "pons", "launchpad_name": "Pons", "liquidity_usd": 2518.27, "logo": "https://chargeit.fun/assets/charge-token.png", "name": "CHARGE", "price_usd": 0.00000691616, "symbol": "CHARGE", "type": "token" } ], "meta": { "block": 95504438, "block_age_ms": 1110, "block_ts": 1792712999000, "chain": "robinhood", "finalized_block": 95493649, "lag_ms": 4, "safe_block": 95497061 } } ``` --- # Chain stats & status > Chain-wide Robinhood Chain numbers (volume, trades, TVL, launches, gas) and the API's own health and supported chains. Source: https://crius.sh/docs/reference/chain/ Chain-wide numbers and the API's own health. `/v1/status` and `/v1/chains` are public and never count against your credits' rate limit tiers. | Endpoint | Method | Plan | Credits | |---|---|---|---| | [Chain stats](#chain-stats) | `GET /v1/{chain}/stats` | Anonymous | 1 | | [Volume history](#volume-history) | `GET /v1/{chain}/volume` | Anonymous | 1 | | [Service status](#service-status) | `GET /v1/status` | Anonymous | 1 | | [Supported chains](#supported-chains) | `GET /v1/chains` | Anonymous | 1 | ## Chain stats **GET** `/v1/{chain}/stats` **Plan:** Anonymous and above (no key needed) · **Cost:** 1 credit per call DEX volume and trades (per DEX), traders, TVL and locked liquidity, launches and graduations per launchpad, pools, gas costs and block times over a window (`1h`, `24h`, `7d`). > DEX volume by DEX, txs, active wallets, gas (L2 + L1 base fee), TVL, new tokens / pools, launchpads, reorgs. ### Parameters | Name | In | Type | Default | Description | |---|---|---|---|---| | `chain` | path, required | string | | Chain slug (`robinhood`) or chain id (`4663`). | | `window` | query | string | `24h` | Stats window. One of `1h`, `24h`, `7d`. | ### Request **cURL** ```bash curl "https://api.crius.sh/v1/robinhood/stats?window=24h" \ -H "x-api-key: $CRIUS_API_KEY" ``` **JavaScript** ```js const res = await fetch("https://api.crius.sh/v1/robinhood/stats?window=24h", { headers: { "x-api-key": process.env.CRIUS_API_KEY }, }); const { data, meta } = await res.json(); ``` **Python** ```python import os, requests r = requests.get( "https://api.crius.sh/v1/robinhood/stats?window=24h", headers={"x-api-key": os.environ["CRIUS_API_KEY"]}, ) body = r.json() print(body["data"]) ``` [Try it in the playground →](https://crius.sh/docs/playground/?op=GET%20%2Fv1%2F%7Bchain%7D%2Fstats) ### Example response Real response captured from the API (arrays trimmed to three items). ```json { "data": { "blocks": { "active_wallets": 205789, "avg_block_time_ms": 101, "tps_1m": 18.8333, "txs": 2570488 }, "chain": "robinhood", "chain_id": 4663, "dex": { "by_dex": { "launch_curve": 6291.49, "pons_curve": 6266676, "uniswap_v2": 8942369, "uniswap_v3": 289370967, "uniswap_v4": 301724002 }, "traders": 133324, "trades": 1813448, "volume_usd": 606310305, "wash_volume_usd": 200421513 }, "eth_usd": 2381.97, "finalized_block": 95493649, "gas": { "avg_swap_cost_eth": 0.00000496024, "avg_swap_cost_usd": 0.0118151, "l1_base_fee_gwei": 0, "l2_gas_price_gwei": 0.02005 }, "head_block": 95504320, "l1_block": 26251549, "launchpads": [ { "graduated": 23, "launches": 1588, "launchpad": "pons", "launchpad_name": "Pons", "volume_usd": 22444782 }, { "graduated": 0, "launches": 0, "launchpad": "long", "launchpad_name": "Long.xyz", "volume_usd": 4704791 }, { "graduated": 0, "launches": 1374, "launchpad": "flap", "launchpad_name": "Flap.sh", "volume_usd": 378098 } ], "liquidity": { "locked_lp_usd": 44757959, "method": "2x quote side (ETH/WETH/USDG) of every pool; V3/V4 in-range", "tvl_usd": 261906682 }, "pools": { "by_dex": { "launch_curve": 1381, "pons_curve": 1590, "uniswap_v2": 1718, "uniswap_v3": 211, "uniswap_v4": 4574 }, "new": 9474 }, "reorgs": { "count": 0, "max_depth": 0 }, "safe_block": 95497061, "tokens": { "by_attribution": { "known_launchpad": 3025, "other": 4646 }, "new": 7671, "new_1h": 284 }, "window": "24h" }, "meta": { "block": 95504320, "block_age_ms": 1169, "block_ts": 1792712987000, "chain": "robinhood", "coverage": { "note": "aggregates cover blocks indexed since start_block until backfill completes", "since_block": 0 }, "finalized_block": 95493649, "lag_ms": 23, "safe_block": 95497061 } } ``` ## Volume history **GET** `/v1/{chain}/volume` **Plan:** Anonymous and above (no key needed) · **Cost:** 1 credit per call On-chain volume per hour or per day, in your time zone (`tz`), plus a weekday × hour pattern over `pattern_days`. > Organic DEX volume (wash round trips and mispriced outliers excluded, reported separately) for 1s, 30s, 1m, 5m, 1h, 6h, 24h, 7d, 30d, 90d, 180d with the previous window and change %; hourly and daily series; average volume by day of week and hour of day with the peak / quietest day and hour. ### Parameters | Name | In | Type | Default | Description | |---|---|---|---|---| | `chain` | path, required | string | | Chain slug (`robinhood`) or chain id (`4663`). | | `tz` | query | string | `UTC` | IANA time zone for series and patterns, e.g. Asia/Dubai | | `hours` | query | integer | `48` | Hourly series length (max 4320) | | `days` | query | integer | `30` | Daily series length (max 365) | | `pattern_days` | query | integer | `90` | Lookback for weekday / hour-of-day patterns (7..365) | ### Request **cURL** ```bash curl "https://api.crius.sh/v1/robinhood/volume?days=3" \ -H "x-api-key: $CRIUS_API_KEY" ``` **JavaScript** ```js const res = await fetch("https://api.crius.sh/v1/robinhood/volume?days=3", { headers: { "x-api-key": process.env.CRIUS_API_KEY }, }); const { data, meta } = await res.json(); ``` **Python** ```python import os, requests r = requests.get( "https://api.crius.sh/v1/robinhood/volume?days=3", headers={"x-api-key": os.environ["CRIUS_API_KEY"]}, ) body = r.json() print(body["data"]) ``` [Try it in the playground →](https://crius.sh/docs/playground/?op=GET%20%2Fv1%2F%7Bchain%7D%2Fvolume) ### Example response Real response captured from the API (arrays trimmed to three items). ```json { "data": { "as_of_ts": 1792713002000, "by_hour": { "lookback_days": 90, "peak_hour": 8, "quietest_hour": 6, "rows": [ { "avg_trades": 177747, "avg_volume_usd": 36027698, "days_counted": 89, "hour": 0, "share_pct": 3.66431 }, { "avg_trades": 166744, "avg_volume_usd": 35665069, "days_counted": 89, "hour": 1, "share_pct": 3.62742 }, { "avg_trades": 162154, "avg_volume_usd": 34941948, "days_counted": 89, "hour": 2, "share_pct": 3.55388 } ] }, "by_weekday": { "lookback_days": 90, "peak_day": "wednesday", "quietest_day": "saturday", "rows": [ { "avg_trades": 4264617, "avg_volume_usd": 968689232, "day": "monday", "days_counted": 13, "share_pct": 14.3911, "total_volume_usd": 12592960015 }, { "avg_trades": 4306977, "avg_volume_usd": 952555293, "day": "tuesday", "days_counted": 13, "share_pct": 14.1514, "total_volume_usd": 12383218808 }, { "avg_trades": 4247466, "avg_volume_usd": 1315579650, "day": "wednesday", "days_counted": 13, "share_pct": 19.5446, "total_volume_usd": 17102535454 } ] }, "chain": "robinhood", "daily": { "busiest_day": { "ts": 1792454400000, "volume_usd": 785839219 }, "days": 3, "rows": [ { "buy_volume_usd": 406035573, "sell_volume_usd": 359285154, "trades": 1990123, "ts": 1792368000000, "volume_usd": 765320727, "wash_volume_usd": 51202821 }, { "buy_volume_usd": 412495058, "sell_volume_usd": 373344161, "trades": 2058495, "ts": 1792454400000, "volume_usd": 785839219, "wash_volume_usd": 63152996 }, { "buy_volume_usd": 409292682, "sell_volume_usd": 364524132, "trades": 1927963, "ts": 1792540800000, "volume_usd": 773816813, "wash_volume_usd": 250233541 } ] }, "hourly": { "busiest_hour": { "ts": 1792587600000, "volume_usd": 76065983 }, "hours": 48, "rows": [ { "buy_volume_usd": 9614183, "sell_volume_usd": 10150419, "trades": 61466, "ts": 1792537200000, "volume_usd": 19764602, "wash_volume_usd": 2319.6 }, { "buy_volume_usd": 18026939, "sell_volume_usd": 10937695, "trades": 70522, "ts": 1792540800000, "volume_usd": 28964634, "wash_volume_usd": 3969.95 }, { "buy_volume_usd": 22028599, "sell_volume_usd": 14188651, "trades": 78243, "ts": 1792544400000, "volume_usd": 36217250, "wash_volume_usd": 542.029 } ] }, "method": { "caught_up": true, "data_since_ts": 1779484440000, "live": "windows up to 1h from the live trade flow (chain time); longer windows from complete minutes plus the live flow", "outliers": "excluded: single trades valued above $25000000 (mispriced quotes), counted in outlier_trades", "table_through_ts": 1792712160000, "volume": "organic DEX volume in USD at trade time (Uniswap V2/V3/V4, launchpad curves)", "wash": "excluded: same-tx round trips — buys and sells of one token in one pool inside one tx that cancel within 2%" }, "tz": "UTC", "windows": { "180d": { "buy_volume_usd": 50850627836, "buys": 251007714, "change_pct": null, "complete": false, "outlier_trades": 762, "prev_volume_usd": null, "sell_volume_usd": 49094120147, "sells": 201749315, "tokens": 1714938, "traders": 8046201, "traders_note": "unique traders / tokens: approximate (HyperLogLog), up to the last complete minute", "trades": 452757029, "volume_usd": 99944747982, "wash_trades": 1094957, "wash_volume_usd": 42838880023 }, "1h": { "buy_volume_usd": 6521622, "buys": 27264, "change_pct": -17.6883, "complete": true, "outlier_trades": 0, "prev_volume_usd": 15480548, "sell_volume_usd": 6220679, "sells": 29534, "tokens": 1407, "traders": 13621, "trades": 56798, "volume_usd": 12742301, "wash_trades": 180, "wash_volume_usd": 17438.9 }, "1m": { "buy_volume_usd": 118041, "buys": 512, "change_pct": -15.0449, "complete": true, "outlier_trades": 0, "prev_volume_usd": 232608, "sell_volume_usd": 79571.7, "sells": 518, "tokens": 155, "traders": 655, "trades": 1030, "volume_usd": 197613, "wash_trades": 0, "wash_volume_usd": 0 }, "1s": { "buy_volume_usd": 1800.8, "buys": 10, "change_pct": -17.5412, "complete": true, "outlier_trades": 0, "prev_volume_usd": 2834.22, "sell_volume_usd": 536.265, "sells": 19, "tokens": 20, "traders": 27, "trades": 29, "volume_usd": 2337.06, "wash_trades": 0, "wash_volume_usd": 0 }, "24h": { "buy_volume_usd": 301601210, "buys": 886515, "change_pct": -21.6648, "complete": true, "outlier_trades": 0, "prev_volume_usd": 773649330, "sell_volume_usd": 304438221, "sells": 926883, "tokens": 14888, "traders": 138035, "traders_note": "unique traders / tokens: approximate (HyperLogLog), up to the last complete minute", "trades": 1813398, "volume_usd": 606039431, "wash_trades": 5664, "wash_volume_usd": 200421513 }, "30d": { "buy_volume_usd": 14140869827, "buys": 42447959, "change_pct": -36.4234, "complete": true, "outlier_trades": 71, "prev_volume_usd": 43327079234, "sell_volume_usd": 13404998806, "sells": 37205101, "tokens": 339305, "traders": 2683156, "traders_note": "unique traders / tokens: approximate (HyperLogLog), up to the last complete minute", "trades": 79653060, "volume_usd": 27545868633, "wash_trades": 291949, "wash_volume_usd": 5473124254 }, "30s": { "buy_volume_usd": 62726.6, "buys": 274, "change_pct": 26.5104, "complete": true, "outlier_trades": 0, "prev_volume_usd": 87242.2, "sell_volume_usd": 47643.9, "sells": 283, "tokens": 99, "traders": 373, "trades": 557, "volume_usd": 110370, "wash_trades": 0, "wash_volume_usd": 0 }, "5m": { "buy_volume_usd": 648763, "buys": 2364, "change_pct": -14.88, "complete": true, "outlier_trades": 0, "prev_volume_usd": 1306464, "sell_volume_usd": 463298, "sells": 2356, "tokens": 408, "traders": 2162, "trades": 4720, "volume_usd": 1112062, "wash_trades": 32, "wash_volume_usd": 168.603 }, "6h": { "buy_volume_usd": 59865359, "buys": 219376, "change_pct": -45.2913, "complete": true, "outlier_trades": 0, "prev_volume_usd": 211705646, "sell_volume_usd": 55955956, "sells": 234561, "tokens": 6654, "traders": 59706, "traders_note": "unique traders / tokens: approximate (HyperLogLog), up to the last complete minute", "trades": 453937, "volume_usd": 115821315, "wash_trades": 2261, "wash_volume_usd": 50239242 }, "7d": { "buy_volume_usd": 2606750843, "buys": 7154932, "change_pct": -7.25784, "complete": true, "outlier_trades": 1, "prev_volume_usd": 5406594475, "sell_volume_usd": 2407441833, "sells": 6604355, "tokens": 83088, "traders": 595487, "traders_note": "unique traders / tokens: approximate (HyperLogLog), up to the last complete minute", "trades": 13759287, "volume_usd": 5014192677, "wash_trades": 53285, "wash_volume_usd": 3158836968 }, "90d": { "buy_volume_usd": 44809183487, "buys": 216119667, "change_pct": null, "complete": true, "outlier_trades": 343, "prev_volume_usd": null, "sell_volume_usd": 43302190175, "sells": 172546045, "tokens": 1473185, "traders": 7252784, "traders_note": "unique traders / tokens: approximate (HyperLogLog), up to the last complete minute", "trades": 388665712, "volume_usd": 88111373662, "wash_trades": 936753, "wash_volume_usd": 40959870437 } } }, "meta": { "block": 95504461, "block_age_ms": 363, "block_ts": 1792713002000, "chain": "robinhood", "finalized_block": 95493649, "lag_ms": 4, "safe_block": 95497061 } } ``` ## Service status **GET** `/v1/status` **Plan:** Anonymous and above (no key needed) · **Cost:** 1 credit per call Per-chain index health: `status` (`live`, `catching_up`, `stalled`, `starting`), indexed block, lag behind the chain head, safe and finalized blocks, and how many tokens, pools and addresses are indexed. Public. For uptime history and incidents see [status.crius.sh](https://status.crius.sh). > Public, no key. ### Request **cURL** ```bash curl "https://api.crius.sh/v1/status" \ -H "x-api-key: $CRIUS_API_KEY" ``` **JavaScript** ```js const res = await fetch("https://api.crius.sh/v1/status", { headers: { "x-api-key": process.env.CRIUS_API_KEY }, }); const { data, meta } = await res.json(); ``` **Python** ```python import os, requests r = requests.get( "https://api.crius.sh/v1/status", headers={"x-api-key": os.environ["CRIUS_API_KEY"]}, ) body = r.json() print(body["data"]) ``` [Try it in the playground →](https://crius.sh/docs/playground/?op=GET%20%2Fv1%2Fstatus) ### Example response Real response captured from the API (arrays trimmed to three items). ```json { "data": { "chains": { "robinhood": { "addresses": 28099296, "block_age_ms": 467, "chain_id": 4663, "finalized_block": 95493649, "indexed_block": 95504215, "lag_ms": 133, "pools": 2729257, "safe_block": 95497061, "start_block": 0, "status": "live", "tokens": 2366366 } }, "region": "dxb-1", "version": "0.1.0" } } ``` ## Supported chains **GET** `/v1/chains` **Plan:** Anonymous and above (no key needed) · **Cost:** 1 credit per call Chains this API serves, with chain id, native symbol and block time. ### Request **cURL** ```bash curl "https://api.crius.sh/v1/chains" \ -H "x-api-key: $CRIUS_API_KEY" ``` **JavaScript** ```js const res = await fetch("https://api.crius.sh/v1/chains", { headers: { "x-api-key": process.env.CRIUS_API_KEY }, }); const { data, meta } = await res.json(); ``` **Python** ```python import os, requests r = requests.get( "https://api.crius.sh/v1/chains", headers={"x-api-key": os.environ["CRIUS_API_KEY"]}, ) body = r.json() print(body["data"]) ``` [Try it in the playground →](https://crius.sh/docs/playground/?op=GET%20%2Fv1%2Fchains) ### Example response Real response captured from the API (arrays trimmed to three items). ```json { "data": [ { "block_time_ms": 100, "chain_id": 4663, "name": "Robinhood Chain", "native": "ETH", "regions": [ "dxb-1" ], "slug": "robinhood", "type": "arbitrum_orbit_l2" } ] } ``` --- # WebSocket stream > Real-time Robinhood Chain data over one WebSocket - trades, prices, live candles, new launches, graduations, new pools, LP and tax changes, wallet activity, with replay and reorg handling. Source: https://crius.sh/docs/reference/stream/ **WS** `wss://api.crius.sh/v1/{chain}/stream` **Plan:** Free and above, key with the `stream` scope · **Cost:** 1 credit per connection One connection carries many subscriptions. Messages are pushed as soon as a block is decoded, typically well under a second after it was produced. ## Connecting Authenticate with the `x-api-key` header, or with `?api_key=` where a client can't set headers (browsers): ```js const ws = new WebSocket(`wss://api.crius.sh/v1/robinhood/stream?api_key=${key}`); ``` On connect the server sends a greeting with your limits: ```json {"ch": "hello", "data": {"chain": "robinhood", "heartbeat_s": 15, "max_subscriptions": 10}} ``` ## Operations Send JSON messages with an `op`: | Op | Message | Reply | |---|---|---| | Subscribe | `{"op": "subscribe", "channels": ["trades:0x…", "launches:all"]}` | `{"ch": "subscribed", "data": {"channels": […], "finality": "latest"}}` | | Unsubscribe | `{"op": "unsubscribe", "channels": ["trades:0x…"]}` | `{"ch": "unsubscribed", …}` | | Settled data only | `{"op": "subscribe", "channels": […], "finality": "safe"}` | events are held until their block is `safe` | | Resume after a reconnect | `{"op": "resume", "seqs": {"trades:0x…": 90455}}` | missed messages (up to 60 s), then `{"ch": "resumed"}` | | Ping | `{"op": "ping"}` | `{"ch": "pong", "ts": …}` | Channel names are lowercase. Subscribing over your plan's limit, or to an Enterprise channel, returns `{"ch": "error", "data": {"code": "channel_denied", …}}` for those channels. ## Channels | Channel | Pushes | |---|---| | `trades:` | Every trade of a token (same shape as the [trade tape](https://crius.sh/docs/reference/trades/#trade-tape)) | | `trades:pool:` | Every trade in one pool | | `price:` | Price updates (`usd`, `eth`, `liquidity_usd`); a snapshot is sent right after subscribing | | `candles::` | The live candle (`t`, `o`, `h`, `l`, `c`, `v`, `n`) for `1s` … `1d` | | `token:` | Price and holder count changes | | `tax:` | Realized buy/sell tax changes | | `lp:` | Liquidity added or removed in the token's pools | | `launches:` / `launches:all` | New launches (`pons`, `flap`, …) | | `graduations:` / `graduations:all` | Graduations, with the new pool | | `pools:new` | Every new Uniswap v2 / v3 / v4 pool, with hook permissions | | `wallet:
` | Trades and transfers of a wallet | | `dev:
` | New tokens launched by a creator | | `firehose:trades` | Every trade on the chain (Enterprise) | Every message has the same envelope: ```json { "ch": "trades:0x0bd7d308f8e1639fab988df18a8011f41eacad73", "seq": 90455, "block": 95503752, "ts": 1792712930000, "data": { "id": "95503752-4-7", "type": "buy", "token": "0x0bd7d308f8e1639fab988df18a8011f41eacad73", "symbol": "WETH", "dex": "uniswap_v4", "trader": "0x2192bc3b4028acc1113f2cd9ac2cba70c36520db", "amount_base": 0.02724675461168212, "amount_quote": 64.939074, "price_usd": 2383.37, "value_usd": 64.9391 } } ``` `seq` increases by one per channel. Keep the last `seq` you saw for each channel and send them in a `resume` op after reconnecting to receive what you missed (60-second replay buffer). ## Heartbeats, finality and reorgs - `{"ch": "heartbeat", "ts": …, "uptime_s": …}` arrives every 15 seconds; reconnect if you hear nothing for 45 seconds. - `{"ch": "finality", "data": {"safe_block": …, "finalized_block": …}}` arrives on every connection whenever the safe or finalized block moves. - If blocks are replaced, a `{"ch": "reorg", "data": {"common_ancestor", "removed_blocks", "depth"}}` message comes first, then every affected event is re-sent with `"removed": true` (same `id`), then the replacement events. Subscribe with `"finality": "safe"` if you never want to see reorged events. > **Tip:** > A complete reconnecting client is in the [real-time stream example](https://crius.sh/docs/examples/stream/). --- # Account API > Manage your Crius account programmatically - email and wallet sign-in, usage and quota, API keys (create, update, rotate, revoke), dashboard sessions and linked wallets. Source: https://crius.sh/docs/reference/account/ The Account API lives at **`https://account.crius.sh`** (the same paths also work on `api.crius.sh`, which forwards them). Account calls are **free**: they never cost credits and have their own limit of 10 requests per second. | Access | Endpoints | |---|---| | No key | sign-up and sign-in (`/v1/account/signup/*`) | | Any key of the account | `GET /v1/account/usage` | | Dashboard session only | everything else: profile, keys, sessions, wallets, billing | API keys can read usage but can never manage the account. Management needs a **session key** from a dashboard sign-in, which lasts 7 days and can't call data endpoints. This is what [dashboard.crius.sh](https://dashboard.crius.sh) uses; you only need these endpoints to build your own tooling. ## Sign up and sign in ### Email code ```bash # 1. Ask for a one-time code (the dashboard also sends a Cloudflare Turnstile token). curl -X POST https://account.crius.sh/v1/account/signup/email \ -H "content-type: application/json" \ -d '{"email": "you@example.com", "turnstile_token": "…"}' # 2. Verify it. "session": true returns a 7-day dashboard session instead of a new API key. curl -X POST https://account.crius.sh/v1/account/signup/email/verify \ -H "content-type: application/json" \ -d '{"email": "you@example.com", "code": "123456", "session": true}' ``` A new email creates an account on the Free plan; a known email signs in. Codes expire after 10 minutes and five wrong attempts void a code. One account per inbox: `+tags`, dots in Gmail addresses and `googlemail.com` are folded together, and disposable inboxes are refused. ### Wallet A wallet [linked to your account](#wallets) can sign in without email: 1. `GET /v1/account/signup/challenge?address=0x…` returns a message to sign (valid 10 minutes). 2. Sign it with `personal_sign` (EIP-191). Nothing is sent on-chain and it costs nothing. 3. `POST /v1/account/signup/wallet` with `{"address", "signature", "session": true}`. ## Account and usage | Method | Path | Returns | |---|---|---| | GET | `/v1/account` | Account id, email, plan, status, linked wallets, limits | | GET | `/v1/account/usage` | Month-to-date credits used and remaining, rate limit, current subscription, daily usage for 30 days, top endpoints this month | ```bash curl https://account.crius.sh/v1/account/usage -H "x-api-key: $CRIUS_API_KEY" ``` Usage is flushed every few seconds, so a request you just made appears almost immediately. ## API keys | Method | Path | Does | |---|---|---| | GET | `/v1/account/keys` | List keys (prefix, name, scopes, restrictions, status, last used) | | POST | `/v1/account/keys` | Create a key; the response contains the secret, **once** | | PATCH | `/v1/account/keys/{key_id}` | Change name, scopes, IP allow-list, allowed origins, rate limit or expiry | | POST | `/v1/account/keys/{key_id}/rotate` | New secret; the old one works for `grace_period_s` (default 3,600, max 7 days) | | DELETE | `/v1/account/keys/{key_id}` | Revoke immediately | Body fields for create and update: ```json { "name": "trading-bot", "scopes": ["read", "stream"], "ip_allowlist": ["203.0.113.7", "10.0.0.0/8"], "allowed_origins": [], "expires_in_days": 90, "limits": { "rps": 5 }, "env": "live" } ``` `scopes` accepts `read`, `stream`, `simulate` and `export`. A key with `allowed_origins` is read-only. `limits.rps` can't exceed your plan. An account can have 20 active keys. ## Sessions | Method | Path | Does | |---|---|---| | GET | `/v1/account/sessions` | Dashboard sign-ins that are still valid | | DELETE | `/v1/account/sessions/{key_id}` | Sign one out | ## Wallets Linked wallets are a sign-in method and are used to pay and control your [subscription on-chain](https://crius.sh/docs/reference/billing/). A wallet belongs to one account, and an account can link up to 10. | Method | Path | Does | |---|---|---| | GET | `/v1/account/wallets` | List linked wallets | | POST | `/v1/account/wallets` | Link: `{"address", "signature"}` over a fresh challenge | | DELETE | `/v1/account/wallets/{address}` | Unlink | > **Note:** > We email you when a key is created, rotated or revoked and when a wallet is linked or unlinked, with the IP that did > it. If you didn't, revoke your keys and sign out every session. --- # Billing & payments > How Crius plans are paid on-chain on Robinhood Chain in USDG, ETH or WETH - pricing, 6 and 12 month discounts, auto-renew with a price cap, upgrades with credit, and the billing endpoints. Source: https://crius.sh/docs/reference/billing/ Crius plans are paid **on-chain on Robinhood Chain** through the CriusPayments contract at [`0xee4ce8614BCd9D910Ae0e4f0995B26eDC017A8ec`](https://robinhoodchain.blockscout.com/address/0xee4ce8614BCd9D910Ae0e4f0995B26eDC017A8ec). You pay from your own wallet; we never hold your funds, and there are no cards or stored payment details. Payments go straight to the Crius treasury. The easiest way to pay is the **Billing** page of the [dashboard](https://dashboard.crius.sh), which does every step below for you. ## Prices | Plan | 1 month | 6 months (10% off) | 12 months (20% off) | |---|---|---|---| | Starter | $19 | $102.60 | $182.40 | | Pro | $79 | $426.60 | $758.40 | | Business | $249 | $1,344.60 | $2,390.40 | - **USDG** is charged exactly at the USD price. - **ETH and WETH** amounts follow the Chainlink ETH/USD feed on Robinhood Chain at the moment you pay. You send a little more than the quote (about 1%) as a maximum, the contract charges the live quote, and any extra ETH is refunded in the same transaction. - Enterprise plans are arranged with us: [support@crius.sh](mailto:support@crius.sh). ## How a payment works 1. **Get your payment reference.** `GET /v1/account/billing` (dashboard session) returns your account's private `account_ref` (a bytes32 only your account can derive), the contract and token addresses, live quotes for every plan, period and token, and your on-chain subscription. 2. **Pay.** Call `pay(account_ref, plan, months, token, maxAmount, minExpiresAt)` on the contract with `plan` 2 (Starter), 3 (Pro) or 4 (Business) and `months` 1, 6 or 12. For USDG and WETH, approve the amount first. 3. **Done.** About 20 blocks later our watcher sees the `PaymentReceived` event, moves your account to the plan until the expiry the contract set, and emails you a receipt. ## Renewals, upgrades and credit - **Paying again extends** your subscription from its current end date, so you never lose days by renewing early. - **Changing plan** converts the unused time of your current plan into credit on the new one; nothing is lost. - **Auto-renew** (USDG or WETH) is opt-in: you approve a maximum price per renewal, and the renewal can be charged from 3 days before expiry. You can cancel any time from the wallet that set it up. If a renewal fails (low balance or allowance), we email you; after 7 days past expiry, auto-renew switches itself off. - When a subscription ends, the account returns to the Free plan. We email you 7 days and 1 day before (unless auto-renew is on). ## Controller wallet The first wallet that pays for an account becomes its on-chain **controller**: the only wallet that can turn auto-renew on or off. If someone else paid for your account first, `POST /v1/account/billing/claim` with `{"wallet": "0x…"}` (one of your [linked wallets](https://crius.sh/docs/reference/account/#wallets)) returns a one-hour signed claim; submit it with `claimController(account_ref, wallet, issued_at, signature)` to take control. One claim per account per hour. > **Note:** > Refunds are described in the [Refund policy](https://crius.sh/refunds/). On-chain transactions are final, so check the plan, period > and amount before you confirm in your wallet. --- # Robinhood Chain > What Robinhood Chain is (chain id 4663), its block times, gas, L1 settlement, native assets (ETH, WETH, USDG), tokenized stocks, and how Crius indexes it. Source: https://crius.sh/docs/concepts/robinhood-chain/ **Robinhood Chain** is an Ethereum layer-2 network (an Arbitrum Orbit chain) with chain id **4663** (`0x1237`). Transactions are ordered by a sequencer and settled on Ethereum. | | | |---|---| | Chain id | `4663` | | Native gas token | ETH | | Block time | about 100 ms | | Official RPC | `https://rpc.mainnet.chain.robinhood.com` | | Explorers | [Blockscout](https://robinhoodchain.blockscout.com), [Hoodscan](https://hoodscan.co) | ## Assets you'll see everywhere | Symbol | Address | Role | |---|---|---| | ETH | `0x0000000000000000000000000000000000000000` | Native gas token; quote asset of many pools and launch curves | | WETH | `0x0bd7d308f8e1639fab988df18a8011f41eacad73` | Wrapped ETH (ERC-20) | | USDG | `0x5fc5360d0400a0fd4f2af552add042d716f1d168` | Dollar stablecoin (6 decimals) | USD prices on Crius are derived from these on-chain pools: a token is priced against its deepest pool's quote asset, and the quote asset is converted to USD through the deepest ETH/USDG pool. ## Two block numbers Robinhood Chain blocks arrive every ~100 ms, but inside a smart contract `block.number` returns the **Ethereum L1 block** (about every 12 seconds). Contract rules written "per block" (anti-snipe windows, sell limits) therefore act on L1 blocks. Crius reports the L2 `block` everywhere and adds `l1_block` where it matters. ## Finality A transaction is visible as soon as the sequencer includes it (`latest`), becomes `safe` when its batch is posted to Ethereum, and `finalized` when Ethereum finalizes that batch. See [Finality & reorgs](https://crius.sh/docs/concepts/finality/). ## How Crius indexes it Crius runs its own Robinhood Chain archive nodes and decodes every block as it arrives: transfers, swaps on every Uniswap version, launchpad events, LP locks, contract calls. State (prices, holders, pools) is kept in memory for fast answers; history is stored back to block one. Every response tells you the block it reflects (`meta.block`) and how far behind the head it is (`meta.lag_ms`, usually well under a second). --- # Launchpads > How token launchpads on Robinhood Chain work (bonding curves, graduation to Uniswap pools, LP locks) and which launchpads Crius attributes, including Pons, Flap.sh, Bankr and Long.xyz. Source: https://crius.sh/docs/concepts/launchpads/ A **launchpad** lets anyone create a token in one transaction. Most start trading on a **bonding curve**: the launchpad contract sells tokens at a price that rises with each buy, against a quote asset (usually ETH). When the curve raises enough, the token **graduates**: the launchpad moves the raised liquidity into a Uniswap pool, often locking or burning the LP position, and trading continues on the DEX. ## Supported launchpads Crius attributes tokens to their launchpad automatically from the factory that created them. Live stats for each are at [`GET /v1/robinhood/launchpads`](https://crius.sh/docs/reference/launchpads/#launchpads). | Id | Name | Model | |---|---|---| | `pons` | Pons | Bonding curve that graduates into a Uniswap v4 pool with the Pons hook; the LP is locked permanently | | `flap` | [Flap.sh](https://flap.sh) | Bonding-curve launchpad | | `bankr` | [Bankr](https://bankr.bot) | Token launches from the Bankr agent | | `long` | [Long.xyz](https://long.xyz) | Token launch platform | | `standard_reserve` | [King of the Markets (Standard Reserve)](https://www.standardreserve.xyz) | Launch competition platform | Tokens from factories we haven't attributed yet are reported with `creation.attribution` other than `known_launchpad`, and `/launch` returns `meta.attribution = "unattributed_factory"`. ## Lifecycle in the API - `launch.status`: `bonding` while on the curve, `graduated` after migration. - `launch.progress_pct`: how far along the curve the token is (100 when graduated). - `launch.curve`, `launch.launched_block`, `launch.graduated_block`, `launch.graduation_threshold`. - The token's market (price, liquidity, candles) follows it from the curve into its pool seamlessly: candles for a launchpad token include the curve history by default. Stream new launches with the `launches:all` (or `launches:pons`, …) channel and graduations with `graduations:all` on the [WebSocket](https://crius.sh/docs/reference/stream/). --- # Uniswap v2, v3 & v4 > How Crius indexes Uniswap v2 pairs, v3 concentrated-liquidity pools and v4 singleton pools with hooks on Robinhood Chain, including liquidity definitions and v4 hook permissions. Source: https://crius.sh/docs/concepts/uniswap/ Crius indexes every Uniswap deployment on Robinhood Chain: v2 pairs, v3 pools at every fee tier, and v4 pools (including dynamic-fee and hooked pools). ## Identifying pools | Version | Pool id in the API | |---|---| | v2 | Pair contract address (20 bytes) | | v3 | Pool contract address (20 bytes) | | v4 | Pool id (32 bytes): all v4 pools live inside one PoolManager contract | ## Liquidity - For v2, reserves are the pair's balances. - For v3 and v4, only **in-range** liquidity counts toward depth, computed from the pool's tick map. - `liquidity_usd` is 2 × the quote side (ETH, WETH or USDG), the convention used by DEX screeners; `quote_liquidity_usd` is the quote side alone. ## v4 hooks A Uniswap v4 pool can attach a **hook**: a contract called before or after swaps and liquidity changes. Hooks enable features like launch taxes and dynamic fees, but a hook can also block swaps, change amounts or stop liquidity removal. The hook's **permissions** are encoded in the low 14 bits of its address, so they can be read without trusting the hook's code. Crius decodes them and turns them into risk flags: | Permission | Risk flag | |---|---| | `beforeSwap` | `can_block_or_reprice_swaps` | | `beforeSwapReturnDelta` / `afterSwapReturnDelta` | `can_modify_swap_amounts` | | `beforeRemoveLiquidity` | `can_gate_liquidity_removal` | | `beforeAddLiquidity` | `can_gate_liquidity_add` | | `afterAddLiquidityReturnDelta` / `afterRemoveLiquidityReturnDelta` | `can_modify_liquidity_amounts` | | unverified source | `unverified` | See [`/hooks`](https://crius.sh/docs/reference/pools/#uniswap-v4-hooks) and [`/hook/{address}`](https://crius.sh/docs/reference/pools/#hook-detail). A token's security check includes its pool hook's permissions and any **hook tax** measured from real trades. --- # Trader attribution & wallet tags > How Crius attributes Robinhood Chain trades to the real trader behind routers, aggregators, bundlers and bot contracts, and what each wallet tag means. Source: https://crius.sh/docs/concepts/attribution/ ## Who actually traded On-chain, the address that sends a transaction (`tx.from`) or calls the pool is often infrastructure: a router, an aggregator, a Relay solver, an ERC-4337 bundler, a launchpad's launch-and-buy helper, Permit2, or a trading bot's contract. Counting those as traders would make every stat wrong. For each swap Crius: 1. computes every address's net token and quote change in the transaction (including internal ETH transfers); 2. removes known infrastructure (pools, the v4 PoolManager, routers, aggregators, Permit2, vaults, lockers, launchpads); 3. takes the address that **received** the token (buy) or **sent** it (sell) as the **trader**; 4. for ERC-4337, uses the smart account as trader and the bundler as `executor`; 5. for Relay and other gasless flows, uses the user whose funds moved, with the solver as `executor`; 6. for bot contracts, uses the contract as trader and tags it `bot`. One transaction can contain several trades (a multi-recipient buy, an arbitrage). Each trade has its own `id` (`--`). ## Wallet tags | Tag | Meaning | |---|---| | `dev` | The token's deployer or launch creator | | `dev_linked` | Funded by or funding the dev, or in the same cluster | | `sniper` | Bought within the first blocks after trading opened | | `bundler` | Part of a coordinated bundle | | `fresh` | A new wallet (under 24 h old or under 5 transactions before its first buy) | | `insider` | Received tokens from the dev or launch contract without buying | | `whale` | Holds 1% or more of supply | | `bot` | Trades through its own contract, or trades like a bot (very frequent, sub-second round trips, same-block buy and sell) | | `top_trader` | Among the best traders by realized PnL | | `pool`, `lp_locker`, `burn`, `launchpad`, `protocol_fee`, `cex`, `bridge` | Infrastructure, excluded from concentration stats by default | Use `exclude=infra` or `exclude=bots` on holder and stats endpoints to leave those wallets out. --- # Finality & reorgs > Finality levels on Robinhood Chain (latest, safe, finalized), how the Crius API marks them, and how chain reorganizations are handled in REST and WebSocket. Source: https://crius.sh/docs/concepts/finality/ Every event Crius returns (trades, transfers, liquidity changes) carries a `finality`: | Level | When | Typical delay | |---|---|---| | `latest` | Included by the Robinhood Chain sequencer | under a second | | `safe` | The batch containing it has been posted to Ethereum | minutes | | `finalized` | Ethereum has finalized that batch | about 15–20 minutes more | Every response's `meta` reports the current `safe_block` and `finalized_block`, so you can tell the level of anything by its block. ## Reorgs Sequencer-ordered blocks are very rarely replaced, but it can happen. When it does: - **REST** responses simply reflect the new chain: replaced events disappear and new ones appear. - **WebSocket** clients receive a `reorg` message (`common_ancestor`, `removed_blocks`, `depth`), then every affected event again with `"removed": true` and the same `id`, then the replacement events. Undo what you did for removed events by `id`. If your application can't handle reversals (accounting, payouts), only act on `safe` data: filter by `finality=safe` where an endpoint supports it, or subscribe to the stream with `"finality": "safe"`, which holds each event until its block is safe. --- # FAQ > Answers to common questions about the Crius Robinhood Chain API - pricing, free plan, data freshness, coverage, history, rate limits, payments and support. Source: https://crius.sh/docs/faq/ ## What is the Crius API? A data API for Robinhood Chain (chain id 4663). It serves real-time and historical token prices, OHLCV candles, trades, holders, pools, launchpad data, security checks and wallet analytics over REST and WebSocket, from Crius' own archive nodes. ## Is there a free plan? Yes. The Free plan includes 1,000,000 credits a month, 10 requests per second and one WebSocket connection, with no card required. Core endpoints such as prices, tokens, trades and candles also work without a key at 2 requests per second per IP. ## How fresh is the data? Each block is decoded as it arrives from our own node, typically within a fraction of a second. Every response includes meta.block and meta.lag_ms so you can see exactly how fresh it is. ## Which tokens and DEXs are covered? Every ERC-20 on Robinhood Chain, every Uniswap v2, v3 and v4 pool (including v4 hooks), launchpads such as Pons, Flap.sh, Bankr, Long.xyz and King of the Markets, LP lockers, and tokenized stocks priced from on-chain pools. ## How far back does history go? To block one of Robinhood Chain. Candles, trades and holder history are available from each token's first block. ## What counts as a credit? Each request costs credits depending on the endpoint, from 1 (prices, token profiles) to 20 (a fresh security simulation). Account API calls are free. Credits reset at the start of each UTC month. ## How do I pay? On-chain on Robinhood Chain in USDG, ETH or WETH through the CriusPayments contract, from the Billing page of the dashboard. 6 months are 10% off and 12 months 20% off. Optional auto-renew uses a price cap you set. ## Do you store card details? No. Payments are on-chain from your own wallet; we never hold funds or payment details. ## Can I use the API from a browser? Yes, with care. Anonymous endpoints work directly. For keyed requests, restrict a key to your site's origin (it becomes read-only) or proxy requests through your backend so the key never reaches the page. ## Is the price data financial advice? No. Data is provided as is for building products and research. Always verify before trading. ## How do I get help? Email support@crius.sh. Service status and incidents are at status.crius.sh. --- # Changelog > Changes to the Crius API, dashboard and documentation. Source: https://crius.sh/docs/changelog/ New endpoints, fields and behaviour changes are listed here, newest first. Additive changes (new fields, new endpoints) can ship at any time; breaking changes are announced here first. ## October 2026 - **Account API moved to `account.crius.sh`.** Accounts, keys and usage are now served by a dedicated control plane. `api.crius.sh/v1/account/*` keeps working. - **Dashboard sessions.** Signing in to the dashboard issues a 7-day session key that can manage the account but can't call data endpoints; API keys can no longer manage the account. New `GET /v1/account/sessions`. - **Account calls are free.** `/v1/account/*` no longer costs credits and has its own rate limit. - **On-chain billing.** Plans can be paid in USDG, ETH or WETH on Robinhood Chain, for 1, 6 or 12 months, with optional auto-renew. New `GET /v1/account/billing` and `POST /v1/account/billing/claim`. - **Email sign-up and wallet sign-in** for the dashboard, with linked wallets. - **New documentation** at crius.sh/docs with a playground, a chart example and Markdown versions of every page. ## Earlier - Launch of the Crius API for Robinhood Chain: tokens, prices, pools, trades, candles, holders (live, snapshots, cohorts, history), traders, security, liquidity, launchpads, fees, wallets, bundles, bubble maps, hooks, discovery, chain stats and the WebSocket stream. --- # For AI agents & LLMs > How AI assistants and agents can read the Crius documentation (llms.txt, llms-full.txt, Markdown pages) and call the Crius API (OpenAPI document, anonymous endpoints). Source: https://crius.sh/docs/ai/ The Crius documentation is built to be read by language models as easily as by people. | Resource | URL | Use | |---|---|---| | `llms.txt` | [`https://crius.sh/llms.txt`](https://crius.sh/llms.txt) | Index of the docs with one-line summaries ([llmstxt.org](https://llmstxt.org) format) | | `llms-full.txt` | [`https://crius.sh/llms-full.txt`](https://crius.sh/llms-full.txt) | All documentation in one Markdown file | | Markdown pages | `https://crius.sh/docs/.md` | Any docs page as clean Markdown, e.g. [`/docs/quickstart.md`](https://crius.sh/docs/quickstart.md) | | OpenAPI 3 | [`https://api.crius.sh/openapi.json`](https://api.crius.sh/openapi.json) | Machine-readable endpoints and parameters, for tool or function definitions | Every docs page also has a **Copy page** button that copies its Markdown, ready to paste into a chat. ## Giving an agent access to the API - Core endpoints (prices, token profiles, pools, trades, candles, search, stats) work **without a key**, so an agent can explore at 2 requests per second. - For anything more, create a dedicated API key for the agent with only the `read` scope, an IP allow-list if it runs on a fixed host, and a per-key rate limit. Rotate or revoke it from the dashboard at any time. - Responses are compact JSON with plain decimal numbers and a `meta.block` that lets the agent cite exactly which block its answer reflects. ## Suggested system prompt snippet ```text You can call the Crius API (https://api.crius.sh) for Robinhood Chain (chain id 4663) data. Docs: https://crius.sh/llms.txt. Send the key in the x-api-key header. Token price: GET /v1/robinhood/token/{address}/price. Token profile: GET /v1/robinhood/token/{address}. Candles: GET /v1/robinhood/token/{address}/candles?interval=1h. Search: GET /v1/robinhood/search?q=. Amounts are in human units, USD values are plain decimals, timestamps are unix milliseconds. ``` ---