Transaction traces: debug_traceTransaction and the Data API trace endpoints
Reconstruct execution call trees for a transaction: the JSON-RPC debug_traceTransaction method with its allowed tracers and guards, and the Data API getTransactionTrace and getBlockTraces endpoints with their finality limits.
Two ways to reconstruct a call tree
A transaction trace is the reconstructed call tree of an execution: which contract was called, with which input, how much gas it consumed, and which sub-calls it made. BlockVectra exposes it through two surfaces:
- JSON-RPC
debug_trace*— runs against the chain's node through the JSON-RPC endpoint, so it can trace recent state the node still has. - Data API traces —
GET /{chain}/transactions/{hash}/traceandGET /{chain}/blocks/{number}/tracesreturn stored, indexed call trees over REST.
Both use the same API key and are metered in CU by method weight (see the weights below). Which one fits depends on whether you need a single transaction or a whole block, how recent the target is, and whether you want to walk a full block without pagination.
Limits that apply to debug_trace*
debug_trace* requests are accepted only for methods and tracers the chain's method policy allows:
- Allowed tracers: the
tracerparameter accepts only the built-in native tracers —callTracer,flatCallTracer,prestateTracer,4byteTracer,noopTracer, or omitting it to use the default struct logger. Any other value is rejected with JSON-RPC error-32602 tracer not allowed, not forwarded, and not billed. - Trace timeout: the
timeoutparameter must be a valid duration and at most 30s; otherwise the request is rejected with-32602 trace timeout not allowed, not forwarded, and not billed. - Node sync guard: while a chain's node is not synced, every method except
eth_chainId— includingdebug_trace*and the hash/height history lookups — returns-32010; the call is not forwarded and not billed. - State window:
debug_traceCall,debug_traceBlockByNumber,debug_traceTransaction, anddebug_traceBlockByHashtarget a block that must be inside the chain's state window. A target earlier than the window, or one that uses thesafe,finalized, orearliesttag, returns-32011. The node's own out-of-window error is not billed. Block and receipt data are not limited by the state window, but they are limited by the node's retained history. - Hash pre-resolution:
debug_traceTransactionanddebug_traceBlockByHashfirst resolve the hash to a block height, then apply the state window. A hash that is not0xplus 64 hex digits returns-32000 transaction not found/block not foundwithout querying the node; a well-formed hash the node does not know returns the same-32000, and a failed lookup is-32603 upstream unavailable(retryable). None of these are forwarded or billed. - Per-chain method policy: which
debug_trace*methods a chain allows is published by the publicGET /v1/chainsresponse. Read it at runtime instead of hardcoding a method list; chains are listed on Supported Chains, and the method reference is in the JSON-RPC methods page.
Requesting debug_traceTransaction with callTracer
The specification's example request carries only the transaction hash. The call below adds the tracer parameter to request a call tree; the value comes from the tracer allowlist above, so no response body is invented here.
export BLOCKVECTRA_API_KEY=rgw_your_api_key
# The specification example (reqTraceTx) passes only the transaction hash:
# {"jsonrpc":"2.0","id":1,"method":"debug_traceTransaction",
# "params":["0xcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"]}
# Add "tracer" to request a call tree with one of the allowed native tracers.
curl -s "https://dev-api.blockvectra.network/v1/robinhood_mainnet" \
-H 'Content-Type: application/json' \
-H "x-api-key: $BLOCKVECTRA_API_KEY" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "debug_traceTransaction",
"params": [
"0xcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
{ "tracer": "callTracer" }
]
}'What the Data API trace endpoints provide
The Data API returns stored call trees for two scopes. Neither is paginated: next_cursor is never present.
GET /{chain}/transactions/{hash}/trace— the call frame of one transaction, looked up by transaction hash.GET /{chain}/blocks/{number}/traces— one call tree per transaction in a block, intx_indexorder. A real, finalized block with zero transactions returnsdata: [].
The response envelope is:
TxTraceEnvelope:datais aCallFramedirectly, plusmeta.BlockTracesEnvelope:datais an array ofBlockTraceItem, each withtxHashand theresultCallFrame, plusmeta.
Both trace endpoints return the standard Ethereum callTracer format. This is an exception to the Data API's money-safety encoding: elsewhere, a value that can exceed 2^53 is serialized as a decimal string; on these two endpoints, value, gas, and gasUsed are 0x-prefixed hex quantities, not decimal strings. Every CallFrame carries type, from, gas, gasUsed, and input; type is one of CALL, DELEGATECALL, STATICCALL, CREATE, CREATE2, or SELFDESTRUCT. to is absent for a CREATE/CREATE2 frame's target, and value is absent for a STATICCALL frame. Optional members are output (absent when the call returned no data), error (absent on success), revertReason (present only for an Error(string) revert), and calls (nested sub-calls in call order). Additional members of the frame are preserved.
To make the shape concrete, here is the CallFrame field skeleton — annotated, not a captured response. The locked specification has no response example for either trace endpoint, so no concrete values are shown:
{
"type": "CALL | DELEGATECALL | STATICCALL | CREATE | CREATE2 | SELFDESTRUCT",
"from": "0x…", // 20-byte address
"to": "0x…", // absent for a CREATE/CREATE2 target
"value": "0x…", // 0x-prefixed hex quantity; absent for STATICCALL
"gas": "0x…", // 0x-prefixed hex quantity
"gasUsed": "0x…", // 0x-prefixed hex quantity
"input": "0x…",
"output": "0x…", // absent when the call returned no data
"error": "…", // absent on success
"revertReason": "…", // absent unless the call reverted with Error(string)
"calls": [] // nested sub-calls in call order; absent for a leaf frame
}Parameters
{chain}(path parameter, required): chain identifier, thechainvalue of an entry inGET /chains. Matching is exact and case-sensitive; aliases and numeric chain IDs are not accepted.{hash}(path parameter, required for the transaction trace): 32-byte transaction hash,0xprefix optional, either digit case.{number}(path parameter, required for the block traces): non-negative block height.
Coverage and finality
- Both endpoints belong to the
tracescapability. A chain without it returns422 no_coverage. Chains that provide this dataset are subject to the Supported Chains page and the dataset directory. - Trace data can start later than the rest of a chain's indexed history. A block before the chain's first traced block, inside a recorded gap, or one whose transactions were indexed but never traced and that is already too far behind the indexed head returns
422 no_coverage;GET /chainsreports the boundary ascoverage.traces_from_block, and a trace request before it, or inside a range that could not be traced, returns422 no_coverage. - The transaction trace resolves the hash to a block, then checks the block against
finalized_block: a resolved block above it returns409 finality_exceeded. Hash lookups have no watermark to check "not indexed yet" against, so a just-submitted transaction whose indexing has not caught up also returns404 not_found; retry briefly before treating it as permanent. - The block traces endpoint takes a block number. A
{number}aboveas_of_blockreturns409 not_indexed_yetwithindexed_through; a{number}at or belowas_of_blockbut abovefinalized_blockreturns409 finality_exceeded. - A recent block with transactions but no trace data yet returns
503 unavailablewith aRetry-Afterheader. Once it is further behind the indexed head than the chain's trace window, it is422 no_coverageinstead.
Requesting a trace from the Data API
export BLOCKVECTRA_API_KEY=rgw_your_api_key
# One transaction's call frame.
curl -s "https://dev-api.blockvectra.network/v1/data/robinhood_mainnet/transactions/0xcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd/trace" \
-H "x-api-key: $BLOCKVECTRA_API_KEY"
# One call tree per transaction in a finalized block.
curl -s "https://dev-api.blockvectra.network/v1/data/robinhood_mainnet/blocks/1/traces" \
-H "x-api-key: $BLOCKVECTRA_API_KEY"Which one to use
| Typical task | Better fit | Why |
|---|---|---|
| Reconstruct a single transaction right after it lands | debug_traceTransaction | It runs against the node's current state, so it is not limited to blocks at or below finalized_block; availability follows the chain's method policy. |
| Read a single transaction's stored call tree | GET /{chain}/transactions/{hash}/trace | Returns the transaction's CallFrame directly over REST; the resolved block must be at or below finalized_block. |
| Read every call tree in one block in one request | GET /{chain}/blocks/{number}/traces | Returns the whole block unpaginated, in tx_index order; the block must be at or below finalized_block. |
| Trace state the node still has but the dataset has not stored yet | debug_trace* | The Data API serves stored data only up to finalized_block; the node can answer for more recent blocks. |
CU per call
Every method is billed by its CU weight. The weights below are read from the platform plans API at build time:
CU weight per call
| Method | CU per call |
|---|---|
debug_trace* | 100 |
data.transaction_trace | 200 |
data.block_traces | 200 |
Weights are read from the platform plans API at build time.
Rejected requests are not billed. For the full billing rules, see What is not billed: error codes and billing rules.
Next steps
- Browse the datasets directory to see every dataset BlockVectra indexes.
- See the free plan and pricing to check what your account includes.
- Log in to the console to create an API key.