API reference
Every endpoint the gateway serves, grouped by how it authenticates. The base
URL is https://www.saxeonetwork.tech/__api/v1.
This page is written by hand; openapi.json is generated from the router and
is the one that cannot drift. If a route is in the spec and not here, the spec
is right and this page is stale — tell us. Last reconciled against the live
spec on 2026-09-14: every path it lists appears below. One path is listed the
other way round — POST /v1/terminal/run is in the spec but not mounted on
the production deployment, because the spec describes the build and that route
is behind a flag.
There are four ways a request authenticates:
- Public routes take no credential. They are per-IP rate limited.
- API-key routes take a
sk-sable_key asAuthorization: Bearer(see Authentication). These are the routes an agent calls. - Session routes take a
sess_Sign-In With Ethereum bearer session and are the account-management surface behind the dashboard. - Admin routes take the operator
SAXEO_ADMIN_TOKEN. The whole group is unmounted (returns404) when no token is configured.
Every billable response carries a signed, metadata-only receipt you can verify without trusting Saxeo.
Machine-readable spec
The gateway describes itself. An OpenAPI 3.1 document covering every wired
endpoint — paths, methods, auth scheme, request and response schemas, the
x-sable-* receipt headers, and the 402 x402 accepts shape — is served
straight off the API:
curl https://www.saxeonetwork.tech/__api/openapi.json
The same document is at https://www.saxeonetwork.tech/__api/v1/openapi.json for
clients pinned to the version prefix, and it is generated from the router
itself.
What the spec is checked for, and what it is not
Be precise about how much that document is worth, because the honest answer is
"the route list, not the payloads". A test parses main.rs and fails the build
when the two disagree, but only on the things it actually compares:
- Checked. Every mounted
(path, method)appears in the spec, and every documented one is mounted — neither can drift. Each operation has a summary, a declared auth scheme, a uniqueoperationId, a declared response for success, a declaration for every path parameter it names, and$refs that all resolve. - Not checked. Whether a declared response schema matches the JSON a handler actually serializes. Nothing compares the two, so a schema here can be wrong. A batch of them was: thirty list operations declared a bare array while the gateway served a named-key envelope, and they were corrected in the document rather than in the handlers, because the served shape is the one clients already depend on. See List shapes for the envelope each list returns.
So generate a client from it, but check a generated list type against one live response before you ship. Request bodies and single-object responses are the parts you can lean on; list envelopes are the part to verify. Where the two ever disagree the served shape is the one that is real — we will not silently change a served shape to match a document.
npx @openapitools/openapi-generator-cli generate \
-i https://www.saxeonetwork.tech/__api/openapi.json \
-g typescript-fetch -o ./sable-client
A few notes for generators. Paths carry their own /v1, so the declared server
is the bare origin — don't add the prefix twice. A handful of literal segments
overlap a template (/v1/receipts/shared/{id} beside /v1/receipts/{id}/share,
/v1/evals/monitors beside /v1/evals/{id}, /v1/services/directory and
/v1/services/manage/{key} beside /v1/services/{slug}); the gateway resolves
these by preferring the literal segment, and those names are reserved, but a
strict generator may want them pinned. Groups that a deployment has not
configured — the admin surface, /metrics, passkeys — are described here even
where they are unmounted and return 404.
For hand-written integrations you usually want the OpenAI or Anthropic SDK pointed at the base URL instead; see SDKs and Quickstart.
List shapes and pagination
Around forty-five endpoints return a list, and they do not all return it the same way. There is no rule that predicts which shape an endpoint uses — the conventions accumulated as the surface grew, and changing a served shape now would break callers who already parse it, so this section documents what is actually served rather than pretending to a consistency that is not there. Read it before you write a parser.
The three envelopes
1. Bare array. The body is the array. There is nowhere to put a cursor or a total, which is why nothing here paginates.
[{ "id": "key_…" }, { "id": "key_…" }]
GET /v1/keys · /v1/webhooks · /v1/webhooks/:id/deliveries ·
/v1/nodes · /v1/auth/wallets · /v1/auth/sessions · /v1/auth/passkeys ·
/v1/orgs · /v1/orgs/:id/members · /v1/orgs/:id/invites ·
/v1/billing/deposits · /v1/services/manage/:slug/calls ·
/v1/usage/sandboxes · /v1/sandboxes/sessions · /v1/sandboxes/snapshots
2. OpenAI list object. {"object": "list", "data": [...]}, used where the
endpoint is OpenAI-compatible and a client SDK expects that literal shape.
{ "object": "list", "data": [{ "id": "file-…" }], "has_more": false }
GET /v1/models · /v1/images/models · /v1/videos/models · /v1/files ·
/v1/batches · /v1/videos/generations. Only /v1/batches carries
has_more; the others omit it.
3. Named-key envelope. The array sits under a key named for the resource, alongside whatever context that endpoint owes you — a cap, a count, a trust statement.
{ "calls": [{ "id": "call_…" }], "count": 3, "cap": 500, "trust_model": "…" }
Everything else, keyed as follows:
| Endpoint | Array key | Also in the envelope |
|---|---|---|
GET /v1/agents | Array keyagents | Also in the envelope— |
GET /v1/agents/:id/runs | Array keyruns | Also in the envelopeagent_id |
GET /v1/calls, /v1/calls/mine | Array keycalls | Also in the envelopecount, cap, trust_model |
GET /v1/evals | Array keyevals | Also in the envelope— |
GET /v1/evals/:id/runs | Array keyruns | Also in the envelope— |
GET /v1/evals/monitors | Array keymonitors | Also in the envelope— |
GET /v1/ghost/sessions | Array keysessions | Also in the envelope— |
GET /v1/guardrails | Array keyguardrails | Also in the envelope— |
GET /v1/guardrails/findings | Array keyevents | Also in the envelopeenforced, scanned_receipts, blocked, totals, note |
GET /v1/judge/verdicts | Array keyverdicts | Also in the envelopetrust_model |
GET /v1/legacy/plans | Array keyplans | Also in the envelopemax_active_plans, custody |
GET /v1/legacy/attesting | Array keyplans | Also in the envelope— |
GET /v1/legacy/claims | Array keyclaims | Also in the envelope— |
GET /v1/mandates | Array keymandates | Also in the envelope— |
GET /v1/mcp-servers | Array keyservers | Also in the envelopedefault_price_micro_usd_per_call |
GET /v1/memory/collections | Array keycollections | Also in the envelope— |
GET /v1/nav/:asset_id/history | Array keyrecords | Also in the envelopeasset_id, note |
GET /v1/attestations/:asset_id/history | Array keyversions | Also in the envelopeasset_id, subject_ref, note, disclaimer |
GET /v1/passport | Array keyagents | Also in the envelopecount, ordered_by |
GET /v1/policies | Array keypolicies | Also in the envelope— |
GET /v1/post/inbox | Array keymessages | Also in the envelopenext_cursor, unread |
GET /v1/post/outbox | Array keymessages | Also in the envelopenext_cursor |
GET /v1/post/threads/:thread_id | Array keymessages | Also in the envelopethread_id |
GET /v1/relays | Array keyrelays | Also in the envelope— |
GET /v1/runs | Array keyruns | Also in the envelope— |
GET /v1/services | Array keyservices | Also in the envelope— |
GET /v1/services/directory | Array keyservices | Also in the envelopeordering, settlement |
GET /v1/services/manage/:slug/calls | Array keycalls | Also in the envelopeservice_id, slug |
GET /v1/state | Array keykeys | Also in the envelopenamespace |
GET /v1/usage/events | Array keyevents | Also in the envelopenext_cursor |
GET /v1/billing/ledger | Array keyentries | Also in the envelopenext_cursor, has_more |
GET /v1/vault/assets | Array keyassets | Also in the envelope— |
GET /v1/vault/assets/:id/holders | Array keyholders | Also in the envelopeasset_id, total_micro_usd, pending_claims_micro_usd, issued_micro_usd |
GET /v1/vault/assets/:id/attesters | Array keyattesters | Also in the envelopeasset_id, roles |
GET /v1/vault/assets/:id/attestations | Array keyattestations | Also in the envelopeasset_id, trust_model |
GET /v1/vault/assets/:id/documents | Array keydocuments | Also in the envelopeasset_id |
GET /v1/vault/transfers | Array keytransfers | Also in the envelope— |
GET /v1/vault/distributions | Array keydistributions | Also in the envelope— |
GET /v1/vault/assets/:id/view-grants | Array keygrants | Also in the envelope— |
GET /v1/vault/claims | Array keyclaims | Also in the envelope— |
What paginates
Four endpoints paginate. Every other list in this document returns one page and stops — see What truncates for where each one stops.
| Endpoint | Page size | Cursor field | Tells you there is more |
|---|---|---|---|
GET /v1/usage/events | Page size?limit= 1–1000, default 100 | Cursor fieldnext_cursor | Tells you there is morenext_cursor is non-null |
GET /v1/billing/ledger | Page size?limit= 1–1000, default 200 | Cursor fieldnext_cursor | Tells you there is morehas_more, stated rather than inferred |
GET /v1/post/inbox | Page size?limit= 1–200, default 50 | Cursor fieldnext_cursor | Tells you there is morenext_cursor is non-null |
GET /v1/post/outbox | Page size?limit= 1–200, default 50 | Cursor fieldnext_cursor | Tells you there is morenext_cursor is non-null |
A cursor is opaque: pass the next_cursor you were given back as
?cursor=, verbatim, and stop when it comes back null. Do not parse one, and
do not construct one — the four encode three different things inside it
(/v1/usage/events and the two post boxes each carry a composite key, with a
different separator each; /v1/billing/ledger carries a bare row id), and
those encodings are internal. /v1/billing/ledger refuses an unparseable cursor with
a 400 rather than silently restarting at page one, because quietly handing
an auditor a different slice of the same money trail is the worse failure.
What truncates
Every other list endpoint returns at most one page and says nothing about
it. There is no has_more, no next_cursor, and no total: a response of
exactly N rows may be the whole answer or the first N of many, and only the
cap below tells you which. Where an endpoint enforces a per-account cap at
creation time, the cap is also the ceiling on the list, so you always have
everything; those are marked complete.
| Cap | Endpoints |
|---|---|
| 25 + 14 | Endpoints/v1/usage — a fixed dashboard slice: the 25 most recent events and 14 daily buckets, alongside lifetime totals. Reconcile against /v1/usage/events, not this |
| 50 | Endpoints/v1/webhooks/:id/deliveries |
| 100 | Endpoints/v1/agents/:id/runs · /v1/billing/deposits · /v1/evals/:id/runs · /v1/ghost/sessions · /v1/legacy/plans · /v1/legacy/attesting · /v1/legacy/claims · /v1/relays · /v1/usage/sandboxes · /v1/sandboxes/sessions · /v1/sandboxes/snapshots · /v1/vault/transfers · /v1/batches (sets has_more) |
| 200 | Endpoints/v1/evals (complete: 200/account) · /v1/evals/monitors (complete: 50/account) · /v1/files · /v1/guardrails · /v1/guardrails/findings (?limit= 1–1000, default 200 — the receipts scanned, echoed back as scanned_receipts) · /v1/memory/collections (complete: 100/account) · /v1/mandates · /v1/orgs/:id/invites · /v1/runs · /v1/services/directory · /v1/vault/distributions |
| 500 | Endpoints/v1/calls, /v1/calls/mine (complete: 500/account, and the envelope carries count and cap) · /v1/post/threads/:thread_id (oldest-first, so the cap drops the newest messages) · /v1/passport |
| 1000 | Endpoints/v1/state (complete: 10,000 keys/account — a namespace over 1000 keys does truncate) |
?limit=, default 50, max 200 | Endpoints/v1/judge/verdicts · /v1/nav/:asset_id/history · /v1/videos/generations |
?limit=, default 50, unclamped | Endpoints/v1/attestations/:asset_id/history — a large ?limit= is honored as written, unlike the row above. Treat 200 as the supported ceiling |
| No limit | Endpoints/v1/keys · /v1/webhooks · /v1/policies · /v1/mcp-servers · /v1/agents · /v1/services · /v1/auth/wallets · /v1/auth/sessions · /v1/auth/passkeys (complete: 20/account) · /v1/orgs · /v1/orgs/:id/members · /v1/nodes · /v1/vault/assets · /v1/vault/assets/:id/* · /v1/vault/claims — these return the account's full set, so they are complete by construction, but they will grow without bound |
If you need a complete record of metered activity or of money, use
GET /v1/usage/events and GET /v1/billing/ledger: they are the two surfaces
that paginate precisely because they are the two an auditor reconciles against,
and a truncated audit trail is worse than no audit trail.
Public
No authentication.
| Method | Path | Notes |
|---|---|---|
| GET | Path/ | NotesService banner JSON. |
| GET | Path/healthz | NotesLiveness check. Returns ok. |
| GET | Path/openapi.json | NotesThe OpenAPI 3.1 document for this whole surface. Also at /v1/openapi.json. |
| GET | Path/v1/models | NotesModel catalog under stable Saxeo ids, with per-Mtok pricing. Models pinned to an unconfigured provider are omitted. |
| GET | Path/v1/images/models | NotesImage-generation model catalog with per-image pricing. Empty until an image provider is enabled on the deployment. |
| POST | Path/v1/images/verify | NotesCheck a generated asset's signed provenance manifest (image or video). Extracts the embedded manifest, strips it, re-hashes, and reports manifest_found / signature_valid / hash_matches independently. Body {asset_b64?, manifest?, signature?}. |
| GET | Path/v1/videos/models | NotesVideo-generation model catalog with per-second pricing plus duration/resolution/aspect-ratio options. Empty until a video provider is enabled on the deployment. |
| POST | Path/v1/videos/verify | NotesAlias for /v1/images/verify — a video provenance manifest is the same signed shape, so one verifier answers for both. |
| GET | Path/v1/nodes | NotesNode registry: the gateway, attested TEE backends, and genuinely enrolled fleet nodes — with each enrolled node's kinds, declared models, speed_factor, clamp_count, and observed reliability/latency. See node agent contract. |
| POST | Path/v1/nodes/heartbeat | NotesNode-key auth (nk-sable_ bearer). The fleet's 60s heartbeat with capability and endpoint refresh. |
| GET | Path/v1/status | NotesRecorded gateway health and uptime, plus confidential and sandbox posture blocks when those backends are configured. |
| GET | Path/v1/attestation | NotesLive verified TEE attestation, or verified:false with a sanitized error. See privacy tiers. |
| GET | Path/v1/billing/plans | NotesSaxeo Pro plan catalog: fees, retention, limits, per-feature flags. |
| GET | Path/v1/billing/methods | NotesHow to pay: treasury address, chains, USDT contracts, confirmations, plus a Solana block when configured. See paying with USDT. |
| GET | Path/v1/receipts/pubkey | NotesThe secp256k1 receipt-signer address and scheme. |
| POST | Path/v1/receipts/verify | NotesVerify a {receipt, signature} (EIP-191). Returns {valid, recovered_address, payload}. |
| GET | Path/v1/receipts/shared/:id | NotesA receipt its owner explicitly shared, viewable at /r/{request_id}. |
| GET | Path/v1/receipts/:id/badge.svg | NotesA live SVG verification badge for a receipt, embeddable via a plain <img>. |
| GET | Path/v1/passport | NotesPublic agent directory: minted passports ranked by verified runs, then receipts. Provable activity, not a trust score. |
| POST | Path/v1/support/nonce | NotesSaxeo Support Program: mint a single-use code and get the exact message both wallets must sign. |
| POST | Path/v1/support/claims | NotesRegister a claim as a SABL holder. Verifies an ed25519 signature (Solana key control), an EIP-191 signature over the same nonce (EVM key control), and a finalized Solana transaction that increased that address's SABL balance. Registration only — never an approval or a promise of payment. |
| GET | Path/v1/support/claims/:address | NotesA registered claim, by Solana address. |
| GET | Path/v1/passport/:handle | NotesPublic agent passport lookup by handle. |
| GET | Path/v1/passport/:handle/proof | NotesEverything needed to verify a passport without trusting this API: the signed credential, its recomputable commitment, the batch root, the ordered sibling hashes, and the public anchors. |
| GET | Path/v1/registry/identity/:handle | NotesERC-8004-shaped identity document for a passport. The off-chain half only — Saxeo has deployed no registry contract, and the erc8004 block says so. |
| GET | Path/v1/anchors/:root | NotesEvery public anchor recorded for one batch root, across backends, with the ordered leaves so the root is recomputable and per-backend instructions for checking it yourself. |
| GET | Path/v1/explorer | NotesPublic proof-explorer feed: aggregate proof counts plus recent owner-shared receipts, passports, and on-chain anchors. |
| GET | Path/v1/services/directory | NotesPublic Saxeo Services directory: listed, enabled services with price, kind, delivered calls and the seller's passport handle. |
| GET | Path/v1/services/:slug | NotesOne service's terms: price, seller payee, and the x402 accepts array a buyer pays against. |
| POST | Path/v1/services/:slug/invoke | NotesBuy one call. Without X-PAYMENT: 402 with the terms. With it: Saxeo verifies the buyer→seller on-chain transfer, runs or forwards the call, and returns it with a signed receipt. Saxeo never holds the funds. |
| GET | Path/v1/vault/chain/:id | NotesContent-free hash chain for a vault asset id, recomputable by anyone. |
| GET | Path/v1/vault/anchors/:id | NotesAn anchor batch: root, ordered event hashes, and Solana signature. |
| GET | Path/v1/vault/view/:token | NotesRead a vault asset through a scoped view key. |
| GET | Path/v1/vault/view/:token/documents/:doc_id | NotesRead one sealed document through a view key carrying the documents scope. |
| GET | Path/v1/vault/claims/:token | NotesA claim link: the asset name and the wallet it is bound to. Never the amount. |
| GET | Path/v1/assets/:asset_id/verification | NotesThe public attestation view for an asset. Unauthenticated and unattributed: it serves the newest record whose every source is publicly re-readable on-chain, and shows neither who ran the check nor how often. A record drawing on an issuer declaration or sealed Vault data has no public view and answers 404 — decided when the record is written, not filtered here. |
| GET | Path/v1/nav/:asset_id | NotesThe latest published NAV record for an asset, signed and independently verifiable. ?nav_id= reads a specific one. A missing asset, one never calculated, and one not published all answer 404 identically. |
| GET | Path/v1/nav/:asset_id/history | NotesEvery published record, newest first. Versioned and never overwritten; each entry verifies on its own. ?limit= (1–200, default 50); one page, no cursor. |
| GET | Path/v1/nav/:asset_id/evidence | NotesProvenance for a published record: source kind, label, retrieval time, and a sha256 of the submitted input. References only — never a price, quantity, or position value. |
| POST | Path/v1/relay-access/:secret | NotesOpen a Relay by its link secret. Body {pin?}; expired, revoked, or capped links answer 404 uniformly. |
| POST | Path/v1/relay-access/:secret/objects/:id | NotesFetch one relay file's content. View-only relays serve only image/* and text/*. |
| GET | Path/v1/judge/public/:id | NotesA published Judge verdict: question, options, per-juror votes and rationales, the evidence root, the signed receipt and its anchor. 404 until its owner publishes it. Viewable at /j/{id}. |
| GET | Path/v1/calls/public/:id | NotesA Sealed Call: commitment, signed receipt, anchor state, and — only after reveal — the text and its salt. A withdrawn call keeps the commitment and nothing else. Viewable at /c/{id}. |
| GET | Path/v1/post/handles/:handle | NotesWhether an Agent Post handle takes mail and at what postage. accepts:false under an allowlist, without revealing the list; an unknown handle is 404. |
| GET | Path/v1/legacy/claim/:token | NotesWhat a Legacy claim link reveals: {plan_name, wallet_required, status}. Unknown and cancelled answer 404 identically. Viewable at /legacy/claim/{token}. |
| GET | Path/v1/arena/leaderboard | NotesArena standings: one row per (suite, model), each backed by a real receipted run. Empty until a deployment configures the runner's house account. |
| GET | Path/v1/arena/suites | NotesEvery declared suite with its canonical tasks_sha256 and cadence. An empty array means nothing has been declared here. |
| GET | Path/v1/arena/suites/:slug | NotesThe declared tasks, verbatim, plus the canonical serialization the hash is taken over — so you can re-hash and re-run them yourself. |
| GET | Path/v1/arena/runs/:id | NotesOne run with its per-task receipt ids. Each is fetchable at /v1/receipts/shared/:id and verifiable at /v1/receipts/verify. |
| GET | Path/v1/sources/public/:id | NotesThe public proof for a source set: its members' (label, sha256, byte_len), the ordered root — byte-identical to a receipt's context.root — and root_recomputes. Fingerprints, never document bytes. |
| GET | Path/v1/kya/public/:handle | NotesThe current KYA credential at a passport handle: caps, policy hashes, attestation and verified history, signed so it verifies through /v1/receipts/verify. 404 when nobody has minted over the handle. |
| POST | Path/v1/terminal/run | NotesKeyless public code execution against a global daily budget. Not mounted on the production deployment — SAXEO_TERMINAL_ENABLED is off, so this path answers 404 with an empty body there. It appears in openapi.json regardless, because the spec describes the build rather than one deployment's flags. |
| POST | Path/v1/assistant | NotesKeyless "Ask Saxeo" assistant. Persists nothing and mints no receipt. |
| GET | Path/.well-known/oauth-authorization-server | NotesOAuth authorization-server metadata (RFC 8414). Root-level, not under /v1. |
| GET | Path/.well-known/oauth-protected-resource | NotesProtected-resource metadata for /v1/mcp (RFC 9728). |
| GET | Path/.well-known/oauth-protected-resource/v1/mcp | NotesThe same document at the resource-suffixed path RFC 9728 clients derive from the WWW-Authenticate header. |
| POST | Path/v1/oauth/register | NotesDynamic client registration (RFC 7591). Public clients only; https or loopback redirect URIs. |
| GET | Path/v1/oauth/client | NotesClient name and whether a redirect URI is registered — what the consent page renders. |
| GET | Path/v1/oauth/authorize | NotesValidates the authorization request, then redirects to the consent page. PKCE S256 required. |
| POST | Path/v1/oauth/token | Notesauthorization_code (single-use, PKCE-bound) and refresh_token (rotating) grants. Form-encoded or JSON. |
| POST | Path/v1/oauth/revoke | NotesRevoke an access or refresh token (RFC 7009). Always 200. |
| POST | Path/v1/agents/:id/hooks/:token | NotesA hosted agent's inbound trigger URL. Authenticates on the token (sha256-stored) plus an optional X-Saxeo-Signature HMAC; queues a run with the body as SAXEO_INPUT and returns 202. |
Auth bootstrap
Public. This is how a wallet gets a session in the first place.
| Method | Path | Notes |
|---|---|---|
| POST | Path/v1/auth/nonce | NotesReturns a {nonce} (EIP-4361, 5-minute TTL) to sign. |
| POST | Path/v1/auth/verify | NotesVerify a SIWE message and signature. Returns a sess_ token, and sets the HttpOnly sable_session cookie. See Authentication. |
| GET | Path/v1/auth/capabilities | NotesWhich sign-in methods this deployment offers: {siwe, passkey, session_cookie}. See Teams. |
| POST | Path/v1/auth/passkey/login/options | NotesWebAuthn assertion options. Not mounted unless passkeys are configured. |
| POST | Path/v1/auth/passkey/login/verify | NotesVerify a passkey assertion. Returns the same session shape SIWE does. |
API-key auth
Bearer sk-sable_.... The metered surface an agent calls.
| Method | Path | Notes |
|---|---|---|
| POST | Path/v1/chat/completions | NotesOpenAI-shape chat completions. Supports stream:true. |
| POST | Path/v1/embeddings | NotesOpenAI-shape embeddings. |
| POST | Path/v1/messages | NotesAnthropic Messages API. Translates and delegates to the chat handler. |
| POST | Path/v1/responses | NotesOpenAI Responses API. Translates and delegates to the chat handler; previous_response_id is refused, since prompts are never persisted. |
| POST | Path/v1/files | NotesUpload a batch input file (multipart, purpose=batch). Sealed at rest with a hard TTL. |
| GET | Path/v1/files | NotesList your files (metadata only). |
| GET | Path/v1/files/:id | NotesOne file's metadata. |
| GET | Path/v1/files/:id/content | NotesDownload a file's content. Gone once its TTL passes, or once its batch ends. |
| DELETE | Path/v1/files/:id | NotesDelete a file; the ciphertext is destroyed immediately. |
| POST | Path/v1/batches | NotesCreate a batch from an uploaded file. Every line is metered and receipted; a batch discount applies if the deployment sets one. |
| GET | Path/v1/batches | NotesList your batches with their request counts. |
| GET | Path/v1/batches/:id | NotesOne batch's status and result file ids. |
| POST | Path/v1/batches/:id/cancel | NotesCancel a batch. Lines already run are still billed and still returned. |
| POST | Path/v1/sandboxes | NotesMetered sandbox code execution. Accepts stream:true and an optional Idempotency-Key header. |
| POST | Path/v1/sandboxes/sessions | NotesOpen a persistent sandbox session: a workspace that survives between commands. Accepts Idempotency-Key. |
| GET | Path/v1/sandboxes/sessions | NotesYour sessions, newest first (metadata only). |
| GET | Path/v1/sandboxes/sessions/:id | NotesOne session: status, alive seconds, exec count, cost. |
| POST | Path/v1/sandboxes/sessions/:id/exec | NotesRun a command in a live workspace. stream:true for SSE. Returns a signed receipt. |
| PUT | Path/v1/sandboxes/sessions/:id/files/*path | NotesWrite one workspace file (raw body, ≤ 8 MiB). Relayed, never stored. |
| GET | Path/v1/sandboxes/sessions/:id/files/*path | NotesRead one workspace file back, as raw bytes. |
| GET | Path/v1/sandboxes/sessions/:id/files | NotesList a workspace directory (?path=). |
| POST | Path/v1/sandboxes/sessions/:id/snapshot | NotesSnapshot the workspace; the archive stays on its node. |
| DELETE | Path/v1/sandboxes/sessions/:id | NotesStop a session. Idempotent. |
| GET | Path/v1/sandboxes/snapshots | NotesYour snapshots. |
| GET | Path/v1/sandboxes/snapshots/:id | NotesOne snapshot's metadata. |
| DELETE | Path/v1/sandboxes/snapshots/:id | NotesDelete a snapshot and the archive behind it. |
| POST | Path/v1/mcp | NotesRemote MCP server, JSON-RPC tools. |
| POST | Path/v1/mcp/servers/:id | NotesMCP Gateway passthrough to a registered third-party MCP server. Every tools/call is allowlist-checked before the upstream is dialed, metered as an mcp_call event, and receipted with an action attestation. |
| POST | Path/v1/keys/delegate | NotesParent-key-authed: mint a bounded delegated sub-key mid-run. |
| GET | Path/v1/credit | NotesKey-authed balance including held and spendable credit: an agent's runway. |
| POST | Path/v1/memory/collections | NotesCreate a Saxeo Memory collection: a metered, sealed knowledge base. |
| GET | Path/v1/memory/collections | NotesList your memory collections. |
| DELETE | Path/v1/memory/collections/:id | NotesDelete a collection and its sealed chunks. |
| POST | Path/v1/memory/collections/:id/documents | NotesChunk, embed, and store a document. Billed as embedding usage. |
| POST | Path/v1/memory/collections/:id/search | NotesSemantic search a collection; returns the top matching chunks. |
| PUT | Path/v1/state/:key | NotesSet durable agent state. Body {value, namespace?}; sealed at rest. |
| GET | Path/v1/state/:key | NotesRead one state value. ?namespace= selects the namespace. |
| GET | Path/v1/state | NotesList state keys in a namespace (no values). |
| DELETE | Path/v1/state/:key | NotesDelete one state value. |
| POST | Path/v1/agents/:id/messages | NotesDeliver a message to another of your agents' mailboxes. Account-scoped. |
| GET | Path/v1/agents/:id/messages | NotesRead an agent's mailbox. ?consume=true marks read; ?unread_only=. |
| POST | Path/v1/pay/requests | NotesMint a signed payment request invoice. Non-custodial; EVM chains. |
| GET | Path/v1/pay/requests/:id | NotesFetch a payment request and its status. |
| POST | Path/v1/pay/requests/:id/settle | NotesVerify the on-chain transfer and return a signed settlement receipt. Body {tx_hash}. |
| POST | Path/v1/images/generations | NotesOpenAI-shape image generation, metered per image with a signed receipt and a signed provenance manifest embedded in the image. Where enabled. |
| POST | Path/v1/videos/generations | NotesStart a video render (text-to-video, or image-to-video with image). Asynchronous: returns 202 with a vid_… job id; poll for the result. Priced per second of output; the model's maximum duration is reserved and the difference released at settlement. |
| GET | Path/v1/videos/generations | NotesThe caller's video jobs, metadata only. ?limit= (1–200, default 50); one page, no cursor. |
| GET | Path/v1/videos/generations/:id | NotesOne job: status (queued|running|succeeded|failed|canceled|expired), progress (0-100), cost, expires_at, asset_available, the signed receipt, and the provenance manifest. |
| GET | Path/v1/videos/generations/:id/content | NotesThe video bytes, owner-only, served as an attachment. Available while asset_available is true — that is, after success and before the TTL destroys the sealed copy. |
| POST | Path/v1/videos/generations/:id/cancel | NotesBest-effort cancel. Polls the provider first: a render already finished is delivered and billed (billed: true), one still in progress is stopped and bills nothing. |
| DELETE | Path/v1/videos/generations/:id | NotesDestroy the stored video now instead of at its TTL. The content-free row and its receipt remain. |
| POST | Path/v1/attestations/check | NotesVerify facts about an on-chain or real-world asset and store a signed, versioned record with a sha256 of every byte read. Statuses are explicit: a source that is unreachable or unconfigured yields UNAVAILABLE, never a guess. Metered per verification — and the price is identical whatever it finds, because payment has no path into a status. |
| GET | Path/v1/attestations/:asset_id | NotesYour current record for an asset. Free. Statuses are recomputed against the freshness window on read, so an aged record reports STALE while status_at_check still says what was true at the time. |
| GET | Path/v1/attestations/:asset_id/history | NotesEvery version, newest first, returned exactly as it was signed. Records are versioned, never overwritten. ?limit= defaults to 50 and is not clamped here; treat 200 as the supported ceiling. Does not paginate — see List shapes. |
| GET | Path/v1/attestations/:asset_id/evidence | NotesThe provenance behind your current record: every reading, its source, when it was taken, and the sha256 of the exact bytes. ?include_body=true returns the bytes, opened from their sealed envelope. Free. |
| POST | Path/v1/attestations/:asset_id/refresh | NotesRe-run the checks, superseding the previous record rather than modifying it. Same engine, same price. Any change fires the matching attestation.* webhook. |
| POST | Path/v1/nav/calculate | NotesCalculate a private NAV from a submitted book. Returns a signed record; the book is sealed at rest and never published. A missing required input answers UNAVAILABLE with no figures, never a number. Metered per calculation. |
| POST | Path/v1/nav/:asset_id/refresh | NotesRecompute the stored book against the current clock, optionally with a newly observed on-chain supply. How a VERIFIED record becomes an honest STALE one. Metered like a calculation. |
| POST | Path/v1/nav/:asset_id/publish | NotesMake one record readable by anyone. Free and idempotent — nobody should have a financial reason to sit on a DISCREPANCY. |
| POST | Path/v1/benchmarks/portfolio | NotesSubmit a portfolio and benchmark it against a peer cohort. Holdings are sealed at rest and destroyed on the chosen retention; peer figures are released only above the minimum cohort size, are deterministically bucketed, and are suppressed rather than approximated otherwise. privacy_tier: "confidential" is refused with 501, never downgraded. Metered per calculation and signed. |
| GET | Path/v1/benchmarks/cohorts | NotesThe comparison universes, with banded participant counts (never exact — a count that ticks by one identifies a joiner), the anti-leakage parameters in force, and the list of guarantees Saxeo explicitly does not implement. |
| GET | Path/v1/benchmarks/:benchmarkId | NotesThe latest result plus the retention position. Another tenant's id answers 404, not 403. |
| GET | Path/v1/benchmarks/:benchmarkId/history | NotesEvery result version, each carrying the methodology version it was computed under. Historical results are never recomputed under a newer methodology. |
| POST | Path/v1/benchmarks/:benchmarkId/refresh | NotesRecompute against the current cohort as a new version. 409 when the sealed holdings were already destroyed by the retention policy — there is deliberately nothing left to recompute from. |
| POST | Path/v1/judge/verdicts | NotesAsk 1–5 juror models the same question over the same labeled evidence and sign the outcome: models, evidence root, every vote. Each juror runs as an in-process chat completion under this key, so holds, caps, policy, guardrails and receipts all apply. The question and rationales are returned once and never stored unless you publish. See The Judge. |
| GET | Path/v1/judge/verdicts | NotesList this account's verdicts. Content-free rows: fingerprints, votes, decision — never the question. |
| GET | Path/v1/judge/verdicts/:id | NotesOne verdict's votes, receipt and anchor state. Still content-free. |
| POST | Path/v1/judge/verdicts/:id/publish | NotesPublish a verdict. The re-supplied question and rationales are checked against the signed fingerprints, then sealed at rest and served at /v1/judge/public/:id. |
| POST | Path/v1/judge/verdicts/:id/unpublish | NotesClose the public page and destroy the sealed content immediately. |
| POST | Path/v1/post/messages | NotesSend Agent Post mail to a passport handle. The sender pays the recipient's postage as a metered post event and gets a signed kind:post receipt. Postage is a Saxeo fee, never credited to the recipient. 402 when short, 403 on policy, 429 on a full inbox. |
| GET | Path/v1/post/inbox | NotesReceived messages, metadata only — listing never opens an envelope. |
| GET | Path/v1/post/outbox | NotesSent messages, metadata only. |
| GET | Path/v1/post/messages/:id | NotesOpen one message (sender or recipient only). |
| POST | Path/v1/post/messages/:id/read | NotesMark a received message read. |
| DELETE | Path/v1/post/messages/:id | NotesDestroy a received message's content now; the content-free row and its receipt remain. |
| GET | Path/v1/post/threads/:thread_id | NotesEvery message in a thread you are party to, opened. |
| GET | Path/v1/post/settings | NotesYour delivery preferences: postage, accept policy, allow and block lists. |
| PUT | Path/v1/post/settings | NotesUpdate any subset of them. Postage is capped at $1.00. |
| POST | Path/v1/calls/commit | NotesThe key-authed twin of POST /v1/calls: an agent seals its own call. |
| POST | Path/v1/calls/commit/:id/reveal | NotesReveal one of the key's account's calls: returns the text and salt_hex. |
| GET | Path/v1/calls/mine | NotesList the key's account's calls (content-free). Complete at 500 per account. |
| POST | Path/v1/notary/receipts | NotesRegister an input and output fingerprint for work Saxeo did not run, and get back the same signed, anchorable receipt an inference gets. Billed per receipt. Proves registration, never correctness — and there is no Idempotency-Key, so a blind retry mints and bills a second one. |
| GET | Path/v1/notary/receipts | NotesYour own registrations, newest first. |
| GET | Path/v1/notary/receipts/:id | NotesOne registration, with its signature and anchor state. |
Saxeo-specific body fields
/v1/chat/completions, /v1/embeddings, /v1/messages, and
/v1/responses accept extra body
fields alongside the standard OpenAI or Anthropic shape:
sable_privacy_tier: override the key's privacy tier for one call.sable_region: pin the serving region.sable_scrub:trueredacts secret and PII shapes from the outbound prompt in-frame before egress.sable_run_id: chain this request's receipt into a named agent run. Also accepted on/v1/sandboxes.sable_context: declare the retrieved context (RAG documents) this call was given. The gateway fingerprints each item and stamps a verifiable context attestation on the receipt, proving the inputs without storing them. Accepted on/v1/messagestoo.
Unknown OpenAI-shape fields pass through to the upstream unchanged.
Session auth
Bearer sess_... from Sign-In With Ethereum. The
account-management surface behind the dashboard.
| Method | Path | Notes |
|---|---|---|
| POST | Path/v1/keys | NotesMint an API key with optional scopes. Plaintext returned once. |
| GET | Path/v1/keys | NotesList keys (prefixes and metadata only) with subtree spend. |
| DELETE | Path/v1/keys/:id | NotesRevoke a key, cascading over its delegated subtree. |
| POST | Path/v1/keys/:id/rotate | NotesMint a scope-identical replacement; the old key expires after a grace window. |
| POST | Path/v1/keys/:id/unfreeze | NotesLift an automatic circuit-breaker freeze on a key. |
| POST | Path/v1/oauth/authorize/approve | NotesGrant OAuth consent to a connector; mints the authorization code and returns where to send the browser. |
| POST | Path/v1/mandates | NotesCreate a signed, bounded spending mandate that mints a constrained sub-key. |
| GET | Path/v1/mandates | NotesList the account's mandates. |
| DELETE | Path/v1/mandates/:id | NotesRevoke a mandate. |
| POST | Path/v1/mandates/:id/proof | NotesMint a publicly-verifiable authorization certificate for a mandate. |
| POST | Path/v1/passport | NotesMint a signed agent passport from the agent's own provable history. |
| POST | Path/v1/mcp-servers | NotesRegister a third-party MCP server to proxy. The upstream URL and credential are sealed at rest. |
| GET | Path/v1/mcp-servers | NotesList registered MCP servers with their proxy URLs and allowlists. |
| PATCH | Path/v1/mcp-servers/:id | NotesEdit name, url, credential, tool allowlist, per-call price, or the enabled gate. |
| DELETE | Path/v1/mcp-servers/:id | NotesDeregister; the stored URL and credential are destroyed. |
| POST | Path/v1/mcp-servers/:id/test | NotesProbe the upstream (initialize + tools/list); returns tool names only. |
| POST | Path/v1/agents | NotesDeploy a hosted agent: seal the code, mint its bounded key, schedule it. Max 20 per account. |
| GET | Path/v1/agents | NotesList hosted agents with schedule, last run, and run count. |
| POST | Path/v1/agents/:id/trigger | NotesRun a hosted agent now. Returns the full sandbox response once; output is never stored. |
| POST | Path/v1/agents/:id/gate | NotesEnable or disable a hosted agent. Body {enabled: bool}. |
| POST | Path/v1/agents/:id/triggers | NotesSet a hosted agent's mailbox trigger and max_runs_per_hour. |
| POST | Path/v1/agents/:id/hooks/rotate | NotesMint or replace the agent's inbound trigger URL. Returned once; the previous URL dies immediately. |
| POST | Path/v1/agents/:id/hooks/disable | NotesDrop the agent's inbound trigger URL. |
| POST | Path/v1/agents/:id/hooks/secret | NotesSet or clear the HMAC secret inbound triggers are verified against. Sealed at rest, never returned. |
| GET | Path/v1/agents/:id/runs | NotesThe agent's last 100 runs: trigger, status, cost, and each signed receipt. Metadata only. |
| GET | Path/v1/agents/:id/runs/:run_id | NotesOne agent run. |
| DELETE | Path/v1/agents/:id | NotesDelete a hosted agent: revokes its key and destroys the sealed code. |
| POST | Path/v1/services | NotesPublish a service — a hosted agent or an HTTPS endpoint you run — at a public URL. The EVM payee must be a wallet linked to your account. |
| GET | Path/v1/services | NotesList your services with delivered calls and on-chain revenue. |
| PATCH | Path/v1/services/manage/:slug | NotesUpdate price, description, directory listing, or enabled state. |
| DELETE | Path/v1/services/manage/:slug | NotesRetire a service. The slug stays reserved and the call history remains. |
| GET | Path/v1/services/manage/:slug/calls | NotesThe last 100 delivered calls: payment metadata, fingerprints and receipts — never content. |
| POST | Path/v1/ghost/sessions | NotesStart a Ghost: an ephemeral scoped key whose metadata is purged at destruction. Key shown once. |
| GET | Path/v1/ghost/sessions | NotesList ghost sessions. The 100 most recent — see What truncates. |
| GET | Path/v1/ghost/sessions/:id | NotesOne ghost session, including seconds_remaining. |
| POST | Path/v1/ghost/sessions/:id/extend | NotesExtend a ghost. Total lifetime capped at 24 hours. |
| POST | Path/v1/ghost/sessions/:id/destroy | NotesDestroy a ghost now: revoke its key, purge its metadata. |
| POST | Path/v1/relays | NotesCreate a Relay: sealed temporary share. One-time share_url returned once. |
| GET | Path/v1/relays | NotesList your relays (metadata only: status, access counts, sizes). The 100 most recent — see What truncates. |
| POST | Path/v1/relays/:id/revoke | NotesRevoke a relay: destroys the ciphertext immediately. |
| GET | Path/v1/runs | NotesList per-run receipt hash chains. The 200 most recent — see What truncates. |
| GET | Path/v1/runs/:id | NotesOne run: its chained, individually-signed receipts. |
| POST | Path/v1/runs/:id/proof | NotesA signed run proof: head hash, receipt count, total cost, span, anchor. |
| POST | Path/v1/runs/:id/audit | NotesA signed, content-free compliance audit pack for the whole run. Optional ?framework=eu_ai_act|soc2 adds a signed compliance mapping — evidence mapping, never a certification. |
| GET | Path/v1/receipts/:id | NotesRe-fetch a stored receipt by request id or usage-event id. |
| POST | Path/v1/receipts/:id/share | NotesOpt a receipt into public fetchability. |
| DELETE | Path/v1/receipts/:id/share | NotesOpt a receipt back out of public fetchability. |
| GET | Path/v1/usage | NotesAggregate lifetime usage for the dashboard. |
| GET | Path/v1/usage/stream | NotesSSE feed of new metering events for the account. |
| GET | Path/v1/usage/events | NotesRaw metering ledger with filters, ?format=csv export, and real pagination: ?limit= 1–1000 (default 100) and an opaque next_cursor. |
| POST | Path/v1/usage/statement | NotesMint a signed spend statement for a period. See AgentFinOps. |
| GET | Path/v1/usage/sandboxes | NotesSandbox run history (metadata only). |
| GET | Path/v1/usage/sandboxes/:id | NotesOne sandbox run. |
| GET | Path/v1/billing/balance | NotesCredit position including held and spendable. |
| POST | Path/v1/billing/deposits | NotesVerify an on-chain USDT transfer and credit it. Idempotent. See paying with USDT. |
| GET | Path/v1/billing/deposits | NotesDeposit history. |
| POST | Path/v1/billing/deposits/refresh | NotesRe-check every pending deposit. |
| GET | Path/v1/billing/ledger | NotesAppend-only credit ledger behind the balance. Paginated: ?limit= 1–1000 (default 200), next_cursor and an explicit has_more. |
| GET | Path/v1/billing/alerts | NotesThe account's balance_low webhook threshold. |
| PUT | Path/v1/billing/alerts | NotesSet the balance_low threshold (null = deployment default). |
| GET | Path/v1/billing/subscription | NotesCurrent Saxeo Pro plan, period end, auto-renew, balance. |
| POST | Path/v1/billing/subscription | NotesSubscribe or change plan. Paid plans debit the monthly fee from the prepaid balance; 402 if it cannot cover it. |
| POST | Path/v1/billing/subscription/cancel | NotesCancel auto-renew; the plan drops to Free at period end. |
| POST | Path/v1/reports/sla | NotesA signed SLA report: recorded uptime telemetry in the verifiable receipt envelope. |
| POST | Path/v1/evals | NotesCreate an eval suite: cases with assertions against a model. |
| GET | Path/v1/evals | NotesList eval suites. |
| DELETE | Path/v1/evals/:id | NotesDelete an eval suite. |
| POST | Path/v1/evals/:id/run | NotesRun the suite against its model (real, metered inference); returns pass rate and regression flag. |
| GET | Path/v1/evals/:id/runs | NotesRun history with pass rate over time. |
| POST | Path/v1/evals/monitors | NotesCreate a drift monitor: run a suite on a schedule (hourly floor) and fire eval_drift_detected when the pass rate falls. |
| GET | Path/v1/evals/monitors | NotesList drift monitors with their last pass rate, failure streak, and next run. |
| PATCH | Path/v1/evals/monitors/:id | NotesPause/resume a monitor or change its interval, threshold, or drop tolerance. |
| DELETE | Path/v1/evals/monitors/:id | NotesDelete a monitor. The suite is untouched. |
| POST | Path/v1/guardrails | NotesCreate a guardrail rule set: PII / secrets / prompt-injection / blocklist detectors, each per direction with an allow, redact, or block action. |
| GET | Path/v1/guardrails | NotesList rule sets, with the deployment's enforcement mode. |
| GET | Path/v1/guardrails/findings | NotesFindings decoded from your own signed receipts: rule, direction, category, count, severity, action, decision — never the matched text, which is never stored. |
| DELETE | Path/v1/guardrails/:id | NotesRevoke a rule set. Keys whose policy referenced it then run unconstrained. |
| POST | Path/v1/webhooks | NotesCreate a webhook; secret returned once. |
| GET | Path/v1/webhooks | NotesList webhooks. |
| DELETE | Path/v1/webhooks/:id | NotesDisable a webhook. |
| GET | Path/v1/webhooks/:id/deliveries | NotesLast 50 delivery attempts. |
| POST | Path/v1/webhooks/:id/test | NotesFire a synthetic webhook_test event at this webhook. |
| GET | Path/v1/auth/me | NotesThe {account_id, wallet_address} for the bearer session. |
| POST | Path/v1/auth/logout | NotesInvalidate the current session. |
| GET | Path/v1/auth/sessions | NotesList the account's live sessions. |
| POST | Path/v1/auth/logout-all | NotesInvalidate every session (the leaked-token remedy). |
| GET | Path/v1/auth/wallets | NotesList wallets linked to the account. |
| POST | Path/v1/auth/wallets | NotesLink an additional wallet (SIWE proof of the new wallet). |
| DELETE | Path/v1/auth/wallets/:addr | NotesUnlink a wallet. Refuses the last one. |
| POST | Path/v1/auth/passkey/register/options | NotesWebAuthn creation options for the signed-in account. |
| POST | Path/v1/auth/passkey/register/verify | NotesRegister a passkey on the signed-in account. Never creates an account. |
| GET | Path/v1/auth/passkeys | NotesList this account's passkeys (metadata only). |
| PATCH | Path/v1/auth/passkeys/:id | NotesRename a passkey. |
| DELETE | Path/v1/auth/passkeys/:id | NotesRemove a passkey. The wallet can still sign in. |
| POST | Path/v1/orgs | NotesCreate an org. The creator's account becomes the billing account. |
| GET | Path/v1/orgs | NotesEvery org the caller belongs to, with their role. |
| GET | Path/v1/orgs/:id | NotesOrg detail plus the caller's role and the member count. |
| PATCH | Path/v1/orgs/:id | NotesRename an org. Admin or higher. |
| DELETE | Path/v1/orgs/:id | NotesDelete an org. Owner only; keys, credit and receipts are untouched. |
| POST | Path/v1/orgs/:id/switch | NotesMint a session acting as the org's billing account under your role. |
| GET | Path/v1/orgs/:id/members | NotesThe member roster. Any member. |
| PATCH | Path/v1/orgs/:id/members/:account_id | NotesChange a member's role. Admin or higher; never above your own. |
| DELETE | Path/v1/orgs/:id/members/:account_id | NotesRemove a member, or leave. Their org sessions die immediately. |
| POST | Path/v1/orgs/:id/invites | NotesMint an invite link. Token returned once; 14-day expiry. Admin or higher. |
| GET | Path/v1/orgs/:id/invites | NotesList invites and their status. Admin or higher. |
| DELETE | Path/v1/orgs/:id/invites/:invite_id | NotesRevoke an unaccepted invite. |
| POST | Path/v1/orgs/invites/:token/accept | NotesJoin an org with an invite link. The account must already exist. |
| POST | Path/v1/vault/assets | NotesRegister a private vault asset; sensitive fields sealed at rest. |
| GET | Path/v1/vault/assets | NotesList the caller's assets. |
| GET | Path/v1/vault/assets/:id | NotesAsset detail plus its hash chain. |
| GET | Path/v1/vault/assets/:id/holders | NotesIssuer-only cap table: every holder and decrypted position. |
| POST | Path/v1/vault/assets/:id/close | NotesIssuer-only, irreversible: chains asset_closed; transfers refuse thereafter. |
| POST | Path/v1/vault/assets/:id/distribute | NotesIssuer-only: record a pro-rata payout to holders. Does not move principal. |
| POST | Path/v1/vault/assets/:id/nav | NotesRecord a NAV or reserves attestation and return a signed proof. |
| POST | Path/v1/vault/assets/:id/view-grant | NotesMint a scoped view key for an asset. |
| GET | Path/v1/vault/assets/:id/view-grants | NotesList an asset's view grants. |
| DELETE | Path/v1/vault/view-grants/:id | NotesRevoke a view grant. |
| GET | Path/v1/vault/portfolio | NotesDecrypted-for-owner totals and recent activity. |
| GET | Path/v1/vault/distributions | NotesDistribution history. |
| POST | Path/v1/vault/transfers | NotesPrivate, value-conserving position transfer to another account's wallet. |
| GET | Path/v1/vault/transfers | NotesTransfer history. |
| POST | Path/v1/vault/proofs | NotesMint a signed selective-disclosure statement, verifiable via /v1/receipts/verify. |
| POST | Path/v1/vault/assets/:id/attesters | NotesIssuer names a third-party attester (auditor, custodian, appraiser, legal). |
| GET | Path/v1/vault/assets/:id/attesters | NotesThe attester roster (issuer sees all; an attester sees their own). |
| DELETE | Path/v1/vault/assets/:id/attesters/:attester_id | NotesRevoke a role. Attestations already recorded stand. |
| POST | Path/v1/vault/assets/:id/attestations | NotesA role-holder records a sealed statement: gateway-signed, optionally attester-wallet-signed. |
| GET | Path/v1/vault/assets/:id/attestations | NotesAttestations on the asset (issuer, holders, attesters). |
| POST | Path/v1/vault/assets/:id/documents | NotesIssuer stores a document sealed at rest; its sha256 is chained. |
| GET | Path/v1/vault/assets/:id/documents | NotesDocument metadata (issuer sees all; holders see shared ones). |
| GET | Path/v1/vault/assets/:id/documents/:doc_id | NotesOne document's bytes, base64. |
| DELETE | Path/v1/vault/assets/:id/documents/:doc_id | NotesIssuer removes it: ciphertext destroyed, hash stays in the chain. |
| GET | Path/v1/vault/claims | NotesClaims you sent to wallets with no Saxeo account yet, amounts opened. |
| POST | Path/v1/vault/claims/:id/cancel | NotesSender refunds an unclaimed claim. |
| POST | Path/v1/vault/claim/:token | NotesSettle a claim into your account (your session must hold its wallet). |
| POST | Path/v1/intents | NotesDark Pool: submit an indication of interest; terms sealed at rest. Matching infrastructure — not an exchange, ATS or broker-dealer, no order book, no custody. 501 unless the operator enabled it. |
| GET | Path/v1/intents/:id | NotesYour own intent, its terms opened for you, and its append-only lifecycle history. Not yours ⇒ 404. |
| POST | Path/v1/intents/:id/cancel | NotesWithdraw a resting intent. Idempotent; 409 if it already matched. |
| POST | Path/v1/matches | NotesAsk whether a compatible counterparty exists for one of your intents. The negative answer is uniform and carries no reason, by design — do not infer one. |
| GET | Path/v1/matches/:id | NotesA match you are a party to. The counterparty's settlement address appears only after both sides confirm; their account, band and size never do. |
| POST | Path/v1/matches/:id/confirm | NotesConfirm your side. When both have, Saxeo signs a settlement instruction the parties execute themselves. |
| POST | Path/v1/matches/:id/settle | NotesBuyer submits the hash of the transfer they already made; Saxeo verifies the cash leg and signs a receipt (the asset leg is reported UNAVAILABLE). |
| GET | Path/v1/markets/:asset_id/status | NotesEligibility rules and your own participation. No depth, no counts of others, no last price — none are published. |
| POST | Path/v1/nodes/enroll | NotesEnroll a fleet node under the account; one-time nk-sable_ key reveal. kinds accepts sandbox, inference, or both; an inference node also declares models / model_map / speed_factor. See node agent contract. |
| DELETE | Path/v1/policies/:id | NotesRevoke a policy. Keys carrying it then run unconstrained and the receipt stamp disappears — to lock a key down, revoke the key. |
| POST | Path/v1/calls | NotesCommit a Sealed Call: a 32-byte salt, commitment = sha256(salt‖text), a receipt signed now, and the commitment queued for the public anchor pass. |
| GET | Path/v1/calls | NotesYour calls, content-free. |
| POST | Path/v1/calls/:id/reveal | NotesReveal now: returns the text and salt_hex so anyone can recompute the commitment. Idempotent; 409 once withdrawn. |
| POST | Path/v1/calls/:id/withdraw | NotesDestroy the text and salt in one statement. The commitment, receipt and anchor stay — they were public from commit. |
| POST | Path/v1/legacy/plans | NotesCreate a Legacy plan: sealed note and files, a check-in cadence, beneficiaries, optional attesters. Returns each beneficiary's claim URL once. |
| GET | Path/v1/legacy/plans | NotesYour plans with their status and deadlines. |
| GET | Path/v1/legacy/plans/:id | NotesPlan detail: parties, object metadata, and the chained events with their anchor state — never content. |
| POST | Path/v1/legacy/plans/:id/checkin | NotesCheck in: reset the deadline, clear the warning and every attester confirmation. |
| PUT | Path/v1/legacy/plans/:id/content | NotesReplace the note and files (re-sealed). |
| POST | Path/v1/legacy/plans/:id/cancel | NotesCancel: every ciphertext is nulled and every claim token killed. The content-free history remains. |
| POST | Path/v1/legacy/plans/:id/attest | NotesConfirm as a named attester. Counts only while the plan is in warning — attesters are a brake, not the timer. |
| GET | Path/v1/legacy/attesting | NotesPlans where one of your wallets is an attester: id, name, status, deadline, your confirmation. Nothing else. |
| GET | Path/v1/legacy/claims | NotesReleased plans naming one of your wallets as a beneficiary. |
| POST | Path/v1/legacy/claims/:plan_id/open | NotesOpen a release: the note, unsealed in-frame, plus the object list. Chains claimed once. |
| GET | Path/v1/legacy/claims/:plan_id/objects/:object_id | NotesOne released file's bytes, base64. |
| POST | Path/v1/nodes/:id/:gate | NotesOwner gate: :gate is disabled or draining, body {set: bool}. |
| POST | Path/v1/engine/builds | NotesDraft an Intelligence Engine build — a named configuration, not a fine-tune. The system prompt is sealed at rest; only its fingerprint enters the canonical spec. |
| GET | Path/v1/engine/builds | NotesEvery version this account owns, newest first. |
| GET | Path/v1/engine/builds/:id | NotesOne version, with its spec_sha256. |
| DELETE | Path/v1/engine/builds/:id | NotesDestroy this version's sealed system prompt. |
| POST | Path/v1/engine/builds/:id/publish | NotesPoint engine/<slug> at this version. At most one version of a slug is published at a time, enforced by a database constraint. |
| POST | Path/v1/engine/builds/:id/unpublish | NotesRetire this version. Pins to it stop resolving rather than silently falling back. |
| GET | Path/v1/engine/resolve/:slug | NotesWhat engine/<slug> serves right now: the version, the spec digest, and the expanded configuration. |
| POST | Path/v1/replay/capsules | NotesRecord one request as a Time Machine capsule. Requires confirm_seal — recording is never implicit. The sealed request is never returned by any endpoint, including to you. |
| GET | Path/v1/replay/capsules | NotesYour capsules, content-free. |
| GET | Path/v1/replay/capsules/:id | NotesOne capsule and its replay history. |
| DELETE | Path/v1/replay/capsules/:id | NotesDestroy the sealed request now. The content-free row remains as your history. |
| POST | Path/v1/replay/capsules/:id/replay | NotesRe-execute the recorded request and diff the output fingerprints. A diff proves the output changed; it can never show what changed. |
| POST | Path/v1/sources/sets | NotesRegister a source set from document fingerprints. An unrecognised field is refused rather than stripped, so a stray "text" cannot leave you believing you uploaded something. |
| GET | Path/v1/sources/sets | NotesYour sets, newest first. |
| GET | Path/v1/sources/sets/:id | NotesOne of your sets, with its members. |
| DELETE | Path/v1/sources/sets/:id | NotesTake a set down from Saxeo. Receipts that cited its root keep citing it — a set is a resolution aid, not the proof. |
| POST | Path/v1/kya/credentials | NotesMint a KYA credential over a handle you own, bound to a key_id or mandate_id. Supersedes that handle's previous credential in the same transaction. |
| GET | Path/v1/kya/credentials | NotesYour credentials, newest first, with their real state. |
| DELETE | Path/v1/kya/credentials/:id | NotesRevoke a credential. |
| POST | Path/v1/autopilot/analyze | NotesLook at your own metered usage and propose a cheaper configuration, with the evidence attached. Evidence is billed inference, so it is opt-in and never gathered by a background pass. |
| GET | Path/v1/autopilot/proposals | NotesOpen and decided proposals, newest first. |
| GET | Path/v1/autopilot/proposals/:id | NotesOne proposal with all of its evidence. |
| POST | Path/v1/autopilot/proposals/:id/adopt | NotesPublish the proposed configuration as a new engine version. Admin-only, and a proposal whose evidence says regression cannot be adopted by anyone, with no override. |
| POST | Path/v1/autopilot/proposals/:id/reject | NotesClose a proposal without adopting it. |
| POST | Path/v1/escrow/claims | NotesAssemble the inputs SaxeoEscrow.claim takes from one of your receipts, and check both of its preconditions before you spend gas. claimable:true means the signature recovers and the payload binds — read as one JSON object it carries exactly one top-level field holding the job id, and declares exactly the escrow's receipt_kind ("" pins “declares no kind/type”, and is not a wildcard). It is never a statement that an escrow exists, is funded, or will pay. No SaxeoEscrow is deployed anywhere as of this writing. |
| GET | Path/v1/escrow/claims | NotesYour own trail of prepared claims. |
| GET | Path/v1/escrow/claims/:request_id | NotesThe same check, read-only. |
Admin
Bearer $SAXEO_ADMIN_TOKEN. The whole group is unmounted and returns 404
when no admin token is configured; a wrong token returns 401.
| Method | Path | Notes |
|---|---|---|
| GET | Path/v1/admin/metrics | NotesDemand-gate numbers: paying accounts, spend by window, events by kind, and billing_enforced. |
| POST | Path/v1/admin/accounts/suspend | NotesThe abuse kill switch. Body {account_id, suspended, reason}. |
| POST | Path/v1/admin/denylist | NotesRefuse one reported payload by its full sha256. Stores no content. |
| POST | Path/v1/admin/nodes/enroll | NotesEnroll a house node under the dedicated house-ops account. |
| POST | Path/v1/admin/nodes/approve | NotesApprove (or un-approve) a node for scheduling — the vetting gate. Body {node_id, approved}. |
Operator metrics
Bearer $SAXEO_METRICS_TOKEN, and served at the root, not under /v1 — a
scraper is infrastructure, not an API consumer. Unmounted (404) when no
metrics token is configured; a wrong token returns 401. Aggregate only: no
per-account series and no request content. See
Observability.
| Method | Path | Notes |
|---|---|---|
| GET | Path/metrics | NotesPrometheus text exposition: HTTP/upstream/sandbox counters, token + cost totals, pool and outbox gauges, fleet counts, attestation state, and sable_leader. |