.md

Streams API

The raw event firehose in chain order, a live tail over server-sent events, and the reorg history. Envelope and cursors are in REST conventions; most apps want the Index API instead.

Streams discovery

GET/v1/streams
Open .md

Lists the Streams routes, the event types and filters /v1/streams/events accepts, and the cursor format. Served ahead of Streams auth, so it never needs a credential.

Returns

The Streams discovery object.

  • 200Route and filter catalog

Raw event firehose

GET/v1/streams/events
Open .md

Canonical chain events in chain order: block height, then transaction position, then event position. Pages are capped at the tip minus a 2-block reorg margin. With no cursor or from_height, the read starts 1000 blocks behind the tip. An empty filtered page still returns a next_cursor past to_height, so a consumer never stalls. Pages at or below tip.finalized_height are immutable: they carry an ETag and answer If-None-Match with 304.

Filters

chainenum#

stacks (default) is the existing Stacks feed, byte-identical to before. bitcoin serves Runes events (rune_etch, rune_mint, rune_transfer, rune_burn — see the RuneStreamsEvent schema) on their own cursor space: a bitcoin cursor only resumes with chain=bitcoin. Stacks-only filters (contract_id, sender, recipient, asset_identifier, filters, clock) 400 on chain=bitcoin; rune and address are bitcoin-only.

2 possible values
stacksbitcoin
typesarray of enum#

Comma-separated event types to include. Default: all of them.

event_typeenum#

One event type, as an alias for types. Mutually exclusive with types; a set must use types.

11 possible values
stx_transferstx_mintstx_burnstx_lockft_transferft_mintft_burnnft_transfernft_mintnft_burnprint
not_typesarray of enum#

Comma-separated event types to exclude, applied after types.

contract_idstring#

Contract principal, or a comma-separated set. Matches print events by the emitting contract and ft/nft events by the asset's contract. Other event types never match.

senderstring#

Principal, or a comma-separated set, matched against the payload's sender. Event types without a sender never match.

recipientstring#

Principal, or a comma-separated set, matched against the payload's recipient.

asset_identifierstring#

Exact <contract>::<asset> match on the payload.

filtersstring#

JSON object of up to 8 labelled filter groups: { "<label>": { types?, contractId?, sender?, recipient?, assetIdentifier? } }. Each value is a string or array of strings. Groups OR together, fields inside a group AND, and the flat filters above still apply to the whole scan. Each event lists the labels it matched in matched. Labels are letters, digits, - and _, 32 characters at most.

runestring#

chain=bitcoin only. A RuneRef: an id (840000:3) or a name, spacers/case ignored (DOG•GO•TO•THE•MOON, dog.go.to.the.moon, doggotothemoon).

addressstring#

chain=bitcoin only. A mainnet address.

Range and paging

limitinteger · 1 to 1000#

Events per page. Default 100. Values above 1000 are clamped to 1000.

cursorstring#

<block_height>:<event_index> from a previous page's next_cursor. Resumes strictly after it. Mutually exclusive with from_cursor and from_height.

from_cursorstring#

Same as cursor. 0:0 starts at genesis.

from_heightinteger#

First block height to read. Mutually exclusive with a cursor. With neither, the read starts 1000 blocks behind the tip.

to_heightinteger#

Last block height to read, inclusive. Always clamped to the tip minus a 2-block reorg margin, which is also the default.

Returns

A cursor envelope. events holds Streams event objects.

  • 200A page of events, the cursor to resume from, the tip it was read against, and any reorgs that touched it
  • 304Finalized page unchanged since the ETag sent in If-None-Match
  • 400A parameter, filter, cursor or body field was refused; code says which
  • 401This bind requires the instance token, and it was missing or wrong
  • 429Rate limited on the hosted API (50/s per IP without a key, 10/s on a free key). Self-hosted instances do not throttle Streams. Retry after Retry-After seconds
  • 503No canonical block indexed yet (CHAIN_DATA_UNAVAILABLE). Wait for the indexer to ingest its first block

Tail the event firehose over SSE

GET/v1/streams/events/stream
Open .md

Server-sent events over the same read as /v1/streams/events, with the same parameters. The server polls every 1.5 seconds by default (STREAMS_SSE_POLL_MS) and writes one frame per event: id is the event's cursor and data is { "event": <StreamsEvent> }, or { "event", "sig", "key_id" } with an ed25519 signature over the event's JSON when the instance has a signing key. After 20 seconds with no events it writes event: ping with empty data; ignore it. With no cursor, from_cursor or from_height, the tail starts at the current tip minus the reorg margin. Last-Event-ID is not read; to resume after a disconnect, reconnect with from_cursor set to the last id you processed.

Filters

chainenum#

stacks (default) is the existing Stacks feed, byte-identical to before. bitcoin serves Runes events (rune_etch, rune_mint, rune_transfer, rune_burn — see the RuneStreamsEvent schema) on their own cursor space: a bitcoin cursor only resumes with chain=bitcoin. Stacks-only filters (contract_id, sender, recipient, asset_identifier, filters, clock) 400 on chain=bitcoin; rune and address are bitcoin-only.

2 possible values
stacksbitcoin
typesarray of enum#

Comma-separated event types to include. Default: all of them.

event_typeenum#

One event type, as an alias for types. Mutually exclusive with types; a set must use types.

11 possible values
stx_transferstx_mintstx_burnstx_lockft_transferft_mintft_burnnft_transfernft_mintnft_burnprint
not_typesarray of enum#

Comma-separated event types to exclude, applied after types.

contract_idstring#

Contract principal, or a comma-separated set. Matches print events by the emitting contract and ft/nft events by the asset's contract. Other event types never match.

senderstring#

Principal, or a comma-separated set, matched against the payload's sender. Event types without a sender never match.

recipientstring#

Principal, or a comma-separated set, matched against the payload's recipient.

asset_identifierstring#

Exact <contract>::<asset> match on the payload.

filtersstring#

JSON object of up to 8 labelled filter groups: { "<label>": { types?, contractId?, sender?, recipient?, assetIdentifier? } }. Each value is a string or array of strings. Groups OR together, fields inside a group AND, and the flat filters above still apply to the whole scan. Each event lists the labels it matched in matched. Labels are letters, digits, - and _, 32 characters at most.

runestring#

chain=bitcoin only. A RuneRef: an id (840000:3) or a name, spacers/case ignored (DOG•GO•TO•THE•MOON, dog.go.to.the.moon, doggotothemoon).

addressstring#

chain=bitcoin only. A mainnet address.

Range and paging

limitinteger · 1 to 1000#

Most events written per poll. Default 100. Values above 1000 are clamped to 1000.

cursorstring#

<block_height>:<event_index> from a previous page's next_cursor. Resumes strictly after it. Mutually exclusive with from_cursor and from_height.

from_cursorstring#

Same as cursor. 0:0 starts at genesis.

from_heightinteger#

First block height to read. Mutually exclusive with a cursor. With neither, the read starts 1000 blocks behind the tip.

to_heightinteger#

Last block height to read, inclusive. Always clamped to the tip minus a 2-block reorg margin, which is also the default.

Returns

text/event-stream

  • 200An open text/event-stream. Frames: id: <cursor> plus data: {"event":{...}} per event, and event: ping after 20 seconds idle
  • 400An unknown query parameter. Other bad values close the stream without a frame
  • 401This bind requires the instance token, and it was missing or wrong
  • 429Rate limited on the hosted API (50/s per IP without a key, 10/s on a free key). Self-hosted instances do not throttle Streams. Retry after Retry-After seconds

Chain reorg history

GET/v1/streams/reorgs
Open .md

Reorgs the indexer recorded, oldest first. Page forward by passing next_since back as since.

Filters

chainenum#

stacks (default) is the existing Stacks feed, byte-identical to before. bitcoin serves Runes events (rune_etch, rune_mint, rune_transfer, rune_burn — see the RuneStreamsEvent schema) on their own cursor space: a bitcoin cursor only resumes with chain=bitcoin. Stacks-only filters (contract_id, sender, recipient, asset_identifier, filters, clock) 400 on chain=bitcoin; rune and address are bitcoin-only.

2 possible values
stacksbitcoin
sincestringrequired#

Where to start. An ISO timestamp returns reorgs detected after it. A <block_height>:<event_index> cursor returns reorgs whose orphaned range ends at or after it. A next_since value (<detected_at>~<id>) resumes after the last reorg delivered.

Range and paging

limitinteger · 1 to 1000#

Reorgs per page. Default 100. Values above 1000 are clamped to 1000.

Returns

A cursor envelope. reorgs holds Reorg objects.

  • 200Reorgs, oldest first
  • 400since is missing or is not a timestamp, cursor or next_since value, or limit is not a positive integer
  • 401This bind requires the instance token, and it was missing or wrong
  • 429Rate limited on the hosted API (50/s per IP without a key, 10/s on a free key). Self-hosted instances do not throttle Streams. Retry after Retry-After seconds

Canonical block by height

GET/v1/streams/canonical/{height}
Open .md

The canonical Stacks block at one height and the Bitcoin block it anchors to. Finalized heights are cached for good and answer If-None-Match with 304; the ETag is the block hash.

Path parameters

heightintegerrequired#

Block height (Stacks by default, Bitcoin with chain=bitcoin).

Query parameters

chainenum#

stacks (default) is the existing Stacks feed, byte-identical to before. bitcoin serves Runes events (rune_etch, rune_mint, rune_transfer, rune_burn — see the RuneStreamsEvent schema) on their own cursor space: a bitcoin cursor only resumes with chain=bitcoin. Stacks-only filters (contract_id, sender, recipient, asset_identifier, filters, clock) 400 on chain=bitcoin; rune and address are bitcoin-only.

2 possible values
stacksbitcoin

Returns

The Streams canonical block object.

  • 200The canonical block. chain=bitcoin returns a StreamsBitcoinCanonicalBlock (btc block hash, no burn-chain fields) instead.
  • 304Block unchanged since the ETag sent in If-None-Match
  • 400height is not a non-negative integer
  • 401This bind requires the instance token, and it was missing or wrong
  • 404No canonical block at that height yet
  • 429Rate limited on the hosted API (50/s per IP without a key, 10/s on a free key). Self-hosted instances do not throttle Streams. Retry after Retry-After seconds

Current chain tip

GET/v1/streams/tip
Open .md

The newest canonical block this instance has indexed, the finality boundary, and how far back this caller can seek. Never cached.

Query parameters

chainenum#

stacks (default) is the existing Stacks feed, byte-identical to before. bitcoin serves Runes events (rune_etch, rune_mint, rune_transfer, rune_burn — see the RuneStreamsEvent schema) on their own cursor space: a bitcoin cursor only resumes with chain=bitcoin. Stacks-only filters (contract_id, sender, recipient, asset_identifier, filters, clock) 400 on chain=bitcoin; rune and address are bitcoin-only.

2 possible values
stacksbitcoin

Returns

The Streams tip object.

  • 200The tip. chain=bitcoin returns a StreamsBitcoinTip (no burn-chain or retention fields) instead.
  • 401This bind requires the instance token, and it was missing or wrong
  • 429Rate limited on the hosted API (50/s per IP without a key, 10/s on a free key). Self-hosted instances do not throttle Streams. Retry after Retry-After seconds
  • 503No canonical block indexed yet (CHAIN_DATA_UNAVAILABLE). Wait for the indexer to ingest its first block
Open .md

Catalog of the Streams routes and filters.

Returned by Streams discovery

Attributes

routesarray of object#

Each route with its method, a one-line description, and for the event feed its event types and filters.

cursorobject#

Cursor format and resume semantics.

reorgs_shapeobject#

Field names and types of a reorg record.

Open .md

One raw chain event. payload is the node's event body; its fields depend on event_type.

Returned by Raw event firehose

Attributes

cursorstringrequired#

<block_height>:<event_index>. Pass as cursor or from_cursor.

block_heightintegerrequired#

Stacks block the event landed in.

block_hashstringrequired#

That block's hash.

burn_block_heightintegerrequired#

Bitcoin block that block anchors to.

tx_idstringrequired#

Transaction that emitted the event.

tx_indexintegerrequired#

Its position in the block.

event_indexintegerrequired#

The event's position among the block's Streams events, from 0.

event_typeenumrequired#

The event's type.

11 possible values
stx_transferstx_mintstx_burnstx_lockft_transferft_mintft_burnnft_transfernft_mintnft_burnprint
contract_idstring · nullablerequired#

Emitting contract for print, asset contract for ft/nft events, null otherwise.

payloadobjectrequired#

The event body. Prints carry topic, value and contract_id; transfers carry sender, recipient, amount or value, and asset_identifier.

tsstring · date-timerequired#

The block's timestamp.

canonicalboolean#

Always true: the firehose serves the canonical chain only.

matchedarray of string#

Labels from filters this event satisfied. Present only when the request used filters.

finalizedbooleanrequired#

true when the block is at or below tip.finalized_height and can no longer reorg.

Open .md

A fork the indexer rolled back. Rows inside orphaned_range were replaced; undo anything you committed from them.

Returned by Chain reorg history

Attributes

idstring#

Reorg id.

detected_atstring · date-time#

When the indexer saw the fork.

fork_point_heightinteger#

First block height the new fork replaced. Undo rows at or above it.

old_index_block_hashstring · nullable#

Index block hash of the abandoned tip.

new_index_block_hashstring · nullable#

Index block hash of the winning tip.

orphaned_rangeobject#

First and last cursor of the rows that were replaced.

new_canonical_tipstring#

Cursor of the new canonical tip.

Open .md

The canonical Stacks block at a height.

Returned by Canonical block by height

Attributes

block_heightintegerrequired#

Stacks block height.

block_hashstringrequired#

Stacks block hash.

burn_block_heightintegerrequired#

Bitcoin block it anchors to.

burn_block_hashstring · nullablerequired#

That Bitcoin block's hash.

is_canonicalbooleanrequired#

Always true.

Open .md

The newest canonical block and how far back this caller can read.

Returned by Current chain tip

Attributes

block_heightintegerrequired#

Highest canonical Stacks block this instance has indexed.

block_hashstringrequired#

That block's hash.

burn_block_heightintegerrequired#

The Bitcoin block it anchors to.

finalized_heightintegerrequired#

Highest Stacks block whose Bitcoin anchor has 6 confirmations. Rows at or below it are immutable.

lag_secondsintegerrequired#

Seconds since the tip block was produced.

oldest_seekable_heightinteger · nullablerequired#

Always null — every account reads full history. Rows past the monthly allowance are a paid read, not a blocked one.

oldest_cursorstring · nullablerequired#

Always null — see oldest_seekable_height.

Edit on GitHub