Skip to content

Build

API reference

In the codeYou will have the complete route surface, its parameters, its responses, and a copyable request for each one.

This page is generated, not written.

npm run openapi:emit boots the real Nest application with a stub database, asks Swagger for the document the controllers describe, and writes it to site/src/data/openapi.json. Everything below is rendered from that file, and a test in the indexer’s own suite fails if a route is added, removed, or renamed without regenerating it.

The same document is served live by a running instance at /docs as an interactive Swagger UI and at /docs-json as raw JSON, so there is one contract in three places rather than three descriptions that drift.

24 operationsread onlyversion 0.1.0

Verified surface

Answers only while two independently signed agreement tuples match at the same canonical height. Everything else is HTTP 503.

GET/tandem/verified/addresses/{address}

Verified carrier activity for an address

Accepts the native SegWit P2WSH address of a carrier. The checksum is validated against the deployment network and the 32-byte witness program is matched against a database-generated projection of the stored keys, so no separately supplied address label is trusted.

Parameters

limitquery
Row cap between 1 and 200. Anything outside that range is rejected.default 50
addresspath
Bech32 P2WSH address. The prefix must match the deployment network.

Responses

200
Carriers controlled by that address, newest first. Wrapped with the agreement both pipelines signed.
400
`address is not a valid carrier P2WSH address`.
503
Verification did not hold. Returned when this pipeline is not ready at a canonical height, pipeline B is unreachable or slow, either envelope is malformed, either signing key is untrusted, either signature fails, any of the nine compared fields differ, or the agreement changed between the two checks around the read.

Try it

curl -sS "http://127.0.0.1:3021/tandem/verified/addresses/tb1q..."

GET/tandem/verified/conflicts

Verified conflict listing

Recorded cases where more than one transaction competed for the same outpoint.

Parameters

limitquery
Row cap between 1 and 200. Anything outside that range is rejected.default 50

Responses

200
Conflicts, newest first. Wrapped with the agreement both pipelines signed.
503
Verification did not hold. Returned when this pipeline is not ready at a canonical height, pipeline B is unreachable or slow, either envelope is malformed, either signing key is untrusted, either signature fails, any of the nine compared fields differ, or the agreement changed between the two checks around the read.

Try it

curl -sS "http://127.0.0.1:3021/tandem/verified/conflicts"

GET/tandem/verified/events/{txid}

Verified canonical events for a transaction

Parameters

txidpath
Transaction id in the usual lowercase display order, 64 hexadecimal characters.

Responses

200
The transaction id and its ordered events. Wrapped with the agreement both pipelines signed.
400
`txid must be 32-byte hex`.
404
`transaction not found`.
503
Verification did not hold. Returned when this pipeline is not ready at a canonical height, pipeline B is unreachable or slow, either envelope is malformed, either signing key is untrusted, either signature fails, any of the nine compared fields differ, or the agreement changed between the two checks around the read.

Try it

curl -sS "http://127.0.0.1:3021/tandem/verified/events/9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d"

GET/tandem/verified/invalid-events

Verified listing of observations that produced no state

Parameters

limitquery
Row cap between 1 and 200. Anything outside that range is rejected.default 50

Responses

200
Invalid observations, newest first. Wrapped with the agreement both pipelines signed.
503
Verification did not hold. Returned when this pipeline is not ready at a canonical height, pipeline B is unreachable or slow, either envelope is malformed, either signing key is untrusted, either signature fails, any of the nine compared fields differ, or the agreement changed between the two checks around the read.

Try it

curl -sS "http://127.0.0.1:3021/tandem/verified/invalid-events"

GET/tandem/verified/mempool

Verified mempool overlay

Unconfirmed observations kept in their own table. They never contribute to canonical state, counters, or roots.

Parameters

limitquery
Row cap between 1 and 200. Anything outside that range is rejected.default 50

Responses

200
Mempool overlay rows, most recently seen first. Wrapped with the agreement both pipelines signed.
503
Verification did not hold. Returned when this pipeline is not ready at a canonical height, pipeline B is unreachable or slow, either envelope is malformed, either signing key is untrusted, either signature fails, any of the nine compared fields differ, or the agreement changed between the two checks around the read.

Try it

curl -sS "http://127.0.0.1:3021/tandem/verified/mempool"

GET/tandem/verified/objects

Verified object listing

Objects newest first by creation height, then by object key.

Parameters

limitquery
Row cap between 1 and 200. Anything outside that range is rejected.default 50

Responses

200
A page of objects. Wrapped with the agreement both pipelines signed.
503
Verification did not hold. Returned when this pipeline is not ready at a canonical height, pipeline B is unreachable or slow, either envelope is malformed, either signing key is untrusted, either signature fails, any of the nine compared fields differ, or the agreement changed between the two checks around the read.

Try it

curl -sS "http://127.0.0.1:3021/tandem/verified/objects"

GET/tandem/verified/objects/{key}

Verified object detail with its chapters

Parameters

keypath
The 32-byte object key as 64 lowercase hex characters.

Responses

200
One object and its ordered chapters. Wrapped with the agreement both pipelines signed.
400
`object key must be 32-byte hex`.
404
`object not found`. A missing row stays a 404 and is not converted into a verification failure.
503
Verification did not hold. Returned when this pipeline is not ready at a canonical height, pipeline B is unreachable or slow, either envelope is malformed, either signing key is untrusted, either signature fails, any of the nine compared fields differ, or the agreement changed between the two checks around the read.

Try it

curl -sS "http://127.0.0.1:3021/tandem/verified/objects/4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f"

GET/tandem/verified/reorgs

Verified reorganization journal

Parameters

limitquery
Row cap between 1 and 200. Anything outside that range is rejected.default 50

Responses

200
Completed rollbacks, newest first. Wrapped with the agreement both pipelines signed.
503
Verification did not hold. Returned when this pipeline is not ready at a canonical height, pipeline B is unreachable or slow, either envelope is malformed, either signing key is untrusted, either signature fails, any of the nine compared fields differ, or the agreement changed between the two checks around the read.

Try it

curl -sS "http://127.0.0.1:3021/tandem/verified/reorgs"

GET/tandem/verified/stats

Verified aggregate counts

Responses

200
Aggregate counters. Wrapped with the agreement both pipelines signed.
503
Verification did not hold. Returned when this pipeline is not ready at a canonical height, pipeline B is unreachable or slow, either envelope is malformed, either signing key is untrusted, either signature fails, any of the nine compared fields differ, or the agreement changed between the two checks around the read.

Try it

curl -sS "http://127.0.0.1:3021/tandem/verified/stats"

GET/tandem/verified/status

Verified deployment and canonical tip

The same status payload as the direct surface, released only while two independently signed agreement tuples match at the same canonical height.

Responses

200
Deployment binding, canonical tip, and mempool count. Wrapped with the agreement both pipelines signed.
503
Verification did not hold. Returned when this pipeline is not ready at a canonical height, pipeline B is unreachable or slow, either envelope is malformed, either signing key is untrusted, either signature fails, any of the nine compared fields differ, or the agreement changed between the two checks around the read.

Try it

curl -sS "http://127.0.0.1:3021/tandem/verified/status"

GET/tandem/verified/transactions/{txid}

Verified transaction detail and its events

Parameters

txidpath
Transaction id in the usual lowercase display order, 64 hexadecimal characters.

Responses

200
The transaction record and its events. Wrapped with the agreement both pipelines signed.
400
`txid must be 32-byte hex`.
404
`transaction not found`.
503
Verification did not hold. Returned when this pipeline is not ready at a canonical height, pipeline B is unreachable or slow, either envelope is malformed, either signing key is untrusted, either signature fails, any of the nine compared fields differ, or the agreement changed between the two checks around the read.

Try it

curl -sS "http://127.0.0.1:3021/tandem/verified/transactions/9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d"

Direct surface

This pipeline's own view. Useful for operating and debugging one node. It carries no claim that any other implementation agrees.

GET/tandem/agreement/{height}

This pipeline's signed agreement tuple at a height

Returns the Ed25519 envelope over the RFC 8785 canonical JSON of the tuple for one canonical height. This is the endpoint an independent pipeline calls to obtain a second opinion, and the same shape this pipeline expects from pipeline B.

Parameters

heightpath
Canonical block height.

Responses

200
The signed agreement envelope.

Try it

curl -sS "http://127.0.0.1:3021/tandem/agreement/1008"

GET/tandem/carriers/{txid}/{vout}

Carrier state at an exact outpoint

Returns the carrier record for one outpoint, including the height that created it and the transaction that spent it if it is no longer current.

Parameters

voutpath
Output index. A carrier is always output index 1.
txidpath
Transaction id in the usual lowercase display order, 64 hexadecimal characters.

Responses

200
The carrier record.
400
`txid must be 32-byte hex` or `vout is invalid`.
404
`carrier not found`.

Try it

curl -sS "http://127.0.0.1:3021/tandem/carriers/9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d/1"

GET/tandem/events/{txid}

Canonical events for one transaction

Returns every event this transaction produced, ordered by event index. A known transaction that produced no event returns an empty list rather than a 404.

Parameters

txidpath
Transaction id in the usual lowercase display order, 64 hexadecimal characters.

Responses

200
The transaction id and its ordered events.
400
`txid must be 32-byte hex`.
404
`transaction not found`.

Try it

curl -sS "http://127.0.0.1:3021/tandem/events/9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d"

GET/tandem/invalid-events

Observations that produced no state

Validity class 0 events, newest first. These record a rejected observation and its reason code without mutating any object.

Parameters

limitquery
Row cap between 1 and 200. Anything outside that range is rejected.default 50

Responses

200
Invalid observations, newest first.

Try it

curl -sS "http://127.0.0.1:3021/tandem/invalid-events"

GET/tandem/objects/{objectKey}

One object and its chapters

Looks up an object by its 32-byte binary key and returns its current state together with every chapter in sequence order.

Parameters

objectKeypath
The 32-byte object key as 64 lowercase hexadecimal characters.

Responses

200
The object and its ordered chapters.
400
`object key must be 32-byte hex`.
404
`object not found`.

Try it

curl -sS "http://127.0.0.1:3021/tandem/objects/4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f4f"

GET/tandem/readiness

Readiness snapshot with the reasons behind it

Same evaluation as `GET /ready`, returned under the protocol prefix. Every failing gate is listed in `reasons`.

Responses

200
Every readiness gate passed.
503
At least one gate failed. The body is the full snapshot including `reasons`.

Try it

curl -sS "http://127.0.0.1:3021/tandem/readiness"

GET/tandem/reorgs

Reorganization journal

One row per completed rollback, newest first, recording the old tip, the common ancestor, the new tip, and how many blocks were rolled back.

Parameters

limitquery
Row cap between 1 and 200. Anything outside that range is rejected.default 50

Responses

200
Completed rollbacks, newest first.

Try it

curl -sS "http://127.0.0.1:3021/tandem/reorgs"

GET/tandem/stats

Aggregate counts

Object, chapter, invalid event, and unresolved conflict counts computed directly from canonical tables.

Responses

200
Aggregate counters.

Try it

curl -sS "http://127.0.0.1:3021/tandem/stats"

GET/tandem/status

Bound deployment and canonical tip

Returns the immutable deployment binding, the highest canonical block this pipeline has recorded, and the mempool overlay row count. `canonicalTip` is null until a block has been recorded.

Responses

200
Deployment binding, canonical tip, and mempool count.

Try it

curl -sS "http://127.0.0.1:3021/tandem/status"

Operations

Liveness, readiness, and metrics. Gate traffic on readiness, never on liveness.

GET/health

Process liveness only

Answers as long as the process is running. It says nothing about dependencies, canonical state, or agreement. The container health check probes this endpoint, so a container can report healthy while `/ready` is refusing traffic. Gate traffic on `/ready`.

Responses

200
The process is up.

Try it

curl -sS "http://127.0.0.1:3021/health"

GET/metrics

Prometheus text exposition

Default Node process metrics under the `tandem_indexer_` prefix, plus `tandem_indexer_ready` and `tandem_indexer_canonical_height`. Those two gauges are refreshed by a request to `/ready`, so scrape readiness as well as metrics.

Responses

200
Prometheus exposition format.

Try it

curl -sS "http://127.0.0.1:3021/metrics"

GET/ready

Fail-closed dependency and canonical-state readiness

Evaluates ten gates and reports every one that failed. Readiness requires valid configuration, a reachable database, a reachable Bitcoin Core on the expected chain that is out of initial block download, a known node height, a canonical tip within the configured lag, a checkpoint at exactly that tip, and a configured signing boundary. Reading this endpoint also refreshes the Prometheus gauges.

Responses

200
Every gate passed.
503
At least one gate failed. The body is the full snapshot and `reasons` names each failure.

Try it

curl -sS "http://127.0.0.1:3021/ready"

Every route is read only. There is no POST, PUT, PATCH, or DELETE anywhere in the service. State changes come from Bitcoin, never from an API call. If you are looking for an endpoint that creates an object, there is not one and there will not be one.

There is no authentication. No API key, no bearer token, no rate limiting, no CORS policy. That applies to the data routes, to /metrics, to /ready, and to /docs. Access control belongs to whatever you put in front of the service, and treating the absence of a lock as permission to expose it publicly would be a mistake.

For how to handle the responses in practice, including the case where the verified surface closes, read the integration guide. For the exact error strings, read error handling.