# Revoke an API key

`DELETE https://api.endless.app/api-keys/{api_key_id}`

Source: https://endless.app/docs/api/api-keys/revoke

The key stops working at once. It stays listed, with what it spent, so its history keeps a name.

## Authentication

- `bearerAuth`: HTTP bearer

## Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `api_key_id` | path | string (uuid) | yes |  |
| `Endless-Api-Version` | header | string | no | Pin the caller to an API major (`1`). Omit to accept the current version. A major this deployment cannot serve is refused with 400 `unsupported_api_version`. |

## Responses

### 200 OK

Content type: `application/json` — object

- `id` (string (uuid), required)
- `organization_id` (string, required)
- `name` (string, required)
- `description` (string | null, required)
- `project_access` ("all" | "selected", required)
- `spending_limit` (integer | null, required)
- `allowed_ips` (array<string>, required)
- `expires_at` (string (date-time) | null, required)
- `last_used_at` (string (date-time) | null, required)
- `created_by_id` (string, required)
- `revoked_at` (string (date-time) | null, required)
- `revoked_by_id` (string | null, required)
- `revoked_reason` ("revoked" | "creator_left" | null, required)
- `created_at` (string (date-time), required)
- `updated_at` (string (date-time), required)
- `token_prefix` (string, required)
- `token_hint` (string, required)
- `secret_created_at` (string (date-time), required)
- `retiring_secrets` (array<object>, required)
  - `id` (string (uuid), required)
  - `token_hint` (string, required)
  - `expires_at` (string (date-time), required)
  - `last_used_at` (string (date-time) | null, required)
  - `created_at` (string (date-time), required)
- `scopes` (array<"models:read" | "generations:read" | "generations:create" | "generations:cancel" | "voices:read" | "voices:write" | "transcripts:read" | "transcripts:create" | "assets:read" | "assets:write" | "assets:delete" | "projects:read" | "projects:write" | "chats:read" | "chats:write" | "canvases:read" | "canvases:write" | "skills:read" | "skills:write" | "schedules:read" | "schedules:write" | "sharing:read" | "sharing:write" | "connectors:read" | "social:read" | "social:query" | "search:query" | "credits:read" | "reports:read" | "profile:read" | "notifications:read" | "notifications:write" | "members:read" | "members:write" | "teams:read" | "teams:write" | "roles:read" | "roles:write" | "settings:read" | "settings:write" | "governance:read" | "governance:write" | "billing:read">, required)
- `status` ("active" | "expired" | "revoked", required)
- `project_ids` (array<string (uuid)>, required)
- `created_by` (object | null, required)
  - `id` (string, required)
  - `first_name` (string | null, required)
  - `last_name` (string | null, required)
  - `email` (string, required)
  - `image_url` (string, required)
- `credits_used` (integer, required)
- `capabilities` (object, required)
  - `can_rotate` (boolean, required)
  - `can_widen` (boolean, required)

### Errors

- `400` (Error): The request is malformed, or failed input validation. `message` names the field and the rule it broke; `data.issues` carries them individually.
- `401` (Error): No bearer token, or a token that failed verification.
- `402` (Error): The workspace has no credits left, or the caller is over a spending limit.
- `403` (Error): Authenticated, but the caller's role in this workspace does not carry the permission this operation needs.
- `404` (Error): No resource with that id, or the caller cannot read it. The two are deliberately one answer, so an id cannot be probed for existence.
- `409` (Error): The request is well-formed, but the resource's current state forbids it — a taken name, a last admin, a limit already reached.
- `429` (Error): The caller has spent its rate-limit window. `Retry-After` says when to come back.
- `500` (Error): The request failed on our side. Safe to retry an idempotent operation with backoff.
