This page publishes the complete request and response schemas for the three
primary Tickets MCP tools: dispatch_ticket, list_tickets, and get_ticket.
Each section provides:
- A request schema table (all parameters, types, required/optional).
- An annotated example request in JSON.
- A response schema table (all top-level and nested fields, types,
required/optional).
- An annotated example response in JSON.
- An error shapes block (standard error envelope).
For connection instructions (OAuth or API key), see
Alchemist Cloud Tickets MCP.
All three tools return ticket summaries using the same Ticket object shape.
Fields marked required are always present; fields marked optional are
omitted when null rather than serialized as null except where noted.
| Field | Type | Presence | Description |
|---|
id | string (uuid) | required | Ticket UUID. Stable identifier for all MCP calls. |
ticketRef | string | required | Human-facing project-scoped ref, e.g. ACME-42. Falls back to #<N> when the project key is not set. |
projectSeq | integer | required | Per-project sequence number (the N in PROJ-N). |
projectId | string (uuid) | required | Project this ticket belongs to. |
title | string | required | Ticket title as filed (may be redrafted server-side from the original dispatch). |
status | string (enum) | required | One of: queued, blocked, running, succeeded, failed, timeout, cancelled, awaiting_input. |
kind | string (enum) | required | One of: feature, fix, refactor, data_operation, org_agent_construction. |
currentPass | integer | null | required | Current pipeline pass number for legacy five-pass tickets. null for dynamic-graph tickets or not-yet-started tickets. |
commitSha | string | null | required | Git commit SHA produced by this ticket, once landed. null until the land node completes. |
branchName | string | null | required | Agent working branch (e.g. agent/<job-id>). null until the ticket starts. |
failureReason | string | null | required | Human-readable reason the ticket failed or timed out. null for non-failed tickets. |
ticketSource | string | null | required | How the ticket was dispatched: mcp, dashboard, cron, etc. |
createdAt | string (ISO 8601) | null | required | When the ticket was created. |
startedAt | string (ISO 8601) | null | required | When the ticket started running. null if not yet started. |
completedAt | string (ISO 8601) | null | required | When the ticket reached a terminal state. null if still in progress. |
dependsOn | string[] (uuid[]) | required | Parent ticket UUIDs this ticket is blocked on. Empty array for independent tickets. |
scopeId | string (uuid) | null | required | Scope batch ID for multi-ticket graphs dispatched together. null for standalone tickets. |
requesterDisplayName | string | null | required | Display name of the human who dispatched the ticket, if captured. |
requesterEmail | string | null | required | Email of the requester, if captured (used for awaiting_input notifications). |
requesterAvatarUrl | string | null | required | Profile picture URL of the requester, if captured. |
requesterChannel | string | null | required | Origin channel: chipp_chat, slack, dashboard, mcp, api, etc. null if not captured. |
requesterExternalRef | string | null | required | Opaque back-reference to the originating context (Slack user + thread, session ID). Never a token/secret. |
categoryId | string (uuid) | null | required | Ticket category (“epic”) UUID. null if uncategorized. |
categoryLabel | string | null | required | Category display label, e.g. "Auth & Billing". null if uncategorized. Soft-deleted categories render as "<name> (deleted)". |
categoryDeleted | boolean | required | true when the category this ticket is tagged with has been soft-deleted. |
Creates and dispatches a new ticket (agent run) for one of your projects.
| Parameter | Type | Required | Description |
|---|
title | string (1-500 chars) | required | Short ticket title. |
project_id | string (uuid) | required if project not set | Target project UUID. Takes precedence over project. |
project | string | required if project_id not set | Target project UUID or human-readable name (e.g. "Acme Widgets"). |
description | string | optional | Full brief / acceptance criteria. Write as a complete, self-contained spec. |
kind | string (enum) | optional | feature (default), fix, refactor, data_operation, or org_agent_construction. Auto-classified from title + description when omitted. |
preset | string (enum) | optional | Pipeline tier override. Default "auto". See pipeline docs for values. |
pass_profile | string (enum) | optional | "auto" (default), "full", or "minimal". Controls whether Security and Docs passes run. |
depends_on | string[] | optional | Parent ticket UUIDs or #N refs. Ticket waits until all parents succeed. Requires depends_on_reason. |
depends_on_reason | string | required when depends_on set | One sentence naming the landed output of the parent that this ticket consumes. |
replaces | string (uuid or #N) | optional | UUID or #N of a cancelled ticket this dispatch refiles. Dependents of the cancelled ticket are auto-repointed. |
seed_from_ref | string | optional | Branch name to seed this ticket’s working branch from (for continuations/salvage of a prior failed ticket). |
job_id | string (uuid) | required when attachments non-empty | Pre-minted job UUID used with mint_attachment_upload_url. |
attachments | AttachmentInput[] | optional | Already-uploaded file references (never inline bytes). See AttachmentInput below. |
confirm_no_attachments | boolean | optional | Set true to acknowledge that a file/path reference in the ticket text is a repo path or URL, not an upload the agent needs to read. |
conversation | ConversationTurn[] | optional | Full conversation transcript leading up to this dispatch. Triggers server-side ticket drafting. |
predrafted | boolean | optional | Set true to file title/description verbatim, skipping server-side redrafting. Default false. |
no_split | boolean | optional | Set true to disable automatic ticket splitting even if the scope estimate exceeds the node threshold. |
requester | RequesterInput | optional | Who dispatched this ticket (display/notification only, not an authorization input). |
category | string | optional | Category name to assign this ticket to. Create-or-get by normalized name. |
operation_key | string | optional | Stable idempotency key for this dispatch node. Repeating the same key returns the original ticket instead of creating a duplicate. |
override_duplicate | boolean | optional | Set true to explicitly allow a near-duplicate dispatch after confirming the duplication is intentional. Audited. |
| Field | Type | Required | Description |
|---|
key | string | required | R2 key returned by mint_attachment_upload_url. |
original_name | string | required | Original filename (e.g. "spec.pdf"). |
content_type | string | required | MIME type (e.g. "application/pdf"). |
size_bytes | number | required | File size in bytes. |
| Field | Type | Required | Description |
|---|
display_name | string | optional | Human display name. |
email | string | optional | Email address for notifications. |
avatar_url | string | optional | Profile picture URL. Must be https://. |
channel | string (enum) | optional | Origin channel: chipp_chat, slack, dashboard, mcp, api, cron, or webhook. |
external_ref | string | optional | Opaque origin pointer (e.g. Slack user + thread ref). Never a token/secret. |
| Field | Type | Required | Description |
|---|
role | string (enum) | required | "user", "assistant", or "system". |
content | string | required | Message text. |
{
"title": "Add dark-mode toggle to the dashboard header",
"project": "Acme Widgets",
"description": "The dashboard header (web/src/routes/dashboard/Header.svelte) should have a sun/moon toggle that switches between light and dark Tailwind themes. Store the preference in localStorage. Acceptance: toggle renders on all breakpoints, preference persists on refresh, WCAG AA contrast passes on both themes.",
"kind": "feature",
"requester": {
"display_name": "Ada Builder",
"email": "ada@example.com",
"channel": "mcp"
},
"operation_key": "scope-abc123:node-0"
}
| Field | Type | Presence | Description |
|---|
ticket | Ticket | required | The dispatched (or idempotently replayed) ticket. See Shared type: Ticket. |
chain | ChainEntry[] | optional | Present only when the drafting gate auto-split this ticket into a dependent chain. Ordered root-first. |
repointed_dependents | RepointResult[] | optional | Present only when replaces was supplied. Lists each formerly-blocked dependent that was auto-repointed onto this ticket. |
duplicate | DuplicateInfo | optional | Present only when this call was short-circuited into an existing ticket (idempotent replay or near-duplicate detection). |
| Field | Type | Presence | Description |
|---|
job_id | string (uuid) | required | Ticket UUID of this chain member. |
title | string | required | Title of this chain member (as drafted). |
ticket_ref | string | required | Human-facing ref (e.g. ACME-43). |
depends_on | string[] | required | UUIDs of the chain members this one waits on. Empty for the root. |
| Field | Type | Presence | Description |
|---|
ticket_id | string (uuid) | required | Dependent ticket that was re-pointed (or failed re-point validation). |
ok | boolean | required | true if re-point succeeded; false if it was skipped. |
reason | string | optional | Present when ok: false. Explains why re-point was skipped (e.g. validation failure or concurrent operator action). |
| Field | Type | Presence | Description |
|---|
existing_job_id | string (uuid) | required | UUID of the existing ticket this call was merged into. |
existing_ticket_ref | string | required | Ref of the existing ticket (e.g. ACME-41). |
match_reason | string | required | Human-readable explanation of why this was treated as a duplicate. |
source | string (enum) | required | "operation_key" (idempotent replay) or "near_duplicate" (content-similarity detection). |
{
"ticket": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"ticketRef": "ACME-42",
"projectSeq": 42,
"projectId": "11111111-1111-4111-8111-111111111111",
"title": "Add dark-mode toggle to the dashboard header",
"status": "queued",
"kind": "feature",
"currentPass": null,
"commitSha": null,
"branchName": null,
"failureReason": null,
"ticketSource": "mcp",
"createdAt": "2026-07-29T14:00:00.000Z",
"startedAt": null,
"completedAt": null,
"dependsOn": [],
"scopeId": null,
"requesterDisplayName": "Ada Builder",
"requesterEmail": "ada@example.com",
"requesterAvatarUrl": null,
"requesterChannel": "mcp",
"requesterExternalRef": null,
"categoryId": null,
"categoryLabel": null,
"categoryDeleted": false
}
}
Example with auto-split chain (when the ticket is large enough to split):
{
"ticket": {
"id": "a1b2c3d4-0000-0000-0000-000000000001",
"ticketRef": "ACME-43",
"projectSeq": 43,
"projectId": "11111111-1111-4111-8111-111111111111",
"title": "Phase 1: Add dark-mode toggle to the dashboard header",
"status": "queued",
"kind": "feature",
"currentPass": null,
"commitSha": null,
"branchName": null,
"failureReason": null,
"ticketSource": "mcp",
"createdAt": "2026-07-29T14:00:05.000Z",
"startedAt": null,
"completedAt": null,
"dependsOn": [],
"scopeId": null,
"requesterDisplayName": "Ada Builder",
"requesterEmail": "ada@example.com",
"requesterAvatarUrl": null,
"requesterChannel": "mcp",
"requesterExternalRef": null,
"categoryId": null,
"categoryLabel": null,
"categoryDeleted": false
},
"chain": [
{
"job_id": "a1b2c3d4-0000-0000-0000-000000000001",
"title": "Phase 1: Add dark-mode toggle to the dashboard header",
"ticket_ref": "ACME-43",
"depends_on": []
},
{
"job_id": "a1b2c3d4-0000-0000-0000-000000000002",
"title": "Phase 2: Persist theme preference and add E2E tests",
"ticket_ref": "ACME-44",
"depends_on": ["a1b2c3d4-0000-0000-0000-000000000001"]
}
]
}
Lists recent tickets for your tenant, newest first.
| Parameter | Type | Required | Description |
|---|
project_id | string (uuid) | optional | Filter to one project. |
status | string (enum) | optional | Filter by status: queued, blocked, running, succeeded, failed, timeout, cancelled, or awaiting_input. |
category | string | optional | Filter by category name (case/whitespace-insensitive). Requires project_id. |
category_id | string (uuid) | optional | Filter by exact category UUID. |
limit | integer (1-100) | optional | Max results to return. Default 20. |
{
"project_id": "11111111-1111-4111-8111-111111111111",
"status": "running",
"limit": 5
}
| Field | Type | Presence | Description |
|---|
tickets | Ticket[] | required | Array of ticket summaries, newest first. See Shared type: Ticket. Empty array when none match. |
count | integer | required | Number of tickets returned (always tickets.length; bounded by limit). |
{
"tickets": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"ticketRef": "ACME-42",
"projectSeq": 42,
"projectId": "11111111-1111-4111-8111-111111111111",
"title": "Add dark-mode toggle to the dashboard header",
"status": "running",
"kind": "feature",
"currentPass": null,
"commitSha": null,
"branchName": "agent/a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"failureReason": null,
"ticketSource": "mcp",
"createdAt": "2026-07-29T14:00:00.000Z",
"startedAt": "2026-07-29T14:00:30.000Z",
"completedAt": null,
"dependsOn": [],
"scopeId": null,
"requesterDisplayName": "Ada Builder",
"requesterEmail": "ada@example.com",
"requesterAvatarUrl": null,
"requesterChannel": "mcp",
"requesterExternalRef": null,
"categoryId": "f0f1f2f3-0000-0000-0000-000000000001",
"categoryLabel": "UI Enhancements",
"categoryDeleted": false
}
],
"count": 1
}
Returns a curated status digest plus enriched detail for one ticket.
This is the default tool for ticket status — reach for get_ticket_reports
(full pass-report text) or get_ticket_graph (per-node diagnostics) only
when this response is not enough.
| Parameter | Type | Required | Description |
|---|
ticket | string | required | Ticket identifier: project-scoped ref (ACME-42), UUID, or legacy global number (#42 or 42). |
The response includes the base Ticket fields (see
Shared type: Ticket) at the key ticket, plus
the additional enriched fields below.
| Field | Type | Presence | Description |
|---|
ticket | Ticket | required | Base ticket summary. See Shared type: Ticket. |
turnsUsed | integer | required | Total agent turns consumed across all nodes in this ticket so far. |
inputTokens | integer | required | Accumulated input tokens across all model calls. |
outputTokens | integer | required | Accumulated output tokens across all model calls. |
autoMergeStatus | string | null | required | Auto-merge status ("merged", "conflicts", etc.) or null. |
creditBlockCount | integer | required | Number of times this ticket has been blocked on credits since the last real top-up. Nonzero means a credit disagreement is cycling. |
graphAmbientInterruptCount | integer | required | Number of ambient-interruption requeues consumed. |
graph | GraphSummary | optional | Compact graph summary. Present for dynamic-graph tickets; absent for legacy five-pass tickets. |
salvageNote | string | optional | Present when the ticket is in a terminal failed/cancelled/timeout state and a checkpoint branch exists. Describes the branch/commit and the resume path (use retry_ticket). |
completionSummary | string | null | required | Terminal digest written by the platform at completion. null for in-progress or not-yet-started tickets. |
latestPhaseSummary | string | optional | In-progress digest from the most recent pass. Absent for not-yet-started tickets. |
outcome | string (enum) | required | fully_verified, implementation_succeeded, partially_verified, failed, timeout, or in_progress. |
deferredItems | OutcomeItem[] | required | Items the agent explicitly deferred to a human or a follow-up ticket. Empty array when none. |
verificationGaps | ContractItem[] | required | Contract assertions the verification pass could not confirm. Empty array when none. |
partiallyVerifiedItems | ContractItem[] | required | Contract assertions that passed partially but have an unresolved agent-work item. Empty array when none. |
followUpRecommendations | OutcomeItem[] | required | Non-blocking suggestions surfaced by the agent for future tickets. Empty array when none. |
humanActionRequired | boolean | required | true when at least one item in humanActions still needs a human to act. |
humanActions | string[] | required | Ordered list of required next steps a human must perform. Empty array when none. |
dependsOnTickets | DependencyRef[] | optional | This ticket’s parent tickets (bounded, omitted when empty). |
followOnTickets | DependencyRef[] | optional | Direct child tickets waiting on this one (bounded, omitted when empty). |
| Field | Type | Presence | Description |
|---|
origin | string (enum) | required | How the graph was planned: "dynamic" (dispatch-time planned), "five_pass_v1" (legacy fixed pipeline). |
status | string (enum) | required | Graph-level rollup: "ready", "running", "succeeded", "failed", "cancelled". |
nodeCount | integer | required | Total number of nodes materialized in the graph (including completed nodes). |
nodes | GraphNodeRef[] | required | Compact node list (capped at 20). |
| Field | Type | Presence | Description |
|---|
ref | string | required | Node ref within the graph (e.g. "implement-1", "review-1"). |
kind | string (enum) | required | Node kind: plan, contract, research, investigate, implement, docs, integration, review, security, verification, qa_authoring, reconcile, merge_repair, land, deploy_verify. |
status | string (enum) | required | Node status: queued, running, succeeded, failed, cancelled, skipped, awaiting_input, blocked. |
| Field | Type | Presence | Description |
|---|
text | string | required | The deferred item or recommendation, as plain text. |
source | string | required | Which pass/report surfaced this item, or "derived" for a pre-migration ticket. |
| Field | Type | Presence | Description |
|---|
assertion | string | required | The specific contract assertion that was not fully verified. |
evidence | string | optional | Evidence the verification node collected (what it checked and what it found). |
source | string | required | Which pass/report surfaced this item, or "derived". |
| Field | Type | Presence | Description |
|---|
ticketRef | string | required | Human-facing ref of the related ticket (e.g. ACME-41). |
title | string | required | Title of the related ticket. |
status | string (enum) | required | Current status of the related ticket. |
{
"ticket": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"ticketRef": "ACME-42",
"projectSeq": 42,
"projectId": "11111111-1111-4111-8111-111111111111",
"title": "Add dark-mode toggle to the dashboard header",
"status": "succeeded",
"kind": "feature",
"currentPass": null,
"commitSha": "abc123def456",
"branchName": "agent/a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"failureReason": null,
"ticketSource": "mcp",
"createdAt": "2026-07-29T14:00:00.000Z",
"startedAt": "2026-07-29T14:00:30.000Z",
"completedAt": "2026-07-29T14:18:45.000Z",
"dependsOn": [],
"scopeId": null,
"requesterDisplayName": "Ada Builder",
"requesterEmail": "ada@example.com",
"requesterAvatarUrl": null,
"requesterChannel": "mcp",
"requesterExternalRef": null,
"categoryId": "f0f1f2f3-0000-0000-0000-000000000001",
"categoryLabel": "UI Enhancements",
"categoryDeleted": false
},
"turnsUsed": 42,
"inputTokens": 180000,
"outputTokens": 24000,
"autoMergeStatus": "merged",
"creditBlockCount": 0,
"graphAmbientInterruptCount": 0,
"graph": {
"origin": "dynamic",
"status": "succeeded",
"nodeCount": 6,
"nodes": [
{ "ref": "plan-1", "kind": "plan", "status": "succeeded" },
{ "ref": "contract-1", "kind": "contract", "status": "succeeded" },
{ "ref": "implement-1", "kind": "implement", "status": "succeeded" },
{ "ref": "review-1", "kind": "review", "status": "succeeded" },
{ "ref": "verification-1", "kind": "verification", "status": "succeeded" },
{ "ref": "land-1", "kind": "land", "status": "succeeded" }
]
},
"completionSummary": "Added a sun/moon toggle to `Header.svelte` that switches between light and dark Tailwind themes. Preference is persisted in `localStorage`. WCAG AA contrast verified on both themes. Merged to staging at abc123def456.",
"outcome": "fully_verified",
"deferredItems": [],
"verificationGaps": [],
"partiallyVerifiedItems": [],
"followUpRecommendations": [
{
"text": "Consider syncing the theme preference with the user's OS-level prefers-color-scheme media query in a follow-up.",
"source": "review-pass-2"
}
],
"humanActionRequired": false,
"humanActions": []
}
{
"ticket": {
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"ticketRef": "ACME-43",
"projectSeq": 43,
"projectId": "11111111-1111-4111-8111-111111111111",
"title": "Migrate user preferences to new schema",
"status": "failed",
"kind": "data_operation",
"currentPass": null,
"commitSha": null,
"branchName": "agent/b2c3d4e5-f6a7-8901-bcde-f12345678901",
"failureReason": "Migration dry-run detected 3 rows that would violate the NOT NULL constraint on preferences.theme. Manual review required before applying.",
"ticketSource": "dashboard",
"createdAt": "2026-07-29T15:00:00.000Z",
"startedAt": "2026-07-29T15:00:30.000Z",
"completedAt": "2026-07-29T15:12:10.000Z",
"dependsOn": [],
"scopeId": null,
"requesterDisplayName": null,
"requesterEmail": null,
"requesterAvatarUrl": null,
"requesterChannel": null,
"requesterExternalRef": null,
"categoryId": null,
"categoryLabel": null,
"categoryDeleted": false
},
"turnsUsed": 18,
"inputTokens": 72000,
"outputTokens": 9000,
"autoMergeStatus": null,
"creditBlockCount": 0,
"graphAmbientInterruptCount": 0,
"completionSummary": null,
"outcome": "failed",
"salvageNote": "Checkpoint branch agent/b2c3d4e5-f6a7-8901-bcde-f12345678901 has 2 committed steps. To resume from this checkpoint, call retry_ticket with ticket id b2c3d4e5-f6a7-8901-bcde-f12345678901.",
"deferredItems": [],
"verificationGaps": [],
"partiallyVerifiedItems": [],
"followUpRecommendations": [],
"humanActionRequired": true,
"humanActions": [
"Review the 3 rows with null theme values in app.user_preferences and backfill a default before retrying the migration."
]
}
{
"ticket": {
"id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"ticketRef": "ACME-44",
"projectSeq": 44,
"projectId": "11111111-1111-4111-8111-111111111111",
"title": "Integrate Stripe Checkout for the Pro plan upgrade",
"status": "awaiting_input",
"kind": "feature",
"currentPass": null,
"commitSha": null,
"branchName": "agent/c3d4e5f6-a7b8-9012-cdef-123456789012",
"failureReason": null,
"ticketSource": "mcp",
"createdAt": "2026-07-29T16:00:00.000Z",
"startedAt": "2026-07-29T16:00:30.000Z",
"completedAt": null,
"dependsOn": [],
"scopeId": null,
"requesterDisplayName": "Ada Builder",
"requesterEmail": "ada@example.com",
"requesterAvatarUrl": null,
"requesterChannel": "mcp",
"requesterExternalRef": null,
"categoryId": null,
"categoryLabel": null,
"categoryDeleted": false
},
"turnsUsed": 11,
"inputTokens": 44000,
"outputTokens": 5500,
"autoMergeStatus": null,
"creditBlockCount": 0,
"graphAmbientInterruptCount": 0,
"completionSummary": null,
"latestPhaseSummary": "Implement node running: Stripe webhook endpoint scaffolded; awaiting the Stripe webhook secret to wire the signature-verification middleware.",
"outcome": "in_progress",
"deferredItems": [],
"verificationGaps": [],
"partiallyVerifiedItems": [],
"followUpRecommendations": [],
"humanActionRequired": true,
"humanActions": [
"Provide the Stripe webhook signing secret via the secure link in the agent's question. Do not paste the secret value into the chat -- use the secure submission link."
]
}
All three tools return errors in the same JSON-RPC error envelope. The data
field carries a structured object with a machine-readable code.
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32600,
"message": "Human-readable explanation of the error.",
"data": {
"code": "MACHINE_READABLE_CODE",
"statusCode": 400
}
}
}
data.code | statusCode | Triggered by |
|---|
NOT_FOUND | 404 | Ticket or project UUID does not exist, or belongs to a different tenant. The error message is the same regardless of which case applies (tenant isolation — no existence leak). |
MISSING_JOB_ID | 400 | dispatch_ticket: attachments non-empty but job_id not supplied. |
ATTACHMENT_REFERENCE_WITHOUT_ATTACHMENTS | 400 | dispatch_ticket: ticket text references a filename but attachments is empty and confirm_no_attachments was not set. |
DEPENDS_ON_REASON_REQUIRED | 400 | dispatch_ticket: depends_on supplied without a depends_on_reason of at least 10 characters. |
REPLACES_NOT_CANCELLED | 400 | dispatch_ticket: replaces refers to a ticket that is not in the cancelled state. |
INVALID_SEED_FROM_REF | 400 | dispatch_ticket: seed_from_ref contains characters outside the allowed branch-name charset. |
INVALID_KIND | 400 | dispatch_ticket: kind is not one of the allowed enum values. |
INVALID_PRESET | 400 | dispatch_ticket: preset is not one of the allowed enum values. |
INVALID_PASS_PROFILE | 400 | dispatch_ticket: pass_profile is not one of the allowed enum values. |
CATEGORY_FILTER_REQUIRES_PROJECT | 400 | list_tickets: category filter supplied without project_id. |
NOT_CANCELLABLE | 409 | cancel_ticket: ticket is already in a terminal state. |
UNAUTHENTICATED | 401 | No valid Authorization: Bearer alch_... header, or the key has been revoked. |
FORBIDDEN | 403 | Valid key but the caller does not have access to the referenced project. |
The NOT_FOUND error is intentionally opaque: whether the ticket or project
does not exist, or exists but belongs to a different tenant, the same error
is returned. This prevents an authenticated caller from probing for UUIDs
that belong to other tenants.