Events
List indexed events, newest first
Required API-key scope: events:read. The durable counterpart to /events/stream: the same decoded events, newest first, with the checkpoint timestamp each frame on the stream lacks.
Optional filters: kinds (comma-separated, Event suffix optional), sender (hex address), tx_digest, created_after / created_before (RFC3339, inclusive, against onchain_at), order, page_token, page_size.
Ordering. order=id (the default) sorts by events.id descending — log insertion order, which tracks chain order only while rows are inserted as they are indexed. A backfill of historical events breaks that: the rows are correct and their onchain_at is the true checkpoint time, but they are inserted at the head of the log. order=onchain_at sorts by onchain_at descending with events.id breaking ties, which is the order a chronological feed wants. onchain_at is nullable — rows indexed before the column existed have none — and those rows sort last under order=onchain_at, after every dated row, ordered among themselves by id descending. They are still counted and still reachable; pass created_after=1970-01-01T00:00:00Z to exclude them, since either time bound already drops a row with no time.
Paging. next_token is opaque: hand it back as page_token and read nothing into it. Its encoding differs per order — an offset for order=id, a (onchain_at, id) keyset cursor for order=onchain_at — and a token minted under one order is rejected with 400 by the other rather than reinterpreted as a position nobody asked for. Under order=onchain_at the last page can be an empty one, when the page before it happened to be exactly page_size long.
Only kinds the pinned SDK can decode are listed or counted — the indexer stores every event matching the wrapper type, which is strictly more than the catalog models. A page can still come back one or two items short of page_size when a row is permanently undecodable; next_token counts rows scanned rather than items returned, so paging never skips.
Authorizations
Talus API Key in the form key_id.secret. The API also accepts Authorization: ApiKey <key_id.secret>, but the docs UI is configured to send x-api-key.
Query Parameters
Comma-separated event kind names (e.g. WalkAdvancedEvent,DAGCreatedEvent). The trailing
Event suffix is optional. Every name must be in the decodable event catalog; an unknown
one is rejected rather than silently matching nothing. Omit for every kind.
Hex address of the transaction sender that emitted the event.
Every event emitted by one transaction.
Only include events whose checkpoint timestamp is at or after this RFC3339 instant.
Filters onchain_at, so rows indexed before on-chain timestamps existed (null) are
excluded by either bound — there is no honest way to place an event with no time.
Only include events whose checkpoint timestamp is at or before this RFC3339 instant.
Which key orders the feed, newest first either way. id (the default) is log
insertion order; onchain_at is the emitting transaction's checkpoint time, with id
breaking ties. The two agree only while rows are inserted in chain order — a backfill of
historical events breaks that, which is what onchain_at exists for.
A value that is neither is rejected by the query parser before the handler runs, so the
400 carries no x-error-code header and no JSON body — unlike every error this endpoint
raises itself. It is not bodiless, though: axum answers with text/plain naming the
parameter, e.g. Failed to deserialize query string: order: unknown variant `garbage`, expected `id` or `onchain_at` . page_size=abc behaves the same way, and has since
before this parameter existed.
Opaque token from the previous response's next_token. Omit for the first page. Its
encoding depends on order, and a token minted under one order is rejected by the other
rather than reinterpreted: in id order it is a row offset, in onchain_at order an
opaque (onchain_at, id) cursor.
Declared as EventPageToken — the same schema next_token returns — so a generated
client can hand a token back without casting the integer form to a string.
Maximum number of items to return. Defaults to 20.
200application/json
Paginated list of decoded events
Monotonic events.id. Doubles as the stream's last_event_id cursor, so a client can
hand the newest id here straight to /events/stream and continue without a gap.
Canonical event kind name, e.g. DAGCreatedEvent.
Checkpoint timestamp of the emitting transaction; null for rows indexed before the column existed, until a backfill re-fetches them.
The fully decoded NexusEvent (id, generics, data, distribution).
Hex-encoded address of the transaction sender.
next_token for /events.
Both forms are opaque — hand the value back as page_token and nothing else. The shape
differs because the orderings need different cursors, and keeping id order an integer is
what lets every token a client already holds keep working.
Total number of matching rows across all pages, in either order.
400
kinds names an event absent from the decodable catalog, a filter value is invalid, or page_token was not minted under the requested order. These carry the usual {error_code, description} body. A value the query parser cannot read at all — an unrecognised order, a non-numeric page_size — is rejected before the handler by axum's own query rejection, so it carries no x-error-code and no JSON body: the response is text/plain naming the offending parameter, e.g. Failed to deserialize query string: order: unknown variant `garbage`, expected `id` or `onchain_at` .
401
Missing or invalid API key.
403
API key lacks the events:read scope.
500
Internal server error