developers · api v1

Live Robinhood Chain data, as an API.

Everything the registry shows is served as JSON: 32 operations across 7 areas. Reads need no key and answer with an ETag. Every example below is the live answer this server gave when the page was rendered, cut to fit. The same document drives Swagger UI and is served raw at openapi.json; agents get the plain-text version at llms.txt. An MCP server is built and will be published to npm soon; until then everything here is plain HTTPS.

curl

curl https://fletch.now/api/v1/chains/4663/assets/TSLA

fetch

const res = await fetch("https://fletch.now/api/v1/chains/4663/assets/TSLA");
const { asset, state } = await res.json();
console.log(asset.address, state.multiplier, state.feed?.price);

MCP · coming soon

# The MCP server (packages/fletch-mcp) is built and not yet published to npm.
# When it is: claude mcp add fletch -- npx -y fletch-mcp

poll with ETag

curl -i https://fletch.now/api/v1/chains/4663/events?limit=20
# … ETag: W/"abc"
curl -i -H 'If-None-Match: W/"abc"' https://fletch.now/api/v1/chains/4663/events?limit=20
# HTTP/1.1 304 Not Modified

Reading

Registry, changelog, chain and status routes are public: 120 requests a minute per address without a key. Every GET answers with an ETag and a Cache-Control on the writing job's cadence; send If-None-Match and an unchanged answer is a 304 with no body.

Writing

Watchers, webhooks, builds and projects need a key: Authorization: Bearer flk_…, created in Settings, 600 requests an hour. Scopes: registry:read, watchers:read, watchers:write, builds:read, projects:read. A signed-in browser session also authenticates.

Shapes and promises

Raw amounts (*Raw, *Wei) are strings, exact as on chain. Prices and multipliers are numbers. Timestamps are ISO 8601. Every figure carries the time it was read. Fields are added, never renamed. A figure that is partial says so (filling, complete: false) rather than pretending.

Status

Whether the registry is live and how old each figure is. Read this first when freshness matters.

GET/chains/{chainId}/statuspublic · 120/min per IP · ETag

Whether the registry is live: the daemon's heartbeat, every job against its cadence, the scanners still reading history, and the age of every published figure

Public. Always 200; the verdict is in the body ('live', 'degraded', 'stale', 'never'), so a stale registry is a fact to read rather than an error to retry. Each job carries its cadence, last successful run, age and verdict ('fresh', 'late', 'failing', 'filling', 'never'); each figure names the job that writes it and the newest timestamp behind it. Also served at /api/v1/status.

ParameterInTypeMeaning
chainId*pathintegere.g. 4663

Responses: 200 Freshness · 404 Unknown chain · 429 Too many anonymous requests

https://fletch.now/api/v1/chains/4663/status

{
  "chainId": 4663,
  "checkedAt": "2026-09-04T21:10:50.436Z",
  "verdict": "degraded",
  "summary": "2 of 27 jobs are not current (stalled: dex-swaps; no completed run yet: transfer-ledger).",
  "daemon": {
    "name": "registry-daemon",
    "alive": true,
    "lastBeatAt": "2026-09-04T21:10:45.280Z",
    "ageSeconds": 5,
    "jobsReported": 27,
    "failing": []
  },
  "head": {
    "block": "54574772",
    "readAt": "2026-09-04T21:10:25.582Z",
    "ageSeconds": 25
  },
  "jobs": [
    {
      "job": "control-plane",
      "cadenceSeconds": 10,
      "verdict": "fresh",
      "lastRunAt": "2026-09-04T21:10:37.396Z",
      "lastOkAt": "2026-09-04T21:10:27.395Z",
      "ageSeconds": 23,
      "rows": 0,
      "error": null,
      "running": true,
      "checkpoints": [
        {
          "name": "…",
          "block": "…",
          "head": "…",
          "behind": "…",
          "updatedAt": "…",
          "blocksPerHour": "…",
          "hoursLeft": "…"
        }
      ]
    },
    {
      "job": "authority-match",
      "cadenceSeconds": 10,
      "verdict": "fresh",
      "lastRunAt": "2026-09-04T21:10:50.204Z",
      "lastOkAt": "2026-09-04T21:10:50.206Z",
      "ageSeconds": 0,
      "rows": 0,
      "error": null,
      "running": false,
      "checkpoints": []
    },
    "… 25 more"
  ],
  "figures": [
    {
      "figure": "state",
      "what": "Multiplier, pending multiplier, pause flags and supply, read from each token's contract",
      "job": "token-state",
      "cadenceSeconds": 300,
      "verdict": "fresh",
      "newestAt": "2026-09-04T21:10:45.786Z",

…
GET/statuspublic · 120/min per IP · ETag

Alias of /chains/4663/status: whether the registry is live

Responses: 200 Freshness · 429 Too many anonymous requests

https://fletch.now/api/v1/status

{
  "chainId": 4663,
  "checkedAt": "2026-09-04T21:10:50.415Z",
  "verdict": "degraded",
  "summary": "2 of 27 jobs are not current (stalled: dex-swaps; no completed run yet: transfer-ledger).",
  "daemon": {
    "name": "registry-daemon",
    "alive": true,
    "lastBeatAt": "2026-09-04T21:10:45.280Z",
    "ageSeconds": 5,
    "jobsReported": 27,
    "failing": []
  },
  "head": {
    "block": "54574772",
    "readAt": "2026-09-04T21:10:25.582Z",
    "ageSeconds": 25
  },
  "jobs": [
    {
      "job": "control-plane",
      "cadenceSeconds": 10,
      "verdict": "fresh",
      "lastRunAt": "2026-09-04T21:10:37.396Z",
      "lastOkAt": "2026-09-04T21:10:27.395Z",
      "ageSeconds": 23,
      "rows": 0,
      "error": null,
      "running": true,
      "checkpoints": [
        {
          "name": "…",
          "block": "…",
          "head": "…",
          "behind": "…",
          "updatedAt": "…",
          "blocksPerHour": "…",
          "hoursLeft": "…"
        }
      ]
    },
    {
      "job": "authority-match",
      "cadenceSeconds": 10,
      "verdict": "fresh",
      "lastRunAt": "2026-09-04T21:10:50.204Z",
      "lastOkAt": "2026-09-04T21:10:50.206Z",
      "ageSeconds": 0,
      "rows": 0,
      "error": null,
      "running": false,
      "checkpoints": []
    },
    "… 25 more"
  ],
  "figures": [
    {
      "figure": "state",
      "what": "Multiplier, pending multiplier, pause flags and supply, read from each token's contract",
      "job": "token-state",
      "cadenceSeconds": 300,
      "verdict": "fresh",
      "newestAt": "2026-09-04T21:10:45.786Z",

…

Registry

Every verified asset on Robinhood Chain with its live state: addresses, multipliers, pauses, feeds, quotes, supply, holders, pools, history.

GET/chains/{chainId}/assetspublic · 120/min per IP · ETag

List (and optionally search) registry assets on a chain, each with its live on-chain state

Public. Anonymous callers get 120 requests a minute per address; a key or a session uses its own budget. Each asset carries `state`: multiplier, pending multiplier, pause flags, supply, canonical proof, the Chainlink feed and Robinhood's quote.

ParameterInTypeMeaning
chainId*pathintegere.g. 4663
qquerystringSymbol or name substring
symbolsquerystringComma-separated exact tickerse.g. TSLA,AAPL
fieldsquerystringExtra per-asset blocks: lookalikes, corporateActions, multiplierHistory, feedRounds, concentration (up to 50 assets)e.g. lookalikes,feedRounds,concentration

Responses: 200 Assets, each with trust and state, plus any extra blocks fields= asked for · 401 Missing or invalid credentials · 403 Credentials valid but missing the required scope · 404 Unknown chain

https://fletch.now/api/v1/chains/4663/assets?symbols=TSLA,AAPL

{
  "assets": [
    {
      "id": "4663:0xaf3d76f1834a1d425780943c99ea8a608f8a93f9",
      "chainId": 4663,
      "address": "0xaf3d76f1834a1d425780943c99ea8a608f8a93f9",
      "symbol": "AAPL",
      "name": "Apple • Robinhood Token",
      "assetType": "stock_token",
      "decimals": 18,
      "status": "active",
      "source": "robinhood-api",
      "sourceUri": "https://api.robinhood.com/rhj/assets",
      "observedAt": "2026-09-04T21:09:22.718Z",
      "firstSeenAt": "2026-09-02T14:53:22.429Z",
      "verifiedAt": "2026-09-04T21:09:30.824Z",
      "onchainName": "Apple • Robinhood Token",
      "onchainSymbol": "AAPL",
      "onchainDecimals": 18,
      "metadataCheckedAt": "2026-09-02T15:09:07.949Z",
      "logoUrl": "https://cdn.robinhood.com/ncw_assets/logos/0xaf3d76f1834a1d425780943c99ea8a608f8a93f9.png",
      "isin": "US0378331005",
      "raw": {
        "id": "0x00000000000000000000000000000000c2425be3658540dd8e2424cbf3c5c649",
        "isin": "US0378331005",
        "status": "ASSET_STATUS_ACTIVE",
        "logoUrl": "https://cdn.robinhood.com/ncw_assets/logos/0xaf3d76f1834a1d425780943c99ea8a608f8a93f9.png",
        "tokenName": "Apple • Robinhood Token",
        "deployments": [
          {
            "chainId": "…",
            "networkName": "…",
            "contractAddress": "…"
          }
        ],
        "tokenSymbol": "AAPL",
        "tokenDecimals": 18,
        "currentMultiplier": "1.000566080061092436",
        "pendingMultiplier": "",
        "tradingCapabilities": {
          "market": "…",
          "extended": "…",
          "overnight": "
…
GET/chains/{chainId}/assets/{symbol}public · 120/min per IP · ETag

Get one registry asset by symbol, with its state, multiplier history, mints and burns, supply snapshots, corporate actions and control-plane events

Public, rate-limited per address when anonymous. Raw amounts are strings (exact on chain); prices and multipliers are numbers.

ParameterInTypeMeaning
chainId*pathinteger
symbol*pathstringe.g. AAPL

Responses: 200 The asset with everything the registry knows about it · 401 Missing or invalid credentials · 403 Credentials valid but missing the required scope · 404 No such asset on this chain

https://fletch.now/api/v1/chains/4663/assets/TSLA

{
  "asset": {
    "id": "4663:0x322f0929c4625ed5bad873c95208d54e1c003b2d",
    "chainId": 4663,
    "address": "0x322f0929c4625ed5bad873c95208d54e1c003b2d",
    "symbol": "TSLA",
    "name": "Tesla • Robinhood Token",
    "assetType": "stock_token",
    "decimals": 18,
    "status": "active",
    "source": "robinhood-api",
    "sourceUri": "https://api.robinhood.com/rhj/assets",
    "observedAt": "2026-09-04T21:09:22.727Z",
    "firstSeenAt": "2026-09-02T14:53:22.436Z",
    "verifiedAt": "2026-09-04T21:09:31.573Z",
    "onchainName": "Tesla • Robinhood Token",
    "onchainSymbol": "TSLA",
    "onchainDecimals": 18,
    "metadataCheckedAt": "2026-09-02T15:08:52.616Z",
    "logoUrl": "https://cdn.robinhood.com/ncw_assets/logos/0x322f0929c4625ed5bad873c95208d54e1c003b2d.png",
    "isin": "US88160R1014",
    "raw": {
      "id": "0x00000000000000000000000000000000cfece3244ea34bb29414dd9488b32d9f",
      "isin": "US88160R1014",
      "status": "ASSET_STATUS_ACTIVE",
      "logoUrl": "https://cdn.robinhood.com/ncw_assets/logos/0x322f0929c4625ed5bad873c95208d54e1c003b2d.png",
      "tokenName": "Tesla • Robinhood Token",
      "deployments": [
        {
          "chainId": "…",
          "networkName": "…",
          "contractAddress": "…"
        }
      ],
      "tokenSymbol": "TSLA",
      "tokenDecimals": 18,
      "currentMultiplier": "1.000000000000000000",
      "pendingMultiplier": "",
      "tradingCapabilities": {
        "market": {
          "whole": "…",
          "fractional": "…"
        },
        "extended": {
          "whole": "…",
          "fractional": "…"

…
GET/chains/{chainId}/assets/{symbol}/holderspublic · 120/min per IP · ETag

Holders largest first with share of supply and what each address is, holder count, the latest concentration reading with the shares that say where the supply sits, and whether the ledger has reached the chain head

Public. `sits` is always one of `float`, `pools`, `issuer`, `bridge`, `contracts`, `unknown`, and names the concentration share this address's balance counts towards; `unknown` means the code probe has not checked this address yet. `label` and `labelKind` (`pool_manager`, `dex_pool`, `issuer`, `bridge_gateway`, `locker`, `contract`, `exchange`, `eoa`) are null for an address the registry has nothing to say about. `rawBalance` is in the token's base units; divide by 10^`decimals`. `sharePct` is that balance over `totalSupplyRaw`, read live, while the concentration shares are over the sum of every positive balance the ledger held at `concentration.asOfBlock`, so the two can differ slightly while the ledger trails the chain. `concentration` carries `floatPct`, `poolsPct`, `issuerPct`, `bridgePct`, `contractsPct` and `unknownPct`, which add to 100: float is the supply in ordinary wallets. `unknownPct` is the share held by addresses the code probe has not checked — it checks every holder above a ten-thousandth of a token's supply, so a tail of small holdings stays here permanently and `floatPct` is always a floor rather than a final answer. `issuerPct` is the share of every wallet labelled `issuer`, which is written only for Stock Tokens, whose mints are the issuer creating inventory; `issuerAddress` is this asset's largest mint recipient whatever the asset type. `concentration.day` is the UTC day of the reading, `takenAt` the ISO instant the job wrote it, and `asOfBlock` the ledger block it was computed at; the job runs every 24 h, so a share can be up to a day old. `concentration.holders` is the address count at that moment, while the top-level `holderCount` is read live and can differ. The shares come from the daily concentration job, which does not run while the transfer ledger is still reading history, so `concentration` is null until the ledger reaches head.

ParameterInTypeMeaning
chainId*pathintegere.g. 4663
symbol*pathstringe.g. TSLA
limitqueryintegerHow many holders, largest first

Responses: 200 Holders · 404 Asset not found · 429 Too many anonymous requests

https://fletch.now/api/v1/chains/4663/assets/TSLA/holders?limit=5

{
  "symbol": "TSLA",
  "decimals": 18,
  "totalSupplyRaw": "12054791000000000000000",
  "holders": [
    {
      "holder": "0x94bab9693ba2f6358507effcbd372b0660afff9d",
      "rawBalance": "715100000000000000000",
      "sharePct": 5.932,
      "asOfBlock": "806999",
      "label": "Contract",
      "labelKind": "contract",
      "sits": "contracts"
    },
    {
      "holder": "0x2f4579ca81717d3d61bf8b6f06571877bbe54a07",
      "rawBalance": "674483573608587708841",
      "sharePct": 5.5951,
      "asOfBlock": "2031999",
      "label": "Contract",
      "labelKind": "contract",
      "sits": "contracts"
    },
    "… 3 more"
  ],
  "holderCount": 314,
  "concentration": null,
  "progress": {
    "ledgerBlock": "2031999",
    "headBlock": "54574772",
    "complete": false
  }
}
GET/chains/{chainId}/assets/{symbol}/activitypublic · 120/min per IP · ETag

Transfers as economics, one row per UTC day: transfers, volume, mints, burns, DvP against USDG, off-hours transfers

ParameterInTypeMeaning
chainId*pathintegere.g. 4663
symbol*pathstringe.g. TSLA
daysqueryinteger

Responses: 200 Days · 404 Asset not found · 429 Too many anonymous requests

https://fletch.now/api/v1/chains/4663/assets/TSLA/activity?days=3

{
  "symbol": "TSLA",
  "decimals": 18,
  "days": [
    {
      "day": "2026-07-03",
      "transfers": 6077,
      "volumeRaw": "246686941144029022100",
      "mints": 0,
      "burns": 0,
      "dvpTransfers": 3471,
      "offhoursTransfers": 3652
    },
    {
      "day": "2026-07-02",
      "transfers": 2276,
      "volumeRaw": "683184252015589469076",
      "mints": 0,
      "burns": 1,
      "dvpTransfers": 1364,
      "offhoursTransfers": 757
    },
    "… 1 more"
  ],
  "ledgerBlock": "2031999",
  "progress": {
    "ledgerBlock": "2031999",
    "headBlock": "54574772",
    "complete": false
  }
}
GET/chains/{chainId}/assets/{symbol}/poolspublic · 120/min per IP · ETag

Pools trading the asset on every DEX the registry reads, deepest first, with venue, price, liquidity, fee, hooks, last-day swaps and volume, and the pool behind the asset's premium to the feed

Public. `venue` is `uniswap_v4` or `uniswap_v3`; a v4 pool is an id inside the one PoolManager and has a null `poolAddress`, a v3 pool is a contract and carries its address. A pool is recorded when one side is this asset and the other is a listed quote (USDG, WETH or another Stock Token). Pools are deepest first by `depthUsd`, how many dollars of the quote token it takes to move the pool's price by 1% — a ceiling, since a move that leaves the position's range runs out of liquidity first, and not the pool's token balance; `liquidity` is the pool's in-range Uniswap liquidity L in raw units, not a dollar figure, and is comparable only between pools of the same pair (its scale follows the two tokens' decimals). `best` is the deepest pool in dollars of any venue, which is the one the asset's premium to the Chainlink feed is measured from, and names its venue. `swaps24h` and `volumeUsd24h` cover the current UTC day and the one before it, and are null for a pool discovered inside that window, whose earlier swaps the scan never read. `discovery` says how far each venue's pool scan has read: while `readingHistory` is true, a pool created in blocks the scan has not reached yet is not listed, and a venue whose `scanned` is false has not been read at all.

ParameterInTypeMeaning
chainId*pathintegere.g. 4663
symbol*pathstringe.g. TSLA

Responses: 200 Pools · 404 Asset not found · 429 Too many anonymous requests

https://fletch.now/api/v1/chains/4663/assets/TSLA/pools

{
  "symbol": "TSLA",
  "feedPriceUsd": 353.98495,
  "best": {
    "poolId": "0xf4acdaeeb7022862a763c9b1b885e11191c889e3",
    "venue": "uniswap_v3",
    "priceUsd": 353.8210691004956,
    "depthUsd": 72705.5,
    "premiumPct": -0.0463
  },
  "pools": [
    {
      "poolId": "0xf4acdaeeb7022862a763c9b1b885e11191c889e3",
      "venue": "uniswap_v3",
      "poolAddress": "0xf4acdaeeb7022862a763c9b1b885e11191c889e3",
      "currency0": "0x322f0929c4625ed5bad873c95208d54e1c003b2d",
      "currency1": "0x5fc5360d0400a0fd4f2af552add042d716f1d168",
      "fee": 3000,
      "feeDynamic": false,
      "feePct": 0.3,
      "tickSpacing": 60,
      "hooks": "0x0000000000000000000000000000000000000000",
      "asset": "TSLA",
      "quote": "USDG",
      "createdBlock": "4702324",
      "sqrtPriceX96": "1490292201840663203842700",
      "tick": -217634,
      "liquidity": "774973935109977185",
      "depthUsd": 72705.5,
      "priceInQuote": 353.8210691004956,
      "priceUsd": 353.8210691004956,
      "swaps24h": null,
      "volumeUsd24h": null,
      "stateCheckedAt": "2026-09-04T21:08:19.213Z"
    },
    {
      "poolId": "0x8517f8071ae5b831b738052f12125e8e3d6c158b78728aa44ce3b25e5104d32e",
      "venue": "uniswap_v4",
      "poolAddress": null,
      "currency0": "0x322f0929c4625ed5bad873c95208d54e1c003b2d",
      "currency1": "0x5fc5360d0400a0fd4f2af552add042d716f1d168",
      "fee": 3000,
      "feeDynamic": false,
      "feePct": 0.3,
      "tickSpacing": 60,
      "hooks": "0x0000000000000000000000000000000000000000",
      "asset": "TSLA",
      "quote": "USDG",
      "create
…
GET/chains/{chainId}/assets/{symbol}/historypublic · 120/min per IP · ETag

One row per UTC day of everything the registry publishes about an asset: multiplier, pause and halt flags, feed price and staleness, bid and ask, divergence, DEX price, premium and liquidity, supply, holders and lookalike count

Public. Written by the state-daily job, which runs hourly and rewrites the current UTC day's row, so a past day can be read back; the live tables carry only the current answer. Each row is a single reading taken at `takenAt`, not a daily open, close, mean or end-of-day value: it is the last reading the job took on that day, and the row for the current day is rewritten on the job's next run, so today's row is a partial day. Compare `takenAt` across rows before treating the series as evenly spaced. `from`/`to` are UTC days and default to the last 90; `days` sets the window length instead of `from`; `at=YYYY-MM-DD` returns that one day (an empty `days` array when no snapshot was taken); `fields` narrows each row to the keys named, `day` always included. `coverage` says how many days are actually on record and the first of them: there is nothing before the day the job first ran. A null is a figure that was not read that day, never a zero: a figure is copied only when the job that writes it read it that day, and `stateCheckedAt`, `feedCheckedAt`, `apiCheckedAt`, `dexCheckedAt` and `blockscoutCheckedAt` say when each group of figures was last read. `ledgerHolders` is written only for assets whose transfer history the ledger had finished reading, and `lookalikes` only once the lookalike scan has completed a pass. Rows are flat versions of the live `state` block: `feedPrice`/`feedStale` are `state.feed.price`/`.stale`, `bid`/`ask`/`tradingHalt` are `state.quote.bid`/`.ask`/`.tradingHalt`, `dexPriceUsd`/`dexPremiumPct`/`dexLiquidity` are `state.dex.priceUsd`/`.premiumPct`/`.liquidity`, `blockscoutHolders` is `state.secondSource.holders`, `multiplier` is `state.multiplier`.

ParameterInTypeMeaning
chainId*pathintegere.g. 4663
symbol*pathstringe.g. TSLA
fromquerystring, dateFirst UTC day, YYYY-MM-DD; must not be after `to`
toquerystring, dateLast UTC day, YYYY-MM-DD; defaults to today
daysqueryintegerWindow length in days ending at `to`; ignored when `from` is given
atquerystring, datee.g. 2026-08-12
fieldsquerystringComma-separated keys to keep from each row: multiplier, tokenPaused, oraclePaused, tradingHalt, feedPrice, feedStale, bid, ask, priceDivergencePct, dexPriceUsd, dexPremiumPct, dexLiquidity, totalSupplyRaw, blockscoutHolders, ledgerHolders, lookalikes, stateCheckedAt, feedCheckedAt, apiCheckedAt, dexCheckedAt, blockscoutCheckedAt, takenAt. `day` is always included; an unknown key is a 400.e.g. feedPrice,dexPremiumPct

Responses: 200 History · 400 at, from, to, days or fields is malformed, or from is after to · 404 Asset not found · 429 Too many anonymous requests

https://fletch.now/api/v1/chains/4663/assets/TSLA/history?days=3

{
  "chainId": 4663,
  "symbol": "TSLA",
  "decimals": 18,
  "from": "2026-09-02",
  "to": "2026-09-04",
  "coverage": {
    "daysOnRecord": 1,
    "firstDay": "2026-09-04",
    "latestDay": "2026-09-04"
  },
  "days": [
    {
      "day": "2026-09-04",
      "multiplier": 1,
      "tokenPaused": false,
      "oraclePaused": false,
      "tradingHalt": false,
      "feedPrice": 353.98495,
      "feedStale": false,
      "bid": 353.4,
      "ask": 353.44,
      "priceDivergencePct": 0.1599,
      "dexPriceUsd": 354.08892833193994,
      "dexPremiumPct": 0.0294,
      "dexLiquidity": "329356678143721780",
      "totalSupplyRaw": "12054791000000000000000",
      "blockscoutHolders": 53069,
      "ledgerHolders": null,
      "lookalikes": null,
      "stateCheckedAt": "2026-09-04T20:37:14.450Z",
      "feedCheckedAt": "2026-09-04T20:37:59.492Z",
      "apiCheckedAt": "2026-09-04T20:37:27.907Z",
      "dexCheckedAt": "2026-09-04T20:38:06.242Z",
      "blockscoutCheckedAt": "2026-09-04T20:15:39.485Z",
      "takenAt": "2026-09-04T20:38:54.112Z"
    }
  ]
}
GET/chains/{chainId}/assets/{symbol}/feed/roundspublic · 120/min per IP · ETag

The Chainlink feed's round history for one asset, newest first: roundId, answer (price × multiplier, USD), startedAt, updatedAt

ParameterInTypeMeaning
chainId*pathintegere.g. 4663
symbol*pathstringe.g. TSLA
sincequerystring, date-time
limitqueryinteger

Responses: 200 Rounds · 404 Asset not found · 429 Too many anonymous requests

https://fletch.now/api/v1/chains/4663/assets/TSLA/feed/rounds?limit=5

{
  "symbol": "TSLA",
  "feed": "0x4a1166a659a55625345e9515b32adecea5547c38",
  "rounds": [
    {
      "roundId": "18446744073709552736",
      "answer": 353.98495,
      "startedAt": "2026-09-04T18:14:24.000Z",
      "updatedAt": "2026-09-04T18:14:36.000Z"
    },
    {
      "roundId": "18446744073709552735",
      "answer": 351.93085,
      "startedAt": "2026-09-04T15:49:22.000Z",
      "updatedAt": "2026-09-04T15:51:34.000Z"
    },
    "… 3 more"
  ]
}

Changelog

Every change the daemon noticed, as JSON with a cursor and as a live stream.

GET/chains/{chainId}/eventspublic · 120/min per IP · ETag

The registry changelog: every pause, block, upgrade, multiplier change, stale feed, supply residual, listing, corporate action and chain status change the daemon recorded

Public. Without `since`/`cursor`: newest first, with `kinds` (every kind the daemon can emit) and `nextCursor`. With `since` or `cursor` (an ISO instant, use the previous `nextCursor`): only newer rows, oldest first, so a consumer catches up without gaps. `kind` matches exactly or by prefix (`registry.`, `multiplier.`); `symbol` narrows to one token; `limit` up to 500.

ParameterInTypeMeaning
chainId*pathintegere.g. 4663
kindquerystringe.g. multiplier.
symbolquerystringe.g. TSLA
sincequerystring, date-time
cursorquerystring, date-time
limitqueryinteger

Responses: 200 Events · 404 Unknown chain · 429 Too many anonymous requests

https://fletch.now/api/v1/chains/4663/events?limit=5

{
  "events": [
    {
      "id": "ev_bdf94498f09e93b9ba74f13a",
      "kind": "dex.pool_new",
      "title": "New Uniswap v4 pool for EWY against USDG, fee 3%",
      "symbol": "EWY",
      "address": "0x8366a39cc670b4001a1121b8f6a443a643e40951",
      "detail": {
        "fee": 30000,
        "hooks": "0x0000000000000000000000000000000000000000",
        "quote": "USDG",
        "venue": "uniswap_v4",
        "poolId": "0x4d75444d0231f0f170419f97f3dee2ad6d4ebe0660075b3c870a51113d20c55f"
      },
      "block": "54571592",
      "txHash": null,
      "occurredAt": "2026-09-04T21:07:58.686Z",
      "observedAt": "2026-09-04T21:07:58.687Z"
    },
    {
      "id": "ev_b80b558acb9d9530b1831a4d",
      "kind": "dex.pool_new",
      "title": "New Uniswap v4 pool for EWY against WETH, fee 4.44%",
      "symbol": "EWY",
      "address": "0x8366a39cc670b4001a1121b8f6a443a643e40951",
      "detail": {
        "fee": 44400,
        "hooks": "0x0000000000000000000000000000000000000000",
        "quote": "WETH",
        "venue": "uniswap_v4",
        "poolId": "0xb97b79f96cf27cf4cce4fb7f629b62c2f8680cad829d6abba483f85f8c17799b"
      },
      "block": "54568657",
      "txHash": null,
      "occurredAt": "2026-09-04T21:07:58.686Z",
      "observedAt": "2026-09-04T21:07:58.687Z"
    },
    "… 3 more"
  ],
  "kinds": [
    "registry.paused",
    "registry.unpaused",
    "… 34 more"
  ],
  "nextCursor": "2026-09-04T21:07:58.687Z|ev_bdf94498f09e93b9ba74f13a"
}
GET/chains/{chainId}/events/streampublic · 120/min per IP · ETag

The same changelog as Server-Sent Events; each frame's id is its observedAt, so Last-Event-ID (or ?since=) resumes without gaps

ParameterInTypeMeaning
chainId*pathintegere.g. 4663
sincequerystring, date-time

Responses: 200 text/event-stream; `event` is the kind, `data` the JSON event · 404 Unknown chain · 429 Too many anonymous requests

https://fletch.now/api/v1/chains/4663/events/stream

: fletch registry events, chain 4663

id: 2026-09-04T12:19:11.292Z
event: token.halted
data: {"id":"ev_feb6…","kind":"token.halted","title":"SOUN trading halted at the issuer","symbol":"SOUN",…}

Chain

The issuer's control plane, the token bridge, the issuer's paperwork, lookalike tokens, DEX venues and chain health.

GET/chains/{chainId}/control-planepublic · 120/min per IP · ETag

The issuer's AccessControlsRegistry: paused, implementation, blocked-address count, and its latest events

Public. One contract governs every Stock Token: this is the surface no other index publishes. `limit` caps events (default 50, max 200).

ParameterInTypeMeaning
chainId*pathintegere.g. 4663
limitqueryinteger

Responses: 200 Registry state and events · 404 Unknown chain · 429 Too many anonymous requests

https://fletch.now/api/v1/chains/4663/control-plane?limit=5

{
  "state": {
    "registry": "0xe10b6f6b275de231345c20d14ab812db62151b00",
    "implementation": "0xb35490d6f9163de4f80d88dc75c3516eb64c5ae2",
    "paused": false,
    "blockedAddresses": 242,
    "lastEventBlock": "657134",
    "checkedAt": "2026-09-04T21:10:27.394Z"
  },
  "events": [
    {
      "event": "Upgraded",
      "account": null,
      "role": null,
      "implementation": "0xb35490d6f9163de4f80d88dc75c3516eb64c5ae2",
      "block": "657134",
      "txHash": "0x6960b46f7020ce38aec873dddd0d7e88270c4d42e469643407b26b7386c6d11a",
      "logIndex": 0
    },
    {
      "event": "RoleRevoked",
      "account": "0x000000000000000000000000000000000000dead",
      "role": "0x9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6",
      "implementation": null,
      "block": "618536",
      "txHash": "0xb7d3455d0cf9f87ecd2c9f92fd8b10ec5eb4e12330db4e6988d777073aa6e69e",
      "logIndex": 0
    },
    "… 3 more"
  ]
}
GET/chains/{chainId}/healthpublic · 120/min per IP · ETag

The chain's latest vital signs: head, block time, base fee, L1 block, batch count, delayed messages, batch-poster balance, status page

ParameterInTypeMeaning
chainId*pathintegere.g. 4663

Responses: 200 Latest reading · 404 Unknown chain · 429 Too many anonymous requests

https://fletch.now/api/v1/chains/4663/health

{
  "health": {
    "headBlock": "54574772",
    "blockTimeMs": 100,
    "baseFeeWei": "821424000",
    "l1Block": "25906553",
    "batchCount": "193326",
    "delayedMessages": "223408",
    "batchPosterBalanceWei": "18871155879684160766",
    "statusPage": "OPERATIONAL",
    "arbosVersion": 61,
    "chainOwners": [
      "0x2a153c6a1b66dbc930a8d7017230ab0253005c09"
    ],
    "finality": {
      "latestConfirmedAssertion": "0x36d2a081afe910119bf36d4e2b7f72736222d93f480463fffba56255784bfba6",
      "confirmedAtL1Block": "25860550",
      "confirmedAgeSeconds": 554066
    },
    "checkedAt": "2026-09-04T21:10:25.582Z"
  }
}
GET/chains/{chainId}/corporate-actionspublic · 120/min per IP · ETag

Corporate actions in progress, as Robinhood publishes them, tied to the token each affects

ParameterInTypeMeaning
chainId*pathintegere.g. 4663

Responses: 200 Actions in progress · 404 Unknown chain · 429 Too many anonymous requests

https://fletch.now/api/v1/chains/4663/corporate-actions

{
  "actions": [
    {
      "id": "0x00000000000000000000000000000000aad6874f8eba489d8a46fe1cbddc8db4",
      "symbol": "JBL",
      "kind": "cash_dividend",
      "status": "in_progress",
      "processDate": "2026-09-02",
      "rate": 0.08
    },
    {
      "id": "0x00000000000000000000000000000000413cbb2a5e924576a297ccb67c272298",
      "symbol": "UPS",
      "kind": "cash_dividend",
      "status": "in_progress",
      "processDate": "2026-09-03",
      "rate": 1.64
    },
    "… 25 more"
  ]
}
GET/chains/{chainId}/dexpublic · 120/min per IP · ETag

The DEX venues the registry reads and what each contributes: pools trading a listed asset, how many carry a dollar price, the last day's swaps and volume, and how many assets take their premium from a pool there

Public. One row per venue read (`uniswap_v4`, `uniswap_v3`), whether or not it has a pool on record yet, so `venues` and `discovery` name the same set. `assetsPricedHere` counts the assets whose deepest pool in dollars sits on that venue, so the venues' figures add up to the assets with a DEX price. `depthUsd` is the dollars of quote it takes to move a pool's price by 1%, added up over the venue's priced pools, and is the figure pools are ranked by; Uniswap's raw liquidity L compares two pools only when they hold the same pair. `swaps24h` and `volumeUsd24h` cover the current UTC day and the one before it — swaps are tallied per UTC day, so the window is between 24 and 48 hours, not a rolling day — and a swap near midnight is attributed from the last block of the scan window that held it, so it can land on the neighbouring day. `checkedAt` is when the state read last priced a pool on that venue; `headAt` inside `discovery` is when the chain head there was read. `discovery` carries each venue's pool scan position against that head; while `readingHistory` is true the counts are a floor, not a total, and while `scanned` is false the venue has not been read at all. The Pons launchpad creates its pools on the Uniswap v3 factory, so they are counted as `uniswap_v3` rather than as a venue of their own.

ParameterInTypeMeaning
chainId*pathintegere.g. 4663

Responses: 200 DEX venues · 404 Unknown chain · 429 Too many anonymous requests

https://fletch.now/api/v1/chains/4663/dex

{
  "venues": [
    {
      "venue": "uniswap_v4",
      "pools": 7258,
      "pricedPools": 7150,
      "depthUsd": 11153379.7,
      "swaps24h": 0,
      "volumeUsd24h": null,
      "assetsPricedHere": 179,
      "checkedAt": "2026-09-04T21:08:19.213Z"
    },
    {
      "venue": "uniswap_v3",
      "pools": 236,
      "pricedPools": 134,
      "depthUsd": 5993738.65,
      "swaps24h": 0,
      "volumeUsd24h": null,
      "assetsPricedHere": 18,
      "checkedAt": "2026-09-04T21:08:19.213Z"
    }
  ],
  "discovery": [
    {
      "venue": "uniswap_v4",
      "scanned": true,
      "scannedToBlock": "54573295",
      "headBlock": "54574772",
      "headAt": "2026-09-04T21:10:25.582Z",
      "blocksBehind": "1477",
      "readingHistory": false
    },
    {
      "venue": "uniswap_v3",
      "scanned": true,
      "scannedToBlock": "34007016",
      "headBlock": "54574772",
      "headAt": "2026-09-04T21:10:25.582Z",
      "blocksBehind": "20567756",
      "readingHistory": true
    }
  ],
  "note": "A pool is recorded when one side is a listed asset and the other is a listed quote (USDG, WETH or another Stock Token). An asset's price and premium come from its deepest pool in dollars, whichever venue that is on: `depthUsd` is how many dollars of the quote token it takes to move a pool's price by 1%, added up over the venue's priced pools, and is the figure pools are ranked by; Uniswap's raw liquidity L compares two pools only when they hold the same pair. It assumes the move stays inside the pool's in-range liquidity, so it is a ceiling for a narrowly concentrated position,
…
GET/chains/{chainId}/bridgepublic · 120/min per IP · ETag

The token bridge: each bridged asset's L1 escrow against its L2 supply, recent deposits and withdrawals seen on L2, and withdrawals past their seven-day window

ParameterInTypeMeaning
chainId*pathintegere.g. 4663
symbolquerystringe.g. WBTC
limitqueryinteger

Responses: 200 Bridge · 404 Unknown chain or asset · 429 Too many anonymous requests

https://fletch.now/api/v1/chains/4663/bridge?limit=5

{
  "escrow": [
    {
      "asset": "WBTC",
      "l1Token": "0x2260fac5e5542a773aa44fbcfedf7c193bc2c599",
      "l1Gateway": "0x85001cc4867c5e1c22da4b79bb8852b9e2a06da0",
      "escrowRaw": "879502",
      "l2SupplyRaw": "878502",
      "inFlightRaw": "1000",
      "checkedAt": "2026-09-04T21:08:19.305Z"
    },
    {
      "asset": "cbBTC",
      "l1Token": "0xcbb7c0000ab88b473b1f5afd9ef808440eed33bf",
      "l1Gateway": "0x85001cc4867c5e1c22da4b79bb8852b9e2a06da0",
      "escrowRaw": "0",
      "l2SupplyRaw": "0",
      "inFlightRaw": "0",
      "checkedAt": "2026-09-04T21:08:19.306Z"
    },
    "… 9 more"
  ],
  "flows": [
    {
      "direction": "withdrawal",
      "asset": "UNI",
      "l1Token": "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984",
      "from": "0x7a8f74c2585f84c781f951b7f2ff21337d5b630b",
      "to": "0x000000000000000000000000000000000000dead",
      "amountRaw": "2000000000000000000000",
      "l2ToL1Id": "1950",
      "block": "54562449",
      "txHash": "0x1b87b54112054576c8cfb9418d3fdc7c8729d2e02c1c0d0cde35b895a6f743d5",
      "occurredAt": "2026-09-04T20:49:38.000Z",
      "claimableAt": "2026-09-11T20:49:38.000Z"
    },
    {
      "direction": "deposit",
      "asset": "UNI",
      "l1Token": "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984",
      "from": "0xc868e62bde5da126281f8b7f6bb6e8eb2f1a804e",
      "to": "0xc868e62bde5da126281f8b7f6bb6e8eb2f1a804e",
      "amountRaw": "2000000000000000000000",
      "l2ToL1Id": null,
      "block": "54552403",
      "txHash": "0x04543ea4f67c66ed108fcfd72665ab66daf1b3dc71bbb272d1f50b5fccfac655",
      "occurred
…
GET/chains/{chainId}/issuerpublic · 120/min per IP · ETag

The issuer's paperwork: every PDF the legal hub lists with ETag, Last-Modified and the token it maps to, plus watched pages and when their text changed

ParameterInTypeMeaning
chainId*pathintegere.g. 4663
kindquerybase_prospectus | supplement | notice | final_terms | other

Responses: 200 Documents and pages · 404 Unknown chain · 429 Too many anonymous requests

https://fletch.now/api/v1/chains/4663/issuer

{
  "documents": [
    {
      "url": "https://cdn.robinhood.com/assets/robinhood/legal/rhj_base_prospectus.pdf",
      "title": "Base Prospectus",
      "kind": "base_prospectus",
      "underlying": null,
      "asset": null,
      "etag": "W/\"3db7ed4d174a54e2edbf77aa74a874d2\"",
      "lastModified": "2026-09-02T20:06:38.000Z",
      "bytes": null,
      "firstSeenAt": "2026-09-04T14:33:38.038Z",
      "changedAt": null,
      "goneAt": null
    },
    {
      "url": "https://cdn.robinhood.com/assets/robinhood/legal/rhj_notice_of_proposed_amendments.pdf",
      "title": "Notice of Proposed Amendments",
      "kind": "notice",
      "underlying": null,
      "asset": null,
      "etag": "W/\"b2e84d80ccc87073af02bb0fd3cb1c5a\"",
      "lastModified": "2026-08-13T19:00:26.000Z",
      "bytes": null,
      "firstSeenAt": "2026-09-04T14:35:25.334Z",
      "changedAt": null,
      "goneAt": null
    },
    "… 202 more"
  ],
  "pages": [
    {
      "page": "chain-notices",
      "url": "https://docs.robinhood.com/chain/notices-and-upgrades/",
      "title": "Notices & Upgrades – Robinhood Chain Documentation",
      "sha256": "21d0d83ec82b893cb715301f70729c4254ae991d930daff98cf715c1c4adcf21",
      "firstSeenAt": "2026-09-04T14:33:43.812Z",
      "changedAt": null,
      "lastSeenAt": "2026-09-04T20:38:28.973Z"
    },
    {
      "page": "corporate-actions",
      "url": "https://docs.robinhood.com/rhj/corporate-actions",
      "title": "Corporate Actions – Robinhood RHJ",
      "sha256": "a3e1fa443b260854924f3e13e1467251c310be9506dd962413ff89f15e469e70",
      "firstSeenAt":
…
GET/chains/{chainId}/lookalikespublic · 120/min per IP · ETag

Every ERC-20 that borrows a listed ticker or exact name at another address, with holders and the beacon check that separates an impostor from an issuer-deployed token

ParameterInTypeMeaning
chainId*pathintegere.g. 4663
symbolquerystringe.g. TSLA
limitqueryinteger

Responses: 200 Lookalikes, most held first · 404 Unknown chain · 429 Too many anonymous requests

https://fletch.now/api/v1/chains/4663/lookalikes?symbol=TSLA&limit=5

{
  "lookalikes": [
    {
      "address": "0x066ad1c8bf4edf5482d6994f18c27216e597f81a",
      "symbol": "TSLA",
      "name": "Tesla • Robinhood Token",
      "decimals": 18,
      "holders": 461,
      "totalSupplyRaw": "1000000000000000000000000000",
      "claims": "TSLA",
      "kind": "impostor",
      "exactName": true,
      "beacon": null,
      "firstSeenAt": "2026-09-04T13:07:17.543Z",
      "lastSeenAt": "2026-09-04T20:42:05.602Z"
    },
    {
      "address": "0x1b33420614e9ef459d047cbe22e5265653776cf7",
      "symbol": "TSLA",
      "name": "OG Memestock",
      "decimals": 18,
      "holders": 346,
      "totalSupplyRaw": "1000000000000000000000000000",
      "claims": "TSLA",
      "kind": "same_ticker",
      "exactName": false,
      "beacon": null,
      "firstSeenAt": "2026-09-04T13:07:17.543Z",
      "lastSeenAt": "2026-09-04T20:42:05.602Z"
    },
    "… 3 more"
  ]
}

Watch

Watchers that alert on transfers and authority events, delivered to Telegram or a signed webhook. Needs a key.

GET/watcherskey · watchers:read

List this account's watchers

Responses: 200 Watchers · 401 Missing or invalid credentials · 403 Credentials valid but missing the required scope

POST/watcherskey · watchers:write

Create a watcher

ParameterInTypeMeaning
Idempotency-KeyheaderstringRepeat a POST with the same key to get the same watcher back instead of creating another.

Responses: 200 Idempotency-Key replay: the existing watcher · 201 Created · 400 Invalid asset id, threshold, wallet, project, or a disabled webhook endpoint · 401 Missing or invalid credentials · 403 Credentials valid but missing the required scope · 404 Asset, project or webhook endpoint not found · 429 Per-account or platform watcher limit reached

GET/watchers/{id}key · watchers:read

Get one watcher

ParameterInTypeMeaning
id*pathstring

Responses: 200 The watcher · 401 Missing or invalid credentials · 403 Credentials valid but missing the required scope · 404 Not found

PATCH/watchers/{id}key · watchers:write

Pause, resume, or re-point a watcher

ParameterInTypeMeaning
id*pathstring

Responses: 200 Updated · 401 Missing or invalid credentials · 403 Credentials valid but missing the required scope · 404 Not found

DELETE/watchers/{id}key · watchers:write

Delete a watcher

ParameterInTypeMeaning
id*pathstring

Responses: 200 Deleted · 401 Missing or invalid credentials · 403 Credentials valid but missing the required scope · 404 Not found

GET/watchers/{id}/runskey · watchers:read

A watcher's delivery history

ParameterInTypeMeaning
id*pathstring
limitqueryinteger

Responses: 200 Deliveries, newest first · 401 Missing or invalid credentials · 403 Credentials valid but missing the required scope · 404 Watcher not found

GET/webhookskey · watchers:read

List this account's webhook endpoints

Responses: 200 Endpoints, oldest first · 401 Missing or invalid credentials · 403 Credentials valid but missing the required scope

POST/webhookskey · watchers:write

Register a webhook endpoint

Returns the signing secret once. Every delivery carries X-Fletch-Signature: t=<unix>,v1=<hex hmac-sha256 over "<t>.<body>"> and X-Fletch-Event.

Responses: 201 Created, with the secret shown once · 400 The URL is not an https:// URL on a public host · 401 Missing or invalid credentials · 403 Credentials valid but missing the required scope · 429 Per-account endpoint limit reached

PATCH/webhooks/{id}key · watchers:write

Enable, disable, or rotate the secret of an endpoint

ParameterInTypeMeaning
id*pathstring

Responses: 200 The endpoint; a rotation includes the new secret once · 400 Neither enabled nor rotateSecret was sent · 401 Missing or invalid credentials · 403 Credentials valid but missing the required scope · 404 Not found

DELETE/webhooks/{id}key · watchers:write

Delete an endpoint

Watchers delivering to it are paused; the response says how many.

ParameterInTypeMeaning
id*pathstring

Responses: 200 Deleted · 401 Missing or invalid credentials · 403 Credentials valid but missing the required scope · 404 Not found

POST/webhooks/{id}/testkey · watchers:write

Send a signed ping to an endpoint now

Always HTTP 200: the endpoint's own answer is in the body as ok, status and error. Sent directly rather than through the delivery outbox, so a failure is not retried.

ParameterInTypeMeaning
id*pathstring

Responses: 200 What the endpoint answered · 401 Missing or invalid credentials · 403 Credentials valid but missing the required scope · 404 Not found

Build

Builds and projects. Needs a key.

GET/projectskey · projects:read

List this account's projects

Responses: 200 Projects · 401 Missing or invalid credentials · 403 Credentials valid but missing the required scope

GET/builds/{id}key · builds:read

Get one build's status, contracts, and toolchain report

ParameterInTypeMeaning
id*pathstring

Responses: 200 The build · 401 Missing or invalid credentials · 403 Credentials valid but missing the required scope · 404 Not found

Chains

The networks Fletch knows.

GET/chainskey · registry:read

List Robinhood Chain networks

Responses: 200 The two Robinhood chains · 401 Missing or invalid credentials · 403 Credentials valid but missing the required scope