From d872b5aac62b2f281954e0f67d80dc409cf23657 Mon Sep 17 00:00:00 2001 From: Gaurav agarwal Date: Fri, 24 Jul 2026 12:19:51 +0530 Subject: [PATCH 1/5] Add Robinhood Events API & WebSocket streams page Stream-first guide to EVM.Events on Robinhood, positioned as a no-node alternative to eth_subscribe/eth_getLogs: verified firehose (full field set), per-contract, per-signature, topic0-hash, decoded-argument, and wallet-scoped streams, plus historical queries (per-tx forensics, top signatures/emitters, window probes) and dataset guidance. Documents LogHeader.Address vs Log.SmartContract proxy semantics and no-0x hash format. All queries live-tested; subscriptions verified over WebSocket. Registers the page in the sidebar. Co-Authored-By: Claude Fable 5 --- .../robinhood/robinhood-events-api.md | 709 ++++++++++++++++++ sidebars.js | 3 +- 2 files changed, 711 insertions(+), 1 deletion(-) create mode 100644 docs/blockchain/robinhood/robinhood-events-api.md diff --git a/docs/blockchain/robinhood/robinhood-events-api.md b/docs/blockchain/robinhood/robinhood-events-api.md new file mode 100644 index 00000000..f0d02455 --- /dev/null +++ b/docs/blockchain/robinhood/robinhood-events-api.md @@ -0,0 +1,709 @@ +--- +title: "Robinhood Events API & WebSocket Streams" +description: "Stream every Robinhood smart contract event over GraphQL WebSockets — decoded logs, topics, call & receipt context. A no-node alternative to eth_getLogs." +sidebar_position: 4 +keywords: + - Robinhood events API + - Robinhood smart contract events + - Robinhood event stream websocket + - Robinhood logs API + - Robinhood eth_getLogs alternative + - Robinhood eth_subscribe logs + - decoded event logs Robinhood + - Robinhood topic0 filter + - Robinhood contract monitoring + - real-time EVM events Robinhood + - Bitquery Robinhood Events API +--- +# Robinhood Events API & WebSocket Streams + +Stream **every smart contract event on Robinhood** with Bitquery GraphQL — decoded arguments, raw topics, and the emitting transaction, call, and receipt joined into one record. The `EVM.Events` cube on `network: robinhood` is a drop-in **alternative to running your own node**: no RPC infrastructure, no log-decoding pipeline, no ABI management for known signatures. + +Open **one WebSocket that listens to everything**, or **hundreds of narrowly filtered sockets** — per contract, per event signature, per raw topic hash, even per decoded argument value. Every subscription on this page was verified live over WebSocket, and every query was executed against the production endpoint before publishing. + +:::note API Key Required +To query or stream data outside the Bitquery IDE, you need an API access token. + +Follow the steps here: [How to generate Bitquery API token ➤](/docs/authorization/how-to-generate/) +::: + +:::tip Related docs +- [EVM Events schema](/docs/schema/evm/events/) +- [Transfers vs Events vs Calls](/docs/start/mental-model-transfers-events-calls/) +- [Robinhood Trades](/docs/blockchain/robinhood/robinhood-trades/) +- [Robinhood Transfers](/docs/blockchain/robinhood/robinhood-transfers/) +- [Robinhood Liquidity & Slippage API](/docs/blockchain/robinhood/robinhood-liquidity/) +- [Robinhood Meme Coin Launches API](/docs/blockchain/robinhood/robinhood-meme-coin-launches/) +- [WebSocket authentication](/docs/authorization/websocket/) +::: + +**On this page:** [Why not a node](#why-stream-events-instead-of-running-a-node) · [Datasets & history](#datasets-and-history) · [Event anatomy](#what-one-event-row-contains) · [Firehose](#stream-all-events-firehose) · [By contract](#stream-events-from-one-contract) · [By signature](#stream-one-event-across-all-contracts) · [By topic0](#stream-by-raw-topic0-signature-hash) · [By argument](#watch-an-address-across-all-decoded-arguments) · [By wallet](#events-from-a-wallets-transactions) · [Historical queries](#latest-events-query) · [Use cases](#use-case-patterns) · [FAQ](#faq) + +--- + +## Why stream events instead of running a node + +| | Your own node (`eth_subscribe` / `eth_getLogs`) | Bitquery Events stream | +| --- | --- | --- | +| Infrastructure | Run and sync a Robinhood node, manage reconnects and reorgs | One WebSocket to `streaming.bitquery.io` | +| Decoding | Raw topics + data; you maintain ABIs and decoders | `Arguments` arrive **decoded and typed** for known signatures; raw `Topics` always included | +| Context | Logs only — separate calls for tx, trace, receipt | Transaction, internal `Call`, and `Receipt` joined onto every event | +| Filtering | Address + topics only | Address, signature name, signature hash, **decoded argument values**, tx sender, time — server-side | +| Backfill | Separate `eth_getLogs` pagination logic | Same query with `dataset: archive` / `combined` | +| Scale | One node, you shard consumers | One firehose socket or hundreds of filtered sockets | + +If you are migrating node code: your `eth_getLogs` `address` filter maps to `LogHeader.Address`, and `topics[0]` maps to `Log.Signature.SignatureHash`. + +--- + +## Datasets and history + +- **`realtime`** (the default) — a rolling window of recent blocks whose depth varies; don't assume it, measure it with the probe below. +- **`archive`** — event history back to when Bitquery indexing began for Robinhood; its head lags the chain by minutes. +- **`combined`** — archive + realtime union; the safe choice for fixed windows (24h, 7d). + +Need bulk history beyond what you want to page through the API? Bitquery can also provide **historical data exports** — [contact support](https://bitquery.io/forms/api). + +### Check the events window + +Run this against `realtime` (or `archive`) to see exactly what the dataset currently holds: + +```graphql +{ + EVM(network: robinhood) { + Events { + count + earliest: Block { Time(minimum: Block_Time) } + latest: Block { Time(maximum: Block_Time) } + } + } +} +``` + +--- + +## What one event row contains + +| Group | What it gives you | +| --- | --- | +| **`Log`** | Emitting context: `SmartContract`, log `Index`, and the `Signature` (`Name`, full `Signature`, `SignatureHash`, `Parsed`) | +| **`Topics`** | The raw indexed topics (`Hash` array — topic0 is the event signature hash) | +| **`Arguments`** | Decoded, typed argument values (`address`, `bigInteger`, `string`, `hex`, `bool`, `integer`) with names | +| **`Transaction`** | Hash, `From`/`To`, value, full gas and fee fields (incl. USD) | +| **`Call`** | The internal call that emitted the log: call path, signature, gas, revert/error flags | +| **`Receipt`** | `GasUsed`, `CumulativeGasUsed`, deployed `ContractAddress`, receipt `Type` | +| **`Block`** | `Number`, `Time`, `Nonce` | + +:::info LogHeader.Address vs Log.SmartContract +`LogHeader.Address` is the **emitting address** — the `address` field a node would return in `eth_getLogs`. `Log.SmartContract` is the **code that produced the log**, which differs behind proxies: several major Robinhood tokens (WETH, USDG) emit through proxy addresses backed by separate implementation contracts. Filter `LogHeader.Address` to watch a deployed address; read `Log.SmartContract` to group proxies that share one implementation. +::: + +Hash fields (`SignatureHash`, `Topics.Hash`) are hex strings **without** a `0x` prefix. + +--- + +## Stream all events (firehose) + +One socket, every event on the chain, with the full record — decoded arguments, raw topics, transaction, call, and receipt. Events arrive in per-block batches. + +:::warning High volume +The unfiltered firehose delivers every event on a busy chain — great for exploration and building your own indexer, heavy for everything else. Use the filtered streams below in production. +::: + +```graphql +subscription { + EVM(network: robinhood) { + Events { + Block { + Number + Time + Nonce + } + Call { + CallPath + InternalCalls + From + To + Signature { + Name + Parsed + Signature + SignatureHash + SignatureType + } + CallerIndex + Create + Delegated + Error + Gas + GasUsed + Index + Reverted + SelfDestruct + Success + Value + ValueInUSD + } + Topics { + Hash + } + Receipt { + CumulativeGasUsed + ContractAddress + Type + GasUsed + } + Transaction { + From + To + Type + Cost + CostInUSD + Gas + GasFeeCap + GasFeeCapInUSD + GasPriceInUSD + GasPrice + GasTipCapInUSD + GasTipCap + Hash + Value + ValueInUSD + } + Arguments { + Name + Type + Value { + ... on EVM_ABI_Integer_Value_Arg { + integer + } + ... on EVM_ABI_String_Value_Arg { + string + } + ... on EVM_ABI_Address_Value_Arg { + address + } + ... on EVM_ABI_BigInt_Value_Arg { + bigInteger + } + ... on EVM_ABI_Bytes_Value_Arg { + hex + } + ... on EVM_ABI_Boolean_Value_Arg { + bool + } + } + } + Log { + Signature { + Name + Abi + Parsed + Signature + SignatureHash + SignatureType + } + SmartContract + EnterIndex + ExitIndex + Index + LogAfterCallIndex + Pc + } + } + } +} +``` + +:::tip WebSocket connection +Connect to `wss://streaming.bitquery.io/graphql?token=YOUR_TOKEN` with the `graphql-transport-ws` subprotocol (`connection_init` → `connection_ack` → `subscribe`). See [WebSocket authentication](/docs/authorization/websocket/). Any subscription on this page also runs as a query — add `limit` and `orderBy` and drop the `subscription` keyword. +::: + +--- + +## Stream events from one contract + +**Protocol monitoring:** everything a single deployed address emits — the streaming equivalent of an `eth_getLogs` address filter. Example: WETH. + +```graphql +subscription { + EVM(network: robinhood) { + Events( + where: { LogHeader: { Address: { is: "0x0bd7d308f8e1639fab988df18a8011f41eacad73" } } } + ) { + Block { + Time + } + Transaction { + Hash + } + Log { + Signature { + Name + } + SmartContract + } + Arguments { + Name + Type + Value { + ... on EVM_ABI_Integer_Value_Arg { + integer + } + ... on EVM_ABI_String_Value_Arg { + string + } + ... on EVM_ABI_Address_Value_Arg { + address + } + ... on EVM_ABI_BigInt_Value_Arg { + bigInteger + } + ... on EVM_ABI_Bytes_Value_Arg { + hex + } + ... on EVM_ABI_Boolean_Value_Arg { + bool + } + } + } + } + } +} +``` + +### Multiple contracts, one socket + +Watch a whole list of contracts with `Address.in` — one socket per protocol instead of one per contract. + +```graphql +subscription { + EVM(network: robinhood) { + Events( + where: { + LogHeader: { + Address: { + in: [ + "0x0bd7d308f8e1639fab988df18a8011f41eacad73" + "0x5fc5360d0400a0fd4f2af552add042d716f1d168" + ] + } + } + } + ) { + Block { + Time + } + Log { + Signature { + Name + } + SmartContract + } + Arguments { + Name + Value { + ... on EVM_ABI_Address_Value_Arg { + address + } + ... on EVM_ABI_BigInt_Value_Arg { + bigInteger + } + } + } + } + } +} +``` + +--- + +## Stream one event across all contracts + +**Network-wide feeds:** filter by decoded signature name to receive one event type from **every** contract — for example, every ERC-20 `Transfer` on Robinhood in a single socket (the backbone of a token indexer). Works the same for `Swap`, `Approval`, `OwnershipTransferred`, or any launchpad event (see [Flap.sh](/docs/blockchain/robinhood/flap-sh-api/) and [Bags.fm](/docs/blockchain/robinhood/bags-fm-api/) for protocol-specific examples). + +```graphql +subscription { + EVM(network: robinhood) { + Events( + where: { Log: { Signature: { Name: { is: "Transfer" } } } } + ) { + Block { + Time + } + Log { + SmartContract + } + Arguments { + Name + Value { + ... on EVM_ABI_Address_Value_Arg { + address + } + ... on EVM_ABI_BigInt_Value_Arg { + bigInteger + } + } + } + } + } +} +``` + +:::note Names can collide +Different ABIs reuse the same event name — Robinhood carries more than one distinct `Swap` signature, for instance. A name filter catches all variants; pin one exact ABI with the [signature-hash filter](#stream-by-raw-topic0-signature-hash) below. +::: + +--- + +## Stream by raw topic0 (signature hash) + +Filter on `Log.Signature.SignatureHash` — the keccak of the event signature, i.e. `topics[0]` — **without the `0x` prefix**. This pins one exact ABI variant, and it also works for **undecoded events**: rows where `Signature.Name` is empty and `Parsed` is `false` still carry their hash and raw `Topics`, so no log on the chain is out of reach. + +Example: the canonical ERC-20 `Transfer(address,address,uint256)` topic0. + +```graphql +subscription { + EVM(network: robinhood) { + Events( + where: { + Log: { + Signature: { + SignatureHash: { + is: "ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef" + } + } + } + } + ) { + Block { + Time + } + Log { + Signature { + Name + SignatureHash + } + SmartContract + } + Topics { + Hash + } + } + } +} +``` + +--- + +## Watch an address across all decoded arguments + +**Wallet / token surveillance:** match events where **any decoded argument** equals an address — transfers in or out, approvals, swaps, or protocol events mentioning it, in one stream, regardless of event type or contract. This is a filter a raw node cannot do server-side. + +```graphql +subscription { + EVM(network: robinhood) { + Events( + where: { + Arguments: { + includes: { + Value: { Address: { is: "0xcaf681a66d020601342297493863e78c959e5cb2" } } + } + } + } + ) { + Block { + Time + } + Log { + Signature { + Name + } + SmartContract + } + Transaction { + Hash + } + Arguments { + Name + Type + Value { + ... on EVM_ABI_Address_Value_Arg { + address + } + ... on EVM_ABI_BigInt_Value_Arg { + bigInteger + } + } + } + } + } +} +``` + +Add `Name: { is: "token" }` (or any argument name) inside `includes` to match a specific argument instead of any position. As a historical query, argument matching scans widely — combine it with a `Block.Time` window or a contract filter for speed. + +--- + +## Events from a wallet's transactions + +Everything emitted by transactions **sent** by one address — a debugging and bot-monitoring view (which pools did my router touch, which events did my deployment emit). + +```graphql +subscription { + EVM(network: robinhood) { + Events( + where: { Transaction: { From: { is: "0xcaf681a66d020601342297493863e78c959e5cb2" } } } + ) { + Block { + Time + } + Transaction { + Hash + } + Log { + Signature { + Name + } + SmartContract + } + } + } +} +``` + +Rows appear only while the wallet is actively sending transactions — swap in any sender you care about. + +--- + +## Latest events query + +The query counterpart of the firehose: page through recent events, newest first. + +```graphql +{ + EVM(network: robinhood) { + Events(limit: { count: 10 }, orderBy: { descending: Block_Time }) { + Block { + Number + Time + } + Transaction { + Hash + From + To + } + Log { + Signature { + Name + SignatureHash + } + SmartContract + Index + } + Arguments { + Name + Type + Value { + ... on EVM_ABI_Integer_Value_Arg { + integer + } + ... on EVM_ABI_String_Value_Arg { + string + } + ... on EVM_ABI_Address_Value_Arg { + address + } + ... on EVM_ABI_BigInt_Value_Arg { + bigInteger + } + ... on EVM_ABI_Bytes_Value_Arg { + hex + } + ... on EVM_ABI_Boolean_Value_Arg { + bool + } + } + } + } + } +} +``` + +--- + +## All events in one transaction + +**Forensics / debugging:** decompose a transaction into its ordered event log. A DEX swap, for example, unrolls into its `Transfer`s, pool `Sync`/`Swap` events, and any protocol hooks — with decoded arguments for each. + +```graphql +{ + EVM(network: robinhood) { + Events( + orderBy: { ascending: Log_Index } + where: { + Transaction: { + Hash: { + is: "0xdb0f8aed6d900da3751670f311dbb8a7ae3f44022d15eff2b72a5d0863a1750f" + } + } + } + ) { + Log { + Index + Signature { + Name + } + SmartContract + } + Arguments { + Name + Type + Value { + ... on EVM_ABI_Integer_Value_Arg { + integer + } + ... on EVM_ABI_String_Value_Arg { + string + } + ... on EVM_ABI_Address_Value_Arg { + address + } + ... on EVM_ABI_BigInt_Value_Arg { + bigInteger + } + ... on EVM_ABI_Bytes_Value_Arg { + hex + } + ... on EVM_ABI_Boolean_Value_Arg { + bool + } + } + } + } + } +} +``` + +--- + +## Top event signatures + +**Discovery:** which events dominate the chain right now — grouped by signature with counts. Rows with an empty `Name` are undecoded signatures; their `SignatureHash` still identifies them. + +```graphql +{ + EVM(network: robinhood) { + Events(limit: { count: 15 }, orderBy: { descendingByField: "count" }) { + Log { + Signature { + Name + SignatureHash + } + } + count + } + } +} +``` + +--- + +## Most active event emitters + +Which contracts emit the most events over a window, and how many distinct signatures each uses — a fast map of what's hot on chain. + +```graphql +{ + EVM(network: robinhood) { + Events( + limit: { count: 10 } + orderBy: { descendingByField: "count" } + where: { Block: { Time: { since_relative: { hours_ago: 1 } } } } + ) { + Log { + SmartContract + } + count + signatures: count(distinct: Log_Signature_SignatureHash) + } + } +} +``` + +--- + +## Event volume in a time window + +One-row stats for dashboards: total events and distinct emitting contracts. Use `dataset: combined` when the window must be complete regardless of the realtime depth. + +```graphql +{ + EVM(network: robinhood) { + Events(where: { Block: { Time: { since_relative: { hours_ago: 1 } } } }) { + count + contracts: count(distinct: Log_SmartContract) + } + } +} +``` + +--- + +## Use-case patterns + +| Goal | Approach | +| --- | --- | +| Token indexer without a node | Stream `Signature.Name: "Transfer"` (or pin the [topic0 hash](#stream-by-raw-topic0-signature-hash)); backfill with the same query on `dataset: archive` | +| DEX analytics | Stream `Swap` by signature hash per ABI variant; join context from `Transaction` / `Call` | +| Launchpad detection | Creation events per protocol — see [Meme Coin Launches](/docs/blockchain/robinhood/robinhood-meme-coin-launches/), [Flap.sh](/docs/blockchain/robinhood/flap-sh-api/), [Bags.fm](/docs/blockchain/robinhood/bags-fm-api/) | +| Pool reserve / price state | Purpose-built cubes are easier — [DEXPoolEvents](/docs/blockchain/robinhood/robinhood-liquidity/) | +| Wallet / compliance watch | [Argument address filter](#watch-an-address-across-all-decoded-arguments) — one stream, every event type | +| Protocol ops & alerting | [Contract filter](#stream-events-from-one-contract) on your deployments; alert on `OwnershipTransferred`, role changes, pauses | +| Incident forensics | [Per-transaction event log](#all-events-in-one-transaction), plus `Call.Reverted` / `Receipt` context | +| Chain discovery | [Top signatures](#top-event-signatures) and [top emitters](#most-active-event-emitters) | + +--- + +## Tips + +1. **Filter production streams.** The firehose is for exploration and full indexers; per-contract, per-signature, and per-hash sockets are cheap — open as many as you need, or multiplex several subscriptions over one WebSocket connection. +2. `LogHeader.Address` = emitting address (node-style filter); `Log.SmartContract` = the code behind it — they differ for proxy contracts. +3. Hash fields have **no `0x` prefix** — `SignatureHash` and `Topics.Hash` are bare hex. +4. Event **names collide across ABIs** (multiple `Swap` variants exist) — filter by `SignatureHash` when exact ABI identity matters. +5. Undecoded events (`Name: ""`, `Parsed: false`) are still delivered and filterable by hash — nothing on chain is invisible. +6. Realtime depth varies — measure it with the [window probe](#check-the-events-window); use `combined` for fixed windows and `archive` for full history (its head lags the chain by minutes). +7. Decoded-argument filters scan broadly as historical queries — scope them with a time window or contract filter; as subscriptions they are cheap. +8. For bulk backfills beyond API paging, ask Bitquery about [historical data exports](https://bitquery.io/forms/api). + +--- + +## FAQ + +### Can I listen to Robinhood contract events without running a node? + +Yes — that is this API's core use. A GraphQL `subscription` on `EVM(network: robinhood) { Events }` over WebSocket replaces `eth_subscribe("logs")`, with decoded arguments and joined transaction/call/receipt context that a node doesn't provide. Backfill uses the same query with `dataset: archive`. + +### Should I open one WebSocket or many? + +Both work. One firehose socket can feed your own router, or you can open a separate narrowly-filtered subscription per contract, signature, or address — hundreds of concurrent filtered sockets are a supported pattern, and several subscriptions can also share one connection. + +### Are event arguments decoded? + +Yes — `Arguments` returns named, typed values (`address`, `bigInteger`, `string`, `hex`, `bool`, `integer`) for known signatures. Unknown signatures still stream with raw `Topics` and their `SignatureHash`. + +### How do I filter by raw topic0? + +Use `Log.Signature.SignatureHash` with the keccak hash of the event signature, **without** the `0x` prefix — see [the topic0 stream](#stream-by-raw-topic0-signature-hash). + +### How far back does Robinhood events data go? + +`archive` reaches back to when Bitquery indexing began for the network, and `realtime` holds a rolling recent window — measure either with the [window probe](#check-the-events-window). For bulk history, Bitquery can additionally provide data exports on request. + +### How do I get every event a specific transaction emitted? + +Filter `Transaction.Hash` and order by `Log_Index` — see [All events in one transaction](#all-events-in-one-transaction). + +### Which cube should I use — Events, Transfers, or Calls? + +`Events` is the decoded-log firehose. For token movements specifically, [Transfers](/docs/blockchain/robinhood/robinhood-transfers/) is pre-modeled with USD enrichment; for pool state, use [DEXPoolEvents](/docs/blockchain/robinhood/robinhood-liquidity/). See [Transfers vs Events vs Calls](/docs/start/mental-model-transfers-events-calls/). diff --git a/sidebars.js b/sidebars.js index 97be946e..a5078fb8 100644 --- a/sidebars.js +++ b/sidebars.js @@ -849,12 +849,13 @@ const sidebars = { slug: "/blockchain/robinhood", title: "Robinhood APIs", description: - "APIs for accessing Robinhood trades, transfers, liquidity, slippage, balances, and meme coin token launches via Bitquery Trading and EVM APIs.", + "APIs for accessing Robinhood trades, transfers, liquidity, slippage, events, balances, and meme coin token launches via Bitquery Trading and EVM APIs.", }, items: [ "blockchain/robinhood/robinhood-trades", "blockchain/robinhood/robinhood-transfers", "blockchain/robinhood/robinhood-liquidity", + "blockchain/robinhood/robinhood-events-api", "blockchain/robinhood/robinhood-meme-coin-launches", "blockchain/robinhood/flap-sh-api", "blockchain/robinhood/bags-fm-api", From b5acbe6943177c1561745b1ff08b56eeda64e3f4 Mon Sep 17 00:00:00 2001 From: Gaurav agarwal Date: Fri, 24 Jul 2026 12:31:48 +0530 Subject: [PATCH 2/5] Add Robinhood Calls & Traces page; Kafka firehose tips; retention notes New stream-first Calls/Traces page (EVM.Calls) as a debug_traceTransaction alternative: verified firehose, per-contract/function/selector streams, Create-true deployment radar, reverted-call monitor, value traces, per-tx call-tree reconstruction, and gas/method analytics. Documents 4-byte uppercase selector format and call-tree semantics; registered in sidebar. Updates Events page archive wording to the ~3-month retention plan and adds Robinhood Kafka stream pointers (per-topic) to the five streaming pages. All queries live-tested; subscriptions verified over WebSocket. Co-Authored-By: Claude Fable 5 --- .../robinhood/robinhood-calls-api.md | 601 ++++++++++++++++++ .../robinhood/robinhood-events-api.md | 8 +- .../robinhood/robinhood-liquidity.md | 4 + docs/blockchain/robinhood/robinhood-trades.md | 4 + .../robinhood/robinhood-transfers.md | 4 + sidebars.js | 1 + 6 files changed, 620 insertions(+), 2 deletions(-) create mode 100644 docs/blockchain/robinhood/robinhood-calls-api.md diff --git a/docs/blockchain/robinhood/robinhood-calls-api.md b/docs/blockchain/robinhood/robinhood-calls-api.md new file mode 100644 index 00000000..3241b8b3 --- /dev/null +++ b/docs/blockchain/robinhood/robinhood-calls-api.md @@ -0,0 +1,601 @@ +--- +title: "Robinhood Calls & Traces API — WebSocket Streams" +description: "Stream Robinhood contract calls and internal traces over GraphQL WebSockets — decoded inputs, call trees, deployments, reverts. A debug_traceTransaction alternative." +sidebar_position: 5 +keywords: + - Robinhood calls API + - Robinhood traces API + - Robinhood internal transactions + - debug_traceTransaction alternative + - trace_filter alternative Robinhood + - Robinhood contract calls websocket + - Robinhood smart contract function calls + - Robinhood contract deployments stream + - Robinhood reverted transactions + - 4-byte selector filter + - Bitquery Robinhood Calls API +--- +# Robinhood Calls & Traces API — WebSocket Streams + +Stream **every contract call and internal trace on Robinhood** with Bitquery GraphQL — top-level calls and nested internal calls, with **decoded input arguments**, gas accounting, revert errors, and the surrounding transaction and receipt joined into one record. The `EVM.Calls` cube on `network: robinhood` replaces a tracing node: no `debug_traceTransaction` loops, no 4-byte databases, no trace decoding pipeline. + +Open **one WebSocket that carries every call on the chain**, or narrowly filtered sockets — per contract, per function, per selector, deployments-only, reverts-only. Every subscription on this page was verified live over WebSocket, and every query was executed against the production endpoint before publishing. + +:::note API Key Required +To query or stream data outside the Bitquery IDE, you need an API access token. + +Follow the steps here: [How to generate Bitquery API token ➤](/docs/authorization/how-to-generate/) +::: + +:::tip Related docs +- [Robinhood Events API](/docs/blockchain/robinhood/robinhood-events-api/) +- [Transfers vs Events vs Calls](/docs/start/mental-model-transfers-events-calls/) +- [Robinhood Transfers](/docs/blockchain/robinhood/robinhood-transfers/) +- [Robinhood Trades](/docs/blockchain/robinhood/robinhood-trades/) +- [WebSocket authentication](/docs/authorization/websocket/) +::: + +**On this page:** [Why not a tracing node](#why-stream-calls-instead-of-tracing-a-node) · [Datasets & history](#datasets-and-history) · [Call anatomy](#what-one-call-row-contains) · [Firehose](#stream-all-calls-firehose) · [By contract](#stream-calls-to-one-contract) · [By function](#stream-by-function-name-or-selector) · [Deployments](#stream-contract-deployments) · [Reverts](#stream-reverted-calls) · [Value traces](#internal-eth-value-transfers) · [By wallet](#calls-from-a-wallet) · [Call tree](#full-call-tree-of-a-transaction) · [Analytics](#top-called-contracts) · [FAQ](#faq) + +--- + +## Why stream calls instead of tracing a node + +| | Tracing node (`debug_traceTransaction` / `trace_filter`) | Bitquery Calls stream | +| --- | --- | --- | +| Infrastructure | Archive node with tracing enabled — heavy to run and sync | One WebSocket to `streaming.bitquery.io` | +| Decoding | Raw calldata; you maintain ABIs and 4-byte lookups | `Arguments` arrive **decoded and typed** for known signatures | +| Scope | Per-transaction or per-block tracing loops | Server-side filters: contract, function name, selector, caller, `Create`, `Reverted`, value, time | +| Context | Trace only — separate calls for tx and receipt | Transaction and `Receipt` joined onto every call | +| Deployments | Diff traces for `CREATE` frames yourself | `Call: { Create: true }` is a filter | +| Backfill | Re-trace history block by block | Same query with `dataset: archive` / `combined` | + +--- + +## Datasets and history + +- **`realtime`** (the default) — a rolling window of recent blocks whose depth varies; measure it with the probe below rather than assuming it. +- **`archive`** — deep call history, retained up to roughly the **last 3 months** (Robinhood is a newer chain, so today the archive holds its complete history; older data ages out as the cap applies); its head lags the chain by minutes. +- **`combined`** — archive + realtime union; the safe choice for fixed windows (24h, 7d). + +For older or bulk history, Bitquery can provide **data exports** — [contact support](https://bitquery.io/forms/api). + +### Check the calls window + +```graphql +{ + EVM(network: robinhood) { + Calls { + count + earliest: Block { Time(minimum: Block_Time) } + latest: Block { Time(maximum: Block_Time) } + } + } +} +``` + +--- + +## What one call row contains + +| Group | What it gives you | +| --- | --- | +| **`Call`** | `From`/`To`, `Value` (+USD), gas fields, `Signature` (function `Name`, full `Signature`, 4-byte `SignatureHash`), flags: `Create`, `Delegated`, `Reverted`, `Success`, `SelfDestruct`, `Error`, plus tree position (`Index`, `CallerIndex`, `CallPath`, `InternalCalls`) | +| **`Arguments`** | Decoded, typed **function input values** (`address`, `bigInteger`, `string`, `hex`, `bool`, `integer`) with parameter names | +| **`Transaction`** | Hash, `From`/`To`, value, full gas and fee fields (incl. USD) | +| **`Receipt`** | `GasUsed`, `CumulativeGasUsed`, `ContractAddress`, receipt `Type` | +| **`Block`** | `Number`, `Time`, `Nonce` | + +Tree semantics: `Index` numbers each call within the transaction, `CallerIndex` points to the parent call's index, and `CallPath` is the position path from the top-level call (e.g. `[2, 0]` = first sub-call of call 2) — enough to rebuild the entire trace tree client-side. + +For calls, `Signature.SignatureHash` is the **4-byte selector** as uppercase hex **without** a `0x` prefix (e.g. `A9059CBB` for `transfer(address,uint256)`). Calls with an empty `Name` are undecoded selectors — still streamed and filterable by hash. Note that on-chain `balanceOf`-style reads made by contracts also appear: this cube sees every call executed, not just state-changing ones. + +--- + +## Stream all calls (firehose) + +One socket, every call on the chain — top-level and internal — with decoded inputs and full context. Events arrive in per-block batches. + +:::warning Very high volume +Calls are the highest-volume cube on a busy chain (every transaction fans out into many internal calls). Use the firehose for exploration and full indexers; filter in production. +::: + +```graphql +subscription { + EVM(network: robinhood) { + Calls { + Block { + Number + Time + Nonce + } + Call { + CallPath + InternalCalls + From + To + Signature { + Name + Parsed + Signature + SignatureHash + SignatureType + } + CallerIndex + Create + Delegated + Error + Gas + GasUsed + Index + Reverted + SelfDestruct + Success + Value + ValueInUSD + } + Receipt { + CumulativeGasUsed + ContractAddress + Type + GasUsed + } + Transaction { + From + To + Type + Cost + CostInUSD + Gas + GasFeeCap + GasFeeCapInUSD + GasPriceInUSD + GasPrice + GasTipCapInUSD + GasTipCap + Hash + Value + ValueInUSD + } + Arguments { + Name + Type + Value { + ... on EVM_ABI_Integer_Value_Arg { + integer + } + ... on EVM_ABI_String_Value_Arg { + string + } + ... on EVM_ABI_Address_Value_Arg { + address + } + ... on EVM_ABI_BigInt_Value_Arg { + bigInteger + } + ... on EVM_ABI_Bytes_Value_Arg { + hex + } + ... on EVM_ABI_Boolean_Value_Arg { + bool + } + } + } + } + } +} +``` + +:::tip WebSocket connection +Connect to `wss://streaming.bitquery.io/graphql?token=YOUR_TOKEN` with the `graphql-transport-ws` subprotocol (`connection_init` → `connection_ack` → `subscribe`). See [WebSocket authentication](/docs/authorization/websocket/). Any subscription on this page also runs as a query — add `limit` and `orderBy` and drop the `subscription` keyword. +::: + +:::tip Prefer Kafka for the firehose +Consuming the full call feed continuously? Bitquery also delivers Robinhood data as **Kafka streams** — decoded transactions, calls, and events on the protobuf topic `robinhood.transactions.proto` — with consumer-group scaling and replay. See [Kafka Streaming Concepts](/docs/streams/kafka-streaming-concepts/). +::: + +--- + +## Stream calls to one contract + +**Protocol ops:** every function invocation of one contract — including internal calls from other contracts, which a mempool or tx-level watcher misses. Example: the Uniswap V4 pool manager. + +```graphql +subscription { + EVM(network: robinhood) { + Calls( + where: { Call: { To: { is: "0x8366a39cc670b4001a1121b8f6a443a643e40951" } } } + ) { + Block { + Time + } + Call { + From + To + Signature { + Name + SignatureHash + } + GasUsed + Success + } + Transaction { + Hash + } + } + } +} +``` + +--- + +## Stream by function name or selector + +**Method-level feeds:** filter by decoded function name to receive one method across **every** contract — for example, every ERC-20 `transfer` call on the chain. + +```graphql +subscription { + EVM(network: robinhood) { + Calls( + where: { Call: { Signature: { Name: { is: "transfer" } } } } + ) { + Block { + Time + } + Call { + From + To + Signature { + Name + SignatureHash + } + } + Arguments { + Name + Type + Value { + ... on EVM_ABI_Address_Value_Arg { + address + } + ... on EVM_ABI_BigInt_Value_Arg { + bigInteger + } + } + } + } + } +} +``` + +To pin one exact ABI variant — or to match an **undecoded** method — filter the 4-byte selector instead (uppercase hex, no `0x`): + +```graphql +subscription { + EVM(network: robinhood) { + Calls( + where: { Call: { Signature: { SignatureHash: { is: "70A08231" } } } } + ) { + Block { + Time + } + Call { + To + Signature { + Name + SignatureHash + } + } + } + } +} +``` + +--- + +## Stream contract deployments + +**New-contract radar:** `Call: { Create: true }` matches every `CREATE`/`CREATE2` frame — top-level and factory-internal. On these rows **`Call.To` is the newly deployed contract address** and `Call.From` is the deployer (`Receipt.ContractAddress` is populated only for top-level deployment transactions). When tested live, this stream caught a launchpad factory deploying a new token contract within seconds. + +```graphql +subscription { + EVM(network: robinhood) { + Calls( + where: { Call: { Create: true } } + ) { + Block { + Time + } + Call { + From + To + Create + Success + } + Transaction { + Hash + From + } + } + } +} +``` + +--- + +## Stream reverted calls + +**Error monitoring:** every failed call with its revert reason — watch your own contracts for breakage, or the whole chain for failing bots and exploits in progress. `Call.Error` carries the message (commonly `execution reverted`). + +```graphql +subscription { + EVM(network: robinhood) { + Calls( + where: { Call: { Reverted: true } } + ) { + Block { + Time + } + Call { + From + To + Error + Reverted + Success + Signature { + Name + } + } + Transaction { + Hash + } + } + } +} +``` + +Scope it with a `Call.To` filter to alert only on your own deployments. + +--- + +## Internal ETH value transfers + +**Value tracing:** calls that move native ETH (`Call.Value > 0`) — including internal transfers that never appear as top-level transaction values. The [Transfers cube](/docs/blockchain/robinhood/robinhood-transfers/) models the same movements with USD enrichment; use Calls when you want them inside their execution context. + +```graphql +subscription { + EVM(network: robinhood) { + Calls( + where: { Call: { Value: { gt: "0" } } } + ) { + Block { + Time + } + Call { + From + To + Value + ValueInUSD + Signature { + Name + } + } + Transaction { + Hash + } + } + } +} +``` + +--- + +## Calls from a wallet + +Everything one address executes — as transaction sender or as an internal caller (routers and bots show up here with their full fan-out). Swap in any address; rows appear only while it is active. + +```graphql +subscription { + EVM(network: robinhood) { + Calls( + where: { Call: { From: { is: "0xcaf681a66d020601342297493863e78c959e5cb2" } } } + ) { + Block { + Time + } + Call { + To + Value + Signature { + Name + } + } + Transaction { + Hash + } + } + } +} +``` + +--- + +## Full call tree of a transaction + +**The `debug_traceTransaction` replacement:** every call frame of one transaction, ordered by `Call_Index`, with `CallerIndex`/`CallPath` to rebuild the tree and decoded arguments per frame. + +```graphql +{ + EVM(network: robinhood) { + Calls( + orderBy: { ascending: Call_Index } + where: { + Transaction: { + Hash: { + is: "0x816be7f8f359f85066599fcd2585cbf7c3b544590315afc5298dc7e538b3678b" + } + } + } + ) { + Call { + Index + CallerIndex + CallPath + From + To + Delegated + Create + Success + GasUsed + Value + Signature { + Name + } + } + } + } +} +``` + +--- + +## Top called contracts + +**Discovery:** the most-invoked contracts over a window, with how many distinct methods each serves. + +```graphql +{ + EVM(network: robinhood) { + Calls( + limit: { count: 10 } + orderBy: { descendingByField: "calls" } + where: { Block: { Time: { since_relative: { hours_ago: 1 } } } } + ) { + Call { + To + } + calls: count + signatures: count(distinct: Call_Signature_SignatureHash) + } + } +} +``` + +--- + +## Top function signatures + +Which methods dominate the chain — grouped by signature with counts. Rows with an empty `Name` are undecoded selectors. + +```graphql +{ + EVM(network: robinhood) { + Calls(limit: { count: 15 }, orderBy: { descendingByField: "count" }) { + Call { + Signature { + Name + SignatureHash + } + } + count + } + } +} +``` + +--- + +## Top gas-burning contracts + +**Gas analytics:** rank contracts by total gas consumed over a window — where the chain's compute actually goes. + +```graphql +{ + EVM(network: robinhood) { + Calls( + limit: { count: 10 } + orderBy: { descendingByField: "gas" } + where: { Block: { Time: { since_relative: { hours_ago: 1 } } } } + ) { + Call { + To + } + gas: sum(of: Call_GasUsed) + calls: count + } + } +} +``` + +--- + +## Call volume in a time window + +One-row stats for dashboards: total calls, distinct callers, distinct called contracts. Use `dataset: combined` when the window must be complete regardless of realtime depth. + +```graphql +{ + EVM(network: robinhood, dataset: combined) { + Calls(where: { Block: { Time: { since_relative: { hours_ago: 1 } } } }) { + count + callers: count(distinct: Call_From) + contracts: count(distinct: Call_To) + } + } +} +``` + +--- + +## Use-case patterns + +| Goal | Approach | +| --- | --- | +| Trace explorer / tx debugger | [Per-transaction call tree](#full-call-tree-of-a-transaction) with `Index`/`CallerIndex`/`CallPath` | +| New-contract & token-factory radar | [`Create: true` stream](#stream-contract-deployments) — `Call.To` is the deployed address | +| Contract error alerting | [`Reverted: true`](#stream-reverted-calls) scoped to your `Call.To` | +| Method-level analytics | [Name / selector streams](#stream-by-function-name-or-selector); counts via [top signatures](#top-function-signatures) | +| Internal ETH flow tracing | [`Value > 0` calls](#internal-eth-value-transfers), or [Transfers](/docs/blockchain/robinhood/robinhood-transfers/) for USD-priced movements | +| Bot / router monitoring | [`Call.From` stream](#calls-from-a-wallet) for the full execution fan-out | +| Chain ops dashboards | [Top called contracts](#top-called-contracts), [gas burners](#top-gas-burning-contracts), [window stats](#call-volume-in-a-time-window) | +| Event-side view of the same activity | [Robinhood Events API](/docs/blockchain/robinhood/robinhood-events-api/) | + +--- + +## Tips + +1. **Filter production streams.** The calls firehose outweighs every other cube — per-contract, per-selector, deployments-only, and reverts-only sockets are cheap. +2. For calls, `SignatureHash` is the **4-byte selector, uppercase hex, no `0x`** (events use the full 32-byte topic hash instead). +3. `Create: true` rows put the **deployed contract in `Call.To`**; `Receipt.ContractAddress` fills only for top-level deployment transactions. +4. Function names collide across ABIs and undecoded methods have empty names — pin exact behavior with the selector filter. +5. Every executed call appears, including contract-to-contract `balanceOf`-style reads — filter by name/selector to cut that noise from analytics. +6. Rebuild trace trees client-side from `Index`, `CallerIndex`, and `CallPath`; `InternalCalls` tells you how many children a frame has. +7. Realtime depth varies — measure with the [window probe](#check-the-calls-window); use `combined` for fixed windows. Archive retains up to roughly the last 3 months of calls; for older or bulk data, ask about [exports](https://bitquery.io/forms/api). +8. Decoded `Arguments` are the function **inputs**; for emitted results, join the same transaction on the [Events API](/docs/blockchain/robinhood/robinhood-events-api/). + +--- + +## FAQ + +### Can I trace Robinhood transactions without a tracing node? + +Yes — filter `EVM.Calls` by `Transaction.Hash` and order by `Call_Index` to get every internal call frame with decoded inputs, gas, and revert state: a `debug_traceTransaction` replacement served over GraphQL. Stream the same cube for live traces. + +### How do I detect new contract deployments in real time? + +Subscribe with `Call: { Create: true }`. Each row's `Call.To` is the freshly deployed contract address and `Call.From` its deployer — factory-internal deployments included. See [Stream contract deployments](#stream-contract-deployments). + +### How do I monitor failed or reverted calls? + +Subscribe with `Call: { Reverted: true }` (optionally scoped by `Call.To` to your contracts) and read `Call.Error` for the revert reason. See [Stream reverted calls](#stream-reverted-calls). + +### How do I filter by a 4-byte function selector? + +Use `Call.Signature.SignatureHash` with the selector as uppercase hex without `0x` — e.g. `A9059CBB` for `transfer(address,uint256)`. This also matches methods whose ABI is unknown (empty `Name`). + +### How far back does Robinhood calls data go? + +`archive` retains up to roughly the last 3 months of calls (on a newer chain like Robinhood that is currently its complete history), and `realtime` holds a rolling recent window — measure either with the [window probe](#check-the-calls-window). For older or bulk history, Bitquery can provide data exports on request. + +### Which cube should I use — Calls, Events, or Transfers? + +`Calls` is execution: who invoked what, with inputs, gas, and reverts. [`Events`](/docs/blockchain/robinhood/robinhood-events-api/) is what contracts emitted. [`Transfers`](/docs/blockchain/robinhood/robinhood-transfers/) is pre-modeled asset movement with USD enrichment. See [Transfers vs Events vs Calls](/docs/start/mental-model-transfers-events-calls/). diff --git a/docs/blockchain/robinhood/robinhood-events-api.md b/docs/blockchain/robinhood/robinhood-events-api.md index f0d02455..44df85b2 100644 --- a/docs/blockchain/robinhood/robinhood-events-api.md +++ b/docs/blockchain/robinhood/robinhood-events-api.md @@ -59,7 +59,7 @@ If you are migrating node code: your `eth_getLogs` `address` filter maps to `Log ## Datasets and history - **`realtime`** (the default) — a rolling window of recent blocks whose depth varies; don't assume it, measure it with the probe below. -- **`archive`** — event history back to when Bitquery indexing began for Robinhood; its head lags the chain by minutes. +- **`archive`** — deep event history, retained up to roughly the **last 3 months** (Robinhood is a newer chain, so today the archive holds its complete history; older data ages out as the cap applies); its head lags the chain by minutes. - **`combined`** — archive + realtime union; the safe choice for fixed windows (24h, 7d). Need bulk history beyond what you want to page through the API? Bitquery can also provide **historical data exports** — [contact support](https://bitquery.io/forms/api). @@ -219,6 +219,10 @@ subscription { Connect to `wss://streaming.bitquery.io/graphql?token=YOUR_TOKEN` with the `graphql-transport-ws` subprotocol (`connection_init` → `connection_ack` → `subscribe`). See [WebSocket authentication](/docs/authorization/websocket/). Any subscription on this page also runs as a query — add `limit` and `orderBy` and drop the `subscription` keyword. ::: +:::tip Prefer Kafka for the firehose +Consuming the full event feed continuously? Bitquery also delivers Robinhood data as **Kafka streams** — decoded transactions, calls, and events on the protobuf topic `robinhood.transactions.proto` — with consumer-group scaling and replay. See [Kafka Streaming Concepts](/docs/streams/kafka-streaming-concepts/). +::: + --- ## Stream events from one contract @@ -698,7 +702,7 @@ Use `Log.Signature.SignatureHash` with the keccak hash of the event signature, * ### How far back does Robinhood events data go? -`archive` reaches back to when Bitquery indexing began for the network, and `realtime` holds a rolling recent window — measure either with the [window probe](#check-the-events-window). For bulk history, Bitquery can additionally provide data exports on request. +`archive` retains up to roughly the last 3 months of events (on a newer chain like Robinhood that is currently its complete history), and `realtime` holds a rolling recent window — measure either with the [window probe](#check-the-events-window). For older or bulk history, Bitquery can provide data exports on request. ### How do I get every event a specific transaction emitted? diff --git a/docs/blockchain/robinhood/robinhood-liquidity.md b/docs/blockchain/robinhood/robinhood-liquidity.md index bf3c7ac5..eeb31417 100644 --- a/docs/blockchain/robinhood/robinhood-liquidity.md +++ b/docs/blockchain/robinhood/robinhood-liquidity.md @@ -872,6 +872,10 @@ subscription { Connect to `wss://streaming.bitquery.io/graphql?token=YOUR_TOKEN` with the `graphql-transport-ws` subprotocol (`connection_init` → `connection_ack` → `subscribe`). See [WebSocket authentication](/docs/authorization/websocket/). ::: +:::tip Prefer Kafka for the firehose +Consuming pool updates at firehose scale? Bitquery also delivers Robinhood DEX data as **Kafka streams** (protobuf topic `robinhood.dextrades.proto`) with consumer-group scaling and replay. See [Kafka Streaming Concepts](/docs/streams/kafka-streaming-concepts/). +::: + --- ## Slippage and price impact diff --git a/docs/blockchain/robinhood/robinhood-trades.md b/docs/blockchain/robinhood/robinhood-trades.md index 553381cc..616281a2 100644 --- a/docs/blockchain/robinhood/robinhood-trades.md +++ b/docs/blockchain/robinhood/robinhood-trades.md @@ -122,6 +122,10 @@ subscription { Run subscriptions against `wss://streaming.bitquery.io/graphql?token=YOUR_TOKEN` with the `graphql-transport-ws` subprotocol (`connection_init` → `connection_ack` → `subscribe`). See [WebSocket authentication](/docs/authorization/websocket/). ::: +:::tip Prefer Kafka for the firehose +Consuming the full Robinhood trade feed continuously? Bitquery also delivers DEX data as **Kafka streams** (protobuf topic `robinhood.dextrades.proto`) with consumer-group scaling and replay. See [Kafka Streaming Concepts](/docs/streams/kafka-streaming-concepts/). +::: + --- ## Historical Trades on Robinhood diff --git a/docs/blockchain/robinhood/robinhood-transfers.md b/docs/blockchain/robinhood/robinhood-transfers.md index 2c44181b..d31a82c1 100644 --- a/docs/blockchain/robinhood/robinhood-transfers.md +++ b/docs/blockchain/robinhood/robinhood-transfers.md @@ -149,6 +149,10 @@ subscription { Connect to `wss://streaming.bitquery.io/graphql?token=YOUR_TOKEN` with the `graphql-transport-ws` subprotocol (`connection_init` → `connection_ack` → `subscribe`). Events arrive in per-block batches. See [WebSocket authentication](/docs/authorization/websocket/). ::: +:::tip Prefer Kafka for the firehose +Consuming all Robinhood transfers continuously? Bitquery also delivers this data as **Kafka streams** (protobuf topic `robinhood.tokens.proto`) with consumer-group scaling and replay. See [Kafka Streaming Concepts](/docs/streams/kafka-streaming-concepts/). +::: + ### Stream whale transfers (USD threshold) Alert when a successful transfer exceeds a USD size. Exclude the zero address to skip wrap/unwrap and mint/burn noise. Because USD is populated for native ETH, this is effectively a **large ETH move alert**. diff --git a/sidebars.js b/sidebars.js index a5078fb8..94da55d9 100644 --- a/sidebars.js +++ b/sidebars.js @@ -856,6 +856,7 @@ const sidebars = { "blockchain/robinhood/robinhood-transfers", "blockchain/robinhood/robinhood-liquidity", "blockchain/robinhood/robinhood-events-api", + "blockchain/robinhood/robinhood-calls-api", "blockchain/robinhood/robinhood-meme-coin-launches", "blockchain/robinhood/flap-sh-api", "blockchain/robinhood/bags-fm-api", From 13825e4bb0f3ed56e3636db6143e1dbc91bec5be Mon Sep 17 00:00:00 2001 From: Gaurav agarwal Date: Fri, 24 Jul 2026 12:55:10 +0530 Subject: [PATCH 3/5] Add Robinhood Balances API page Balances cube guide: wallet portfolios, as-of-date time travel, native and single-token balances, multi-address batches, top holders, rich lists, USD whale floors, holder counts, wallet profiling (first/last change, update count), per-currency network totals, and the BalanceUpdates live delta stream (WS-verified) with Kafka pointer. Documents grouping-follows-selection, selectWhere (HAVING) semantics, signed deltas, and native-only USD enrichment. All queries live-tested; registered in sidebar. Co-Authored-By: Claude Fable 5 --- .../robinhood/robinhood-balances-api.md | 460 ++++++++++++++++++ sidebars.js | 1 + 2 files changed, 461 insertions(+) create mode 100644 docs/blockchain/robinhood/robinhood-balances-api.md diff --git a/docs/blockchain/robinhood/robinhood-balances-api.md b/docs/blockchain/robinhood/robinhood-balances-api.md new file mode 100644 index 00000000..6fbcaa0b --- /dev/null +++ b/docs/blockchain/robinhood/robinhood-balances-api.md @@ -0,0 +1,460 @@ +--- +title: "Robinhood Balances API — Portfolios, Holders & History" +description: "Query Robinhood wallet balances with Bitquery GraphQL: full portfolios, token holders, holder counts, balance history by date, and live balance-update streams." +sidebar_position: 6 +keywords: + - Robinhood balances API + - Robinhood wallet balance + - Robinhood token holders API + - Robinhood holder count + - Robinhood portfolio API + - Robinhood balance history + - Robinhood richest wallets + - Robinhood balance updates stream + - eth_getBalance alternative + - Bitquery Robinhood Balances +--- +# Robinhood Balances API — Portfolios, Holders & History + +Query **wallet and token balances on Robinhood** with Bitquery GraphQL. The `EVM.Balances` cube returns **computed balances with built-in aggregates** — amount, USD value, first/last change time, and update count — grouped by whatever dimensions you select: one wallet's full portfolio, one token's holder list, or network-wide per-currency totals, all in single calls that would take thousands of `eth_getBalance` / `balanceOf` RPCs. For live changes, the companion **`BalanceUpdates`** cube streams every balance delta over WebSocket. + +Every query on this page was executed against the production endpoint before publishing, and the balance-update subscriptions were verified live over WebSocket. + +:::note API Key Required +To query or stream data outside the Bitquery IDE, you need an API access token. + +Follow the steps here: [How to generate Bitquery API token ➤](/docs/authorization/how-to-generate/) +::: + +:::tip Related docs +- [Robinhood Token Supply API](/docs/blockchain/robinhood/robinhood-token-supply/) +- [Robinhood Transfers](/docs/blockchain/robinhood/robinhood-transfers/) +- [Robinhood Trades](/docs/blockchain/robinhood/robinhood-trades/) (for prices to value non-ETH holdings) +- [Robinhood Events API](/docs/blockchain/robinhood/robinhood-events-api/) +- [WebSocket authentication](/docs/authorization/websocket/) +::: + +**On this page:** [Concepts](#datasets-grouping-and-selectwhere) · [Portfolio](#all-token-balances-of-an-address-portfolio) · [As-of-date](#balance-as-of-a-date-time-travel) · [Single token](#native-eth-and-single-token-balances) · [Multi-address](#balances-for-multiple-addresses) · [Top holders](#top-holders-of-a-token) · [Rich list](#richest-native-eth-wallets) · [Whales](#whale-holders-by-usd) · [Holder count](#holder-count-of-a-token) · [Wallet profile](#wallet-profile-first-seen-last-active-update-count) · [Currency totals](#network-wide-per-currency-totals) · [Stream](#stream-balance-changes-balanceupdates) · [FAQ](#faq) + +--- + +## Why query balances here instead of an RPC loop + +| | Node RPC (`eth_getBalance` / `balanceOf` calls) | Bitquery Balances | +| --- | --- | --- | +| Whole portfolio | One call **per token** you already know about | One call returns every token the wallet holds | +| Token holders | Impossible without indexing all transfers yourself | One query, sortable, with holder counts | +| History | Archive node + block-pinned calls | `Block.Date.till` gives the balance as of any date | +| Extras | — | USD value, first/last change time, update count, live delta stream | + +--- + +## Datasets, grouping, and selectWhere + +- Use **`dataset: combined`** — balances are computed from history, and combined guarantees the full picture. +- **Grouping follows your selection.** Filter/select `Balance.Address` to get per-wallet rows; select only `Currency` to get network-wide per-currency totals; select both for wallet × token rows. +- **`selectWhere` filters aggregated results** (like SQL `HAVING`): `Amount(selectWhere: { gt: "0" })` drops zero/dust rows after the balance is computed. Amount thresholds are strings. +- **`AmountInUSD` is populated for native ETH; token rows generally return `0`.** USDG is a dollar stablecoin, so its `Amount` is effectively USD; value other tokens by joining prices from the [Trades API](/docs/blockchain/robinhood/robinhood-trades/). + +--- + +## All token balances of an address (portfolio) + +Everything a wallet holds in one call. The `selectWhere` keeps only non-zero rows. + +```graphql +{ + EVM(network: robinhood, dataset: combined) { + Balances( + where: { Balance: { Address: { is: "0x9c0489b89ae473de6edcb159f21c3019ba730282" } } } + ) { + Currency { + Symbol + SmartContract + } + Balance { + Amount(selectWhere: { gt: "0" }) + AmountInUSD + } + } + } +} +``` + +--- + +## Balance as of a date (time travel) + +Add `Block.Date.till` to compute the same portfolio **as of any date** — audits, tax snapshots, "what did this whale hold before the launch". A date before the wallet's first activity returns no rows. + +```graphql +{ + EVM(network: robinhood, dataset: combined) { + Balances( + where: { + Block: { Date: { till: "2026-07-20" } } + Balance: { Address: { is: "0x9c0489b89ae473de6edcb159f21c3019ba730282" } } + } + ) { + Currency { + Symbol + SmartContract + } + Balance { + Amount(selectWhere: { gt: "0" }) + AmountInUSD + } + } + } +} +``` + +--- + +## Native ETH and single-token balances + +Filter `Currency.Native: true` for the ETH balance, or pin one contract for a single token — with the change-history aggregates included. + +```graphql +{ + EVM(network: robinhood, dataset: combined) { + Balances( + where: { + Balance: { Address: { is: "0x9c0489b89ae473de6edcb159f21c3019ba730282" } } + Currency: { Native: true } + } + ) { + Currency { + Symbol + Native + } + Balance { + Amount + AmountInUSD + } + } + } +} +``` + +```graphql +{ + EVM(network: robinhood, dataset: combined) { + Balances( + where: { + Balance: { Address: { is: "0x9c0489b89ae473de6edcb159f21c3019ba730282" } } + Currency: { SmartContract: { is: "0x0bd7d308f8e1639fab988df18a8011f41eacad73" } } + } + ) { + Currency { + Symbol + SmartContract + } + Balance { + Amount + AmountInUSD + FirstChangeTime + LastChangeTime + UpdateCount + } + } + } +} +``` + +--- + +## Balances for multiple addresses + +Batch a watchlist with `Address.in` — one row per address (per selected currency). + +```graphql +{ + EVM(network: robinhood, dataset: combined) { + Balances( + where: { + Balance: { + Address: { + in: [ + "0x9c0489b89ae473de6edcb159f21c3019ba730282" + "0xcaf681a66d020601342297493863e78c959e5cb2" + ] + } + } + Currency: { Native: true } + } + ) { + Balance { + Address + Amount + AmountInUSD + } + } + } +} +``` + +--- + +## Top holders of a token + +Select `Balance.Address` (grouping per wallet), filter the token, and order by amount — a holder leaderboard in one query. Example: USDG. + +```graphql +{ + EVM(network: robinhood, dataset: combined) { + Balances( + limit: { count: 10 } + orderBy: { descending: Balance_Amount } + where: { Currency: { SmartContract: { is: "0x5fc5360d0400a0fd4f2af552add042d716f1d168" } } } + ) { + Balance { + Address + Amount(selectWhere: { gt: "0" }) + AmountInUSD + } + } + } +} +``` + +--- + +## Richest native ETH wallets + +The same pattern on the native currency. Note that **contracts appear as holders** — the WETH contract naturally tops native rankings since it custodies wrapped ETH; filter or label known contracts for a pure-wallet list. + +```graphql +{ + EVM(network: robinhood, dataset: combined) { + Balances( + limit: { count: 10 } + orderBy: { descendingByField: "Balance_Amount" } + where: { Currency: { Native: true } } + ) { + Balance { + Address + Amount(selectWhere: { gt: "0" }) + AmountInUSD + } + } + } +} +``` + +--- + +## Whale holders (by USD) + +`selectWhere` on `AmountInUSD` keeps only balances above a USD floor — reliable for native ETH (see the [USD note](#datasets-grouping-and-selectwhere)); for tokens, threshold the raw `Amount` instead. + +```graphql +{ + EVM(network: robinhood, dataset: combined) { + Balances( + limit: { count: 10 } + orderBy: { descendingByField: "Balance_Amount" } + where: { Currency: { Native: true } } + ) { + Balance { + Address + Amount + AmountInUSD(selectWhere: { gt: "10000" }) + } + } + } +} +``` + +--- + +## Holder count of a token + +One number: distinct addresses that have ever held the token. Combine with the top-holders query for distribution dashboards. + +```graphql +{ + EVM(network: robinhood, dataset: combined) { + Balances( + where: { Currency: { SmartContract: { is: "0x5fc5360d0400a0fd4f2af552add042d716f1d168" } } } + ) { + holders: count(distinct: Balance_Address) + } + } +} +``` + +--- + +## Wallet profile: first seen, last active, update count + +The built-in aggregates turn balances into a wallet profiler: `FirstChangeTime` (when the wallet first touched each asset), `LastChangeTime` (most recent activity), and `UpdateCount` (how many balance changes) — age, dormancy, and activity signals with no extra indexing. + +```graphql +{ + EVM(network: robinhood, dataset: combined) { + Balances( + where: { Balance: { Address: { is: "0x9c0489b89ae473de6edcb159f21c3019ba730282" } } } + ) { + Currency { + Symbol + SmartContract + } + Balance { + Amount(selectWhere: { gt: "0" }) + FirstChangeTime + LastChangeTime + UpdateCount + } + } + } +} +``` + +--- + +## Network-wide per-currency totals + +With no address dimension, rows group per currency: `Amount` becomes the **total held across all addresses**, with network-level change stats — the full field set of the cube on display. + +```graphql +{ + EVM(network: robinhood, dataset: combined) { + Balances(limit: { count: 10 }) { + Currency { + Decimals + Symbol + SmartContract + DelegatedTo + Fungible + HasURI + Name + Native + ProtocolName + } + Balance { + Amount(selectWhere: { gt: "0" }) + AmountInUSD + FirstChangeTime + LastChangeTime + UpdateCount + } + } + } +} +``` + +--- + +## Stream balance changes (BalanceUpdates) + +`Balances` is a query cube — for live data, subscribe to **`BalanceUpdates`**: every balance delta as it happens, with a **signed `Amount`** (negative for outflows), USD value, and the causing transaction. Filter by address for a wallet tracker or by currency for a token-flow feed. + +```graphql +subscription { + EVM(network: robinhood) { + BalanceUpdates { + Block { + Time + } + BalanceUpdate { + Address + Amount + AmountInUSD + } + Currency { + Symbol + SmartContract + } + Transaction { + Hash + } + } + } +} +``` + +```graphql +subscription { + EVM(network: robinhood) { + BalanceUpdates( + where: { Currency: { Native: true } } + ) { + Block { + Time + } + BalanceUpdate { + Address + Amount + AmountInUSD + } + Currency { + Symbol + } + } + } +} +``` + +:::tip WebSocket connection +Connect to `wss://streaming.bitquery.io/graphql?token=YOUR_TOKEN` with the `graphql-transport-ws` subprotocol (`connection_init` → `connection_ack` → `subscribe`). Updates arrive in per-block batches. See [WebSocket authentication](/docs/authorization/websocket/). +::: + +:::tip Prefer Kafka for the firehose +Consuming all balance changes continuously? Bitquery also delivers Robinhood token data as **Kafka streams** (protobuf topic `robinhood.tokens.proto`) with consumer-group scaling and replay. See [Kafka Streaming Concepts](/docs/streams/kafka-streaming-concepts/). +::: + +--- + +## Use-case patterns + +| Goal | Approach | +| --- | --- | +| Wallet / portfolio page | [Portfolio query](#all-token-balances-of-an-address-portfolio); poll, or apply [BalanceUpdates](#stream-balance-changes-balanceupdates) deltas for live UX | +| Tax / audit snapshots | [Balance as of a date](#balance-as-of-a-date-time-travel) with `Block.Date.till` | +| Token distribution dashboards | [Top holders](#top-holders-of-a-token) + [holder count](#holder-count-of-a-token) | +| Rich lists & whale tracking | [Native rankings](#richest-native-eth-wallets), [USD floors](#whale-holders-by-usd) | +| Wallet profiling (age, dormancy) | [First/last change + update count](#wallet-profile-first-seen-last-active-update-count) | +| Exchange / custody monitoring | [Multi-address batch](#balances-for-multiple-addresses) + address-filtered `BalanceUpdates` stream | +| Supply-side view | [Per-currency totals](#network-wide-per-currency-totals), or the [Token Supply API](/docs/blockchain/robinhood/robinhood-token-supply/) | + +--- + +## Tips + +1. Always use **`dataset: combined`** for balance queries — balances are computed from full history. +2. Remember grouping follows selection: add or drop `Balance.Address` / `Currency` fields to pivot between wallet, token, and network views. +3. Use `selectWhere` (post-aggregation) for balance thresholds; regular `where` filters raw rows before aggregation. +4. `AmountInUSD` is native-ETH-only in practice — USDG's `Amount` ≈ dollars; price other tokens via the [Trades API](/docs/blockchain/robinhood/robinhood-trades/). +5. Keep a `limit` on holder-style queries — popular tokens have very large holder sets. +6. Contracts show up in holder lists (WETH tops native rankings by design) — filter known contract addresses for people-only lists. +7. `BalanceUpdates.Amount` is a **signed delta**, not an absolute balance — sum deltas or re-query `Balances` for the current figure. +8. An as-of-date query before a wallet's first activity returns no rows — that's the correct answer, not an error. + +--- + +## FAQ + +### How do I get all token balances of a Robinhood address? + +Query `EVM.Balances` on `dataset: combined` filtered by `Balance.Address`, selecting `Currency` and `Balance.Amount` — one call returns the full portfolio. Add `Amount(selectWhere: {gt: "0"})` to hide dust and emptied positions. + +### How do I get the balance at a past date? + +Add `Block: { Date: { till: "YYYY-MM-DD" } }` to any balance query — the cube recomputes balances as of that date. See [time travel](#balance-as-of-a-date-time-travel). + +### How do I list the top holders of a token? + +Filter the token's `Currency.SmartContract`, select `Balance.Address`, and order by `Balance_Amount` descending — see [Top holders](#top-holders-of-a-token). `count(distinct: Balance_Address)` gives the holder count. + +### Why is AmountInUSD 0 for my token balances? + +USD enrichment covers native ETH; token rows generally return `0`. USDG is a dollar stablecoin (read `Amount` as USD), and other tokens can be valued by joining prices from the [Trades API](/docs/blockchain/robinhood/robinhood-trades/). + +### Can I stream balances in real time? + +`Balances` itself is a query cube, but **`BalanceUpdates`** streams every signed balance delta live over WebSocket — filter by address or currency. See [Stream balance changes](#stream-balance-changes-balanceupdates). + +### Is this a replacement for eth_getBalance? + +For anything beyond a single known token it's strictly stronger: whole portfolios, holder lists, holder counts, historical as-of-date balances, and change aggregates come from single queries instead of RPC loops over an archive node. diff --git a/sidebars.js b/sidebars.js index 94da55d9..f6e0fdea 100644 --- a/sidebars.js +++ b/sidebars.js @@ -857,6 +857,7 @@ const sidebars = { "blockchain/robinhood/robinhood-liquidity", "blockchain/robinhood/robinhood-events-api", "blockchain/robinhood/robinhood-calls-api", + "blockchain/robinhood/robinhood-balances-api", "blockchain/robinhood/robinhood-meme-coin-launches", "blockchain/robinhood/flap-sh-api", "blockchain/robinhood/bags-fm-api", From b2d43968f9d8b62dd75b8d4778d95c4e9c0ed9bf Mon Sep 17 00:00:00 2001 From: Gaurav agarwal Date: Fri, 24 Jul 2026 13:05:25 +0530 Subject: [PATCH 4/5] Remove BalanceUpdates from Balances page Drops the BalanceUpdates stream section and all references; live balance-change needs now point to polling and Kafka streams (robinhood.tokens.proto). Co-Authored-By: Claude Fable 5 --- .../robinhood/robinhood-balances-api.md | 79 +++---------------- 1 file changed, 11 insertions(+), 68 deletions(-) diff --git a/docs/blockchain/robinhood/robinhood-balances-api.md b/docs/blockchain/robinhood/robinhood-balances-api.md index 6fbcaa0b..ac680b93 100644 --- a/docs/blockchain/robinhood/robinhood-balances-api.md +++ b/docs/blockchain/robinhood/robinhood-balances-api.md @@ -1,6 +1,6 @@ --- title: "Robinhood Balances API — Portfolios, Holders & History" -description: "Query Robinhood wallet balances with Bitquery GraphQL: full portfolios, token holders, holder counts, balance history by date, and live balance-update streams." +description: "Query Robinhood wallet balances with Bitquery GraphQL: full portfolios, token holders, holder counts, richest wallets, and balance history by any date." sidebar_position: 6 keywords: - Robinhood balances API @@ -10,15 +10,14 @@ keywords: - Robinhood portfolio API - Robinhood balance history - Robinhood richest wallets - - Robinhood balance updates stream - eth_getBalance alternative - Bitquery Robinhood Balances --- # Robinhood Balances API — Portfolios, Holders & History -Query **wallet and token balances on Robinhood** with Bitquery GraphQL. The `EVM.Balances` cube returns **computed balances with built-in aggregates** — amount, USD value, first/last change time, and update count — grouped by whatever dimensions you select: one wallet's full portfolio, one token's holder list, or network-wide per-currency totals, all in single calls that would take thousands of `eth_getBalance` / `balanceOf` RPCs. For live changes, the companion **`BalanceUpdates`** cube streams every balance delta over WebSocket. +Query **wallet and token balances on Robinhood** with Bitquery GraphQL. The `EVM.Balances` cube returns **computed balances with built-in aggregates** — amount, USD value, first/last change time, and update count — grouped by whatever dimensions you select: one wallet's full portfolio, one token's holder list, or network-wide per-currency totals, all in single calls that would take thousands of `eth_getBalance` / `balanceOf` RPCs. -Every query on this page was executed against the production endpoint before publishing, and the balance-update subscriptions were verified live over WebSocket. +Every query on this page was executed against the production endpoint before publishing. :::note API Key Required To query or stream data outside the Bitquery IDE, you need an API access token. @@ -31,10 +30,9 @@ Follow the steps here: [How to generate Bitquery API token ➤](/docs/authorizat - [Robinhood Transfers](/docs/blockchain/robinhood/robinhood-transfers/) - [Robinhood Trades](/docs/blockchain/robinhood/robinhood-trades/) (for prices to value non-ETH holdings) - [Robinhood Events API](/docs/blockchain/robinhood/robinhood-events-api/) -- [WebSocket authentication](/docs/authorization/websocket/) ::: -**On this page:** [Concepts](#datasets-grouping-and-selectwhere) · [Portfolio](#all-token-balances-of-an-address-portfolio) · [As-of-date](#balance-as-of-a-date-time-travel) · [Single token](#native-eth-and-single-token-balances) · [Multi-address](#balances-for-multiple-addresses) · [Top holders](#top-holders-of-a-token) · [Rich list](#richest-native-eth-wallets) · [Whales](#whale-holders-by-usd) · [Holder count](#holder-count-of-a-token) · [Wallet profile](#wallet-profile-first-seen-last-active-update-count) · [Currency totals](#network-wide-per-currency-totals) · [Stream](#stream-balance-changes-balanceupdates) · [FAQ](#faq) +**On this page:** [Concepts](#datasets-grouping-and-selectwhere) · [Portfolio](#all-token-balances-of-an-address-portfolio) · [As-of-date](#balance-as-of-a-date-time-travel) · [Single token](#native-eth-and-single-token-balances) · [Multi-address](#balances-for-multiple-addresses) · [Top holders](#top-holders-of-a-token) · [Rich list](#richest-native-eth-wallets) · [Whales](#whale-holders-by-usd) · [Holder count](#holder-count-of-a-token) · [Wallet profile](#wallet-profile-first-seen-last-active-update-count) · [Currency totals](#network-wide-per-currency-totals) · [FAQ](#faq) --- @@ -45,7 +43,7 @@ Follow the steps here: [How to generate Bitquery API token ➤](/docs/authorizat | Whole portfolio | One call **per token** you already know about | One call returns every token the wallet holds | | Token holders | Impossible without indexing all transfers yourself | One query, sortable, with holder counts | | History | Archive node + block-pinned calls | `Block.Date.till` gives the balance as of any date | -| Extras | — | USD value, first/last change time, update count, live delta stream | +| Extras | — | USD value, first/last change time, update count | --- @@ -346,62 +344,8 @@ With no address dimension, rows group per currency: `Amount` becomes the **total --- -## Stream balance changes (BalanceUpdates) - -`Balances` is a query cube — for live data, subscribe to **`BalanceUpdates`**: every balance delta as it happens, with a **signed `Amount`** (negative for outflows), USD value, and the causing transaction. Filter by address for a wallet tracker or by currency for a token-flow feed. - -```graphql -subscription { - EVM(network: robinhood) { - BalanceUpdates { - Block { - Time - } - BalanceUpdate { - Address - Amount - AmountInUSD - } - Currency { - Symbol - SmartContract - } - Transaction { - Hash - } - } - } -} -``` - -```graphql -subscription { - EVM(network: robinhood) { - BalanceUpdates( - where: { Currency: { Native: true } } - ) { - Block { - Time - } - BalanceUpdate { - Address - Amount - AmountInUSD - } - Currency { - Symbol - } - } - } -} -``` - -:::tip WebSocket connection -Connect to `wss://streaming.bitquery.io/graphql?token=YOUR_TOKEN` with the `graphql-transport-ws` subprotocol (`connection_init` → `connection_ack` → `subscribe`). Updates arrive in per-block batches. See [WebSocket authentication](/docs/authorization/websocket/). -::: - -:::tip Prefer Kafka for the firehose -Consuming all balance changes continuously? Bitquery also delivers Robinhood token data as **Kafka streams** (protobuf topic `robinhood.tokens.proto`) with consumer-group scaling and replay. See [Kafka Streaming Concepts](/docs/streams/kafka-streaming-concepts/). +:::tip Continuous balance data via Kafka +Need balance changes as a continuous feed? Bitquery delivers Robinhood token data as **Kafka streams** (protobuf topic `robinhood.tokens.proto`) with consumer-group scaling and replay. See [Kafka Streaming Concepts](/docs/streams/kafka-streaming-concepts/). ::: --- @@ -410,12 +354,12 @@ Consuming all balance changes continuously? Bitquery also delivers Robinhood tok | Goal | Approach | | --- | --- | -| Wallet / portfolio page | [Portfolio query](#all-token-balances-of-an-address-portfolio); poll, or apply [BalanceUpdates](#stream-balance-changes-balanceupdates) deltas for live UX | +| Wallet / portfolio page | [Portfolio query](#all-token-balances-of-an-address-portfolio); poll on an interval for live UX | | Tax / audit snapshots | [Balance as of a date](#balance-as-of-a-date-time-travel) with `Block.Date.till` | | Token distribution dashboards | [Top holders](#top-holders-of-a-token) + [holder count](#holder-count-of-a-token) | | Rich lists & whale tracking | [Native rankings](#richest-native-eth-wallets), [USD floors](#whale-holders-by-usd) | | Wallet profiling (age, dormancy) | [First/last change + update count](#wallet-profile-first-seen-last-active-update-count) | -| Exchange / custody monitoring | [Multi-address batch](#balances-for-multiple-addresses) + address-filtered `BalanceUpdates` stream | +| Exchange / custody monitoring | [Multi-address batch](#balances-for-multiple-addresses) on a polling schedule | | Supply-side view | [Per-currency totals](#network-wide-per-currency-totals), or the [Token Supply API](/docs/blockchain/robinhood/robinhood-token-supply/) | --- @@ -428,8 +372,7 @@ Consuming all balance changes continuously? Bitquery also delivers Robinhood tok 4. `AmountInUSD` is native-ETH-only in practice — USDG's `Amount` ≈ dollars; price other tokens via the [Trades API](/docs/blockchain/robinhood/robinhood-trades/). 5. Keep a `limit` on holder-style queries — popular tokens have very large holder sets. 6. Contracts show up in holder lists (WETH tops native rankings by design) — filter known contract addresses for people-only lists. -7. `BalanceUpdates.Amount` is a **signed delta**, not an absolute balance — sum deltas or re-query `Balances` for the current figure. -8. An as-of-date query before a wallet's first activity returns no rows — that's the correct answer, not an error. +7. An as-of-date query before a wallet's first activity returns no rows — that's the correct answer, not an error. --- @@ -453,7 +396,7 @@ USD enrichment covers native ETH; token rows generally return `0`. USDG is a dol ### Can I stream balances in real time? -`Balances` itself is a query cube, but **`BalanceUpdates`** streams every signed balance delta live over WebSocket — filter by address or currency. See [Stream balance changes](#stream-balance-changes-balanceupdates). +`Balances` is a query cube — poll it on your interval for live UX. For continuous balance-change feeds at firehose scale, Bitquery delivers Robinhood token data over [Kafka streams](/docs/streams/kafka-streaming-concepts/). ### Is this a replacement for eth_getBalance? From 60d21e46f0083bc20256f195ac7734cea8c307eb Mon Sep 17 00:00:00 2001 From: Gaurav agarwal Date: Fri, 24 Jul 2026 13:14:26 +0530 Subject: [PATCH 5/5] Add Token Holders API page; move holder queries off the Balances page New Holders-cube page: top-holder rankings (user's flagship query), current vs ever holder counts, balance floors, distribution stats (avg/median/p99), dormancy screens via LastChangeTime, tokenized stock holders, native rich list, and offset pagination for snapshots. Documents no-USD-field and LastChangeTime semantics. Balances page now focuses on wallet portfolios and links holder use cases to the new page. All queries live-tested; registered in sidebar. Co-Authored-By: Claude Fable 5 --- .../robinhood/robinhood-balances-api.md | 114 +------ .../robinhood/robinhood-token-holders-api.md | 319 ++++++++++++++++++ sidebars.js | 1 + 3 files changed, 333 insertions(+), 101 deletions(-) create mode 100644 docs/blockchain/robinhood/robinhood-token-holders-api.md diff --git a/docs/blockchain/robinhood/robinhood-balances-api.md b/docs/blockchain/robinhood/robinhood-balances-api.md index ac680b93..d313e403 100644 --- a/docs/blockchain/robinhood/robinhood-balances-api.md +++ b/docs/blockchain/robinhood/robinhood-balances-api.md @@ -1,21 +1,18 @@ --- -title: "Robinhood Balances API — Portfolios, Holders & History" -description: "Query Robinhood wallet balances with Bitquery GraphQL: full portfolios, token holders, holder counts, richest wallets, and balance history by any date." +title: "Robinhood Balances API — Wallet Portfolios & History" +description: "Query Robinhood wallet balances with Bitquery GraphQL: full portfolios, multi-address batches, wallet profiling, and balance history as of any date." sidebar_position: 6 keywords: - Robinhood balances API - Robinhood wallet balance - - Robinhood token holders API - - Robinhood holder count - Robinhood portfolio API - Robinhood balance history - - Robinhood richest wallets - eth_getBalance alternative - Bitquery Robinhood Balances --- -# Robinhood Balances API — Portfolios, Holders & History +# Robinhood Balances API — Wallet Portfolios & History -Query **wallet and token balances on Robinhood** with Bitquery GraphQL. The `EVM.Balances` cube returns **computed balances with built-in aggregates** — amount, USD value, first/last change time, and update count — grouped by whatever dimensions you select: one wallet's full portfolio, one token's holder list, or network-wide per-currency totals, all in single calls that would take thousands of `eth_getBalance` / `balanceOf` RPCs. +Query **wallet balances on Robinhood** with Bitquery GraphQL. The `EVM.Balances` cube returns **computed balances with built-in aggregates** — amount, USD value, first/last change time, and update count — grouped by whatever dimensions you select: one wallet's full portfolio, a batch of wallets, or network-wide per-currency totals, all in single calls that would take thousands of `eth_getBalance` / `balanceOf` RPCs. For token-centric holder rankings and counts, use the dedicated [Token Holders API](/docs/blockchain/robinhood/robinhood-token-holders-api/). Every query on this page was executed against the production endpoint before publishing. @@ -26,13 +23,14 @@ Follow the steps here: [How to generate Bitquery API token ➤](/docs/authorizat ::: :::tip Related docs +- [Robinhood Token Holders API](/docs/blockchain/robinhood/robinhood-token-holders-api/) - [Robinhood Token Supply API](/docs/blockchain/robinhood/robinhood-token-supply/) - [Robinhood Transfers](/docs/blockchain/robinhood/robinhood-transfers/) - [Robinhood Trades](/docs/blockchain/robinhood/robinhood-trades/) (for prices to value non-ETH holdings) - [Robinhood Events API](/docs/blockchain/robinhood/robinhood-events-api/) ::: -**On this page:** [Concepts](#datasets-grouping-and-selectwhere) · [Portfolio](#all-token-balances-of-an-address-portfolio) · [As-of-date](#balance-as-of-a-date-time-travel) · [Single token](#native-eth-and-single-token-balances) · [Multi-address](#balances-for-multiple-addresses) · [Top holders](#top-holders-of-a-token) · [Rich list](#richest-native-eth-wallets) · [Whales](#whale-holders-by-usd) · [Holder count](#holder-count-of-a-token) · [Wallet profile](#wallet-profile-first-seen-last-active-update-count) · [Currency totals](#network-wide-per-currency-totals) · [FAQ](#faq) +**On this page:** [Concepts](#datasets-grouping-and-selectwhere) · [Portfolio](#all-token-balances-of-an-address-portfolio) · [As-of-date](#balance-as-of-a-date-time-travel) · [Single token](#native-eth-and-single-token-balances) · [Multi-address](#balances-for-multiple-addresses) · [Wallet profile](#wallet-profile-first-seen-last-active-update-count) · [Currency totals](#network-wide-per-currency-totals) · [FAQ](#faq) --- @@ -41,7 +39,7 @@ Follow the steps here: [How to generate Bitquery API token ➤](/docs/authorizat | | Node RPC (`eth_getBalance` / `balanceOf` calls) | Bitquery Balances | | --- | --- | --- | | Whole portfolio | One call **per token** you already know about | One call returns every token the wallet holds | -| Token holders | Impossible without indexing all transfers yourself | One query, sortable, with holder counts | +| Token holders | Impossible without indexing all transfers yourself | One sortable query on the [Holders API](/docs/blockchain/robinhood/robinhood-token-holders-api/) | | History | Archive node + block-pinned calls | `Block.Date.till` gives the balance as of any date | | Extras | — | USD value, first/last change time, update count | @@ -194,93 +192,9 @@ Batch a watchlist with `Address.in` — one row per address (per selected curren --- -## Top holders of a token +## Token holders -Select `Balance.Address` (grouping per wallet), filter the token, and order by amount — a holder leaderboard in one query. Example: USDG. - -```graphql -{ - EVM(network: robinhood, dataset: combined) { - Balances( - limit: { count: 10 } - orderBy: { descending: Balance_Amount } - where: { Currency: { SmartContract: { is: "0x5fc5360d0400a0fd4f2af552add042d716f1d168" } } } - ) { - Balance { - Address - Amount(selectWhere: { gt: "0" }) - AmountInUSD - } - } - } -} -``` - ---- - -## Richest native ETH wallets - -The same pattern on the native currency. Note that **contracts appear as holders** — the WETH contract naturally tops native rankings since it custodies wrapped ETH; filter or label known contracts for a pure-wallet list. - -```graphql -{ - EVM(network: robinhood, dataset: combined) { - Balances( - limit: { count: 10 } - orderBy: { descendingByField: "Balance_Amount" } - where: { Currency: { Native: true } } - ) { - Balance { - Address - Amount(selectWhere: { gt: "0" }) - AmountInUSD - } - } - } -} -``` - ---- - -## Whale holders (by USD) - -`selectWhere` on `AmountInUSD` keeps only balances above a USD floor — reliable for native ETH (see the [USD note](#datasets-grouping-and-selectwhere)); for tokens, threshold the raw `Amount` instead. - -```graphql -{ - EVM(network: robinhood, dataset: combined) { - Balances( - limit: { count: 10 } - orderBy: { descendingByField: "Balance_Amount" } - where: { Currency: { Native: true } } - ) { - Balance { - Address - Amount - AmountInUSD(selectWhere: { gt: "10000" }) - } - } - } -} -``` - ---- - -## Holder count of a token - -One number: distinct addresses that have ever held the token. Combine with the top-holders query for distribution dashboards. - -```graphql -{ - EVM(network: robinhood, dataset: combined) { - Balances( - where: { Currency: { SmartContract: { is: "0x5fc5360d0400a0fd4f2af552add042d716f1d168" } } } - ) { - holders: count(distinct: Balance_Address) - } - } -} -``` +Holder rankings, counts, whale floors, distribution stats, and dormancy screens have a dedicated cube and page — see the **[Robinhood Token Holders API](/docs/blockchain/robinhood/robinhood-token-holders-api/)**. --- @@ -356,8 +270,7 @@ Need balance changes as a continuous feed? Bitquery delivers Robinhood token dat | --- | --- | | Wallet / portfolio page | [Portfolio query](#all-token-balances-of-an-address-portfolio); poll on an interval for live UX | | Tax / audit snapshots | [Balance as of a date](#balance-as-of-a-date-time-travel) with `Block.Date.till` | -| Token distribution dashboards | [Top holders](#top-holders-of-a-token) + [holder count](#holder-count-of-a-token) | -| Rich lists & whale tracking | [Native rankings](#richest-native-eth-wallets), [USD floors](#whale-holders-by-usd) | +| Token distribution, rich lists & whales | [Token Holders API](/docs/blockchain/robinhood/robinhood-token-holders-api/) rankings, counts, and balance floors | | Wallet profiling (age, dormancy) | [First/last change + update count](#wallet-profile-first-seen-last-active-update-count) | | Exchange / custody monitoring | [Multi-address batch](#balances-for-multiple-addresses) on a polling schedule | | Supply-side view | [Per-currency totals](#network-wide-per-currency-totals), or the [Token Supply API](/docs/blockchain/robinhood/robinhood-token-supply/) | @@ -370,9 +283,8 @@ Need balance changes as a continuous feed? Bitquery delivers Robinhood token dat 2. Remember grouping follows selection: add or drop `Balance.Address` / `Currency` fields to pivot between wallet, token, and network views. 3. Use `selectWhere` (post-aggregation) for balance thresholds; regular `where` filters raw rows before aggregation. 4. `AmountInUSD` is native-ETH-only in practice — USDG's `Amount` ≈ dollars; price other tokens via the [Trades API](/docs/blockchain/robinhood/robinhood-trades/). -5. Keep a `limit` on holder-style queries — popular tokens have very large holder sets. -6. Contracts show up in holder lists (WETH tops native rankings by design) — filter known contract addresses for people-only lists. -7. An as-of-date query before a wallet's first activity returns no rows — that's the correct answer, not an error. +5. For holder rankings and counts, use the dedicated [Token Holders API](/docs/blockchain/robinhood/robinhood-token-holders-api/) — its `Holders` cube is built for the token-centric view. +6. An as-of-date query before a wallet's first activity returns no rows — that's the correct answer, not an error. --- @@ -388,7 +300,7 @@ Add `Block: { Date: { till: "YYYY-MM-DD" } }` to any balance query — the cube ### How do I list the top holders of a token? -Filter the token's `Currency.SmartContract`, select `Balance.Address`, and order by `Balance_Amount` descending — see [Top holders](#top-holders-of-a-token). `count(distinct: Balance_Address)` gives the holder count. +Use the dedicated [Token Holders API](/docs/blockchain/robinhood/robinhood-token-holders-api/) — its `Holders` cube returns sortable holder rankings, holder counts, distribution stats, and dormancy screens. ### Why is AmountInUSD 0 for my token balances? diff --git a/docs/blockchain/robinhood/robinhood-token-holders-api.md b/docs/blockchain/robinhood/robinhood-token-holders-api.md new file mode 100644 index 00000000..62a98e31 --- /dev/null +++ b/docs/blockchain/robinhood/robinhood-token-holders-api.md @@ -0,0 +1,319 @@ +--- +title: "Robinhood Token Holders API — Rankings, Counts & Distribution" +description: "Query Robinhood token holders with Bitquery GraphQL: top-holder rankings, holder counts, distribution stats, whale floors, dormancy screens, and stock-token holders." +sidebar_position: 7 +keywords: + - Robinhood token holders API + - Robinhood top holders + - Robinhood holder count + - Robinhood token distribution + - Robinhood richest wallets + - Robinhood whale holders + - Robinhood NVDA holders + - Robinhood airdrop snapshot + - Robinhood dormant holders + - Bitquery Robinhood Holders +--- +# Robinhood Token Holders API — Rankings, Counts & Distribution + +Query **token holders on Robinhood** with Bitquery's dedicated `EVM.Holders` cube — the token-centric view: who holds a token, ranked by balance, with per-holder change history (`FirstChangeTime`, `LastChangeTime`, `UpdateCount`) built in. One query replaces the transfer-indexing pipeline you would otherwise need, and it powers holder leaderboards, holder counts, distribution stats, whale floors, dormancy screens, and airdrop snapshots. + +For the wallet-centric view — one address's full portfolio — use the [Robinhood Balances API](/docs/blockchain/robinhood/robinhood-balances-api/) instead. Every query on this page was executed against the production endpoint before publishing. + +:::note API Key Required +To query or stream data outside the Bitquery IDE, you need an API access token. + +Follow the steps here: [How to generate Bitquery API token ➤](/docs/authorization/how-to-generate/) +::: + +:::tip Related docs +- [Robinhood Balances API](/docs/blockchain/robinhood/robinhood-balances-api/) +- [Robinhood Token Supply API](/docs/blockchain/robinhood/robinhood-token-supply/) +- [Robinhood Transfers](/docs/blockchain/robinhood/robinhood-transfers/) (live movement between holders) +- [Robinhood Trades](/docs/blockchain/robinhood/robinhood-trades/) (prices to value holdings) +::: + +**On this page:** [Concepts](#cube-concepts) · [Top holders](#top-holders-of-a-token) · [Holder count](#holder-count-of-a-token) · [Whale floors](#holders-above-a-balance-floor) · [Distribution](#holder-distribution-statistics) · [Dormant holders](#dormant-holders-diamond-hands) · [Stock tokens](#tokenized-stock-holders-nvda) · [ETH rich list](#native-eth-rich-list) · [Pagination](#paginating-full-holder-snapshots) · [FAQ](#faq) + +--- + +## Cube concepts + +- **Rows are (holder, token) pairs**: `Holder.Address` plus a `Balance` with `Amount`, `FirstChangeTime`, `LastChangeTime`, and `UpdateCount`. Select `Currency` fields when you query across tokens. +- Use **`dataset: archive`** — holder tables are computed from full history. +- **No USD field on this cube** — threshold and rank by token `Amount` (USDG ≈ dollars); join prices from the [Trades API](/docs/blockchain/robinhood/robinhood-trades/) to value holdings. +- **`Balance.LastChangeTime.till` filters by inactivity, not history**: a **future** date includes every holder (the current snapshot); a **past** date returns only wallets whose balance hasn't changed since then — with their frozen balances — which makes it a dormancy screen, not time travel. +- A plain `count` includes **everyone who ever held** (including now-zero balances). Add `Balance: { Amount: { gt: "0" } }` for **current** holders — the two numbers differ a lot on active tokens. +- The cube also accepts `Holder.Address` filters for wallet-side lookups, but portfolios are better served by the [Balances API](/docs/blockchain/robinhood/robinhood-balances-api/). + +--- + +## Top holders of a token + +The holder leaderboard — ranked by balance, with each holder's history stats. Example: USDG. The future-dated `LastChangeTime.till` explicitly includes all holders (see [concepts](#cube-concepts)); tighten it to screen for dormancy. + +```graphql +{ + EVM(dataset: archive, network: robinhood) { + Holders( + where: { + Currency: { SmartContract: { is: "0x5fc5360d0400a0fd4f2af552add042d716f1d168" } } + Balance: { LastChangeTime: { till: "2026-07-31T11:59:59Z" } } + } + limit: { count: 100 } + orderBy: { descending: Balance_Amount } + ) { + Holder { + Address + } + Balance { + Amount + FirstChangeTime + LastChangeTime + UpdateCount + } + } + } +} +``` + +--- + +## Holder count of a token + +One number per question: how many wallets **currently** hold the token (with the `gt: "0"` filter), or how many **ever** held it (without). + +```graphql +{ + EVM(dataset: archive, network: robinhood) { + Holders( + where: { + Currency: { SmartContract: { is: "0x5fc5360d0400a0fd4f2af552add042d716f1d168" } } + Balance: { Amount: { gt: "0" } } + } + ) { + holders: count + } + } +} +``` + +Drop the `Balance` filter to count all-time holders instead. + +--- + +## Holders above a balance floor + +**Whale lists and eligibility checks:** a regular `where` filter on `Balance.Amount` keeps only holders above a threshold — for USDG, the floor is effectively in dollars. + +```graphql +{ + EVM(dataset: archive, network: robinhood) { + Holders( + where: { + Currency: { SmartContract: { is: "0x5fc5360d0400a0fd4f2af552add042d716f1d168" } } + Balance: { Amount: { ge: "100000" } } + } + limit: { count: 10 } + orderBy: { descending: Balance_Amount } + ) { + Holder { + Address + } + Balance { + Amount + } + } + } +} +``` + +--- + +## Holder distribution statistics + +Concentration analysis in one aggregate call: current holder count, total held, and the mean / median / 99th-percentile holder size. Expect a long tail — the median holder is typically far below the mean. + +```graphql +{ + EVM(dataset: archive, network: robinhood) { + Holders( + where: { + Currency: { SmartContract: { is: "0x5fc5360d0400a0fd4f2af552add042d716f1d168" } } + Balance: { Amount: { gt: "0" } } + } + ) { + holders: count + total: sum(of: Balance_Amount) + avg: average(of: Balance_Amount) + med: median(of: Balance_Amount) + p99: quantile(of: Balance_Amount, level: 0.99) + } + } +} +``` + +`standard_deviation` and other `quantile` levels are available for deeper concentration metrics (top-N share is easiest computed client-side from the [top holders](#top-holders-of-a-token) list against `total`). + +--- + +## Dormant holders (diamond hands) + +Set `LastChangeTime.till` to a **past** date to keep only wallets whose balance hasn't moved since then — their `Amount` is the balance frozen at their last change. Combine with `FirstChangeTime` and `UpdateCount` to separate long-term holders from one-touch airdrop recipients. + +```graphql +{ + EVM(dataset: archive, network: robinhood) { + Holders( + where: { + Currency: { SmartContract: { is: "0x5fc5360d0400a0fd4f2af552add042d716f1d168" } } + Balance: { LastChangeTime: { till: "2026-07-01T00:00:00Z" }, Amount: { gt: "0" } } + } + limit: { count: 10 } + orderBy: { descending: Balance_Amount } + ) { + Holder { + Address + } + Balance { + Amount + FirstChangeTime + LastChangeTime + UpdateCount + } + } + } +} +``` + +--- + +## Tokenized stock holders (NVDA) + +Robinhood's tokenized equities are ordinary ERC-20s, so holder analytics work unchanged — `Amount` reads as the tokenized share count. Example: NVIDIA; swap in AAPL (`0xaf3d76f1834a1d425780943c99ea8a608f8a93f9`) or any other stock token. + +```graphql +{ + EVM(dataset: archive, network: robinhood) { + Holders( + where: { Currency: { SmartContract: { is: "0xd0601ce157db5bdc3162bbac2a2c8af5320d9eec" } } } + limit: { count: 10 } + orderBy: { descending: Balance_Amount } + ) { + Holder { + Address + } + Balance { + Amount + FirstChangeTime + LastChangeTime + UpdateCount + } + } + } +} +``` + +--- + +## Native ETH rich list + +Filter `Currency.Native: true` for the chain's largest ETH holders. **Contracts appear as holders** — the WETH contract naturally tops the list since it custodies wrapped ETH; filter or label known contracts for a people-only ranking. + +```graphql +{ + EVM(dataset: archive, network: robinhood) { + Holders( + where: { Currency: { Native: true } } + limit: { count: 10 } + orderBy: { descending: Balance_Amount } + ) { + Holder { + Address + } + Balance { + Amount + } + } + } +} +``` + +--- + +## Paginating full holder snapshots + +**Airdrop snapshots and exports:** page through the complete holder set with `limit.offset`, keeping the same `orderBy` so pages don't overlap. + +```graphql +{ + EVM(dataset: archive, network: robinhood) { + Holders( + where: { Currency: { SmartContract: { is: "0x5fc5360d0400a0fd4f2af552add042d716f1d168" } } } + limit: { count: 5, offset: 5 } + orderBy: { descending: Balance_Amount } + ) { + Holder { + Address + } + Balance { + Amount + } + } + } +} +``` + +For very large one-off snapshots, Bitquery can also provide [data exports](https://bitquery.io/forms/api). + +--- + +## Use-case patterns + +| Goal | Approach | +| --- | --- | +| Holder leaderboard page | [Top holders](#top-holders-of-a-token), refreshed on your interval | +| Distribution / concentration dashboards | [Holder count](#holder-count-of-a-token) + [distribution stats](#holder-distribution-statistics); top-N share client-side | +| Airdrop eligibility & snapshots | [Balance floors](#holders-above-a-balance-floor) + [offset pagination](#paginating-full-holder-snapshots) | +| Diamond-hands / dormancy analysis | [`LastChangeTime` screens](#dormant-holders-diamond-hands) with `FirstChangeTime` / `UpdateCount` | +| Stock-token cap tables | [Tokenized stock holders](#tokenized-stock-holders-nvda) | +| Live movement between holders | Stream the token on the [Transfers API](/docs/blockchain/robinhood/robinhood-transfers/) | + +--- + +## Tips + +1. Use `dataset: archive` and always keep a `limit` — popular tokens have very large holder sets. +2. Add `Balance: { Amount: { gt: "0" } }` whenever you mean **current** holders; plain counts include every wallet that ever held. +3. There is no USD field on this cube — rank and threshold in token units (USDG ≈ dollars) and join prices from the [Trades API](/docs/blockchain/robinhood/robinhood-trades/) for valuations. +4. `LastChangeTime.till` in the future = full current snapshot; in the past = dormancy screen with frozen balances. It is not an as-of-date balance calculator — for historical *balances* use the [Balances API's date filter](/docs/blockchain/robinhood/robinhood-balances-api/). +5. Contracts are holders too (WETH tops native rankings by design) — maintain a label list to exclude them from people-only rankings. +6. `UpdateCount` separates active traders (high) from set-and-forget holders (low) at a glance. + +--- + +## FAQ + +### How do I get the top holders of a Robinhood token? + +Query `EVM.Holders` on `dataset: archive`, filter `Currency.SmartContract`, and order by `Balance_Amount` descending — see [Top holders](#top-holders-of-a-token). Each row includes the holder's first/last change time and update count. + +### How do I get a token's holder count? + +Run the [holder-count query](#holder-count-of-a-token) with `Balance: { Amount: { gt: "0" } }` for current holders, or without it for all-time holders. + +### Can I take an airdrop snapshot of all holders? + +Yes — page through the full holder set with `limit: { count, offset }` under a stable `orderBy`, optionally with a [balance floor](#holders-above-a-balance-floor) for eligibility. For very large snapshots, ask about data exports. + +### How do I find dormant or diamond-hand holders? + +Set `Balance.LastChangeTime.till` to a past date — only wallets untouched since then return, with their frozen balances. See [Dormant holders](#dormant-holders-diamond-hands). + +### Why is there no USD value on holder rows? + +The Holders cube reports token amounts only. Use token-unit thresholds (USDG ≈ dollars), or multiply amounts by a price from the [Trades API](/docs/blockchain/robinhood/robinhood-trades/). + +### Should I use Holders or Balances? + +`Holders` is token-centric (one token → many wallets): rankings, counts, distribution. [`Balances`](/docs/blockchain/robinhood/robinhood-balances-api/) is wallet-centric (one wallet → many tokens): portfolios, multi-address batches, and as-of-date balance history. diff --git a/sidebars.js b/sidebars.js index f6e0fdea..c4cf84b1 100644 --- a/sidebars.js +++ b/sidebars.js @@ -858,6 +858,7 @@ const sidebars = { "blockchain/robinhood/robinhood-events-api", "blockchain/robinhood/robinhood-calls-api", "blockchain/robinhood/robinhood-balances-api", + "blockchain/robinhood/robinhood-token-holders-api", "blockchain/robinhood/robinhood-meme-coin-launches", "blockchain/robinhood/flap-sh-api", "blockchain/robinhood/bags-fm-api",