> For the complete documentation index, see [llms.txt](https://docs.triton.one/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.triton.one/sui/graphql.md).

# GraphQL

The Sui GraphQL API, with endpoints, authentication, example queries, and retention limits.

GraphQL RPC is a flexible, ergonomic interface for reading data from the Sui blockchain, submitting transactions, and simulating transactions. Instead of a fixed set of methods, GraphQL lets you request exactly the fields you need — across transactions, objects, events, balances, and checkpoints — in a single composable query, reducing overfetching and round trips.

Under the hood, our GraphQL service is backed by the Sui **General-purpose Indexer**, which ingests checkpoint data into a Postgres-compatible database and serves it through a strongly typed schema. It is the best fit for frontends, explorers, dashboards, and any data-driven application that benefits from filtered, nested, or point-in-time queries.

{% hint style="warning" %}
**Triton no longer serves Sui JSON-RPC.** Sui 1.82 removes the JSON-RPC service from the Sui full node, and Triton runs Sui 1.82 or later on mainnet and testnet. Use [gRPC](/sui/grpc.md) on mainnet or testnet, or GraphQL on mainnet shared endpoints.
{% endhint %}

## When to use GraphQL

GraphQL is the best choice when your application:

* Needs to render **structured results in a frontend**, such as wallets, explorers, and dashboards.
* Benefits from **flexible, composable queries** that fetch only the fields you need and combine multiple entities (transactions, objects, events, balances) in one request.
* Requires **filtered historical access**, such as all transactions sent by an address, all transactions that called a given function, or all live objects of a given type.
* Wants **consistent, point-in-time reads** across one or more requests, as if the responses came from a snapshot at a specific checkpoint.

For **high-performance, low-latency point lookups** and **real-time checkpoint streaming**, use [gRPC](/sui/grpc.md) instead. Many production stacks use both: gRPC for hot-path lookups and streaming, GraphQL for flexible reads and frontends.

## How it works

The GraphQL service answers each request from one of three backing data sources, each with its own retention window. Understanding which source serves which query helps you set the right expectations for data availability:

| Data source                                     | Example queries                                                                                         | Retention on our service      |
| ----------------------------------------------- | ------------------------------------------------------------------------------------------------------- | ----------------------------- |
| **Consistent store**                            | Live objects owned by an address, live objects by type, address balances                                | \~1 hour (recent checkpoints) |
| **Filtered indexes (Postgres)**                 | `events`, and `transactions` filtered by address, object, function, or kind                             | **About 30 days**             |
| **Full-history indexes and the archival store** | A transaction by digest, a checkpoint by sequence number, an object at a past version, epochs, packages | Not limited to the window     |

{% hint style="info" %}
**Filtered queries stop at about 30 days.** Event queries and transaction filters cover only the most recent 10,368,000 checkpoints, **about 30 days**, and they don't fall back to older data. Point lookups, such as a transaction by digest, a checkpoint by sequence number, or an object at a specific version, aren't limited to that window. For older filtered history, see [Data retention](#data-retention-and-historical-data).
{% endhint %}

## Endpoints

The GraphQL service is served over HTTPS at the `/graphql` path on your Sui endpoint. All queries are sent as `POST` requests with a JSON body containing your GraphQL `query` and optional `variables`.

GraphQL is available on mainnet only. Testnet endpoints don't serve `/graphql`.

| Plan          | GraphQL endpoint                                          | Auth                             |
| ------------- | --------------------------------------------------------- | -------------------------------- |
| **Free test** | `https://mainnet.sui.rpcpool.com/graphql`                 | None (rate-limited)              |
| **Shared**    | `https://<your-endpoint>.mainnet.sui.rpcpool.com/graphql` | `X-Token` header or token in URL |
| **Dedicated** | Not served on a dedicated node                            | —                                |

GraphQL isn't part of a dedicated node. It runs on shared infrastructure, and a dedicated node's endpoint doesn't serve `/graphql`.

{% hint style="warning" %}
We provide a free shared GraphQL endpoint for testing and evaluation. It is strictly rate-limited and intended for development use only, **not for production traffic**.
{% endhint %}

{% hint style="info" %}
`<your-endpoint>` is your unique endpoint slug, visible in the [customer dashboard](https://customers.triton.one/). The token is the same one used for your gRPC and Archival endpoints.
{% endhint %}

## Authentication

All non-free endpoints require authentication with your token — the same token used for your standard gRPC endpoint. You can find it in the [customer dashboard](https://customers.triton.one/). There are two equivalent ways to supply it.

{% tabs %}
{% tab title="X-Token header" %}

```bash
curl -X POST https://<your-endpoint>.mainnet.sui.rpcpool.com/graphql \
  -H "X-Token: <your-token>" \
  -H "Content-Type: application/json" \
  -d '{ "query": "{ epoch { referenceGasPrice } }" }'
```

{% endtab %}

{% tab title="Token in URL" %}

```bash
curl -X POST https://<your-endpoint>.mainnet.sui.rpcpool.com/<your-token>/graphql \
  -H "Content-Type: application/json" \
  -d '{ "query": "{ epoch { referenceGasPrice } }" }'
```

The URL form is convenient for tools that can only set a URL and not custom headers. Both methods are equivalent — use whichever fits your client.
{% endtab %}

{% tab title="Free test endpoint" %}
The free test endpoint accepts the same requests with no token at all:

```bash
curl -X POST https://mainnet.sui.rpcpool.com/graphql \
  -H "Content-Type: application/json" \
  -d '{ "query": "{ epoch { referenceGasPrice } }" }'
```

{% endtab %}
{% endtabs %}

## Quickstart

A GraphQL request is a JSON object with a `query` string and, optionally, a `variables` object.

This query reads only current chain state — the chain identifier and the reference gas price for the current epoch — so it returns immediately without touching historical or archival data.

{% code title="Request" %}

```bash
curl -X POST https://<your-endpoint>.mainnet.sui.rpcpool.com/graphql \
  -H "X-Token: <your-token>" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "{ chainIdentifier epoch { referenceGasPrice } }"
  }'
```

{% endcode %}

{% code title="Response" %}

```json
{
  "data": {
    "chainIdentifier": "4btiuiMPvEENsttpZC7CZ53DruC3MAgfznDbASZ7DR6S",
    "epoch": {
      "referenceGasPrice": "100"
    }
  }
}
```

{% endcode %}

## Example queries

The following examples cover common tasks. Each is a GraphQL document you send as the `query` field of a request; where a query declares variables, supply them in the request's `variables` object.

### Reference gas price for the latest epoch

```graphql
query {
  epoch {
    referenceGasPrice
  }
}
```

### A transaction by its digest

Fetch a transaction and its effects — gas sponsor, gas price and budget, execution status, and the checkpoint it landed in.

```graphql
query ($digest: String!) {
  transaction(digest: $digest) {
    gasInput {
      gasSponsor { address }
      gasPrice
      gasBudget
    }
    effects {
      status
      timestamp
      checkpoint { sequenceNumber }
      epoch { epochId referenceGasPrice }
    }
  }
}
```

Variables:

```json
{ "digest": "<transaction-digest>" }
```

### Balances owned by an address

List the address's balance for every coin type it holds. To read a single coin type, use `balance(coinType: "0x2::sui::SUI")` instead.

```graphql
query ($address: SuiAddress!) {
  address(address: $address) {
    balances {
      nodes {
        coinType { repr }
        totalBalance
      }
    }
  }
}
```

### All transactions that touched an object

Trace every transaction that modified, transferred, or deleted a given object — useful for following a `Coin`, `StakedSui`, or NFT.

```graphql
query ($objectID: SuiAddress!) {
  transactions(filter: { affectedObject: $objectID }) {
    pageInfo { hasNextPage endCursor }
    nodes {
      digest
      sender { address }
      effects {
        objectChanges {
          nodes { address }
        }
      }
    }
  }
}
```

### Filter transactions by function

Find the last 10 transactions that called a specific Move function.

```graphql
query {
  transactions(
    last: 10
    filter: { function: "0x2::transfer::public_transfer" }
  ) {
    nodes { digest }
  }
}
```

### Execute a transaction

GraphQL is not read-only. `executeTransaction` submits a signed transaction and waits for finality, and you can select fields from `effects` in the same request to read the result immediately, without waiting for a separate indexed query. If the transaction can't reach finality, the error comes back in the response's top-level `errors` array.

```graphql
mutation ($tx: Base64!, $sigs: [Base64!]!) {
  executeTransaction(transactionDataBcs: $tx, signatures: $sigs) {
    effects {
      status
      gasEffects {
        gasSummary { computationCost }
      }
    }
  }
}
```

`transactionDataBcs` is the Base64-encoded, BCS-serialized unsigned transaction data (for example, from `sui client call --serialize-unsigned-transaction`), and each entry in `signatures` is a Base64-encoded signature over that data (for example, from `sui keytool sign`).

### Simulate a transaction

Use `simulateTransaction` to preview effects, estimate gas, or test logic without committing onchain.

```graphql
query ($tx: JSON!) {
  simulateTransaction(transaction: $tx, checksEnabled: true, doGasSelection: true) {
    effects {
      status
      gasEffects {
        gasSummary { computationCost storageCost }
      }
    }
    outputs {
      returnValues { value { json } }
    }
  }
}
```

## Key concepts

### Pagination and connections

Fields that return multiple results are **connections** following the [GraphQL Cursor Connections Specification](https://relay.dev/graphql/connections.htm). They accept `first`/`after` (forward) or `last`/`before` (backward) arguments and return `pageInfo` (with `hasNextPage` and `endCursor`) alongside `nodes`. Read the first page, then pass the returned `endCursor` as `after` to fetch the next page. Cursors are opaque — only use a cursor value returned by a previous response.

```graphql
query ($after: String) {
  checkpoints(first: 5, after: $after) {
    pageInfo { hasNextPage endCursor }
    nodes { digest timestamp }
  }
}
```

### Scope and consistency

Every request is evaluated as of a single checkpoint. By default this is the latest checkpoint the service has fully indexed. You can pin queries to an earlier checkpoint for historical reads using `checkpoint(sequenceNumber: ...) { query { ... } }`, and cursors for live-object queries encode the checkpoint at which pagination began, so later pages remain consistent even as new checkpoints arrive.

### Limits

Requests are validated against complexity and payload rules (query depth, input/output node counts, page sizes, and request timeouts) in addition to rate limits. You can query the active limits at runtime:

```graphql
{
  serviceConfig {
    maxQueryDepth
    maxQueryNodes
    maxOutputNodes
    maxPageSize(type: "Query", field: "objects")
    queryTimeoutMs
  }
}
```

### Checking the available range

Because retention varies by data source, check the available checkpoint range before starting a long pagination run or a historical query:

```graphql
{
  serviceConfig {
    availableRange(type: "Query", field: "transactions", filters: ["affectedAddress"]) {
      first { sequenceNumber }
      last { sequenceNumber }
    }
  }
}
```

Data outside the available range isn't served, so use fresh cursors and keep the checkpoint bounds of filtered queries within the available range.

## Data retention and historical data

Our GraphQL service keeps the most recent 10,368,000 checkpoints of filtered indexes, **about 30 days**: events, and transactions filtered by address, object, function, or kind. Point lookups by digest, checkpoint sequence number, or object version aren't limited to this window.

For older data, use the [Archival service](/sui/archival.md). It serves the complete history of Sui mainnet from genesis and exposes the gRPC `LedgerService` interface for point lookups of transactions, checkpoints, and historical object states.

{% hint style="info" %}
GraphQL's filtered queries don't fall back to older data. If your application needs older records, query the Archival endpoint directly. A common pattern is to serve recent data from GraphQL and route deep-history point lookups to Archival.
{% endhint %}

## Exploring the schema

The Sui GraphQL schema is introspectable, so any GraphQL client library can discover the full set of available types and fields programmatically via a standard introspection query. For the complete, human-readable schema — every query, mutation, type, and field — see the [official Sui GraphQL reference](https://docs.sui.io/references/sui-graphql).

## What's next

* [gRPC](/sui/grpc.md) — high-performance point lookups and checkpoint streaming
* [Archival service](/sui/archival.md) — full historical data beyond the GraphQL window
* [Dedicated nodes](/sui/dedicated-nodes.md) — private Sui infrastructure

## Resources

* [Official: GraphQL for Sui RPC](https://docs.sui.io/develop/accessing-data/graphql/graphql-rpc)
* [Official: Querying Data with GraphQL RPC](https://docs.sui.io/develop/accessing-data/graphql/query-with-graphql)
* [Official: Sui GraphQL schema reference](https://docs.sui.io/references/sui-graphql)
* [Official: JSON-RPC migration guide](https://docs.sui.io/develop/accessing-data/json-rpc-migration)
* [GraphQL Cursor Connections Specification](https://relay.dev/graphql/connections.htm)

***

<i class="fa-life-ring">:life-ring:</i> Contact support by clicking the chat icon in your [customer dashboard](https://customers.triton.one)\ <i class="fa-briefcase">:briefcase:</i> Sales questions? [Contact us](https://triton.one/contact)\ <i class="fa-sparkles">:sparkles:</i> AI agent? Read [llms.txt](https://docs.triton.one/llms.txt)\ <i class="fa-rss">:rss:</i> Follow updates: [Blog](https://blog.triton.one) · [X](https://x.com/triton_one) · [YouTube](https://www.youtube.com/@triton_one_ltd) · [Telegram](https://t.me/tritonone) · [GitHub](https://github.com/rpcpool)
