Skip to main content
Graph Node exposes a powerful GraphQL API for querying indexed blockchain data from subgraphs. The API automatically generates query types based on your subgraph schema and provides advanced filtering, sorting, and pagination capabilities.

API Endpoint

Once Graph Node is running, the GraphQL HTTP server is available at:
http://localhost:8000
You can query specific subgraphs using these URL patterns:
curl -X POST http://localhost:8000/subgraphs/name/<subgraph-name>

Schema-Based Type Generation

Graph Node automatically generates GraphQL query types from your subgraph schema. For each entity type in your schema, the API provides:
  • Single entity query: entityName(id: ID!): EntityType
  • Collection query: entityNames(first, skip, orderBy, orderDirection, where): [EntityType!]!

Example Schema

schema.graphql
type Token @entity {
  id: ID!
  name: String!
  symbol: String!
  decimals: Int!
  totalSupply: BigInt!
}

type Transfer @entity(immutable: true) {
  id: ID!
  from: Bytes!
  to: Bytes!
  amount: BigInt!
  blockNumber: BigInt!
  timestamp: Timestamp!
}

Generated Query Types

From the schema above, Graph Node generates:
Generated API
type Query {
  # Single entity queries
  token(id: ID!, block: Block_height): Token
  transfer(id: ID!, block: Block_height): Transfer
  
  # Collection queries
  tokens(
    first: Int = 100
    skip: Int = 0
    orderBy: Token_orderBy
    orderDirection: OrderDirection
    where: Token_filter
    block: Block_height
  ): [Token!]!
  
  transfers(
    first: Int = 100
    skip: Int = 0
    orderBy: Transfer_orderBy
    orderDirection: OrderDirection
    where: Transfer_filter
    block: Block_height
  ): [Transfer!]!
}

Entity Types and Fields

Supported GraphQL Types

Graph Node supports the following scalar types in entity definitions:
ID
String
Unique identifier for entities. Stored as text or bytea in PostgreSQL.
String
String
UTF-8 encoded text strings.
Bytes
Bytes
Byte arrays, typically for Ethereum addresses and hashes. Must be prefixed with 0x.
Int
Int
32-bit signed integer.
Int8
Int8
64-bit signed integer.
BigInt
BigInt
Arbitrary precision integer, stored as PostgreSQL numeric.
BigDecimal
BigDecimal
Arbitrary precision decimal, stored as PostgreSQL numeric.
Boolean
Boolean
Boolean value (true or false).
Timestamp
Timestamp
Unix timestamp in microseconds since epoch. Available from spec version 1.1.0.

Entity Attributes

Marks a GraphQL type as a storable entity.
type Account @entity {
  id: ID!
  balance: BigInt!
}
Options:
  • immutable: true - Entity versions are never updated (optimized storage)
  • timeseries: true - Entity is a timeseries data point (immutable with timestamp)
Creates reverse lookups for entity relationships.
type Token @entity {
  id: ID!
  transfers: [Transfer!]! @derivedFrom(field: "token")
}

type Transfer @entity {
  id: ID!
  token: Token!
  amount: BigInt!
}
The transfers field on Token is automatically populated from Transfer entities.
Immutable entities are write-once and never updated, enabling storage optimizations.
type Event @entity(immutable: true) {
  id: ID!
  blockNumber: BigInt!
  timestamp: Timestamp!
  data: String!
}
Storage Optimization:
  • Uses block$ column instead of block_range
  • Simple BTree indexes instead of GiST indexes
  • Enforces unique(id) constraint

Query Arguments

All collection queries support these arguments:
first
Int
default:"100"
Number of entities to return. Maximum value is configurable per Graph Node instance.
skip
Int
default:"0"
Number of entities to skip. Useful for pagination.
orderBy
Enum
Field to sort results by. Can be any field in the entity or nested field (e.g., token__symbol).
orderDirection
Enum
Sort direction: asc (ascending) or desc (descending). Default is asc.
where
Filter
Filter conditions for entities. See Query Filters for details.
block
Block_height
Query historical state at a specific block. See Time-Travel Queries.

Basic Query Examples

query {
  token(id: "0x1234") {
    id
    name
    symbol
    decimals
    totalSupply
  }
}

Response Format

Graph Node returns responses in standard GraphQL format:
{
  "data": {
    "tokens": [
      {
        "id": "0x1234",
        "name": "Example Token",
        "symbol": "EXT",
        "decimals": 18,
        "totalSupply": "1000000000000000000000000"
      }
    ]
  },
  "errors": []
}

Error Handling

Errors are returned in the errors array:
{
  "data": null,
  "errors": [
    {
      "message": "Entity not found",
      "locations": [{"line": 2, "column": 3}],
      "path": ["token"]
    }
  ]
}

Interfaces

Graph Node supports GraphQL interfaces for polymorphic entities:
interface Transaction {
  id: ID!
  hash: Bytes!
  blockNumber: BigInt!
}

type Swap implements Transaction @entity {
  id: ID!
  hash: Bytes!
  blockNumber: BigInt!
  amountIn: BigInt!
  amountOut: BigInt!
}

type Transfer implements Transaction @entity {
  id: ID!
  hash: Bytes!
  blockNumber: BigInt!
  from: Bytes!
  to: Bytes!
  amount: BigInt!
}
Query interfaces to fetch all implementing types:
query {
  transactions(first: 10) {
    id
    hash
    blockNumber
    ... on Swap {
      amountIn
      amountOut
    }
    ... on Transfer {
      from
      to
      amount
    }
  }
}

Performance Considerations

Only query fields you need. Large text fields and arrays can be expensive:
# Good: Selective fields
query {
  tokens(first: 100) {
    id
    symbol
  }
}

# Avoid: All fields when not needed
query {
  tokens(first: 100) {
    id
    name
    symbol
    decimals
    totalSupply
    largeDescriptionField
  }
}
Be cautious with nested queries that can multiply data fetched:
# Can fetch large amounts of data
query {
  tokens(first: 100) {
    id
    transfers(first: 100) {
      # This fetches up to 10,000 transfers (100 * 100)
      id
      amount
    }
  }
}

Next Steps

Build docs developers (and LLMs) love