API keys
Operations tagged API keys in the public API.
About API keys
An API key is the credential every authenticated request sends as Authorization: Bearer agy_live_… (or agy_test_…): a prefix naming the mode, a public 16-character key_id, and a 32-character secret. Only a hash of the secret is stored; the secret is shown once, when the key is minted.
Managed in the dashboard. Keys are minted, listed, rotated and revoked in the dashboard; no credential can mint or list credentials. The API has one key operation: DELETE /api_keys/{id} revokes the calling key itself — a kill switch for a leaked key — and needs keys:write.
Scopes are fixed when the key is minted; to change them, mint a new key and revoke the old one. A write scope also grants its read (chatbots:write covers chatbots:read). profile:write is high-risk: only the account owner can grant it, it is confirmed on its own, and a personal access token never carries it. The catalogue, with what each scope grants, is x-agentency-scopes in this document; each operation names the scope it needs in x-agentency-scope.
Modes. A test key (agy_test_) reads and writes the same real account and spends the same message credits as a live key; it differs only in its lower default rate limit (x-agentency-rate-limits).
Rotation and expiry. Rotating mints a successor and keeps the old key working for up to 24 hours (rotation_grace_until; less when the old key expires sooner). A revoked, expired or rotated-out key, or one used from outside its IP allowlist, is 401 UNAUTHENTICATED; the precise reason is recorded in GET /request_logs.
IDs you will meet.
id— the key's integer id, fromGET /me→key.id; the only idDELETE /api_keys/{id}accepts.key_id— the public identifier inside the key string. Safe to log; no operation takes it.
IDs on this page
- API key id
<API_KEY_ID> - Integer: the calling key's own
id, not itskey_idstring. Any other id is 403INSUFFICIENT_SCOPE.Get it from
- GET /v1/me returns it as
key.id - Only the key that sends the request can be revoked here. Other keys are listed and revoked in the dashboard.
- GET /v1/me returns it as
Revoke the calling API key
{id} must be that key's own id (key.id from GET /me); any other id is 403 INSUFFICIENT_SCOPE with details.required: "self", whatever it names. The key stops authenticating at once — a retry, even with the same Idempotency-Key, is 401 — and a rotated-out key loses the rest of its grace window. Emits api_key.revoked and emails the account owner; when a concurrent revoke landed first the answer is still 200, with no second event. Other keys are managed in the dashboard.- Required scope
- keys:write
- Idempotency
- Accepts Idempotency-Key
- Webhook events
- api_key.revoked
- Rate limits
Integer: the calling key's ownid(path)API key idid, not itskey_idstring. Any other id is 403INSUFFICIENT_SCOPE.Placeholder in the samples:
<API_KEY_ID>Get it from
- GET /v1/me returns it as
key.id - Only the key that sends the request can be revoked here. Other keys are listed and revoked in the dashboard.
- GET /v1/me returns it as
Path parameters
idintegerRequiredThe calling key's id.
Header parameters
Idempotency-KeystringOptionalMakes a retry safe. The first 2xx answer is stored for 24 h and replayed for the same key withIdempotency-Replayed: true; a retry while the first request runs is 409IDEMPOTENCY_IN_FLIGHT; the same key with a different payload is 422IDEMPOTENCY_KEY_REUSED; a malformed key is 400INVALID_IDEMPOTENCY_KEY.Min length:
16Max length:128Pattern:^[A-Za-z0-9_-]+$
Responses
- 200Success.
objectstringRequiredAlways
api_keyidintegerRequiredThe revoked key's id.deletedbooleanRequiredAlwaystrue. The key row is kept, revoked, so its request logs still name it.
- 400A tenant selector header named a tenant other than the API key's own (
ACCOUNT_SELECTOR_NOT_SUPPORTED): an all-digitX-Account-Idother than the key owner's id or, whileworkspaces.context_enabledis on, anX-Workspace-Idother than the key's workspace (ws_prefix optional, case-insensitive). A header naming the key's own tenant, or a non-numericX-Account-Id, is ignored; a key cannot switch tenants, so send neither. A mutation that honoursIdempotency-Keyalso returnsINVALID_IDEMPOTENCY_KEYwhen that header is not 16–128[A-Za-z0-9_-]characters.Error codesACCOUNT_SELECTOR_NOT_SUPPORTEDINVALID_IDEMPOTENCY_KEY
- 401Missing or invalid API key.
Error codesUNAUTHENTICATED
- 403The API key is missing a required scope.
Error codesACCOUNT_SUSPENDEDINSUFFICIENT_SCOPE
- 409The request conflicts with the current resource state.
Error codesIDEMPOTENCY_IN_FLIGHT
- 422Validation failed. See
error.details.Error codesIDEMPOTENCY_KEY_REUSED
- 429Rate limited. Honour the Retry-After header before retrying.
Error codesRATE_LIMITED
- 500Unexpected server error. Retry with the same Idempotency-Key.
Error codesSERVER_ERROR
Request
curl -X DELETE 'https://api.agentency.com/v1/api_keys/<API_KEY_ID>' \
-H "Authorization: Bearer <YOUR_KEY>" \
-H "Content-Type: application/json"Response
Example 200 response
{
"object": "api_key",
"id": 1,
"deleted": true
}