Management API
/v1 is the administrative API: organizations, members, agents, API keys, credentials, webhooks,
log streams, SSO connections, domains, and audit. It authenticates with an
org API key and answers on any host the platform serves,
including every tenant subdomain.
The full endpoint list, with request and response schemas, is in the API reference. This page covers the conventions that apply across all of it.
Almost every resource is org-scoped and addressed under its organization:
/v1/organizations/:orgId/<resource>The exceptions are organization creation itself (POST /v1/organizations), and the two audit
endpoints (/v1/audit_logs, /v1/events), which take organization_id as a query parameter
because a platform-scoped key may read across orgs.
Lists come back wrapped in data:
{ "data": [ { "key_id": "key_…", "name": "ci-deploy", "key_prefix": "a1b2c3d4", "scopes": ["credentials:issue"] } ]}Single resources are returned bare, without a wrapper. Creates return 201 with the created object.
Deletes and revocations return { "ok": true }.
Secrets are shown once
Section titled “Secrets are shown once”Five endpoints return a value that is never retrievable again, because only its hash is stored:
| Endpoint | One-time value |
|---|---|
POST /v1/organizations/:orgId/api_keys | api_key (sk_live_…) |
POST /v1/organizations/:orgId/agents | client_secret |
POST /v1/organizations/:orgId/agents/:clientId/rotate_secret | client_secret |
POST /v1/organizations/:orgId/webhooks | secret (whsec_…) |
POST /v1/organizations/:orgId/directory/scim_token | token (scim_…) |
Subsequent GETs on those resources return metadata only — id, name, prefix, scopes, timestamps.
Write the secret to your secret store as part of the same operation that creates it.
Idempotency
Section titled “Idempotency”POST requests accept an Idempotency-Key header. The first response for a given key is cached for
24 hours and replayed on any repeat:
POST /v1/organizations/org_01J…/api_keys HTTP/1.1Authorization: Bearer sk_live_…Idempotency-Key: 6f1c9e2a-provision-ci
{ "name": "ci-deploy", "scopes": ["credentials:issue"] }A replayed response carries a marker so you can tell it apart from a fresh one:
HTTP/1.1 201 CreatedIdempotency-Replayed: trueThis matters most on exactly the endpoints above: a retry after a network timeout would otherwise mint a second API key or a second agent secret, and you would have no way to tell which one the first attempt returned.
Two details worth knowing. The key is scoped to the API key that used it, not to the org — a
cached response can contain a one-time secret, so it will only ever replay to the same principal
that created it. And 5xx responses are never cached, only deterministic 2xx and 4xx outcomes,
so a retry after a transient server error genuinely re-runs.
Choosing where to write
Section titled “Choosing where to write”Several capabilities are reachable three ways, and picking the wrong one creates work:
| You want | Use |
|---|---|
| Your own backend to provision and administer tenants | /v1 with an org or platform API key |
| Your customer’s IT admin to configure their own SSO, directory sync, domains, or log streams | Admin Portal link |
| A human on your team to click through it | The console |
The Admin Portal is the one that saves the most support time: it is a signed, expiring link you mint
through /v1 and send to the customer, and it scopes exactly which flows they can self-serve.
Reading what happened
Section titled “Reading what happened”Every privileged /v1 call writes an audit event naming the API key that made it.
A subset also fires a webhook. If you are reconciling state — “did that member actually
get added?” — the audit log is the authority, and GET /v1/events is the cursor feed built for
exactly that kind of downstream sync.