Skip to main content
Geth exposes an optional GraphQL endpoint that allows you to query blockchain data with flexible field selection. A single GraphQL request can retrieve data from multiple resources that would otherwise require several JSON-RPC calls.

Enabling GraphQL

GraphQL is served over the HTTP transport, so --http must be enabled alongside --graphql:
geth --http --graphql
The GraphQL handler is registered on the same HTTP server as the JSON-RPC API but at a different path:
PathDescription
/graphqlGraphQL endpoint (POST for queries)
/graphql/uiGraphiQL interactive browser playground
With default settings the endpoints are:
  • http://localhost:8545/graphql
  • http://localhost:8545/graphql/ui
The --graphql flag does not accept an --graphql.api namespace list. The GraphQL interface always exposes its own fixed schema regardless of which --http.api namespaces are enabled.

GraphiQL playground

Open http://localhost:8545/graphql/ui in a browser to access the GraphiQL interactive editor. It provides:
  • Syntax highlighting and autocompletion
  • Inline documentation browser (click the Docs panel)
  • Query history
  • Variable and header editors
This is the fastest way to explore the available schema and prototype queries before embedding them in application code.

Example queries

{
  block(number: 12345678) {
    number
    hash
    timestamp
    gasUsed
    gasLimit
    baseFeePerGas
    transactionCount
    miner {
      address
    }
  }
}

Sending queries with curl

GraphQL queries are sent as HTTP POST requests with a JSON body:
curl -X POST http://localhost:8545/graphql \
  -H 'Content-Type: application/json' \
  --data '{
    "query": "{ block { number hash timestamp } }"
  }'
Example response:
{
  "data": {
    "block": {
      "number": "0xbc614e",
      "hash": "0x...",
      "timestamp": "0x641a2f80"
    }
  }
}

Schema overview

The GraphQL schema exposes three root types:
Root typeDescription
QueryRead operations (blocks, transactions, accounts, logs)
MutationWrite operations (sendRawTransaction only)
PendingData from the current pending state

Query fields

FieldArgumentsDescription
blocknumber, hashFetch a block by number or hash; returns latest if neither is provided
blocksfrom, toFetch a range of blocks
transactionhashFetch a transaction by hash
logsfilterFetch log entries matching a filter
pendingAccess the current pending state
gasPriceEstimated gas price in wei
maxPriorityFeePerGasEstimated EIP-1559 priority fee in wei
syncingCurrent sync status, or null if in sync
chainIDCurrent chain ID

Block fields (selected)

FieldDescription
numberBlock number
hashBlock hash
timestampUnix timestamp
gasUsed / gasLimitGas usage
baseFeePerGasEIP-1559 base fee (post-London)
transactionsList of transactions in the block
account(address)Account state at this block
call(data)Execute a read-only call against this block’s state
withdrawalsBeacon chain withdrawals (post-Shanghai)

Mutation

The only mutation is sendRawTransaction, which broadcasts a signed RLP-encoded transaction and returns its hash:
mutation {
  sendRawTransaction(
    data: "0x02f86c..."
  )
}

Advantages over JSON-RPC

  • Flexible field selection — request only the fields you need; no over-fetching or under-fetching.
  • Batching in one request — retrieve a block, its transactions, and account balances in a single HTTP round trip using nested queries.
  • Typed schema — the schema is self-documenting and tools like GraphiQL can provide autocompletion and inline documentation.
  • Range queries — the blocks field lets you fetch multiple consecutive blocks in one query.

Limitations

GraphQL is read-only with the exception of sendRawTransaction. It does not expose administrative, debug, mining, or subscription APIs. For those operations, use the JSON-RPC API or the JavaScript console.
Other limitations to be aware of:
  • Query nesting depth is capped at 20 levels to prevent resource exhaustion.
  • Subscriptions are not supported; use eth_subscribe over WebSocket for real-time event streaming.
  • Account state queries are scoped to a specific block; there is no way to query historical state outside the node’s retained state history.

Build docs developers (and LLMs) love