Use code JSON50 for 50% off your first month of any plan Code JSON50 - 50% off your first month
Skip to content

Checkpoint Streams

Part of the gRPC Gateway: Checkpoint Streams extends the standard SubscribeCheckpoints subscription. Everything on this page works with stock Sui gRPC clients — no custom SDK required.

Overview

A stock Sui node's SubscriptionService/SubscribeCheckpoints only streams checkpoints from the moment you connect. Inodra Checkpoint Streams lets you start that same stream from any checkpoint in history — genesis, last month, or five minutes ago — and follow it seamlessly all the way to the live tip and beyond, on a single connection.

Think of it as a Kafka-style "consume from offset," for Sui checkpoints.

Same fields, historical and live

Historical checkpoints return the same field set as the live tip for a given read_mask — structured fields and transactions.balance_changes included. The stream is consistent end to end; the field set does not change as you cross from historical to live. (Two rare exceptions track the chain itself, not a limitation of history: for sponsored / multi-agent transactions the order of signatures may differ from a live read, and the top-level checkpoint signature — the validator certificate — can take more than one valid form.)

     Your chosen start                  live tip
           │                                │
  ─────────┼──────── full history ──────────┼──── live ──►
           └──────────── one gRPC stream ───┴───────────►

Quick Start

Add one header to a standard SubscribeCheckpoints call:

bash
grpcurl -H "x-api-key: YOUR_API_KEY" \
  -H "x-inodra-start-checkpoint: 50000000" \
  -d '{"read_mask":{"paths":["sequence_number","digest"]}}' \
  mainnet-grpc.inodra.com:443 sui.rpc.v2.SubscriptionService/SubscribeCheckpoints

The stream begins at checkpoint 50000000 and runs forward continuously — through history, across the live boundary, and on as new checkpoints are produced. Without the header, the call behaves exactly like a normal node subscription (live tip only).

Headers

HeaderRequiredMeaning
x-inodra-start-checkpointYesCheckpoint sequence number to start from (inclusive)
x-inodra-end-checkpointNoStop after this checkpoint (inclusive); the stream then completes OK

A bounded range (start + end) gives you a reproducible replay: same range, same checkpoints, clean completion. Requests with end < start are rejected with INVALID_ARGUMENT.

Delivery Guarantees

  • Strictly ordered: checkpoints arrive as start, start+1, start+2, … — never out of order.
  • Exactly-once per connection: no duplicates and no gaps within a single stream.
  • Cursor on every message: each SubscribeCheckpointsResponse carries its cursor (the checkpoint sequence number).

Reconnecting

The server holds no session state. If your connection drops, reconnect with x-inodra-start-checkpoint set to your last processed cursor + 1:

javascript
let lastCursor = await loadCheckpointFromMyDatabase()

function connect() {
  const meta = {
    'x-api-key': API_KEY,
    'x-inodra-start-checkpoint': String(lastCursor + 1)
  }
  // ... subscribe, and on each message: process it, then persist msg.cursor
}

Across reconnects this gives you at-least-once delivery — make your processing idempotent on the checkpoint sequence number (most indexers already are).

Field Selection (read_mask)

The read_mask works exactly as it does on a Sui node — request only the fields you need:

json
{
  "read_mask": {
    "paths": [
      "sequence_number",
      "digest",
      "summary.bcs.value",
      "contents.bcs.value",
      "transactions.transaction.bcs.value",
      "transactions.effects.bcs.value",
      "transactions.events.bcs.value",
      "objects.objects.bcs.value"
    ]
  }
}

Good to know for historical checkpoints:

  • Structured fields work historically. A mask requesting structured fields (object owners/types, transaction kinds, effects, transactions.balance_changes, …) is honored for historical checkpoints too — they come back populated and matching the live node, not sparse.
  • BCS is still the fast path. If you only need the *.bcs.value payloads (what most indexing frameworks decode locally), request just those — it's the lightest, highest-throughput mode.

Typical Patterns

Bootstrap an indexer from genesis

bash
grpcurl -H "x-api-key: YOUR_API_KEY" \
  -H "x-inodra-start-checkpoint: 0" \
  -d '{"read_mask":{"paths":["sequence_number","contents.bcs.value","transactions.transaction.bcs.value","transactions.effects.bcs.value"]}}' \
  mainnet-grpc.inodra.com:443 sui.rpc.v2.SubscriptionService/SubscribeCheckpoints

One stream takes the indexer from empty to fully synced to live-following — there is no separate "backfill phase" to orchestrate.

Replay an exact range

bash
grpcurl -H "x-api-key: YOUR_API_KEY" \
  -H "x-inodra-start-checkpoint: 86400000" \
  -H "x-inodra-end-checkpoint: 86500000" \
  -d '{"read_mask":{"paths":["sequence_number","digest"]}}' \
  mainnet-grpc.inodra.com:443 sui.rpc.v2.SubscriptionService/SubscribeCheckpoints

The stream completes with OK after the end checkpoint — ideal for audits, reconciliation windows, and re-running a pipeline over a known range.

Throughput & Pacing

Historical replay is delivered as fast as your client consumes it, with adaptive pacing that keeps the flow continuous rather than bursty. Slow consumers are fine: gRPC flow control applies backpressure end to end, and the stream stays gap-free at whatever rate you process. There is no penalty for processing inline — the next checkpoint simply waits for you.

Errors

StatusMeaning
INVALID_ARGUMENTMalformed header value, or end < start
NOT_FOUNDThe requested checkpoint isn't available from any source
RESOURCE_EXHAUSTEDConcurrent stream limit reached — close idle streams or contact us to raise
UNAVAILABLETransient upstream issue — reconnect from your last cursor + 1
INTERNALA corrupt archive chunk the tip-bucket fallback also couldn't recover; contact support
UNIMPLEMENTEDCursor streaming isn't enabled on this endpoint

Billing

Checkpoint Streams is billed per delivered checkpoint, with historical and live-tip delivery metered separately. See pricing for current rates and plan limits.

  • gRPC Gateway — endpoints, authentication, TLS, server reflection
  • Warp Streams — filtered real-time events/addresses/coins/objects over WebSocket/SSE (use Warp when you want filtered live data; use Checkpoint Streams when you want every checkpoint, including history)
  • Webhooks — push notifications to your HTTPS endpoint

Released under the MIT License.