Skip to Content
API ReferenceAgents API

Agents API

The Agents API issues and manages AI-agent identity: did:solidus DIDs scoped to agents (never their operator), BBS+ credentials, ERC-8004 on-chain passports, and spend mandates — a scoped, verifiable spend authorization a counterparty can check without calling back to Solidus.

Base URL: https://agents.solidus.network/v1

This is the surface @solidus/mcp and the agent SDKs consume directly.


The full spec

Every route on this page is generated from the same zod schemas the server validates requests against — the spec cannot drift from what the server actually does, because it isn’t hand-maintained. This page is a curated tour, not the exhaustive reference; for the complete, current request/response shape of every route, use:

  • Interactive reference: https://agents.solidus.network/documentation
  • Raw OpenAPI 3.1 document: https://agents.solidus.network/openapi.json

Authentication

Operator-gated routes accept a single operatorBearer scheme with two interchangeable credential shapes, both sent as Authorization: Bearer <token>:

  • Operator JWT — minted by POST /v1/operators, expires per the server’s configured TTL.
  • API key — a revocable sk_... key from POST /v1/api-keys, for long-lived programmatic/integrator use.
curl https://agents.solidus.network/v1/agents \ -H "Authorization: Bearer sk_..."

A handful of routes are public by design — no auth, because the proof of authorization travels in the request itself:

  • POST /v1/mandates/check — the mandate-check flow below
  • POST /v1/credentials/verify — live credential verification
  • GET /v1/agents/{agentId}/card, GET /v1/credentials/{credentialId}/descriptor, GET /v1/status-lists/{listId} — resolvable public documents

Key flow: register an operator, create an agent

# 1. Register an operator — returns a bearer token curl -X POST https://agents.solidus.network/v1/operators \ -H "content-type: application/json" \ -d '{"kyc": {"credentialRef": "urn:solidus:credential:kyc-abc", "assuranceLevel": "substantial"}}'
// Response 201 { "operator": { "id": "...", "tenantId": "...", "kycAssuranceLevel": "substantial", "createdAt": "..." }, "token": "eyJhbGciOiJFZERTQSIs..." }
# 2. Create an agent under that operator — gets its own did:solidus DID curl -X POST https://agents.solidus.network/v1/agents \ -H "Authorization: Bearer eyJhbGciOiJFZERTQSIs..." \ -H "content-type: application/json" \ -d '{"custody": "managed"}'
// Response 201 { "agent": { "id": "...", "operatorId": "...", "did": "did:solidus:testnet:...", "custody": "managed", "status": "active", "capabilities": [], "passport": null, "createdAt": "..." } }

Key flow: the mandate-check — the wedge feature

A spend mandate is a BBS+ credential that authorizes an agent to spend up to a limit, in a currency, on a rail, until an expiry — issued once via POST /v1/agents/{agentId}/mandates, then checked by any counterparty without ever calling back to the issuing operator. The proof travels as an X-Solidus-Mandate envelope header; the check is public, unauthenticated, and fails closed at every step (unknown mandate, expired, revoked, over-limit, wrong currency, wrong rail).

This is exactly what @solidus/mcp’s check_mandate tool calls:

curl -X POST https://agents.solidus.network/v1/mandates/check \ -H "content-type: application/json" \ -d '{ "envelope": "<the X-Solidus-Mandate header value>", "amount": "12.50", "currency": "USDC", "rail": "x402" }'
// Response 200 — authorized { "authorized": true, "agentDid": "did:solidus:testnet:...", "principalDid": "did:solidus:testnet:...", "maxAmount": "50", "expiresAt": "2026-08-01T00:00:00.000Z", "verifiedAsOf": "2026-07-22T01:00:00.000Z" }
// Response 200 — denied (any reason: unknown mandate, expired, revoked, over-limit, wrong currency/rail, invalid proof) { "authorized": false, "reason": "mandate revoked" }

authorized/reason are passed through verbatim by @solidus/mcp — this is the exact refusal contract that makes the whole product trustworthy, and it does not change without a corresponding SDK release.


Route index

Route groupBase pathAuth
Operators/v1/operatorsPublic register, operatorBearer for reads/updates
Agents/v1/agentsoperatorBearer (except the public agent card)
Credentials/v1/agents/{agentId}/credentialsoperatorBearer (issue/list/revoke); public verify + descriptor live under /v1/credentials
Status lists/v1/status-lists/{listId}Public (draft-ietf-oauth-status-list JWT)
Mandates/v1/agents/{agentId}/mandates, /v1/mandates/checkoperatorBearer for lifecycle; the check itself is public
Billing/v1/billing/usageoperatorBearer
Webhooks/v1/webhooksoperatorBearer
API keys/v1/api-keysoperatorBearer
ERC-8004/v1/erc8004operatorBearer

For each route’s exact request body, response shape, and status codes, see https://agents.solidus.network/documentation.


Error format

Errors follow RFC 7807 Problem Details, the same shape across every route:

{ "type": "https://solidus.network/errors/validation", "title": "Validation Error", "status": 400, "detail": "envelope: Required", "instance": "/v1/mandates/check" }

What generated clients cover

A generated client (Go, Python, and others — in progress) wraps this HTTP surface only. It will not replace @solidus/agent-identity’s BBS+ selective disclosure, key handling, or credential-bundle helpers — those are libraries, not HTTP wrappers. Use the TypeScript SDK packages for that; use a generated client (or this spec directly) for calling the API from another language.

Last updated on