Documentation Index
Fetch the complete documentation index at: https://mintlify.com/mystenlabs/sui/llms.txt
Use this file to discover all available pages before exploring further.
Sui’s GraphQL API provides a flexible, efficient way to query blockchain data. It offers a modern alternative to JSON-RPC with powerful filtering, pagination, and field selection.
GraphQL Endpoint
Mainnet:
https://sui-mainnet.mystenlabs.com/graphql
Testnet:
https://sui-testnet.mystenlabs.com/graphql
Devnet:
https://sui-devnet.mystenlabs.com/graphql
Why GraphQL?
GraphQL offers several advantages over REST/JSON-RPC:
- Precise Queries: Request exactly the fields you need
- Single Request: Fetch related data in one query
- Strongly Typed: Schema-based with built-in validation
- Powerful Filtering: Rich query capabilities
- Nested Queries: Retrieve related objects in a single request
- Real-time Updates: Subscriptions for live data
Quick Start
HTTP Request
curl -X POST https://sui-mainnet.mystenlabs.com/graphql \
-H "Content-Type: application/json" \
-d '{
"query": "{ chainIdentifier }"
}'
JavaScript Client
const query = `
query {
chainIdentifier
epoch {
epochId
referenceGasPrice
}
}
`;
const response = await fetch('https://sui-mainnet.mystenlabs.com/graphql', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query }),
});
const data = await response.json();
console.log(data);
TypeScript SDK
import { SuiGraphQLClient } from '@mysten/sui.js/graphql';
const client = new SuiGraphQLClient({
url: 'https://sui-mainnet.mystenlabs.com/graphql',
});
const { data } = await client.query({
query: `
query {
chainIdentifier
}
`,
});
Schema Exploration
Use GraphQL introspection to explore the schema:
query {
__schema {
types {
name
description
}
}
}
Or use GraphQL Playground:
- Navigate to the GraphQL endpoint in your browser
- Explore the schema in the “Docs” panel
- Test queries interactively
Common Queries
query {
chainIdentifier
serviceConfig {
maxQueryDepth
maxQueryNodes
requestTimeoutMs
}
}
Get Current Epoch
query {
epoch {
epochId
referenceGasPrice
startTimestamp
endTimestamp
validatorSet {
totalStake
}
}
}
Get Object by ID
query GetObject($id: SuiAddress!) {
object(address: $id) {
address
version
digest
owner {
__typename
... on AddressOwner {
owner {
address
}
}
... on Shared {
initialSharedVersion
}
}
asMoveObject {
contents {
type {
repr
}
json
}
}
}
}
Variables:
Get Owned Objects
query GetOwnedObjects($owner: SuiAddress!, $first: Int) {
address(address: $owner) {
objects(first: $first) {
nodes {
address
version
digest
asMoveObject {
contents {
type {
repr
}
}
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
}
Get Transaction Block
query GetTransaction($digest: String!) {
transactionBlock(digest: $digest) {
digest
sender {
address
}
gasInput {
gasSponsor {
address
}
gasPrice
gasBudget
}
effects {
status
gasEffects {
gasObject {
address
}
gasSummary {
computationCost
storageCost
storageRebate
}
}
}
}
}
Query Events
query GetEvents($filter: EventFilter, $first: Int) {
events(filter: $filter, first: $first) {
nodes {
sendingModule {
package {
address
}
name
}
type {
repr
}
sender {
address
}
json
bcs
}
pageInfo {
hasNextPage
endCursor
}
}
}
Variables:
{
"filter": {
"eventType": "0x2::coin::CoinCreated"
},
"first": 10
}
Get Balance
query GetBalance($owner: SuiAddress!, $type: String) {
address(address: $owner) {
balance(type: $type) {
coinType {
repr
}
coinObjectCount
totalBalance
}
}
}
GraphQL uses cursor-based pagination:
query GetObjectsWithPagination(
$owner: SuiAddress!
$first: Int
$after: String
) {
address(address: $owner) {
objects(first: $first, after: $after) {
nodes {
address
version
}
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
}
}
}
To get the next page, use the endCursor as the after parameter:
{
"owner": "0x...",
"first": 50,
"after": "eyJvIjoxMDAsImMiOjUwfQ"
}
Nested Queries
Fetch related data in a single query:
query GetTransactionWithObjects($digest: String!) {
transactionBlock(digest: $digest) {
digest
sender {
address
objects(first: 5) {
nodes {
address
}
}
}
effects {
objectChanges {
nodes {
address
idCreated
idDeleted
}
}
}
}
}
Filtering
Use filters to narrow results:
query GetFilteredObjects($owner: SuiAddress!) {
address(address: $owner) {
objects(
first: 50
filter: {
type: "0x2::coin::Coin"
}
) {
nodes {
address
asMoveObject {
contents {
type {
repr
}
}
}
}
}
}
}
Error Handling
GraphQL returns errors in a standardized format:
{
"data": null,
"errors": [
{
"message": "Object not found",
"locations": [{ "line": 2, "column": 3 }],
"path": ["object"]
}
]
}
Rate Limits
The public GraphQL endpoint has rate limits:
- Query Depth: Maximum 15 levels deep
- Query Nodes: Maximum 500 nodes per query
- Request Timeout: 30 seconds
- Rate Limit: Subject to fair use policies
For production use:
- Run your own indexer with GraphQL
- Use a managed RPC provider
- Implement caching and batching
Next Steps