GraphQL API
Auto-generated from your TOML config. Every table gets a query endpoint.
Endpoints
Enable the API with [api] port in TOML or --api-port on the CLI.
| Path | Description |
|---|---|
| / | GraphiQL IDE |
| /graphql | GraphQL endpoint |
| /health | Liveness probe |
| /ready | Readiness (503 during backfill) |
| /metrics | Prometheus metrics |
Query shape
Each table is a root field named after the table. It returns a connection: the rows are under nodes and the paging state is under pageInfo.
{
usdc_transfers(first: 10) {
nodes {
block_number
tx_hash
value
}
pageInfo {
hasNextPage
endCursor
}
}
_meta {
block
}
}_meta.block is the last committed block, so you can tell how fresh the data is.
Filter operators
Filters go in the where argument as column or column_suffix. Which suffixes a column gets depends on its type:
| Suffix | Meaning |
|---|---|
| (none) | Equal |
| _ne | Not equal |
| _in | In list |
| _not_in | Not in list |
| _gt | Greater than |
| _gte | Greater than or equal |
| _lt | Less than |
| _lte | Less than or equal |
| _contains | Contains substring |
| _starts_with | Starts with |
Numeric values, including uint256 amounts, are passed as strings, for example value_gte: "1000000000". A column overridden in columns to a type other than text, numeric, bigint, integer, boolean, or bytea only gets equality, _in, and _not_in.
Filter composition
Filters at the same level in where are combined with AND. OR takes a list of filter objects, and each of those can nest its own OR.
{
usdc_transfers(
where: {
OR: [
{ from_address: "0xAbc..." }
{ to_address: "0xAbc..." }
]
value_gte: "1000000000"
}
orderBy: block_number
orderDirection: DESC
first: 50
) {
nodes {
block_number
tx_hash
from_address
to_address
value
block_timestamp
}
}
}Pagination
first defaults to 100 and is capped at 1000. Two pagination modes:
Cursor-based
{
usdc_transfers(first: 100, after: "<endCursor from the previous page>") {
nodes {
block_number
tx_hash
}
pageInfo {
hasNextPage
endCursor
}
}
}Pass the previous page's pageInfo.endCursor as after and keep the same orderBy and orderDirection. Stop when hasNextPage is false. Best for large datasets and infinite scroll.
Offset-based
{
usdc_transfers(first: 50, skip: 100) {
nodes {
block_number
tx_hash
}
}
}Use first and skip for simple page-based navigation.
Sorting
{
usdc_transfers(
orderBy: block_number
orderDirection: ASC
first: 10
) {
nodes {
block_number
value
}
}
}orderBy accepts any column name and defaults to id. orderDirection is ASC or DESC (uppercase) and defaults to DESC.