Overview
The indexer follows Kaspa's chain tip live, classifies every covenant event (born / moved / retired), decodes spend-time script reveals, and serves the whole index as static JSON from a CDN. Reads are cheap and cacheable — poll as often as you like.
Networks
Every path takes a network segment. Swap testnet-10 for mainnet anywhere. Mainnet's first smart coins arrived July 2, 2026; their full history starts there.
GET/data/{network}-live.json
The small, fast feed — network stats, the chain tip, and the ~150 newest life events. This is the one to poll (a few KB, refreshes every few seconds).
Request
curl -s https://kascov-explorer.web.app/data/testnet-10-live.json
Response · 200
{
"stats": { "covenants": 89747, "active": 6566, "events": 403794 },
"tip_daa": 509571904,
"tip_at_ms": 1751799000000,
"processed_daa": 509571904,
"recent_events": [
{ "covenant_id": "b11acf6c…459c6",
"kind": "genesis", "txid": "a86041…e684",
"accepting_daa": 508951007 }
]
}
| Field | Type | Notes |
| stats.covenants | int | distinct smart coins ever seen |
| stats.active | int | coins with a live UTXO right now |
| tip_daa · processed_daa | int | chain tip vs. last block applied — the gap is the honest sync lag |
| recent_events[].kind | string | genesis · transition · burn |
GET/data/{network}.json
The grid — stats plus one summary row per covenant. One request tells you about every smart coin on the network (can be multiple MB; cache it).
Response · 200
{
"stats": { … },
"covenants": [
{ "covenant_id": "b11acf6c…459c6", "name": "nimble-teal-newt-b11a",
"status": "active", "born_value": 1000000000, "live_value": 1000000000,
"event_count": 1, "genesis_daa": 508951007, "last_daa": 508951007,
"template": "SilverScript · Mecenas" }
]
}
| Field | Type | Notes |
| status | string | active or burned |
| born_value · live_value | int | sompi held at birth / right now |
| template | string? | recognized contract, or a state shape like p2sh commitment |
GET/data/{network}/stream
Server-sent events — one JSON message the moment the indexer sees each life event, plus a : ka keep-alive every 25s. Treat messages as hints and confirm through the polled feeds (some CDNs buffer streams).
Request
curl -N https://kascov-explorer.web.app/data/testnet-10/stream
Each message
data: {"covenant_id":"b11acf6c…","kind":"genesis",
"txid":"a86041…","accepting_daa":508951007}
GET/data/{network}/c/{covenant_id}.json
One coin's whole life — the complete event timeline and every UTXO with decoded scripts, recognized templates, and spend-time reveals. 404 if the id is unknown.
Response · 200
{
"covenant_id": "da2fe117…5d6d7", "name": "lively-slate-urchin-da2f",
"status": "burned", "event_count": 2, "lineage_complete": true,
"genesis_txid": "823d33…80c5", "genesis_daa": 509571333,
"events": [
{ "seq": 0, "kind": "genesis", "txid": "823d33…80c5", "accepting_daa": 509571333 },
{ "seq": 1, "kind": "burn", "txid": "1461f8…07ed", "accepting_daa": 509571520 }
],
"utxos": [
{ "outpoint": "823d33…80c5:0", "value": 500000000, "live": false,
"template": "p2sh commitment",
"state_fields": [ { "name": "program_hash", "value": "d9a9e982…f475d17" } ],
"revealed_template": "SilverScript · Escrow",
"revealed_fields": [ { "name": "arbiter_hash", "value": "f4445661…" } ] }
]
}
| Field | Type | Notes |
| lineage_complete | bool | false means kascov started watching mid-life; earlier history is honestly missing |
| utxos[].revealed_template | string? | the contract a P2SH state actually ran, decoded and hash-verified when it was spent |
| …_fields[] | array | { name, value } — labeled constructor arguments |
GET/data/{network}/tx/{txid}.json
Which smart coin did this transaction touch? Genesis, moves and burns all resolve.
Response · 200
{ "covenant_id": "b11acf6c…459c6" }
Not covenant traffic · 404
{ "error": "not found" }
GET/data/{network}/addr/{address-or-pubkey}.json
Which smart coins has this address touched? Accepts kaspa:… / kaspatest:… or raw 32/33-byte pubkey hex. Matches p2pk covenant states.
Response · 200
{
"address": "kaspatest:qp9…hzy0",
"pubkey": "4b3402be…e9f2",
"covenants": [
{ "covenant_id": "…", "name": "…", "role": "controls_now" }
]
}
| Field | Type | Notes |
| covenants[].role | string | controls_now · states_seen |
GET/data/{network}/digest.json
The last 24 hours in one object — births, moves, burns, value born, the busiest coin, the biggest birth, and how many coins are alive. Refreshes about once a minute.
Response · 200
{
"births": 24762, "moves": 25948, "burns": 55074,
"value_born": 4831200000000, "alive": 6566,
"busiest": { "covenant_id": "…", "name": "curious-jade-zebra-6366", "events": 1185 },
"biggest_birth": { "covenant_id": "…", "name": "rapid-violet-seal-b788", "value": 937465200000000 }
}
GET/data/{network}/templates.json
What runs on this network — recognized script templates aggregated over every state UTXO. Unrecognized scripts are counted, never hidden.
Response · 200
{
"templates": [
{ "name": "p2sh commitment", "live_states": 6297, "live_value": 62970000000,
"ever_seen": 14459, "covenants": 5990, "revealed_runs": 3 }
],
"unrecognized": { "ever_seen": 12, "live_states": 4 }
}
| Field | Type | Notes |
| revealed_runs | int | compiled contracts proven at spend time; a tx sweeping N states counts N |
GET/data/{network}/activity.json?range=24h
The histogram behind the activity chart — life-event counts per DAA bucket. Empty buckets are omitted; treat them as zeros.
| Query | Type | Notes |
| range | enum | 1h · 6h · 24h · 48h · all (default 24h) |
Response · 200
{
"range": "24h", "bucket_daa": 6000,
"buckets": [ { "daa": 509540000, "births": 812, "moves": 903, "burns": 1740 } ]
}
GET/data/{network}/families.json
Covenant apps — clusters of coins that moved together in a transaction (multi-contract flows), union-found over shared txids. Each family lists its members with their recognized template.
Response · 200
{
"families": [
{ "size": 2, "members": [
{ "covenant_id": "09ef275e…", "template": "p2sh commitment", "shared_txs": 8 },
{ "covenant_id": "901be291…", "template": "p2sh commitment", "shared_txs": 8 }
] }
]
}