ccledger Community API
A non-custodial records and payments API for Canton Network. The on-chain record actions — attest, attest-mutual, mint — are fully live: each writes an immutable record on Canton MainNet and returns an on-chain proof (contract ID, update/transaction ID, ledger offset). Unlock is live and free (it releases a previously created lock back to its owner). The legacy balance-funded value endpoints — transfer, lock, settle — are permanently disabled (HTTP 403 non_custodial); on-chain value movement is moving to the delegated facilitation flow, where you sign from your own wallet and ccledger relays as the featured application — rolling out now.
Built by Blueprint, a Hivemind Capital Partners ecosystem company. Blueprint operates a Canton Network validator on Global MainNet. ccledger is non-custodial, enforced in code: prepaid CC is a non-refundable service credit (“fee credits”) that pays per-action fees only and never funds on-chain value movement — there is no withdrawal endpoint. No validator, no Daml, no keys held by us. Every API key includes 50 trial record actions — top up fee credits for paid tier at 100 RPM. Hold CCL for discount.
non_custodial); value movement arrives via the delegated facilitation flow (rolling out).
Why Use ccledger
- Immutable on-chain records, no gas fees — Attest, co-sign, and record issuance on Canton MainNet with one call. No wallet to wire up, no gas fees. 50 trial record actions included with every API key (max 25/day). Top up fee credits for paid tier at 100 RPM (2.0 CC fee per record action, 5.0 CC fee for mutual attestation). Hold CCL for discount.
- Non-custodial value movement (rolling out) — The balance-funded transfer/lock/settle mode is permanently disabled (403
non_custodial): fee credits never fund value movement. On-chain CC will move from your own wallet via the delegated facilitation flow — you sign aCreateTransferCommand, ccledger relays it as the featured application over Splice’s audited Amulet and Canton Token Standard contracts. Unlock remains live and free for previously created locks. - On-chain proof — Every response includes contract ID, update/transaction ID, ledger offset, synchronizer ID, and effective timestamp. A verifiable on-chain record — look it up on any Canton participant.
- Canton Network MainNet — Not a testnet or simulation. Your transactions and records exist on the same global synchronization domain used by major financial institutions.
- Self-service registration — One POST request returns an API key instantly. No approval process, no KYC, no waiting.
- Non-custodial, enforced in code — You keep your Loop wallet and keys. Prepaid CC is a non-refundable fee credit: it pays per-action fees only, never funds on-chain value movement, and cannot be withdrawn (there is no withdrawal endpoint). The balance-funded value endpoints are hard-gated at 403 — ccledger never holds customer CC as a spendable balance.
- Query and verify — Retrieve any past action by ID, filter by app name or type, get aggregate statistics. Full audit trail.
- No infrastructure to manage — Blueprint runs the Canton validator, token-standard integration, and database. 50 trial record actions to get started. Paid tier unlocks unlimited record throughput at 2.0 CC fee per record action (5.0 CC fee for mutual attestation). Hold CCL for discount. You just call the API.
Canton Network
Canton Network is a privacy-enabled, interoperable blockchain network designed for institutional use. Unlike public chains, Canton uses Daml smart contracts with built-in privacy — participants only see data they are authorized to see.
How Canton Works
- Daml smart contracts — Contracts are written in Daml, a purpose-built language for multi-party workflows. Each contract has explicit visibility and authorization rules.
- Global synchronization domain — All participants share a single source of truth without exposing private data. Transactions are atomic across parties.
- Validators — Network participants run validator nodes that host applications and process transactions. Blueprint operates one of these validators.
- Participant nodes — Each validator runs a participant node connected to the global domain. ccledger submits commands through Blueprint’s participant.
What Happens On-Chain
What ccledger does on Canton MainNet depends on the action type:
- Record actions (attest, attest-mutual, mint) — live today — the gateway creates an immutable record contract. The key fields recorded on-chain are listed below.
- Unlock — live and free — releases a previously created
LockedAmulet(LockedAmulet_UnlockV2) back to its owner. - Value movement (transfer, lock, settle) — the balance-funded mode is permanently disabled (403
non_custodial). When the delegated facilitation flow ships, the sender signs aCreateTransferCommandfrom their own wallet and ccledger relays it, exercising Splice’s Amulet and Canton Token Standard choices (TransferFactory_Transfer;LockedAmuletescrow; the allocation flowAllocationFactory_Allocate→Allocation_ExecuteTransfer).
| Data | Description |
|---|---|
| dataHash | Your SHA-256 hash — a fingerprint of your off-chain data |
| submittedBy | Your application name |
| batchId | Unique record identifier (UUID) |
| gateway | Blueprint’s Canton party ID (signatory) |
| timestamp | When the record was committed on-chain |
Once created, an attestation record is immutable — it exists on Canton MainNet for the lifetime of the network, and no one, including Blueprint, can modify or delete it. Every live action returns an on-chain proof (contract ID, update/transaction ID, ledger offset) you can verify against the Canton participant.
Architecture
ccledger is a Spring Boot application running alongside Blueprint’s Canton validator. Here is the complete request flow from your application to on-chain proof.
- Validate API key, check rate limit & fee credits
- Debit the fee & record the action (idempotent)
- Exercise the on-chain action — an attestation/issuance record, or an unlock release
splice-validator-participant-1:5001 · Submit & wait for commitInfrastructure
| Component | Detail |
|---|---|
| Cloud | AWS EC2, us-east-1 (Virginia) |
| TLS | Caddy with automatic HTTPS (Let’s Encrypt) |
| Backend | Spring Boot on Eclipse Temurin 21, Docker container |
| Database | PostgreSQL (operational cache — API keys, action records, audit trail) |
| Canton SDK | Daml, Splice |
| Auth | Auth0 M2M client credentials for participant gRPC |
| Validator | Blueprint validator on Canton Global MainNet |
| Daml package | ccledger-blueprint.dar |
Source of Truth
The Canton ledger is the source of truth for on-chain records and value. Attestations, mutual attestations, and issuance records are immutable record contracts; unlock releases are real Amulet transactions. The PostgreSQL database tracks API keys, fee credits, the CCL discount credit, and action history for fast queries and rate-limit enforcement. Records already committed on-chain persist on the ledger regardless of the database.
On-Chain Proof Model
ccledger returns an on-chain proof for every live action. What that proof references depends on the action type.
Record actions (attest, attest-mutual, mint) record data on-chain: you provide a dataHash — a SHA-256 fingerprint of your off-chain data — and ccledger writes it into an immutable record contract. Your raw data never touches our servers; you hash it locally and send only the hash.
Unlock releases a previously created lock: the proof references the on-chain Amulet transaction that released the LockedAmulet back to its owner.
Every action returns:
contractId— the Canton contract identifiertransactionId— the Canton update/transaction IDledgerOffset— global sequence number on the ledgersynchronizerId— which Canton domain processed iteffectiveAt— when the Canton sequencer committed it
Look any of these up against a Canton participant to independently verify the action.
Getting Started
From zero to on-chain proof in three steps. No wallet, no gas fees. 50 trial transactions included.
Base URL
https://ccledger.xyzStep 1: Register for an API Key
One POST request. No approval needed. Returns your key instantly.
curl -X POST https://ccledger.xyz/api/v1/community/register \
-H 'Content-Type: application/json' \
-d '{"appName": "my-app", "cantonParty": "user-party::1220abc..."}'cantonParty: Optional, and an echoed hint only — it is not bound to your key at registration. Your Canton party is bound on your first verified fee-credit top-up: a verified on-chain CC transfer from that party (via your Loop wallet), claimed by your authenticated key, is the proof of control. CCL Builder Rewards attach to the bound party.
The cantonParty field is optional at registration and only echoed back. The first verified top-up permanently binds the sender party to your key; from then on, top-ups must come from that party.
{
"apiKey": "cb_community_abc123...",
"appName": "my-app",
"cantonParty": "user-party::1220abc...",
"tier": "community",
"rateLimitRpm": 10,
"scopes": ["community:write"],
"trialCreditsRemaining": 50,
"message": "Store this API key securely -- it will not be shown again. 50 trial transactions included (max 25/day)."
}X-API-Key header for all subsequent requests. Your key includes 50 trial transactions (max 25/day) — no deposit needed to start.
Step 2: Call Any Action Endpoint
Choose from 7 action types. Here’s an example using attest:
curl -X POST https://ccledger.xyz/api/v1/community/attest \
-H 'X-API-Key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"appName": "my-app",
"dataOwner": "user-123",
"dataId": "invoice-456",
"dataHash": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
"description": "Invoice attestation for Q1 2026"
}'Step 3: Get On-Chain Proof
Every successful action returns a proof object with the on-chain record:
{
"actionId": "77f83164-0be3-40d2-a1c5-9e8f7d6b5a4c",
"actionType": "attest",
"status": "confirmed",
"appName": "my-app",
"dataHash": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
"mintedAt": "2026-03-04T23:02:34.774Z",
"proof": {
"contractId": "000f8f4427be3817...",
"transactionId": "12202b581a05cafd...",
"ledgerOffset": 2087132,
"synchronizerId": "global-domain::1220b1431ef2...",
"effectiveAt": "2026-03-04T23:02:31.915Z",
"packageId": null,
"templateId": null
},
"rewardMarkerCreated": false
}
The contractId uniquely identifies the Daml contract on Canton MainNet. The transactionId is the Canton transaction hash. The ledgerOffset is the global sequence number. These are permanent, immutable records.
API Reference
15 REST endpoints. All return JSON. Base URL: https://ccledger.xyz. For the interactive explorer with try-it-out, see the API Explorer.
X-API-Key header. The registration and stats endpoints are public (no auth).Error responses: See the Error Responses section below for the exact format returned by each HTTP status code (400, 401, 402, 403, 404, 429, 500).
Registration
Register for a community API key. No authentication required. Rate limited to 3 registrations per IP per 24 hours. The cantonParty field is an optional echoed hint only — your Canton party is bound on your first verified fee-credit top-up (the verified transfer is the proof of control), which is also what attaches CCL Builder Rewards.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
appName | string | Yes | Your application name (3–100 characters) |
cantonParty | string | No | Your Canton party ID from your Loop wallet (max 512 characters). Echoed hint only — it is not bound to your key at registration. Your Canton party is bound on your first verified fee-credit top-up: the verified on-chain transfer from that party is the proof of control. |
contactEmail | string | No | Optional contact email address |
{
"appName": "your-app-name",
"cantonParty": "user-party::1220abc...",
"contactEmail": "dev@example.com"
}Response (201 Created):
{
"apiKey": "cb_community_a1b2c3d4e5f6g7h8i9j0...",
"appName": "your-app-name",
"cantonParty": "user-party::1220abc...",
"tier": "community",
"rateLimitRpm": 10,
"scopes": ["community:write"],
"trialCreditsRemaining": 50,
"message": "Store this API key securely -- it will not be shown again. Use it in the X-Api-Key header for all community API requests."
}Action Endpoints
Seven action endpoints. The record actions (attest, attest-mutual, mint) are fully live — they write immutable records on Canton MainNet and return an on-chain proof. Unlock is live and free. The balance-funded value endpoints (transfer, lock, settle) are permanently disabled by the enforced non-custodial policy and return HTTP 403 non_custodial; on-chain value movement is moving to the delegated facilitation flow (you sign from your own wallet, ccledger relays as the featured application) — rolling out, not yet callable.
Required Fields (all action types)
| Field | Type | Required | Description |
|---|---|---|---|
appName | string | Yes | Your application identifier (1–100 characters) |
dataHash | string | Yes | SHA-256 hash, hex-encoded (max 128 characters). For record actions it is the recorded fingerprint; for unlock it is an attached reference. |
Some actions require additional fields: attest-mutual needs attestorParty; unlock needs lockId. The disabled value endpoints kept their request shapes (transfer: recipient + amount; lock: amount + duration; settle: recipient party + amount) for the facilitation rollout, but currently return 403 before validation. See each endpoint below and the Action Types section.
Common Response Fields
| Field | Type | Description |
|---|---|---|
actionId | string (UUID) | Unique identifier assigned by ccledger |
actionType | string | The action type (attest, attest-mutual, transfer, lock, unlock, mint, settle) |
status | string | confirmed when on-chain, failed on ledger error. Mutual attestation returns pending_signature until the attestor co-signs; an ambiguous on-chain submit (e.g. an unlock release) returns needs_reconciliation |
appName | string | Your application name (echoed back) |
dataHash | string | Your data hash (echoed back) |
mintedAt | string (ISO 8601) | When the action was confirmed on-chain |
proof.contractId | string | Canton contract ID (hex-encoded) |
proof.transactionId | string | Canton transaction hash (hex-encoded) |
proof.ledgerOffset | integer | Global ledger sequence number |
proof.synchronizerId | string | Canton synchronizer (global-domain::...) |
proof.effectiveAt | string (ISO 8601) | Timestamp when the transaction was committed by the Canton sequencer |
proof.packageId | string or null | Daml package identifier. Always null for community action proofs. |
proof.templateId | string or null | Fully qualified Daml template identifier. Always null for community action proofs. |
rewardMarkerCreated | boolean | Reserved field, always false. |
Record a data attestation. Use for audit trails, compliance records, data integrity proofs. Additional fields: dataOwner, dataId, description.
curl -X POST https://ccledger.xyz/api/v1/community/attest \
-H 'X-API-Key: YOUR_KEY' \
-H 'Content-Type: application/json' \
-d '{"appName":"my-app","dataHash":"a1b2c3...","description":"Audit record"}'Create a mutual attestation proposal that requires the attestor party to co-sign. Costs 5.0 CC. Required field: attestorParty (Canton party ID of the co-signer). Additional fields: dataOwner, dataId, description, assetType. Returns status pending_signature until the attestor co-signs the proposal (then confirmed).
curl -X POST https://ccledger.xyz/api/v1/community/attest-mutual \
-H 'X-API-Key: YOUR_KEY' \
-H 'Content-Type: application/json' \
-d '{"appName":"my-app","dataHash":"a1b2c3...","attestorParty":"attestor::1220abcdef...","description":"Mutual audit record"}'Permanently disabled (403 non_custodial). ccledger is non-custodial, enforced in code: prepaid CC credits pay per-action fees only and never fund on-chain value movement, so the legacy balance-funded transfer mode is permanently disabled — every call currently returns HTTP 403. On-chain CC movement is moving to the delegated facilitation flow: you keep your own wallet and keys, sign a CreateTransferCommand yourself, and ccledger relays and submits it as the featured application (CIP-0104 confirmer). Rolling out — not yet callable. The request shape (recipient, amount, required Idempotency-Key header, CC caps) is retained for the rollout.
Current response (403):
{
"error": "non_custodial",
"message": "ccledger is non-custodial: prepaid CC credits pay per-action fees only and never fund on-chain value movement. Balance-funded /transfer is permanently disabled. On-chain CC moves from your own wallet via the delegated facilitation flow (rolling out now — see https://ccledger.xyz/docs). Record actions (attest, attest-mutual, mint records) remain fully available.",
"status": 403
}Permanently disabled (403 non_custodial). The legacy balance-funded time-locked escrow (locking CC into an on-chain LockedAmulet) is permanently disabled by the enforced non-custodial policy — every call currently returns HTTP 403 with the same body as /transfer (the message names /lock). Escrow will run from your own wallet via the delegated facilitation flow (rolling out). POST /unlock remains live and free for previously created locks. The request shape (amount, duration as integer seconds or ISO-8601, required Idempotency-Key header) is retained for the rollout.
Live and free (no fee). Release a time-lock created by a previous /lock and restore the locked CC to its owner. Required: lockId — the LockedAmulet contract ID returned in the lock’s proof. Releases the on-chain LockedAmulet (LockedAmulet_UnlockV2). Not affected by the non-custodial gate — it does not fund new value movement; it only releases/unwinds a previously created lock. Optional: reference. Returns 404 if no matching lock exists, 409 if it was already unlocked.
curl -X POST https://ccledger.xyz/api/v1/community/unlock \
-H 'X-API-Key: YOUR_KEY' \
-H 'Content-Type: application/json' \
-d '{"appName":"my-app","lockId":"00a1b2c3d4e5f6...","dataHash":"d4e5f6...","reference":"release-001"}'Record an issuance or certificate on-chain. ccledger is a non-issuer — this does not mint Canton Coin (only the DSO can) or a tradeable token. It writes an immutable record for issuance and certificate use cases. Additional fields: owner, tokenId, tokenName, amount, metadata, reference.
curl -X POST https://ccledger.xyz/api/v1/community/mint \
-H 'X-API-Key: YOUR_KEY' \
-H 'Content-Type: application/json' \
-d '{"appName":"my-app","dataHash":"e5f6a1...","owner":"creator-1","tokenId":"nft-001","tokenName":"MY-TOKEN","amount":"1","metadata":"{\"collection\":\"genesis\"}","reference":"mint-001"}'Permanently disabled (403 non_custodial). The legacy balance-funded atomic settlement (token-standard allocation flow AllocationFactory_Allocate → Allocation_ExecuteTransfer) is permanently disabled by the enforced non-custodial policy — every call currently returns HTTP 403 with the same body as /transfer (the message names /settle). Atomic settlement will run from your own wallet via the delegated facilitation flow (rolling out). The request shape (recipient party in parties, amount, required Idempotency-Key header) is retained for the rollout.
Query Endpoints
List past actions. Requires API key. Supports query parameters for filtering.
| Parameter | Type | Description |
|---|---|---|
appName | string | Filter by application name |
actionType | string | Filter by type: attest, attest-mutual, transfer, lock, unlock, mint, settle |
dataOwner | string | Filter by data owner |
status | string | Filter by status: pending, pending_signature, confirmed, failed, needs_reconciliation, unlocking, unlocked |
reference | string | Filter by reference identifier |
page | integer | Page number, 0-indexed (default: 0) |
size | integer | Page size (default: 50, max: 100) |
curl "https://ccledger.xyz/api/v1/community/actions?appName=my-app&actionType=attest" \
-H 'X-API-Key: YOUR_KEY'Response: Returns a JSON array of action detail objects.
[
{
"actionId": "77f83164-0be3-40d2-a1c5-9e8f7d6b5a4c",
"actionType": "attest",
"appName": "my-app",
"dataOwner": "user-123",
"dataId": "invoice-456",
"dataHash": "9f86d081884c7d65...",
"description": "Invoice attestation for Q1 2026",
"reference": null,
"assetType": null,
"status": "confirmed",
"proof": {
"contractId": "000f8f4427be3817...",
"transactionId": "12202b581a05cafd...",
"ledgerOffset": 2087132,
"synchronizerId": "global-domain::1220b1431ef2...",
"effectiveAt": "2026-03-04T23:02:31.915Z",
"packageId": null,
"templateId": null
},
"rewardMarkerCreated": false,
"createdAt": "2026-03-04T23:02:30.100Z",
"completedAt": "2026-03-04T23:02:34.774Z"
}
]Get a single action by its UUID. Returns the full action detail record with on-chain proof. Returns 404 if the action does not exist or does not belong to your API key.
curl https://ccledger.xyz/api/v1/community/actions/77f83164-0be3-40d2-a1c5-9e8f7d6b5a4c \
-H 'X-API-Key: YOUR_KEY'Public aggregate statistics. No authentication required. Returns total counts and a breakdown by action type.
curl https://ccledger.xyz/api/v1/community/statsResponse:
{
"totalActions": 79,
"confirmedActions": 76,
"rewardMarkersCreated": 0,
"activeApps": 23,
"actionsByType": {
"attest": 35,
"transfer": 12,
"lock": 8,
"unlock": 8,
"mint": 8,
"settle": 8,
"ledger-submit": 14
},
"costPerAction": 2.0,
"costPerMutualAction": 5.0,
"paidTierRpm": 100,
"communityTierRpm": 10,
"loyaltyTokensMinted": 0,
"registeredKeys": 30,
"registeredParties": 2,
"cclBlueprintTreasury": 0,
"partyStats": [...],
"ledgerSubmissions": 14,
"confirmedLedgerSubmissions": 14,
"successRate": 96.2,
"ccRevenue": 45.0,
"ccDeposits": 100.0,
"trialToPaidRate": 25.0,
"avgDailyActions7d": 11.3,
"weekOverWeekPct": 15.0,
"busiestDay": "2026-03-25",
"peakHour": 14,
"avgSecondsToConfirm": 3.2
}Public time-series chart data for analytics dashboards. No authentication required. Returns daily counts within the requested time window.
| Parameter | Type | Description |
|---|---|---|
window | string | Time window: 7d, 30d (default), or 90d |
curl "https://ccledger.xyz/api/v1/community/chart?window=30d"Response:
{
"window": "30d",
"communityActions": [
{"date": "2026-03-15", "count": 12},
{"date": "2026-03-16", "count": 8}
],
"actionsByType": {
"attest": [{"date": "2026-03-15", "count": 5}],
"transfer": [{"date": "2026-03-15", "count": 4}]
},
"ledgerSubmissions": [{"date": "2026-03-15", "count": 2}],
"registrations": [{"date": "2026-03-15", "count": 3}],
"cclMinted": [],
"activeKeys": [{"date": "2026-03-15", "count": 5}]
}Balance & Credits
Prepaid CC is a non-refundable service credit (“fee credits”) that pays per-action fees only — it never funds on-chain value movement, and there is no withdrawal endpoint (credits are a one-way prepayment, not a custodial balance). Send CC from your Loop wallet and your fee credits are auto-credited within seconds. Community tier includes 50 trial record actions (max 25/day) at no cost. Paid tier (100 RPM) costs 2.0 CC fee per record action (5.0 CC for mutual attestation). Simply holding CCL gives you a discount on every action.
Fees (deterministic, no hidden costs)
| Action Type | Base Fee |
|---|---|
| Record actions (attest, mint) | 2.0 CC (hold CCL for discount) |
| Mutual attestation (attest-mutual) | 5.0 CC (hold CCL for discount) |
| Unlock | Free — no fee (releases a previously created lock to its owner) |
| Trial actions (50 included, record actions only) | 0 CC |
| Transfer / lock / settle | — balance-funded mode permanently disabled (403 non_custodial); fee credits never fund value movement |
CCL Discount Curve
Your discount is based on the CCL you hold (cclOnchainHoldings), tracked on your ccledger account. Formula: discount = 50% × (1 - 1/(1 + cclOnchainHoldings/200))
| CCL Held | Discount | CC/Action | CC/Mutual |
|---|---|---|---|
| 0 | 0% | 2.000 | 5.000 |
| 50 | 10% | 1.800 | 4.500 |
| 100 | 16.7% | 1.667 | 4.167 |
| 200 | 25% | 1.500 | 3.750 |
| 500 | 35.7% | 1.286 | 3.214 |
| 1,000 | 41.7% | 1.167 | 2.917 |
Discount increases with more CCL held (up to ~50%). Hold CCL to lower your CC cost per action — CCL is never spent, only CC is charged at the discounted rate. Your discount is shown in GET /balance (cclOnchainHoldings, discountedCostPerAction, discountedCostPerMutual, discountPercent). The more CCL you hold, the larger your discount.
Unified balance endpoint. Returns your fee-credit balance (ccBalance — non-refundable prepaid CC that pays per-action fees only), CCL balance, your CCL discount balance (cclOnchainHoldings — the CCL you hold that drives your discount), tier, rate limit, base and discounted fee per action, CCL mint progress (cantonParty, cclTotalMinted, cclActionsTowardNext, cclNextMilestone), discount info, and recent transaction history. Your discount is based on the CCL you hold, tracked on your ccledger account. Requires API key.
curl https://ccledger.xyz/api/v1/community/balance \
-H 'X-API-Key: YOUR_KEY'Response:
{
"tier": "paid",
"rateLimitRpm": 100,
"ccBalance": 42.5,
"costPerAction": 2.0,
"costPerMutualAction": 5.0,
"discountedCostPerAction": 1.667,
"discountedCostPerMutual": 4.167,
"discountPercent": "16.7%",
"trialCreditsRemaining": 48,
"trialCreditsTotal": 50,
"trialDailyUsed": 2,
"trialDailyLimit": 25,
"cclBalance": 100.0,
"cclOnchainHoldings": 100.0,
"cantonParty": "user-party::1220abcdef...",
"cclTotalMinted": 100,
"cclActionsTowardNext": 2,
"cclNextMilestone": 10,
"recentTransactions": [
{
"id": 1,
"type": "deposit",
"amount": 50.0,
"balanceAfter": 50.0,
"referenceId": null,
"cantonTxId": "tx-abc123",
"description": "CC deposit from Canton tx tx-abc123",
"createdAt": "2026-03-04T14:30:00Z"
}
]
}Dry-run pricing preview. Returns the exact fee an action would cost before you spend anything: the base fee, the CCL-discounted fee you would actually pay, your discount percent, the CCL you hold, your fee-credit balance, and whether you can afford it. Read-only — no side effects. Requires API key. Required: actionType (one of attest, attest-mutual, transfer, lock, unlock, mint, settle; 400 otherwise). Optional: amount — for transfer/lock/settle, echoed back as moveAmount. For transfer/lock/settle the note states the non-custodial gate (those endpoints return 403 today); quoting a gated action does not imply it is callable.
curl -X POST https://ccledger.xyz/api/v1/community/quote \
-H 'X-API-Key: YOUR_KEY' \
-H 'Content-Type: application/json' \
-d '{"actionType":"attest"}'Response:
{
"actionType": "attest",
"currency": "CC",
"baseFee": 2.0,
"fee": 1.667,
"discountPercent": "16.7%",
"cclOnchainHoldings": 100.0,
"balance": 42.5,
"sufficientForFee": true,
"moveAmount": null,
"note": null
}Top-up address:
blueprint-validator-1::1220daab58adcae026bd2ca7ad95014f678bda3ce2a6f91b744cf3ec3d87f09deeacHow to get CC: Buy Canton Coin on Coinbase → transfer to your Loop wallet → send to the Blueprint validator address above. Fee credits auto-credit. Tier auto-upgrades.
Fee-credit top-up (manual fallback). Tops up your fee credits — the non-refundable prepaid CC that pays per-action fees only (never funds value movement; cannot be withdrawn). The primary top-up method is automatic (see above). Use this endpoint only if auto-detection hasn’t processed your transfer yet. Verifies the transaction via gRPC Ledger API (extracts amount from contract arguments, verifies sender is signatory, filters non-transfer contract types). Minimum top-up: 1.0 CC. Your Canton party is bound on the first verified top-up (the verified transfer is the proof of control); after binding, the sender must match (returns 403 on mismatch). Automatically upgrades your key from community (10 RPM) to paid tier (100 RPM). Returns 409 if the transaction was already credited.
curl -X POST https://ccledger.xyz/api/v1/community/deposit \
-H 'X-API-Key: YOUR_KEY' \
-H 'Content-Type: application/json' \
-d '{"transactionId":"canton-tx-abc123def456","amount":50.0}'Response (200 OK):
{
"credited": 50.0,
"newBalance": 92.5,
"tier": "paid",
"rateLimitRpm": 100,
"message": "Deposited 50.0 CC. Paid tier active (100 RPM)."
}Action Types
Seven action types. Three write immutable records (attest, attest-mutual, mint) — fully live. Unlock is live and free. The balance-funded value actions (transfer, lock, settle) are permanently disabled (403 non_custodial); value movement arrives via the delegated facilitation flow (rolling out). All live actions return the same on-chain proof format.
| Action | Status | What It Does | Key Fields |
|---|---|---|---|
| Attest | Live | Immutable record — audit trails, compliance records, document hashes, KYC/AML attestations (2.0 CC fee or 1 trial credit) | dataOwner, dataId, description |
| Attest-Mutual | Live | Immutable record — two-party, co-signed non-repudiation (5.0 CC fee or 1 trial credit) | attestorParty (required), dataOwner, dataId, description |
| Mint | Live | Immutable record for issuance/certificate use cases. Non-issuer — not Canton Coin, not a tradeable token (2.0 CC fee or 1 trial credit) | owner, tokenId, tokenName, amount, metadata, reference |
| Unlock | Live, free | Releases a previously created LockedAmulet back to its owner (no fee; not affected by the non-custodial gate) |
lockId (required, from the lock’s proof), reference |
| Transfer | Disabled (403) | Balance-funded CC transfer — permanently disabled by the non-custodial policy; replaced by the delegated facilitation flow (sender-signed, rolling out) | recipient, amount CC, reference; Idempotency-Key header — retained for the rollout |
| Lock | Disabled (403) | Balance-funded time-locked escrow (LockedAmulet) — permanently disabled; facilitation flow rolling out |
amount CC, duration, reference; Idempotency-Key header — retained for the rollout |
| Settle | Disabled (403) | Balance-funded atomic settlement via the allocation flow — permanently disabled; facilitation flow rolling out | parties (recipient party), amount CC, settlementId, reference; Idempotency-Key header — retained for the rollout |
dataHash too (a hex string, max 128 chars) — there it is a mandatory attached reference, not optional.
Computing a Data Hash
JavaScript / Node.js
const crypto = require('crypto');
const data = JSON.stringify({ invoice: 'INV-001', amount: 5000, currency: 'USD' });
const hash = crypto.createHash('sha256').update(data).digest('hex');
// hash = "5a1c3ef7b9d2..." (64 hex characters)Python
import hashlib, json
data = json.dumps({"invoice": "INV-001", "amount": 5000, "currency": "USD"})
hash = hashlib.sha256(data.encode()).hexdigest()
# hash = "5a1c3ef7b9d2..." (64 hex characters)Bash
echo -n '{"invoice":"INV-001","amount":5000,"currency":"USD"}' | sha256sum | cut -d' ' -f1On-Chain Proof
Every action response includes a proof object. These fields are your verifiable, on-chain evidence that the action settled on Canton MainNet.
| Field | Format | Description |
|---|---|---|
contractId | Hex string (~140 chars) | Unique identifier of the Daml contract on the ledger. This is the canonical reference for the on-chain record. |
transactionId | Hex string (68 chars) | Canton transaction hash. Identifies the specific transaction that created the contract. |
ledgerOffset | Integer | Global monotonically-increasing sequence number. Every transaction on the participant gets a unique offset. |
synchronizerId | global-domain::1220... | The Canton synchronization domain where the transaction was committed. global-domain = Canton MainNet. |
effectiveAt | ISO 8601 timestamp | The timestamp at which the transaction was committed by the Canton sequencer. |
packageId | String or null | Daml package identifier. Always null for community action proofs; populated for enterprise (ledger submission) proofs. |
templateId | String or null | Fully qualified Daml template identifier (e.g., Module:Template). Always null for community action proofs. |
What Makes This Proof Trustworthy
- Finality — Once committed on Canton, a transaction is final, and an attestation record cannot be modified or deleted by anyone, including Blueprint.
- Consensus — The transaction was committed through Canton’s global synchronization protocol, validated by the sequencer and mediator.
- Ordering — The
ledgerOffsetgives a total ordering of all events. You can prove that record A was created before record B. - Timestamping — The
effectiveAttimestamp is set by the Canton sequencer, not by Blueprint’s application.
Trial Credits & CCL Builder Rewards
Trial Credits
Every new API key includes 50 trial credits (max 25 per day). Trial credits fund the record actions only — attest, attest-mutual, and mint — so you can test without paying CC. They never fund value movement (the balance-funded transfer/lock/settle endpoints are disabled for everyone — 403 non_custodial).
- 50 total trial credits per API key, non-renewable
- 25/day cap to prevent abuse (resets daily UTC)
- Automatic refund if a trial action fails on-chain
- Check remaining credits via
GET /api/v1/community/balance(trialCreditsRemaining,trialDailyUsed)
When trial credits are exhausted, record actions return 402 (x402/p402-style — see Error Responses). Top up fee credits by sending CC from your Loop wallet to the Blueprint validator (auto-credited; minimum 1.0 CC) to upgrade to paid tier for unlimited record actions. POST /deposit is available as a manual fallback.
CCL Builder Rewards
Every 10th CC-paid action (not trial) earns 1 CCL Builder Reward on your account, tracked per API key.
- 1 CCL per 10 CC-paid actions (attest, attest-mutual, mint; unlock is free and does not count)
- Discount based on the CCL you hold (
cclOnchainHoldings), tracked on your ccledger account - Hold CCL to reduce your CC cost per action — the discount approaches ~50%
- CCL is never spent on actions; only CC is charged at the discounted rate
- See CCL Builder Rewards for full details on the discount curve
CCL Builder Rewards
CCL is an account-based, non-transferable discount credit for the ccledger ecosystem. Hold CCL to reduce your CC cost per action — the discount approaches ~50%. Your discount is based on the CCL you hold, tracked on your ccledger account. The more CCL you hold, the larger your discount.
cclOnchainHoldings). The more CCL you hold, the larger your discount.Discount Curve
Discount is based on cclOnchainHoldings — the CCL you hold on your ccledger account. Formula: discount = 50% × (1 - 1/(1 + cclOnchainHoldings/200))
| CCL Held | Discount | CC/Action | CC/Mutual |
|---|---|---|---|
| 0 | 0% | 2.000 | 5.000 |
| 10 | 2.4% | 1.952 | 4.881 |
| 50 | 10% | 1.800 | 4.500 |
| 100 | 16.7% | 1.667 | 4.167 |
| 200 | 25% | 1.500 | 3.750 |
| 500 | 35.7% | 1.286 | 3.214 |
| 1,000 | 41.7% | 1.167 | 2.917 |
Discount increases with more CCL held (up to ~50%).
Earning CCL
CCL Builder Rewards are earned automatically. Every 10 CC-paid actions (attest, attest-mutual, mint; unlock is free and does not count) earns 1 CCL on your ccledger account. Trial actions do not count — only CC-paid actions earn CCL. Your Canton party is bound on your first verified fee-credit top-up.
Hold to Save
CCL is a discount credit tracked on your ccledger account. The more CCL you hold, the larger your discount on every action — your cclOnchainHoldings drives your discounted rates. CCL is never spent on actions; only CC is charged, at the discounted rate.
Billing Order
When you submit an action, ccledger deducts in this order: fee credits (at the discounted rate based on the CCL you hold) → trial credits → 402 if all exhausted. CCL is held for the discount only and is never charged.
CCL Endpoint
Your CCL balance, CCL discount balance (cclOnchainHoldings), mint progress, and current discounted rates are all included in the unified GET /api/v1/community/balance endpoint (see Balance & Credits above).
Error Responses
Error response formats vary by endpoint and status code. Below is the exact response body for each error condition.
400 Bad Request
Returned by the registration endpoint when the request body is invalid:
// POST /register — missing or invalid appName
{
"error": "bad_request",
"message": "appName is required",
"status": 400
}// POST /register — appName length violation
{
"error": "bad_request",
"message": "appName must be 3-100 characters",
"status": 400
}Returned by action endpoints when required fields (appName or dataHash) are missing or invalid:
// POST /attest — missing appName
{
"error": "bad_request",
"message": "appName is required",
"status": 400
}// POST /attest — appName exceeds max length
{
"error": "bad_request",
"message": "appName must not exceed 100 characters",
"status": 400
}// POST /attest — missing dataHash
{
"error": "bad_request",
"message": "dataHash is required",
"status": 400
}// POST /attest — dataHash exceeds max length
{
"error": "bad_request",
"message": "dataHash must not exceed 128 characters",
"status": 400
}401 Unauthorized
Returned when the X-API-Key header is missing or contains an invalid key. Note: the 401 response uses {"message":"..."} only — there is no error field.
// No X-API-Key header provided
{
"message": "Unauthorized"
}// Invalid or revoked API key
{
"message": "Invalid API key"
}402 Payment Required (x402/p402-style)
Returned by record actions when trial credits are exhausted (community tier) or fee credits are insufficient (paid tier). The body includes the standard error/message/status plus x402Version: 1 and an accepts array, so an x402/p402 agent client can pay-and-retry with no bespoke integration. Paying = topping up fee credits by sending CC to the payTo gateway party (non-refundable; fees only), then retrying.
{
"error": "payment_required",
"message": "Trial credits exhausted. Send CC to the Blueprint validator to fund your fee credits (auto-credited), or use POST /deposit as fallback.",
"status": 402,
"x402Version": 1,
"accepts": [
{
"scheme": "exact",
"network": "canton",
"asset": "CC",
"maxAmountRequired": "2.0",
"resource": "/api/v1/community/attest",
"payTo": "blueprint-validator-1::1220daab58adcae026bd2ca7ad95014f678bda3ce2a6f91b744cf3ec3d87f09deeac",
"description": "Fund this action by sending CC to the Blueprint validator party, then retry.",
"maxTimeoutSeconds": 300
}
]
}403 Forbidden
Returned by POST /transfer, POST /lock, and POST /settle on every call — the balance-funded value-movement mode is permanently disabled by the enforced non-custodial policy. This is a 403, not a 402: no payment or tier unlocks it. Do not retry; use record actions today, and the delegated facilitation flow for value movement once it ships. (The message names /lock or /settle on those endpoints.)
{
"error": "non_custodial",
"message": "ccledger is non-custodial: prepaid CC credits pay per-action fees only and never fund on-chain value movement. Balance-funded /transfer is permanently disabled. On-chain CC moves from your own wallet via the delegated facilitation flow (rolling out now — see https://ccledger.xyz/docs). Record actions (attest, attest-mutual, mint records) remain fully available.",
"status": 403
}POST /deposit also returns 403 when the transaction sender does not match the Canton party bound to your key by its first verified top-up.
404 Not Found
Returned by GET /api/v1/community/actions/{actionId} when the action ID does not exist or does not belong to your API key:
{
"error": "not_found",
"message": "Action not found",
"status": 404
}429 Too Many Requests
Returned when you exceed the rate limit. The API-key rate limiter includes retryAfterSeconds in the JSON body and a Retry-After HTTP header. The registration rate limiter returns a standard error response.
// Action or query rate limit exceeded
{
"message": "Rate limit exceeded",
"retryAfterSeconds": 60
}// Registration rate limit (3 per IP per 24 hours)
{
"error": "rate_limit_exceeded",
"message": "Maximum 3 registrations per IP per 24 hours",
"status": 429
}500 Internal Server Error
Returned when the Canton ledger operation fails (e.g., participant unavailable). Returns an ActionResponse with status: "failed" and a null proof:
{
"actionId": "7f3a9b2c-1d4e-5f6a-...",
"actionType": "attest",
"status": "failed",
"appName": "my-app",
"dataHash": "a1b2c3d4...",
"mintedAt": null,
"proof": null,
"rewardMarkerCreated": false
}Security Model
ccledger is designed with a minimal trust surface. Here is exactly what the API can and cannot do.
- Non-custodial, enforced in code — ccledger never holds customer CC as a spendable value balance. Prepaid CC is a non-refundable fee credit: it pays per-action fees only, never funds on-chain value movement, and cannot be withdrawn (no withdrawal endpoint exists). The balance-funded value endpoints (transfer, lock, settle) are hard-gated at 403
non_custodial. - Your data is private — Only you can see your actions and balance. No one else can access your data.
- On-chain proof, off-chain data — You send a hash, not raw data. ccledger never sees your underlying records. The hash is stored on-chain as proof, but the data it represents remains entirely within your system.
- Rate limiting — Community tier: 10 RPM (50 trial TX, max 25/day). Paid tier: 100 RPM. Registration: 3 per IP per 24 hours.
- TLS everywhere — All connections use HTTPS with automatic certificate management. No plaintext data in transit.
- Top-up verification — Fee-credit top-ups are verified on-chain via the Canton Ledger API. Your Canton party is bound on the first verified top-up (the verified transfer is the proof of control), and later top-ups must come from the bound party. Amounts are extracted from on-chain contract arguments, not user-supplied.
Rate Limits
Rate limits protect the shared infrastructure and ensure fair access for all developers.
| Endpoint | Limit | Window |
|---|---|---|
| Action endpoints (attest, attest-mutual, transfer, lock, unlock, mint, settle) | 10 RPM (community) / 100 RPM (paid) | Per minute, per API key |
| Query endpoints (actions list, single action) | 10 RPM (community) / 100 RPM (paid) | Per minute, per API key |
| Registration | 3 requests | Per 24 hours, per IP |
| Stats | No limit | Public endpoint |
When rate limited, the API returns HTTP 429 with a JSON body. For API-key rate limits, the response includes a retryAfterSeconds field. See Error Responses for exact response formats.
MCP Server
ccledger exposes 15 MCP tools via Streamable HTTP. AI agents (Claude Desktop, Claude Code, LangChain, CrewAI, etc.) can connect and call the API with zero friction.
Endpoint
https://ccledger.xyz/mcpTools (15)
| Tool | Description | Auth |
|---|---|---|
register_api_key | Register for an API key (50 trial record-action credits) | No |
get_stats | Public network statistics | No |
quote | Dry-run pricing preview — exact fee, CCL discount, balance, and affordability before spending (read-only) | apiKey |
submit_attest | Record an immutable attestation on-chain (2.0 CC fee or 1 trial credit) | apiKey |
submit_attest_mutual | Create mutual attestation proposal (5.0 CC fee or 1 trial credit) | apiKey |
submit_mint | Record an issuance/certificate; non-issuer, not CC (2.0 CC fee or 1 trial credit) | apiKey |
submit_unlock | Release a previously created LockedAmulet by lockId (free — no fee; not gated) | apiKey |
submit_transfer | Gated — the balance-funded mode returns 403 non_custodial; facilitation flow rolling out | apiKey |
submit_lock | Gated — the balance-funded mode returns 403 non_custodial; facilitation flow rolling out | apiKey |
submit_settle | Gated — the balance-funded mode returns 403 non_custodial; facilitation flow rolling out | apiKey |
get_balance | Fee credits, CCL discount balance (drives discount), tier, CCL mint progress, discounted rates | apiKey |
deposit_cc | Manual fee-credit top-up fallback (top-ups are auto-detected; min 1.0 CC; non-refundable) | apiKey |
list_actions | List past actions | apiKey |
get_action_by_id | Get single action by UUID | apiKey |
get_action | Alias for get_action_by_id | apiKey |
Connect from Claude Desktop / Claude Code
Add to your claude_desktop_config.json or project .mcp.json:
{
"mcpServers": {
"ccledger": {
"type": "url",
"url": "https://ccledger.xyz/mcp"
}
}
}AI Discovery Files
- llms.txt — LLM-optimized overview (llmstxt.org spec)
- llms-full.txt — Complete reference for agents
- .well-known/agent.json — A2A agent card
- openapi.json — OpenAPI 3.1 spec with x-llm-hint annotations
FAQ
POST /api/v1/community/quote; check your discount via GET /api/v1/community/balance.non_custodial. When the delegated facilitation flow ships, you keep your own wallet and keys, sign a CreateTransferCommand yourself, and ccledger relays and submits it as the featured application (CIP-0104 confirmer) — it never takes custody of your CC.blueprint-validator-1::1220daab58adcae026bd2ca7ad95014f678bda3ce2a6f91b744cf3ec3d87f09deeac) — fee credits auto-credit within seconds, your Canton party is bound on this first verified top-up, and your tier upgrades to paid automatically. Fee credits are non-refundable and pay fees only — they never fund on-chain value movement and cannot be withdrawn. POST /deposit is available as a manual fallback.false. You can ignore it.contractId or transactionId from the proof object. These can be looked up against any Canton participant connected to the global domain. You can also query your actions back through the API using GET /api/v1/community/actions/{actionId}.cclOnchainHoldings), tracked on your ccledger account — discount = 50% × (1 - 1/(1 + cclOnchainHoldings/200)). The more CCL you hold, the larger your discount. CCL is never spent on actions; only CC is charged at the discounted rate. See CCL Builder Rewards for full details.LockedAmulet back to its owner. Three are the legacy balance-funded value actions — transfer, lock, settle — permanently disabled by the non-custodial policy (403 non_custodial); value movement arrives via the delegated facilitation flow (rolling out). All live actions return the same on-chain proof format.Verification
How to verify that your on-chain records are real and immutable.
Via the API
Query any action by its ID to retrieve the full proof:
curl https://ccledger.xyz/api/v1/community/actions/YOUR_ACTION_ID \
-H 'X-API-Key: YOUR_KEY'Via the Stats Endpoint
Verify aggregate counts match your expectations:
curl https://ccledger.xyz/api/v1/community/statsData Hash Verification
To verify that a record matches your original data:
- Retrieve the action from the API using its
actionId - Recompute the SHA-256 hash of your original data
- Compare the hash against the
dataHashfield in the response - If they match, the on-chain record corresponds to your original data
Canton Participant Verification
For maximum independence, you can verify contracts directly against a Canton participant. The contractId in the proof object is the canonical Daml contract identifier on the global domain. Any Canton participant with visibility to Blueprint’s contracts can look up this ID.
Ready to build?