Skip to content

Error codes

A failed request returns an HTTP status and this body:

{ "error": { "code": "INSUFFICIENT_SCOPE", "message": "api key requires scope 'write'" } }

message is a developer-facing description and may change. Codes do not change, so branch on code. Some errors carry extra fields (for example unknown_keys on INVALID_LABELS).

Code Status Meaning and what to do
UNAUTHORIZED 401 The key is missing or wrong. Calling a request that is not open to API keys with a key also returns this.
API_KEY_REVOKED 401 The key was revoked. Create a new one.
API_KEY_EXPIRED 401 The key has expired. Create a new one.
AGENT_KEY_REVOKED 401 The AI agent key was revoked. Check the agent’s status with the operator.
TOKEN_REVOKED 401 The token belongs to a CLI or AI coding tool connection that was disconnected. Sign in again (reconnect) from that tool.
TOKEN_EXPIRED 401 The CLI or AI coding tool token has expired. The CLI and AI coding tools refresh it on their own — when calling directly, get a new token with the refresh token.
FORBIDDEN 403 Not allowed. Also returned when the person who created the key has left the workspace.
ACCOUNT_SUSPENDED 403 The account of the person who created the key is suspended.
ACCOUNT_DELETION_PENDING 403 The account of the person who created the key is scheduled for deletion (grace period). The key works again if that person signs in and cancels the deletion.
ACCOUNT_DELETED 403 The account of the person who created the key has been deleted. The key will not work again — have someone else create a new key.
INSUFFICIENT_SCOPE 403 The key lacks the scope this request needs (read, write, or metrics:ingest).
WORKSPACE_MISMATCH 403 The x-workspace-slug header does not match the key’s workspace. Drop the header or fix it.
DEV_TOOLS_DISABLED_FOR_WORKSPACE 403 A workspace admin turned off developer tool connections (CLI and AI coding tools) for this workspace, or disconnected this CLI sign-in from this workspace. REST requests made with a personal key (gtk_) keep working.
WRITER_ROLE_REQUIRED 403 The person who created the key (for an agent key, the agent) is now a viewer and cannot write.
AGENT_NOT_ASSIGNED 403 This issue is not assigned to this AI agent. Agent keys write only to assigned issues; reads still work.
WORKSPACE_SUSPENDED_FULL 403 The workspace is suspended; both reads and writes are blocked. Contact your workspace admin.
WORKSPACE_SUSPENDED_READ_ONLY 403 The workspace is suspended in read-only mode. Reads work; writes are blocked.
SYSTEM_SOURCE_FORBIDDEN 403 A key cannot store values with source: "system_etl". Leave source out.
VALIDATION 400 The body or query does not match the expected shape. Unknown fields also return this.
WORKSPACE_REQUIRED 400 A CLI sign-in token works across workspaces, so every request must pick one. Send the x-workspace-slug header (-W <slug> in the CLI).
INVALID_LABELS 400 labels contains a dimension the metric does not define. Check unknown_keys.
METRIC_LABEL_EMPTY 400 A value in labels is empty or only whitespace. Fill in the dimensions listed in empty_keys, or leave those keys out.
REF_NOT_IN_WORKSPACE 400 A reference such as a team or project belongs to another workspace (field names it).
NOT_IN_WORKSPACE 400 A label you passed when creating an issue (label_ids) is not in this workspace (field names the field). If any one is missing, the issue is not created.
LABEL_IS_GROUP 400 label_ids contains a label group itself. Groups can’t be applied — pick a label inside the group.
LABEL_GROUP_EXCLUSIVE 400 label_ids contains more than one label from the same label group. Pick one per group (group_id names the group).
INVALID_PARENT 400 The parent issue (parent_id) cannot go there (another team, or an issue that cannot have a parent). Check reason.
CYCLE_IN_OTHER_TEAM 400 The cycle belongs to a different team than the issue. Pick a cycle of the issue’s team.
MILESTONE_NOT_IN_PROJECT 400 The milestone does not belong to the issue’s project (including when the issue has no project). Set the issue’s project and pick one of its milestones. Changing only the project clears a milestone that no longer fits.
STATUS_IN_OTHER_TEAM 400 The status is dedicated to a different team (field: "status_id"). Pick a shared status or one of the issue’s team.
STATUS_ARCHIVED 400 The status was deleted (archived) (field: "status_id"). Pick a usable status again with GET /api/v1/workflow_states?available_for_team=<team_id>.
INVALID_STATUS_MAPPING 400 A status in the status_map you sent with a restore is not usable by that team (another team’s only · deleted · outside this workspace), or a key is not a status of this workspace (field: "status_map" · status_ids). The issue was not changed. Pick again from the candidates of STATUS_MAPPING_REQUIRED.
AI_AGENT_REVOKED 400 A revoked AI agent cannot be the assignee.
PRECONDITION_REQUIRED 412 The PATCH body has no expected_version. Read the issue and send its version.
NOT_FOUND 404 The target does not exist or this key cannot see it. The two are not distinguished.
VERSION_CONFLICT 409 Someone changed it after you read it. Read it again and send the new version.
STATUS_MAPPING_REQUIRED 409 The status in the version you are restoring (or of a sub-issue that moves back with it) was deleted (archived) or is not usable by the resulting team. The issue was not changed. required lists those statuses (archived: true = deleted), candidates the statuses you can pick and suggested same-name matches. Pick one per source status and send the request again with status_map ({ source status_id: target status_id }).
NO_TARGET_STATES 422 A mapping is needed but the resulting team has no status to pick. Create statuses in the workflow settings first.
CONCURRENT_MOVE 409 The request overlapped with another change being processed. Send the same request again shortly.
METRIC_ARCHIVED 409 Archived metrics do not accept values. Unarchive it on the Metrics screen.
SYSTEM_METRIC_READONLY 409 The value is computed by the system and cannot be overwritten.
LOCK_TIMEOUT 503 Another operation on the same target overlapped. Retry shortly.
STATEMENT_TIMEOUT 503 The query took too long and was stopped. Narrow it (limit, filters).

Going over a limit returns 429. That response may not carry a code in the format above, so judge by the status and wait for the Retry-After header (seconds) before retrying. The limits are listed under API keys.