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"
}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"
}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"
}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"
}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
}
}