Skip to content
Browse the docs

Console · Published 2026-09-28 · Updated 2026-09-28 · AgentiSend

API keys

Create, rotate and delete keys on the API keys screen. A viewer can read the list. Creating one needs an admin or an owner.

The API keys screen is at /api-keys in the console. It lists every key, creates one, rotates one and deletes one. Budgets and the kill switch are not on this screen. They are on Agents.

What the screen calls

The list is GET /api-keys.

curl -sS -X GET https://api.agentisend.com/api-keys \
  -H "Authorization: Bearer $AGENTISEND_API_KEY"
200
{
  "data": [],
  "has_more": false,
  "next_cursor": "example",
  "object": "list"
}
Response

Creating a key is POST /api-keys. The body is a name, a permission (full_access or sending_access) and an optional domain_scope. The token comes back once. The list never includes it again.

curl -sS -X POST https://api.agentisend.com/api-keys \
  -H "Authorization: Bearer $AGENTISEND_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"name":"example","permission":"full_access"}'
201
{
  "budget_per_period": 1000,
  "created_at": "2026-09-04T09:14:00.000Z",
  "domain_scope": "example",
  "expires_at": "2026-09-04T09:14:00.000Z",
  "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42",
  "last_used_at": "2026-09-04T09:14:00.000Z",
  "loop_guard": "off",
  "name": "example",
  "period": "monthly",
  "permission": "full_access",
  "previous_key_expires_at": "2026-09-04T09:14:00.000Z",
  "rate_ceiling_per_minute": 600,
  "request_count_30d": -9007199254740991,
  "rotated_at": "2026-09-04T09:14:00.000Z",
  "scopes": [],
  "system": false,
  "token": "as_abababababababababababababababababababababababababababababababab",
  "token_prefix": "as_abababab"
}
Response

Rotating a key is POST /api-keys/{id}/rotate. grace_hours is 0, 1 or 24: the token it replaces stops at once, after one hour, or after a day. The new token is shown once.

curl -sS -X POST https://api.agentisend.com/api-keys/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42/rotate \
  -H "Authorization: Bearer $AGENTISEND_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"grace_hours":0}'
200
{
  "budget_per_period": -9007199254740991,
  "created_at": "2026-09-04T09:14:00.000Z",
  "domain_scope": "example",
  "expires_at": "2026-09-04T09:14:00.000Z",
  "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42",
  "last_used_at": "2026-09-04T09:14:00.000Z",
  "loop_guard": "off",
  "name": "example",
  "period": "hourly",
  "permission": "full_access",
  "previous_key_expires_at": "2026-09-04T09:14:00.000Z",
  "rate_ceiling_per_minute": -9007199254740991,
  "request_count_30d": -9007199254740991,
  "rotated_at": "2026-09-04T09:14:00.000Z",
  "scopes": [],
  "system": false,
  "token": "example",
  "token_prefix": "example"
}
Response

Deleting a key is DELETE /api-keys/{id}.

curl -sS -X DELETE https://api.agentisend.com/api-keys/9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42 \
  -H "Authorization: Bearer $AGENTISEND_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)"
200
{
  "deleted": false,
  "id": "9c8f8f0e-3d1a-4d3f-9a1e-2b7c1a0f5e42"
}
Response

An admin or an owner can make these changes. A viewer who tries is refused:

{
  "error": {
    "code": "insufficient_role",
    "message": "Your role on this account cannot make this change.",
    "fix": "Ask an owner to make the change, or to raise your role with PATCH /team/members/:id.",
    "docs_url": "https://agentisend.com/docs/errors#insufficient_role",
    "retryable": false
  }
}

A key whose permission is sending_access is refused on these routes:

{
  "error": {
    "code": "restricted_api_key",
    "message": "This API key is restricted to sending only.",
    "fix": "Use a full_access key (POST /api-keys with permission=full_access) for management endpoints.",
    "docs_url": "https://agentisend.com/docs/errors#restricted_api_key",
    "retryable": false
  }
}

Next