API keys & scopes
Keys are scoped, budgeted, and revocable. Execution scopes and management scopes are never implied by each other.
Scopes
| Scope | Allows | Default |
|---|---|---|
catalog:read | Browse the catalog and read tool schemas | Yes |
tools:execute | Quote and execute catalog tools (billable) | Yes |
rpc:execute | Send Solana JSON-RPC requests (billable) | Yes |
jobs:read | Read asynchronous job status and results | Yes |
jobs:write | Cancel jobs | Yes |
usage:read | Read usage, receipts and exports | Yes |
balance:read | Read workspace balance | Yes |
mcp | Use the scoped MCP discovery/execution interface | — |
keys:manage | Create, rotate and revoke API keys | — |
webhooks:manage | Configure webhooks | — |
deposits:manage | Create deposit intents and submit signatures | — |
projects:manage | Create and edit projects | — |
market:sell | Manage marketplace credentials, offers, earnings and payouts | — |
market:sell
The market:sell scope lets an autonomous seller manage credentials, offers, earnings and payouts via /v1/market/offers*. It is a management scope: it never allows execution, and execution scopes never imply it. See Selling capacity.
Budgets, ceilings and expiry
- Monthly budget — the key stops executing billable calls once its month-to-date charges reach the budget.
- Per-request ceiling — any request whose quote or ceiling exceeds it is rejected with
ceiling_too_low/spend_limit_exceeded. - Allowed tools — restrict a key to a list of tool keys.
- Routing — per-key
routing(mode,max_unit_price_usd,exclude_offers) overrides the workspace policy for market-routed native routes. - Expiry — expired keys return
403 key_expired.
Lifecycle
Rotate issues a new secret for the same key record and revokes the old secret. Revoke disables the key immediately; in-flight requests complete, new ones fail with 403 key_revoked.
Store secrets safely
The raw secret is displayed once. Put it in a secret manager or environment variable; never commit it or ship it to a browser.
API
text
GET /v1/keys → { items: ApiKeyRecord[] }
POST /v1/keys CreateKeyRequest → { key: ApiKeyRecord, secret } (secret shown once)
PATCH /v1/keys/{id} → ApiKeyRecord
POST /v1/keys/{id}/revoke → ApiKeyRecord
POST /v1/keys/{id}/rotate → { key, secret }
CreateKeyRequest = { name, project_id?, scopes[], environment?: "production"|"test",
expires_at?, monthly_budget_usd?, per_request_ceiling_usd?, allowed_tool_keys?,
routing?: { mode, max_unit_price_usd?, exclude_offers? } }