Blueprint Canton Chain API
The complete Canton Network transaction record over one REST API. Every Canton Coin transaction since genesis (June 2024) is indexed on Blueprint's own validator infrastructure and exposed with per-party resolution — the query surface the chain itself does not offer.
Canton's public Scan API serves a single global feed with no per-party filter, and a participant's Ledger API only sees parties it hosts. Blueprint's index closes that gap: any transaction, any party, any balance — cursor-paginated, filterable, and seconds behind the chain head.
What you can query
- Global feed — hundreds of millions of transactions from genesis, filterable by type, mining round, or calendar day.
- Any party's history — complete, in either direction, with the party's role in every transaction. No wallet, node, or hosting relationship required.
- Live balances & holdings — point-in-time ACS snapshots: unlocked/locked coin, accrued holding fees, active holding contracts.
- Rounds, names, network — mining-round activity, the ANS directory, DSO and super-validator metadata, current CC fee configuration.
- Aggregates & market data — daily transaction and CC-volume series, plus CC price and market cap.
How it works
https://ccscan.xyz — all endpoints are read-only
GETs returning JSON. Machine-readable spec at /openapi.json,
interactive explorer at /api-docs/.
Getting Started
No SDK or signup needed to evaluate — the API speaks plain HTTPS + JSON:
# Chain head + the 12 newest transactions
curl -s https://ccscan.xyz/api/overview
# Page the global feed, newest first
curl -s "https://ccscan.xyz/api/txs?limit=50"
# One transaction, by seq or event id
curl -s https://ccscan.xyz/api/tx/320000000
# Find a party, then pull its full history and live balance
curl -s "https://ccscan.xyz/api/party/search?q=cumberland"
P="Cumberland-1::12201aa8a23046d5740c9edd58f7e820c83e7f5c58f25551f955f3252d3a04240860"
curl -s "https://ccscan.xyz/api/party/$P/txs?before_seq=0&limit=100"
curl -s "https://ccscan.xyz/api/party/$P/balance"
Reconciliation loop in four lines: read next_after_seq from each page and persist it —
the cursor is stable across restarts and retries.
after=0
while true; do
page=$(curl -s "https://ccscan.xyz/api/party/$P/txs?after_seq=$after&limit=100")
# process $page, then:
after=$(echo "$page" | jq .next_after_seq)
[ "$(echo "$page" | jq .count)" = 0 ] && sleep 30
doneAuthentication & Plans
Browsing is open — the API answers unauthenticated requests at an anonymous, per-IP rate so the explorer and quick evaluation just work. For production and programmatic use, authenticate with an API key to unlock a higher plan.
Send your key on every request as either header:
curl -H "Authorization: Bearer cck_your_key_here" \
https://ccscan.xyz/api/overview
# or
curl -H "X-API-Key: cck_your_key_here" \
https://ccscan.xyz/api/overviewPlans
| Tier | Rate limit | Included volume | For |
|---|---|---|---|
| Anonymous | 300 req/min (per IP) | — | Browsing & evaluation — no key |
| Free | 300 req/min | 10,000/day · 150,000/mo | Prototyping & low-volume apps |
| Pro | 3,000 req/min | Uncapped | Production integrations |
| Enterprise | 30,000 req/min | Uncapped | High-volume / dedicated workloads |
Create a key on the pricing page — passkey sign-in,
no card needed for Free. Live tier details are always at GET /api/plans.
Custom limits, SLAs, or dedicated capacity?
Contact Blueprint.
Subscriptions & secure checkout
Free keys issue instantly with just an email. Paid plans (Pro and Enterprise) are purchased through Stripe Checkout — the same PCI-DSS-compliant, embedded payment flow used across fintech. Card details are entered directly into Stripe and never touch ccscan's servers; we only ever store a Stripe customer and subscription identifier. Pay by card, Link, Cash App Pay, Klarna, or US bank (ACH).
The instant payment succeeds your account is upgraded and your API key is issued. For security only a hash of the key is stored, so the raw key is shown once at checkout — and you can create or copy keys anytime from your dashboard. Fulfillment is confirmed server-side by a signature-verified Stripe webhook, so your upgrade lands even if you close the tab.
Rate-limit headers
Every API response reports your current budget:
| Header | Meaning |
|---|---|
RateLimit-Limit | Requests allowed in the current window |
RateLimit-Remaining | Requests left in the window |
RateLimit-Reset | Seconds until the window resets |
X-Plan | The plan applied to this request |
X-Quota-Daily-Limit / -Remaining | Included daily volume & what's left (quota-capped plans) |
X-Quota-Monthly-Limit / -Remaining | Included monthly volume & what's left (quota-capped plans) |
429 Too Many Requests with a
Retry-After header (seconds); an exhausted daily or monthly quota also
returns 429, naming the window that resets it. An invalid or revoked key
returns 401. Quotas pool across all keys on one account — when Free volume
gets tight, Pro removes the caps.
Cursors & Pagination
Every transaction carries a monotonic integer seq assigned at ingest — the
universal cursor. List endpoints return up to limit rows (max 100) and a
cursor for the next page:
| Direction | Request param | Response cursor | Semantics |
|---|---|---|---|
| Newest first | before_seq | next_before_seq | Rows with seq < before_seq; 0 = start at the newest |
| Oldest first (party history) | after_seq | next_after_seq | Rows with seq > after_seq; 0 = start at genesis |
before_seq walks backward from the head (start at 0), after_seq walks forward from genesis. Chain the returned next_*_seq to fetch the next page.- Cursors are deterministic: no gaps, no overlap, safe to chain across retries.
count: 0means the range is exhausted (head reached, or the party's first transaction).after_seqandbefore_seqare mutually exclusive — sending both returns400.
Transactions
The global feed, newest first. Filters compose freely:
| Param | Type | Description |
|---|---|---|
before_seq | int | Cursor; 0/omitted = newest |
type | enum | transfer · mint · tap · abort_transfer_instruction |
round | int | Limit to one mining round |
day | date | Jump to a UTC day (YYYY-MM-DD) — resolved by binary search over the seq key, ~30 index probes |
limit | int | Default 25, max 100 |
One transaction by seq (digits) or full event id. Returns the list shape
plus detail — the complete financial body: sender with input amount and
fees, every receiver with amounts and receiver fees, balance changes with per-party
deltas and holding-fee rates, transfer kind, and the ledger offset.
Parties
Parties are Canton identities of the form name::fingerprint. URL-encode the
full id in paths. Over 420,000 parties have appeared on-chain; all are queryable.
Case-insensitive substring search over every party ever seen (min 2 chars, up to 50 matches).
A curated starting set for discovery: Blueprint's validator, every super validator, and featured-app providers — each with a display name and a tag (validator / super validator / featured app).
First/last activity with seqs, transaction count (exact to 100,000, then tx_count_capped: true), and the party's ANS entry when registered.
The party's complete history from genesis, forward (after_seq) or backward
(before_seq), optionally filtered by type. Each row adds
roles — how this party appears in that transaction
(sender / receiver / balance_change).
Live balance at the most recent valid ACS snapshot: total_unlocked_coin,
total_locked_coin, total_coin_holdings, accrued holding fees, and
total_available_coin (holdings − fees). Amounts are decimal strings with
10 dp. summary: null = no CC held at the snapshot.
The active Amulet holding contracts behind that balance (amounts, lock state), page size 200 with the Scan after token.
Whether the party is a validator, super-validator, and/or
app-provider (from the reward types it collects), plus a sync
indicator: active when ccscan’s index is within a few rounds of the network head round,
inactive when the index has fallen further behind, or unknown when the party is not a validator or the
network tip is unavailable (rounds_behind reports the gap). It also returns
recent reward performance (a fast bounded scan of the latest transactions) and exact
lifetime reward totals (a cached full-history scan; lifetime.complete=false
only if the history is too large to total in real time). Canton issues no validator liveness
rewards, so liveness is measured by round progress, not reward recency.
Rounds
One mining round (~10 minutes each): tx_count, first/last seq, start and end
times, plus a newest-first page of the round's transactions (same cursor semantics).
Some automation records carry round 0 — they are indexed but do not belong to a
user-facing round.
Names (ANS)
Canton Name Service directory entries — name, the user party id
it resolves to, url/description, and expiry. Prefix filter is lowercased server-side;
page size up to 1000. Reverse lookup (party → name) is included in the party summary.
Network
One call for network metadata: DSO state (party id, voting threshold, SV node states),
the super-validator scan directory, Splice instance names, Scan version, and the current
AmuletRules payload — the authoritative CC fee schedule and traffic limits.
The compact economics snapshot behind the landing page: on-chain oracle CC price, the current open mining round with its open/close timing, issuance per year, the app/validator reward split, synchronizer traffic price, holding-fee rate, SV and featured-app counts, and protocol version — one cheap call instead of four.
The validator directory: every party that collected validator rewards in the trailing
7 days, ranked, with is_sv flags and a per-day reward series.
Background-computed; pending: true until the first rollup lands.
Governance
The DSO governs Canton by on-chain vote requests. ccscan decodes them into readable proposals — action, category, requester, per-SV votes — and archives every decided proposal permanently, past the upstream scan's ~100-item window.
Open and recently-closed proposals with per-proposal tallies, category counts, and an
all-time status tally. limit caps closed history (5–200, default 40).
One proposal by tracking contract id: everything in the list row plus
all_votes (every SV's accept/reject with reasons), the raw action payload,
and sv_count — the current electorate size for the tally denominator.
Per-SV voting participation across all archived decided proposals: votes cast, accept/reject split, and participation rate per super validator.
Stats & Market
Per-day series from genesis: transaction counts by type and CC volume
(transferred/minted/tapped), aggregated from the full index. While the one-time
backfill is completing, complete: false and days appear oldest-first;
progress = aggregated_to_seq / head_seq.
Always-current per-day counts for the trailing 1–30 days, computed live against the
index (10-minute cache). The final entry is the current partial day
(partial: true).
Canton Coin market data: USD and BTC price, market cap, 24h change (CoinGecko,
120s cache). Degrades to available: false rather than failing.
Search
One box for everything. The classifier recognizes sequence numbers and round numbers
(digits), event ids, exact party ids (::), party-id fragments, and ANS name
prefixes — returning up to 20 typed results with the key to feed the matching endpoint.
Live & Streaming
The same real-time layer that drives the explorer's pulse chart is part of the API. Both
endpoints are served entirely from memory and are metering-exempt — they
never consume your rate or quota budget. GET /api/status is metering-exempt too.
Snapshot of the trailing ~3 minutes: ~2s head-seq samples (t0 +
ts[] offsets, seqs[], rounds[]) plus
instant / 1m / 5m throughput (tps_10s, tps_60s,
tps_5m). A 2s poll is always safe.
Server-Sent Events: the live payload — plus each newly indexed transaction in
txs[] — pushed the moment the chain head moves, sub-second after ingest.
The first event arrives immediately with a ~30-transaction backfill. Streams recycle
after ~120s and EventSource reconnects transparently; at connection
capacity the endpoint returns 503 — fall back to polling
/api/live.
# every new Canton transaction, as it lands
curl -sN https://ccscan.xyz/api/live/streamWant push without holding a connection? Webhooks deliver per-party transaction events to your endpoint, signed, on Free and up.
Data Model
Transaction row
{
"seq": 320000000, // monotonic cursor, assigned at ingest
"event_id": "#1220ce…:0", // Canton event id, globally unique
"round": 103286, // mining round (0/null on a few records)
"tx_type": "transfer", // transfer | mint | tap | abort_transfer_instruction
"tx_date": "2026-07-06 03:16:12.337540+00:00",
"amount": 1.0, // headline CC per `nature`; null only for aborts
"nature": "send", // send | reward | self | mint | tap | abort | other
"rewards": null, // validator+SV+app rewards claimed, when nature=reward
"parties": { "<party>": ["sender"], "<party>": ["receiver"] },
"kind": "preapproval_send" // transfer_kind, when the type is transfer
}Transaction types
| Type | Meaning |
|---|---|
transfer | CC moved on-ledger. The nature field refines it: send (to a distinct receiver), reward (a validator / super-validator / app-provider collecting rewards into its own balance — no separate recipient), or self (a self-transfer / coin merge). Every transfer moves value — amount is the headline for that nature. kind further distinguishes direct transfers, pre-approved sends, and transfer-instruction flows. |
mint | New CC issued to a party — defined in the protocol; not observed on Canton MainNet to date. |
tap | Faucet-style issuance — defined for DevNet-originated economics; not observed on Canton MainNet (0 to date). |
abort_transfer_instruction | A pending transfer instruction was aborted. |
Roles
A party appears in a transaction as sender, receiver, and/or
balance_change (its holdings were touched — e.g. fees or change). Roles come
from the indexed per-party join, so history queries are exact, not heuristic.
Amounts
The chain records amounts as 10-dp decimal strings; the API's amount headline
field is a JSON number for convenience, while detail and balance endpoints
preserve the original decimal strings for accounting-grade use.
Methodology
How the numbers on this site are derived — published so every figure is auditable.
- Headline amounts are derived, never stored. For a
sendthe amount is the sum of receiver amounts; for arewardcollection it is the gross rewards claimed; for aselftransfer it is the sender change; aborts have no amount. The full rawdetailis always returned, so you can re-derive or re-define any headline. - The validator coupon is de-duplicated. Across protocol eras the same validator reward is reported in
input_validator_reward_amount,input_validator_faucet_amount, or both. Every reward total on this site takesmax(reward, faucet)— summing them double-counts. - Economics follow Canton's burn-mint model. Reward collections mint new CC (split into app / validator / super-validator components); every fee — sender, receiver, and holding fees — burns. Net issuance is minted minus burned, accumulated from genesis by the background aggregator.
- Accounting-grade values are decimal strings. Balance and detail amounts are 10-decimal-place strings; the headline
amountis a JSON number for convenience. Use the strings when exactness matters. - The liveness field is index freshness, not per-party activity.
rounds_behindcompares ccscan’s index head to the network head, so it is the same for every party queried; it is reported only for parties that actually collect validator or super-validator rewards, andunknownotherwise. Canton issues no validator liveness rewards, and a synced validator only collects every ~40–50 rounds, so neither reward recency nor collection round is a sound per-validator liveness signal. Treat this field as “is ccscan current?”, not “is this validator up?”.
Freshness & Sources
| Data | Source | Freshness |
|---|---|---|
| Transactions, parties, rounds, search | Blueprint's chain index (validator infrastructure) | Continuously ingesting; typically seconds behind head — verify via ingest_cursor_at in /api/overview |
| Balances, holdings, ANS, network | SV Scan API pass-through | Live, short server-side cache (30s–1h by endpoint) |
| Daily aggregates | Index post-processing | /api/stats/recent always current; /api/stats/daily backfilling from genesis |
| Market data | CoinGecko | 120s cache |
Errors
Errors are JSON with an error message and a conventional status:
| Status | Meaning |
|---|---|
400 | Invalid parameter (unknown type, both cursors at once) |
401 | API key supplied but unknown, inactive, or revoked |
404 | Transaction, party, round, or page not found |
429 | Rate limit or daily/monthly quota exceeded — see the RateLimit-* and X-Quota-* response headers |
502 | The Scan API upstream did not respond — retry shortly |
503 + building: true | A supporting index is still building — retry in minutes |
Unknown parties in search-style endpoints are not errors: they return count: 0.
Webhooks
Signed party-activity events, pushed the moment a party's transaction indexes — no polling. Create webhooks from your dashboard (plan limits: Free 1 · Pro 10 · Enterprise 50). Endpoints must be public HTTPS.
{
"event": "party.activity",
"party": "party-name::1220…",
"tx": { "seq": 322500123, "tx_type": "transfer", "amount": "12.5", "parties": { "…": ["sender"] } },
"sent_at": 1783900000.123
}Every delivery carries X-CCScan-Signature: sha256=HMAC_SHA256(secret, raw_body) — verify it before
trusting the payload. Ten consecutive failed deliveries disable a webhook (re-enable from the dashboard).
Delivery is at-most-once: reconcile against /api/party/<id>/txs for completeness.
Stability & Versioning
The endpoints in openapi.json are the stable v1 contract:
fields are additive-only, and any breaking change ships under a new path with at least
12 months of notice here and in the spec. Undocumented /api/* routes
(they power the explorer UI) may change without notice — build against the spec, not the network tab.
Live service health is published at /status.
Agents & Discovery
- /openapi.json — OpenAPI 3.1, the authoritative machine-readable contract.
- /api-docs/ — interactive explorer with runnable requests.
- /llms.txt — compact orientation for LLM agents (llmstxt.org format).
- /llms-full.txt — the complete inline agent reference: auth, pagination, every endpoint's shape, worked examples.
GET /api— a machine index of these discovery URLs.
Responses are flat, stable JSON with integer cursors — designed to be trivially consumed by agent frameworks and reconciliation pipelines alike.
FAQ
What is the ccscan Canton chain API?
A read-only REST API serving full-history Canton Network chain data — every Canton Coin transaction since genesis (June 2024), per-party history and balances, mining rounds, ANS names, governance, and network configuration.
Do I need an API key?
No. Browsing is anonymous at 300 requests/min per IP. A Free key matches that 300/min and adds per-key quotas (10,000/day, 150,000/month) plus usage analytics; Pro raises throughput to 3,000 requests/min and Enterprise to 30,000 — get one at /pricing.
How do I authenticate?
Send your key as Authorization: Bearer <key> or the X-API-Key header. Your remaining budget is returned in RateLimit-* response headers on every call.
How fresh is the data?
The index typically trails the chain head by seconds (ingest_cursor_at in /api/overview is the live signal); balances, holdings, names, and network state are relayed live from the SV Scan API. Current lag is published at /status.
Can AI agents use the API?
Yes — automated access within your rate limits is welcome. Start at /llms.txt or the machine index at GET /api.
Access & Commercial
The API is open for evaluation. For production workloads — commercial terms, rate guarantees, SLAs, dedicated read capacity, or custom endpoints (webhooks, bulk export, bespoke aggregates) — talk to Blueprint:
- theblueprint.xyz — company, platform, and contact.
- The same infrastructure powers Blueprint's institutional reconciliation pipelines — the endpoints documented here are the ones we run in production ourselves.