Arcade · BSV Transaction Broadcaster

The world's most scalable transaction broadcast manager

A high-throughput, callback-driven gateway for submitting BSV transactions, tracking their lifecycle, and streaming status updates to subscribers in real time.

API Reference

Click any endpoint to expand its full request / response contract, headers, and examples. The defaults below cover the everyday submit-and-track flow.

API server base URL
—
Content Encoding
UTF-8
Status Codes
2xx · 4xx · 5xx

Chaintracks API

Chaintracks is a separate Arcade listener for block-header tracking. Its default local base URL is http://localhost:8083; use the Chaintracks Service or Ingress URL configured by your deployment rather than the API server base URL above. New integrations should use /chaintracks/v2. The /chaintracks/v1 surface remains for legacy RPC-compatible clients.

Default listener
http://<arcade-host>:8083
Availability check
GET /health
Current API
/chaintracks/v2
curl -fsS http://localhost:8083/health
# {"status":"ok"}

curl -fsS http://localhost:8083/chaintracks/v2/network
curl -fsS http://localhost:8083/chaintracks/v2/height
curl -fsS http://localhost:8083/chaintracks/v2/tip

Operational check: /health (and its /ready alias) confirms that the Chaintracks listener is live. A successful /network or /height request confirms that the Chaintracks API is serving data. /tip is a stronger chain-state check: it returns a header and X-Block-Height once a tip is available, or 404 before then.

Current v2 endpoints

All paths below are GET requests relative to the Chaintracks base URL.

PathPurpose
/chaintracks/v2/networkConfigured network.
/chaintracks/v2/heightCurrent best-chain height known to Chaintracks.
/chaintracks/v2/tipCurrent tip header as JSON.
/chaintracks/v2/tip.binCurrent serialized 80-byte tip header.
/chaintracks/v2/headers?height={height}&count={count}Consecutive serialized headers as raw bytes.
/chaintracks/v2/headers.bin?height={height}&count={count}The same header run, with start-height and header-count response headers.
/chaintracks/v2/header/height/{height}Header at a height as JSON.
/chaintracks/v2/header/height/{height}.binSerialized 80-byte header at a height.
/chaintracks/v2/header/hash/{hash}Header by block hash as JSON.
/chaintracks/v2/header/hash/{hash}.binSerialized 80-byte header by block hash.
/chaintracks/v2/tip/streamServer-Sent Events stream of the current and future tip headers.
/chaintracks/v2/reorg/streamServer-Sent Events stream of reorganization events.
/chaintracks/{file}Range-enabled download of an individual stored header file.

Legacy v1 compatibility endpoints

V1 legacy RPC requests return a {"status":"success","value":...} envelope (or an error envelope). The non-stream JSON and binary v2-style endpoints above are also available when only v2 is replaced with v1; the two SSE endpoints are v2-only.

PathPurpose
/chaintracks/v1/getChainConfigured network.
/chaintracks/v1/getPresentHeightCurrent best-chain height.
/chaintracks/v1/findChainTipHashHexCurrent tip hash.
/chaintracks/v1/findChainTipHeaderHexCurrent tip header.
/chaintracks/v1/findHeaderHexForHeight?height={height}Header by height.
/chaintracks/v1/findHeaderHexForBlockHash?hash={hash}Header by block hash.
/chaintracks/v1/getHeaders?height={height}&count={count}Consecutive headers in a hex-encoded response value.

Need schemas and response details? The OpenAPI reference covers the legacy v1 RPC endpoints and most v2 operations. This page also records the v1 direct-path compatibility aliases, /headers.bin, and stored-header-file download paths that are not represented there.

Reports liveness of the API server process and the upstream Datahub endpoints it depends on. Suitable as a Kubernetes liveness probe. blockHeight is this instance's processed chain-tip height — a freshness signal (datahub_urls[].healthy is reachability-only), letting clients detect a stale chain view and route around it. Each datahub_urls entry also carries the transaction policy that node advertised, so a policy rejection can be traced to the endpoint that enforced it; policy is absent for endpoints no node_status has announced.

Response

200 OK
{
  "healthy": true,
  "version": "v0.8.0",
  "status": "ok",
  "blockHeight": 958779,
  "datahub_urls": [
    {
      "url": "https://...",
      "source": "discovered",
      "healthy": true,
      "policy": {
        "miningFee": { "satoshis": 100, "bytes": 1000 },
        "maxtxsizepolicy": 100000000,
        "maxscriptsizepolicy": 500000,
        "maxtxsigopscountspolicy": 4294967295
      }
    }
  ]
}

Indicates that the process has finished start-up and is ready to accept traffic. Suitable as a Kubernetes readiness probe.

Response

200 OK
{
  "status": "ready"
}

Returns Arcade's effective transaction policy in the ARC schema so clients can discover the fee rate and size limits before building transactions. Every value reflects exactly what intake enforces. When the operator hasn't pinned a fee, miningFee tracks the lowest fee the network will accept — the minimum advertised across peer node_status announcements — and Arcade enforces that same floor at intake; it falls back to the built-in default until a peer is heard. Also served at /v1/policy.

Response

200 OK
{
  "policy": {
    "miningFee": { "satoshis": 100, "bytes": 1000 },
    "maxtxsizepolicy": 10485760,
    "maxscriptsizepolicy": 500000,
    "maxtxsigopscountspolicy": 4294967295,
    "standardFormatSupported": true
  },
  "timestamp": "2026-08-07T12:00:00Z"
}

Returns the current lifecycle state of a previously submitted transaction, including its merkle path once mined. With ?callbackToken=<token> the response adds a callbacks array: the webhook delivery state (attempts, lastAttemptAt, lastResult, nextRetryAt) of that token's submissions — lastResult "status 403" with climbing attempts means arcade is POSTing and the receiver's edge is refusing.

Headers

HeaderRequirementDescription
Accept Optional application/json (default).

Response

200 OK
{
  "txid": "<hex>",
  "txStatus": "SEEN_ON_NETWORK",
  "status": "SEEN_ON_NETWORK",
  "timestamp": "2026-05-20T12:00:00Z",
  "blockHash": "<hex|null>",
  "blockHeight": 870123,
  "merklePath": "<BUMP hex|null>",
  "extraInfo": "",
  "competingTxs": [],
  "callbacks": [
    {
      "callbackUrl": "https://...",
      "lastDeliveredStatus": "SEEN_ON_NETWORK",
      "attempts": 14,
      "lastAttemptAt": "2026-05-20T12:00:00Z",
      "lastResult": "status 403",
      "nextRetryAt": "2026-05-20T12:05:00Z"
    }
  ]
}

Long-lived Server-Sent Events stream that pushes lifecycle updates for every transaction submitted under the supplied callback token. Hosted by Arcade's standalone SSE service — a separate listener from the main API (default port 8082, fronted by its own Kubernetes Service in production). CORS is permissive on this endpoint so browsers can connect directly with the EventSource API.

Headers

HeaderRequirementDescription
Accept Recommended text/event-stream
Last-Event-ID Optional Nanosecond timestamp returned by Arcade as the id of the last event the client received. Triggers a catchup replay of every status update that occurred strictly after this timestamp. Omit on first connect to receive the current persisted status of every txid registered under the token.

Request Body

?callbackToken=<token> the same opaque token sent as X-CallbackToken when submitting transactions. Scopes the stream to that token's transactions.

GET /events?callbackToken=my-token

Open a stream from JavaScript. Last-Event-ID is handled automatically by the browser on reconnect.

const es = new EventSource(
  "https://arcade.example.com/events?callbackToken=my-token"
);
es.addEventListener("status", (e) => {
  const status = JSON.parse(e.data);
  console.log(status.txid, status.txStatus);
});

Tail the stream from a shell.

curl -N "https://arcade.example.com/events?callbackToken=my-token"

Response

200 OK · text/event-stream
id: 1716205200123456789
event: status
data: {"txid":"<hex>","txStatus":"SEEN_ON_NETWORK","timestamp":"2026-05-20T12:00:00Z"}

id: 1716205260987654321
event: status
data: {"txid":"<hex>","txStatus":"MINED","timestamp":"2026-05-20T12:01:00Z"}

: keepalive

Submits one Bitcoin SV transaction for validation, propagation, and lifecycle tracking. Synchronous policy validation runs before the 202 is returned; fee and script checks are delegated to the network. Pick the body encoding that matches your client — raw bytes are the most efficient.

Headers

HeaderRequirementDescription
Content-Type Required One of application/octet-stream, text/plain (hex), or application/json — see the request body tabs below.
X-CallbackUrl Optional Webhook URL Arcade should POST status events to as this transaction progresses through the network. Must be a public HTTPS endpoint; private/loopback hosts are rejected unless the deployment is configured to allow them. Every POST carries User-Agent: arcade-webhook/<version> — allowlist the arcade-webhook/ prefix so edge bot rules don't reject deliveries; per-submission delivery health is inspectable via GET /tx/:txid?callbackToken=<token>.
X-CallbackToken Recommended Opaque bearer token. Sent on every outbound webhook as Authorization: Bearer <token>, and used to scope Server-Sent Events streams when the client subscribes via SSE.
X-FullStatusUpdates Optional Set to "true" to receive every status transition (RECEIVED, SEEN_ON_NETWORK, SEEN_ON_MULTIPLE_NODES, MINED, IMMUTABLE). Default behavior delivers only terminal/notable transitions.

Request Body

Raw serialized transaction bytes. Most efficient — no encoding overhead. Supports Extended Format; the canonical txid is derived from the parsed transaction structure, not from a hash of the wire bytes.

<binary raw transaction bytes>

Hex-encoded serialized transaction as a UTF-8 string. Whitespace is trimmed before decoding.

0100000001abc...def00000000

JSON envelope carrying the hex-encoded transaction. Useful for clients that cannot easily send a raw or text/plain body.

{
  "rawTx": "0100000001abc...def00000000"
}

Response

202 Accepted
{
  "txid": "<hex>",
  "status": 202,
  "txStatus": "RECEIVED"
}

// Idempotent re-submit of a txid Arcade has already seen (txStatus echoes the existing state):
{
  "txid": "<hex>",
  "status": 202,
  "txStatus": "SEEN_ON_NETWORK"
}

Submits a batch of concatenated raw transactions in a single HTTP request. Each transaction is parsed, validated, dedup-CAS'd, and published as part of one fan-out. Bodies are capped at 256 MiB.

Headers

HeaderRequirementDescription
Content-Type Required application/octet-stream — the only encoding accepted for batches.
X-CallbackUrl Optional Webhook URL Arcade should POST status events to as this transaction progresses through the network. Must be a public HTTPS endpoint; private/loopback hosts are rejected unless the deployment is configured to allow them. Every POST carries User-Agent: arcade-webhook/<version> — allowlist the arcade-webhook/ prefix so edge bot rules don't reject deliveries; per-submission delivery health is inspectable via GET /tx/:txid?callbackToken=<token>.
X-CallbackToken Recommended Opaque bearer token. Sent on every outbound webhook as Authorization: Bearer <token>, and used to scope Server-Sent Events streams when the client subscribes via SSE.
X-FullStatusUpdates Optional Set to "true" to receive every status transition (RECEIVED, SEEN_ON_NETWORK, SEEN_ON_MULTIPLE_NODES, MINED, IMMUTABLE). Default behavior delivers only terminal/notable transitions.

Request Body

Concatenated raw transaction bytes. No length prefixes or separators — each transaction is parsed sequentially using the stream parser.

<binary raw tx 1><binary raw tx 2>...<binary raw tx N>

Response

202 Accepted
{
  "submitted": 42,
  "duplicates": 3,
  "total": 45
}

Internal endpoint used by the Merkle Service to deliver SEEN_ON_NETWORK, SEEN_ON_MULTIPLE_NODES, STUMP and BLOCK_PROCESSED events. Bearer authentication is mandatory; the deployment refuses to start without a configured callback token.

Headers

HeaderRequirementDescription
Authorization Required Bearer <callback_token>. Compared in constant time against the configured token.
Content-Type Required application/json

Request Body

CallbackMessage envelope; the type field discriminates the variant.

{
  "type": "SEEN_ON_NETWORK",
  "txid": "<hex>",
  "txids": ["<hex>", "..."],
  "blockHash": "<hex>",
  "subtreeIndex": 0,
  "stump": "<base64>"
}

Response

200 OK
(empty body)

Lists block processing milestones (header seen, BLOCK_PROCESSED received, compound BUMP built) in descending-height order. Paginates via a height-cursor; pass the lowest height returned from the previous page as before-height to fetch the next page.

Headers

HeaderRequirementDescription
Accept Optional application/json (default).

Request Body

?limit=<int> default 50, max 200. ?before-height=<int> cursor — pass the lowest height from the previous page.

GET /api/v1/blocks/processing-status?limit=50&before-height=870000

Response

200 OK
{
  "blocks": [
    {
      "blockHash": "<hex>",
      "blockHeight": 870123,
      "headerSeenAt": "2026-05-20T12:00:00Z",
      "processedAt": "2026-05-20T12:00:30Z",
      "bumpBuiltAt": "2026-05-20T12:00:45Z",
      "status": "compound-bump-built",
      "orphanedAt": null,
      "hasBlockProcessed": true,
      "hasCompoundBUMP": true
    }
  ],
  "nextCursor": 870000
}

Returns the block processing milestones for one block, looked up by block hash.

Response

200 OK
{
  "blockHash": "<hex>",
  "blockHeight": 870123,
  "headerSeenAt": "2026-05-20T12:00:00Z",
  "processedAt": "2026-05-20T12:00:30Z",
  "bumpBuiltAt": "2026-05-20T12:00:45Z",
  "status": "compound-bump-built",
  "orphanedAt": null,
  "hasBlockProcessed": true,
  "hasCompoundBUMP": true
}

Requests that the upstream Merkle Service re-emit STUMP and BLOCK_PROCESSED callbacks for the given block hash. Useful for healing a deployment whose callback stream missed a block.

Response

202 Accepted
{
  "status": "accepted",
  "blockHash": "<hex>"
}