Skip to Content
API referenceAPI overview
Open in Claude Open in ChatGPT

API overview

AgentValet exposes two public API surfaces:

  • The agent API at https://api.agentvalet.ai/v1/*. Every call is signed by the agent’s RS256 key and brokered to the upstream SaaS platform via read_platform, write_platform or delete_platform. This is what your agent invokes at runtime.
  • The owner API at https://api.agentvalet.ai/v1/approvals/* and via the dashboard’s edge functions. These are the dashboard’s writes (approve, revoke, register, audit). Most operators won’t call these directly — they’re documented for enterprise integrators building custom dashboards.

For everything else (billing, OAuth callback, webhooks), there’s no public contract and we reserve the right to change the surface area without notice.

How agents call AgentValet

The recommended path is through the AgentValet MCP server, not by hitting /v1/actions directly. The MCP server handles JWT signing, endpoint discovery, error envelope parsing, and the long-poll for approval results. If you’re building inside Claude Code, Claude Desktop, Cursor, or another MCP-aware host, install the AgentValet MCP and call:

write_platform({ platform: "slack", endpoint: "/api/chat.postMessage", scope: "chat:write", body: { channel: "#general", text: "Hello" } })

Reads use read_platform (always GET, no method argument) and deletions use delete_platform (always DELETE). write_platform accepts POST, PUT or PATCH, defaulting to POST.

The MCP server signs the request, sends it to POST /v1/actions, waits up to 50 seconds for owner approval if needed, and returns the upstream SaaS response. See Get started for installation.

Which package do I want?

You’re buildingUseWhy
An agent inside Claude Code, Claude Desktop, Cursor, or another MCP host@agentvalet/mcp-serverNo code. Install it, call read_platform / write_platform / delete_platform
A Node agent that isn’t MCP — LangChain, a cron job, a service@agentvalet/clientSame governance, a typed SDK instead of raw HTTP
A Python agent that isn’t MCPagentvaletThe Python port. Same endpoints, same approval semantics, sync and async
A CrewAI crewcrewai-agentvaletBuilds one typed CrewAI tool per granted platform
Your own MCP server, and you want policy enforced inside it@agentvalet/mcp-brokerWrap once; every tool is checked, credentialed, audited
Anything elsePOST /v1/actionsYou sign the JWT and handle approvals yourself
Plain git on a machine that must hold no GitHub credentialGoverned gitPoint the remote at the broker; clone, fetch and push are governed calls

Reach for the raw endpoint last. Calling it directly means implementing RS256 assertion signing, the 202 owner-approval long-poll, and the retry semantics by hand — all of which the packages above already do.

import { AgentValet } from "@agentvalet/client"; const av = AgentValet.fromEnv(); await av.call({ platform: "slack", endpoint: "/api/chat.postMessage", method: "POST", scope: "chat:write", data: { channel: "#general", text: "Hello" }, });

If you still need the raw endpoint, see POST /v1/actions.

Authentication

All agent-facing endpoints require an RS256-signed JWT in the Authorization: Bearer <token> header. Claims:

ClaimRequiredNotes
agent_idyesThe agent’s id as shown in the dashboard (agt_…)
owner_idyesThe owning organisation’s owner UUID
iatyesIssued-at timestamp (seconds)
expyesExpiry. The first-party SDKs and MCP server sign 60-second tokens; the proxy checks only that exp has not passed
suboptionalIf present, must match the agent’s spiffe_id

The JWT is verified against the public key registered for the agent (agents.public_key_pem). A mismatch returns 401 Invalid JWT. It does not count toward the circuit breaker.

The Paperclip company-key path is also supported for the Paperclip adapter — see the in-app guide on Paperclip key setup.

Owner-facing endpoints

Dashboard mutations use the owner’s session JWT from our sign-in provider in the same Authorization: Bearer header. The proxy verifies it against the provider’s JWKS.

Rate limits

Endpoint groupLimitNotes
POST /v1/actionsPer-org, per-minute. See your plan.Counted per proxy replica. Independent of upstream SaaS rate limits
GET /v1/approvals/:id60/min per agentPolling the result of a pending approval
GET /v1/agents/me/pending-actions30/min per agent24h pending + completed window
POST /v1/approvals/passkeys/*10/minRegistration per owner; sign begin / finish per approval

Exceeding a limit returns 429 Too Many Requests with a Retry-After header.

Error envelope

All errors return a JSON body with this shape:

{ "error": "Permission denied", "reason": "scope_not_granted", "correlation_id": "0f4c9a61-2b7d-4e3a-9c85-6d1e0a2b3f47", "audit_id": "5d0e2f7a-3c1b-4a9e-8f6d-0b2c4e6a8d10", "report_hint": { "report_url": "https://api.agentvalet.ai/v1/agents/self/diagnostics", "suggested_payload": { "severity": "error", "code": "permission_denied", "message": "<replace with one-sentence agent narrative>", "platform": "slack", "endpoint": "/api/chat.postMessage", "correlation_id": "0f4c9a61-2b7d-4e3a-9c85-6d1e0a2b3f47" }, "prompt": "If you'd like to lodge a self-report so the owner sees this, POST your narrative to report_url with the suggested_payload (replace `message`)." } }
  • error — a stable identifier. Don’t substring; switch on it. Some are sentences (Permission denied, Invalid JWT); the machine code then rides in reason or code.
  • detail — human-readable, may change between releases.
  • correlation_id — the request id (also audit_log.request_id); quote this when filing a bug or emailing support.
  • report_hint — when present, your agent can POST the suggested payload to lodge a self-report tied back to this request. See report_self_diagnostic.

Endpoint reference

  • POST /v1/actions — proxy a call to a connected platform
  • POST /v1/agents/children: mint a scope-attenuated child identity for a subagent
  • Approvals API — owner-facing decide + agent-facing poll
  • Passkeys — WebAuthn enrolment + biometric approval
  • Agent pending actions — agent introspection
  • Signed governance receipts — GET /v1/audit/{id}/receipt, a JWS per proxy decision, verifiable offline against /.well-known/agentvalet-receipt-keys.json
  • TRQP authorization & recognition — ToIP Trust Registry Query Protocol v2.0 over the same permission check; public for organisations that publish identity documents
  • POST /v1/authzen/access — AuthZEN 1.0 decision (decision, reason, require_approval); agent bearer may query itself, owner bearer any agent in its org
  • did:web identity documents — GET /agents/{agentId}/did.json and GET /.well-known/did.json
  • Per-person tokens — caller on /v1/actions (or the X-AV-Caller header), POST /v1/consent/caller/start, GET /v1/consent/caller/status/{token}; one upstream token per person on a shared connection

OpenAPI document

The agent-facing surface is described by an OpenAPI 3.1 document at https://api.agentvalet.ai/v1/openapi.json. A contract test runs on every push and holds it to the live route table in three directions: every documented path is served, every route on the test’s public agent/SDK route list is documented, and no billing, admin or webhook route appears. Generate a client from it in any language and it will not learn a phantom route.

Last updated on