Credidax
Credidax checks each request a developer's AI agent sends to another operator's service against the agent's mandate and credit, then records the outcome on a receipt.
In development · API contract v0.5 · Credit counted in test units with no cash value
Example. Values from the Credidax v0.5 contract fixtures.
Authorization check for one request
agent_042 asks svc_normalize to run op_normalize for 3 units.
- Mandate
mandate_001allowsop_normalize - 3 units is within the 5-unit limit per request
- 3 units is within the mandate's 10-unit total
- 20 of the agent's 20 units are available
authorized3 units reserved, 17 left
One agent buys a three-unit job from another operator
The requester agent, agent_042, belongs to one account. The normalization service belongs to a second account. Credidax records each state the request passes through.
Example. Routes, field names, and amounts come from the v0.5 API contract and its fixtures. The transaction ID, receipt ID, and timestamps after registration are sample values.
The developer registers the agent
The developer registers
agent_042. Its credit profile starts at a score of 500 with a credit limit of 20 units.POST /v1/agents 201 Created
{ "id": "agent_042", "operator_account_id": "acct_requester", "status": "active", "capabilities": ["normalize-record"], "created_at": "2026-10-17T20:00:00Z" }GET /v1/agents/agent_042/credit 200 OK
{ "agent_id": "agent_042", "scoring_version": "v0.5.0", "score": 500, "credit_limit": 20, "reserved_credit": 0, "updated_at": "2026-10-17T20:00:00Z" }A mandate sets what the agent may spend
The account owner lets
agent_042call one operation on one service, up to five units per request and 10 units in total, until December 1, 2026. The owner can revoke the mandate at any time.POST /v1/mandates 201 Created
{ "id": "mandate_001", "principal_account_id": "acct_requester", "agent_id": "agent_042", "allowed_operations": ["op_normalize"], "allowed_services": ["svc_normalize"], "per_action_limit": 5, "total_limit": 10, "expires_at": "2026-12-01T00:00:00Z", "revoked_at": null, "parent_mandate_id": null }The service lists its operation and price
Service listings are public. The operation publishes its input schema and its price of three units, so the agent knows what to send and how much credit the call will hold.
GET /v1/services/svc_normalize/operations 200 OK
[ { "id": "op_normalize", "service_id": "svc_normalize", "input_schema": { "type": "object", "required": ["text"], "properties": { "text": { "type": "string" } } }, "price_units": 3, "constraints": {} } ]Credidax reserves three units and calls the provider
Credidax checks the mandate and the agent's credit, holds three units, and sends the job to the provider. The response carries a transaction ID that stays the same while the provider works.
POST /v1/transactions
Authorization: Bearer <agent credential> Idempotency-Key: demo-request-001 Content-Type: application/json { "requester_agent_id": "agent_042", "operation_id": "op_normalize", "mandate_id": "mandate_001", "input": { "text": " Copper Lake " }, "requested_units": 3 }202 Accepted
{ "transaction": { "id": "txn_example", "requester_agent_id": "agent_042", "operation_id": "op_normalize", "mandate_id": "mandate_001", "idempotency_key": "demo-request-001", "status": "proposed", "requested_units": 3, "created_at": "2026-10-17T20:01:00Z" }, "receipt_id": null, "status_url": "/v1/transactions/txn_example" }Settlement frees the credit and issues a receipt
The provider reports the job completed. Settlement releases the reservation, so
agent_042has all 20 units available again.The receipt lists the evidence and journal entries behind it. A redacted copy sits at
/v1/public/receipts/{id}for anyone holding the link.GET /v1/receipts/rcpt_example 200 OK
{ "id": "rcpt_example", "transaction_id": "txn_example", "provider_outcome": "completed", "evidence_ids": ["ev_example_1"], "journal_entry_ids": ["jrn_example_1", "jrn_example_2"], "issued_at": "2026-10-17T20:01:05Z" }Available credit at each state, in test units State Available proposed20 authorized20 reserved17 submitted17 acknowledged17 settled20
What Credidax gives developers
The examples use the same agent and mandate as the transaction above.
Denials before the provider runs
Suppose
agent_042already had 19 of its 20 units reserved. The same three-unit request would fail the credit check, and Credidax would return the denial without calling the provider.Example. The message text and request ID are sample values.
POST /v1/transactions 403 Forbidden
{ "error": { "code": "CREDIT_LIMIT_EXCEEDED", "message": "Requested 3 units; 1 unit available.", "request_id": "req_example" } }Denial cases in the v0.5 fixtures Request Code 3 units requested while 19 of 20 are reserved CREDIT_LIMIT_EXCEEDEDop_buyrequested under a mandate forop_normalizeOUT_OF_SCOPEMandate revoked before the request MANDATE_REVOKEDMandate expired on Oct. 1, 2026 MANDATE_EXPIRED8 units requested against a 5-unit limit per request ACTION_LIMIT_EXCEEDEDIdempotency key reused with a different body IDEMPOTENCY_CONFLICTOne reservation per request, even on retry
Every transaction call carries an
Idempotency-Key. A retry with the same key and body returns the original response, so Credidax holds the credit once. The same key with a different body returnsIDEMPOTENCY_CONFLICT.Retries with Idempotency-Key: demo-request-001Retry Result Same key, same body The original response for txn_exampleSame key, different body IDEMPOTENCY_CONFLICTA score and a limit for each agent
Credit belongs to one registered agent. Its score runs from 0 to 1000 and moves only on that agent's own evidence, even when one operator runs several agents.
The v0.5 scoring function is deterministic, and each change cites the evidence events behind it. The score is experimental, and no one has validated it as a forecast of how an agent behaves elsewhere.
- provider_completed
- provider_declined
- provider_failed
- timeout
- unauthorized_attempt
- dispute_opened
- dispute_resolved
- transaction_reversed
The evidence events that can move a score in v0.5 Narrower mandates for helper agents
An agent can hand part of a job to a helper agent under a child mandate that names its parent. A child mandate that asks for more than its parent allows returns
DELEGATION_EXCEEDS_PARENT.Example.
agent_043and its limits are sample values.POST /v1/mandates
{ "agent_id": "agent_043", "parent_mandate_id": "mandate_001", "allowed_operations": ["op_normalize"], "per_action_limit": 3, "total_limit": 6 }Plain HTTP calls with JSON bodies
Every route sits under
/v1, and each step in the example is one HTTP call, so an agent framework is optional. Authenticated calls take a bearer credential, and transaction calls also need anIdempotency-Key.Anyone with a receipt link can read the redacted public copy, which leaves out personal details and credentials.
Routes in the v0.5 API contract Method Path Does POST /v1/accountsCreate an account POST /v1/agentsRegister an agent POST /v1/agents/{id}/credentialsIssue a new agent credential GET /v1/agents/{id}/creditRead an agent's credit profile GET /v1/servicesList services, public POST /v1/servicesRegister a service GET /v1/services/{id}/operationsList a service's operations, public POST /v1/mandatesCreate a mandate POST /v1/mandates/{id}/revokeRevoke a mandate POST /v1/transactionsSubmit a transaction GET /v1/transactions/{id}Read transaction status POST /v1/transactions/{id}/settleSettle on the provider's confirmation POST /v1/transactions/{id}/disputeOpen a dispute GET /v1/receipts/{id}Full receipt with evidence GET /v1/public/receipts/{id}Redacted receipt, public GET /v1/healthService health, public
Ask for developer access
Write to us with what your agent does and which service it would call.