API
Behold, the public API
The listener API is a read-only JSON HTTP service used to resolve handles, look up data needed for registration, and get information about the protocol.
Mainnet
All listed routes are GET (HEAD is also supported), and CORS allows any origin. IDs in responses are 64-character lowercase hex without 0x. Handles are 3-63 lowercase ASCII letters and digits with no normalization.
On most routes, omitting launcher_id selects the root registry, whose launcher is the default. If the index is too stale, important reads will return 503 with "code": "index_stale" instead of a normal response.
GET /healthz
Liveness probe; returns an empty 200.
GET /handle/{handle}
Returns a live (unspent) slot plus information about the resolved singleton (if available, name NFT data as well) for a given handle. The data can be used to construct the coin id of the latest unspent handle slot and the latest NFTs, which can be checked on-chain to exist but not be spent for confirmation. slot_parent_id is the parent of that slot coin; slot_parent_parent_id and slot_parent_inner_puzzle_hash are its compact lineage proof (parent amount is the registry singleton amount, typically 1). Together they are enough to spend the slot trustlessly. pending_transfer is null when no transfer is executable, or the same object as GET /handle/{handle}/pending-transfer.
{handle}
yes
handle (in path)
launcher_id
no
Registry launcher id (64-char hex)
include_metadata
no
If true, include NFT metadata CLVM as hex (when available)
bypass_expiration_safety_check
no
If true, return the proof even after expiration (410 otherwise)
{
"registry_launcher_id": "<hex32>",
"handle": "alice",
"slot": {
"counter": 0,
"handle_hash": "<hex32>",
"neighbors": { "left_value": "<hex32>", "right_value": "<hex32>" },
"expiration": 4102444800,
"owner_launcher_id": "<hex32>",
"resolved_launcher_id": "<hex32>"
},
"slot_parent_id": "<hex32>",
"slot_parent_parent_id": "<hex32>",
"slot_parent_inner_puzzle_hash": "<hex32>",
"slot_confirmation_height": 90,
"resolved_singleton": { "...same shape as GET /singletons/{launcher_id}..." },
"indexed_peak_height": 116,
"pending_transfer": null
}GET /handle/{handle}/pending-transfer
Returns a performable pending ownership transfer for the handle, or 204 if none is executable. The same payload is also embedded as pending_transfer on GET /handle/{handle} (null instead of 204). This should be queried and asserted to return 204 (or pending_transfer: null) when an offer involving a handle NFT is accepted.
{handle}
yes
handle (in path)
launcher_id
no
Registry launcher id
200:
GET /singletons/{launcher_id}
Returns information about a followed singleton. The API tracks all owner and resolved singletons for all handles registered in followed registries.
{launcher_id}
yes
64-char hex launcher id
include_metadata
no
If true, include NFT metadata CLVM as hex (when available)
nft is null for non-NFT singletons. nft.metadata is omitted unless include_metadata=true.
GET /registrations/{handle}
Returns the latest confirmed register or expire action for a handle.
{handle}
yes
handle (in path)
launcher_id
no
Registry launcher id
action_kind is "register" or "expire". Fees are mojos of the current payment CAT.
GET /recent-registrations
Returns the newest register/expire events, plus the running count of registered handles. This is used for the front page of XCHandles.
launcher_id
no
Registry launcher id
limit
no
Page size; default and maximum 50
GET /expiring
Returns a cursor-paginated directory of handles that are in an expiration auction or about to expire.
view
yes
active (in the 28-day auction) or soon (expires within 30 days)
cursor
no
Obtained from a previous page; used for pagination
limit
no
Page size; default and maximum 50
launcher_id
no
Registry launcher id
view=active:
view=soon:
next_cursor is omitted on the last page. Fees are mojos for a 1-year registration. Quotes use the effective base: the last generation whose activation_timestamp is at or before confirmed_timestamp (what a buyer pays after unrolling). The directory does not include the generation list or remaining unrolls.
GET /price
Live Price Singleton snapshot: committed (pre-unroll) base, remaining executable unrolls, and index freshness. Optional launcher_id selects a registry; omitting it uses the default.
launcher_id
no
Registry launcher id
current_base_price is the committed registry / pricing puzzle (before unrolling). unrolls are remaining generations from the current scheduler generation onward, in order. A row with activation_timestamp <= confirmed_timestamp is due (a wallet can unroll now). The payable base after unrolling is the last due unroll’s base_price, or current_base_price if nothing is due. Before the first generation row that value is launch price 1. Stale index: 503 index_stale.
GET /schedule
The full static generation list baked into the Price Singleton launcher, including already-activated rows. This list does not change; the last row’s base_price holds after that timestamp. There are no peak or timestamp freshness fields. Optional launcher_id is the same as on other routes.
launcher_id
no
Registry launcher id
Clients use /schedule for future window math (reminder crossings, home tables). Do not treat a missing later row as a vault-era fallback.
GET /neighbors
Given a handle hash, returns the neighboring handle slots, each slot's parent coin id, and its compact lineage proof (parent_parent_id and parent_inner_puzzle_hash; parent amount is always 1). This endpoint alone (plus on-chain data) is enough to enable trustless registrations for light clients.
launcher_id
yes
Registry launcher id
handle_hash
yes
handle tree hash (64-char hex)
Errors
Chain-backed reads other than /neighbors use:
Status
code
400
invalid_handle, invalid_launcher_id, invalid_view
404
handle_not_found, registry_not_followed, singleton_not_followed
410
handle_expired
503
index_stale, singleton_incomplete, singleton_mismatch, resolution_incomplete, resolution_mismatch
Last updated