Skip to main content

/docs/credits-api

Credits API reference

The IICP credit system tracks token-based compute spend across the mesh. Coordinators use the quote pre-flight to estimate cost before dispatching CIP tasks. Workers earn credits via the award endpoint after completing a sub-task. All amounts are denominated in credit units — 1 credit ≈ 1 000 inference tokens at the base rate.

Heads up — this is an API reference.You only need it if you're building tooling that reads balances or settles credits directly. If you're just running a node, settlement is automatic — nothing here to do. The full endpoint reference is below.

GET/api/v1/credits/balance

Returns the credit balance for the authenticated node. The quickest way is the CLI: iicp-node credits (auto-selects your node; v0.7.40+). The API endpoint below is useful for scripts and custom dashboards.

Auth

Authorization: Bearer <node_token>

Request

curl -sf https://iicp.network/api/v1/credits/balance \
  -H "Authorization: Bearer <node_token>"

Response 200

{
  "node_id": "550e8400-...",
  "balance": 38.5,
  "unit": "credit",
  "tokens_per_credit": 1000
}

GET/api/v1/credits/summary

Lifetime income / spending / balance for the authenticated node — earned, spent, and what's left, in one call. reconciles is an integrity check: it is true only when balance == total_earned − total_spent. A tampered or inconsistent ledger surfaces as false — so the numbers are self-checking, not taken on trust.

Operator wallet. When the node is delegation-bound to an operator identity, the response also carries an operator_wallet object that rolls up balance, earned, spent, transaction count and reconcile status across allof the operator's non-archived nodes — one wallet keyed by your identity, backed by per-node audit rows. It is nullwhen the node is not yet operator-bound; the operator's raw public key is never returned.

Auth

Authorization: Bearer <node_token>

Request

curl -sf https://iicp.network/api/v1/credits/summary \
  -H "Authorization: Bearer <node_token>"

Response 200

{
  "node_id": "550e8400-...",
  "total_earned": 142.5,
  "total_spent": 38.25,
  "balance": 104.25,
  "tx_count": 27,
  "reconciles": true,
  "unit": "credit",
  "tokens_per_credit": 1000,
  "operator_wallet": {        // null when the node is not operator-bound
    "total_balance": 263.75,  // SUM across all the operator's non-archived nodes
    "total_earned": 302.0,
    "total_spent": 38.25,
    "tx_count": 82,
    "node_count": 3,
    "reconciles": true,
    "operator_fingerprint": "4f93aa10b2c7"
  }
}

GET/api/v1/credits/quote

CIP pre-flight — estimates the credit cost for a task before dispatch (S.12 §8). The coordinator calls this before dispatching to check if the consumer has sufficient balance. Quote is valid for 60 seconds.

Auth

Authorization: Bearer <node_token> (coordinator node token)

Query parameters

ParameterDescription
intentRequired. Intent URN for the task (e.g. urn:iicp:intent:llm:chat:v1)
max_tokensRequired. Positive integer — the maximum token budget for the task; used to compute the credit estimate. Missing or non-positive values return 422.
nodesOptional. Comma-separated node IDs to quote against. Omit to quote against all eligible nodes
min_reputationOptional. Float 0–1. Excludes candidate nodes below this reputation score before quoting.

Request

curl -sf 'https://iicp.network/api/v1/credits/quote?intent=urn:iicp:intent:llm:chat:v1&max_tokens=500' \
  -H "Authorization: Bearer <node_token>"

Response 200

{
  "quote_id": "q_AbC123xyz789",
  "estimated_credits": 0.5,
  "min_credits": 0.5,
  "max_credits": 0.5,
  "price_per_1000_tokens": 1.0,
  "nodes_quoted": 7,
  "quote_expires_at": "2026-05-22T15:01:00Z",
  "currency": "iicp_credits",
  "consumer_balance": 38.5,
  "effective_balance": 263.75,
  "balance_scope": "operator_wallet",
  "operator_wallet_balance": 263.75,
  "balance_sufficient": true
}

If balance_sufficient: false, the consumer identity does not have enough effective credits to cover the estimated cost. Operator-bound nodes use operator_wallet; unbound nodes use their node-local balance. The coordinator should not dispatch. min_credits and max_credits bracket the per-node price spread (they collapse to one value when a single rate applies).

POST/api/v1/credits/award

Submits a signed CIPWorkerReceipt to credit tokens to a worker node. The coordinator calls this after receiving a CIP RESPONSE from a worker. The receipt HMAC signature is verified before crediting.

Note for operators: You do not call this endpoint directly. The coordinator proxy submits it automatically after receiving a valid CIP RESPONSE. See CIP worker setup for the automated flow.

Auth

Authorization: Bearer <coordinator_node_token>

Request body

FieldDescription
node_idUUID of the worker node to credit
task_idTask ID from the CIP CALL
tokens_usedInteger token count from the worker result
nonce32+ char random hex — prevents replay attacks
expires_atISO-8601 timestamp — receipt must be submitted before this time (5 min from issue)
response_hashRequired. 64-char lowercase hex SHA-256 of the worker response — binds the receipt to the result it credits
signature64-char HMAC-SHA256 hex of the canonical message (see below)
amountCredits to award — must not exceed ceil(tokens_used / 1000) × credit_cost_multiplier × 1.1
cip_parent_task_idOptional. UUID of the coordinator's original task
cip_session_keyOptional. Session key from the CIP CALL envelope
reasonOptional. Audit string persisted with the ledger entry

Response 200

{
  "node_id": "550e8400-...",
  "awarded": 0.5,
  "balance": 39.0,
  "spent": 0.5,
  "spend_scope": "operator_wallet",
  "debit_count": 1,
  "spend_reason": null
}

balance is the new post-award balance. spent is the amount debited from the querying identity. Operator-bound consumers spend from their pooled wallet; unbound consumers spend from the node-local balance.spend_reason is null on success or an insufficient-balance reason if the debit failed (award still succeeds — debit is SHOULD, not MUST per S.12 v0.6.11). All receipt-validation failures return HTTP 422 with error code IICP-E027.

Nonce lifecycle

  1. Worker generates a 32+ char random hex nonce when building the receipt.
  2. Nonce is included in the HMAC canonical message and in the receipt body.
  3. Directory rejects any nonce already seen within a 24-hour window (atomic set-if-not-exists) — this prevents replay attacks where a receipt is submitted twice.
  4. Receipt must be submitted before expires_at (5 minutes from issue time).

HMAC canonical message

The signature covers this deterministically-ordered string, encoded as UTF-8:

"{task_id}:{tokens_used}:{cip_parent_task_id}:{cip_session_key}:{nonce}:{response_hash}"
# Extended form (CIP v0.6.11+): append querying_node_id when present:
# "{task_id}:...:{response_hash}:{querying_node_id}"
# Use empty string for optional fields (cip_parent_task_id, cip_session_key) when absent:
# e.g. "550e8400-...:142:::a3f2b8c9...:e3b0c44298fc1c149afbf4c8996fb924..."

Signed with HMAC-SHA256 using the worker's node HMAC key — provisioned by the directory at registration, distinct from the bearer token.

GET/api/v1/credits/transactions

Returns the ledger transaction history for the authenticated node.

curl -sf https://iicp.network/api/v1/credits/transactions \
  -H "Authorization: Bearer <node_token>"

Error codes

CodeHTTPWhen it occurs
IICP-E036402Proxy pre-dispatch credit check failed — consumer S-Credit balance is below the computed routing cost. The proxy aborts before dispatching. Check balance with iicp-node credits or GET /api/v1/credits/balance.
IICP-E027422CIPWorkerReceipt rejected at /credits/award: HMAC signature mismatch, HMAC key not provisioned, receipt expired, nonce replayed, amount exceeds ceiling, or rate limit exceeded (1 000 credits/hr per node)
validation_error422/credits/quote: intent or max_tokens missing, or max_tokens not a positive integer

Rate limits

LimitValue
Max credits awarded per hour per node1 000
Receipt nonce validity window300 s (5 min)
Nonce replay dedup window24 h