{"openapi":"3.1.0","info":{"title":"Clanker Ship API","version":"1.0.0","description":"The Clanker Ship API does everything the website does: workspaces and people, products and environments, planning, clanker messages, test runs and secrets. It runs the same services and permission checks as the website.\n\nCreate an API key under Security settings on the website, then send it as `Authorization: Bearer ctk_…` or `X-API-Key: ctk_…`. Requests act as the key's user, with that user's role in each workspace. A workspace API key (`cwk_…`) acts in its one workspace with its own role. Clankers connect over MCP at `/mcp` with clanker OAuth instead of API keys."},"paths":{"/v1/me":{"get":{"tags":["Profile"],"operationId":"profile.get","parameters":[],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"The person, or the workspace API key, the request acts for.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/User"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns the user the API key acts for. An account API key returns itself, with its workspace and role.","summary":"Get your profile"},"patch":{"tags":["Profile"],"operationId":"profile.update","parameters":[],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"type":"boolean","enum":[true],"description":"Always true: the change was made."}},"additionalProperties":false}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Sets your display name and records a `profile.updated` event in each workspace you belong to. Account API keys cannot change a profile.","summary":"Update your profile","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","description":"Your new display name."}},"additionalProperties":false,"examples":[{"name":"Maya Patel"}]}}},"required":true}}},"/v1/me/photo":{"post":{"tags":["Profile"],"operationId":"profile.uploadPhoto","parameters":[],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","image"],"properties":{"ok":{"type":"boolean","enum":[true],"description":"Always true: the photo was replaced."},"image":{"type":"string","description":"URL of your new profile photo."}},"additionalProperties":false,"examples":[{"ok":true,"image":"https://images.clankership.com/users/Us3NfP8kLq2V/profile-Ph8KcV2nRx4M.webp"}]}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Replaces your profile photo with a PNG, JPEG or WebP image under 5 MB. Account API keys cannot change a profile.","summary":"Upload a profile photo","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["photo"],"properties":{"photo":{"type":"string","format":"binary","description":"A PNG, JPEG or WebP image under 5 MB for your profile photo."}}}}}}}},"/v1/me/preferences":{"get":{"tags":["Profile"],"operationId":"profile.getPreferences","parameters":[],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Which emails you want. A user who never saved preferences gets the defaults.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationPreferences"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns which emails you want, or the defaults if you never saved any. Account API keys have no preferences.","summary":"Get your notification preferences"},"patch":{"tags":["Profile"],"operationId":"profile.updatePreferences","parameters":[],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"type":"boolean","enum":[true],"description":"Always true: the change was made."}},"additionalProperties":false}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Saves both email preferences, so send both fields. Account API keys have no preferences.","summary":"Update your notification preferences","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["productUpdates","workspaceActivity"],"properties":{"productUpdates":{"type":"boolean","description":"Whether to email you Clanker Ship product updates. Defaults to true."},"workspaceActivity":{"type":"boolean","description":"Whether to email you activity in your workspaces. Defaults to false."}},"additionalProperties":false,"examples":[{"productUpdates":false,"workspaceActivity":true}]}}},"required":true}}},"/v1/me/home":{"get":{"tags":["Profile"],"operationId":"profile.getHome","parameters":[],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A website path, such as /w/acme or /onboarding.","content":{"application/json":{"schema":{"type":"string","description":"A website path, such as /w/acme or /onboarding.","examples":["/w/acme"]}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns the website path to open after sign-in: `/w/{slug}` for a workspace you belong to, or `/onboarding` when you belong to none. It first adds you to every workspace whose allowed domains include your email's domain.","summary":"Get your home path"}},"/v1/me/onboarding":{"get":{"tags":["Profile"],"operationId":"profile.getOnboarding","parameters":[],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["existing","completedSteps","finished"],"properties":{"existing":{"anyOf":[{"$ref":"#/components/schemas/Workspace"},{"type":"null"}],"description":"A workspace you already belong to, or null when you should create one."},"completedSteps":{"type":"array","items":{"type":"string","enum":["install-plugin","sign-in","create-ticket","invite-team"]},"description":"The onboarding steps you finished, in order: of install-plugin, sign-in, create-ticket, invite-team."},"finished":{"type":"boolean","description":"True once you finished every step or skipped onboarding."}},"additionalProperties":false,"examples":[{"existing":null,"completedSteps":["install-plugin"],"finished":false}]}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns a workspace you already belong to, or `existing: null` when you belong to none, and the onboarding steps you finished. It first adds you to every workspace whose allowed domains include your email's domain.","summary":"Get your onboarding"}},"/v1/me/onboarding/steps/{step}":{"post":{"tags":["Profile"],"operationId":"profile.completeOnboardingStep","parameters":[{"name":"step","in":"path","schema":{"type":"string","description":"An onboarding step: install-plugin, sign-in, create-ticket, invite-team.","examples":["install-plugin"]},"required":true,"description":"An onboarding step: install-plugin, sign-in, create-ticket, invite-team."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["completedSteps","finished"],"properties":{"completedSteps":{"type":"array","items":{"type":"string","enum":["install-plugin","sign-in","create-ticket","invite-team"]},"description":"The onboarding steps you finished, in order: of install-plugin, sign-in, create-ticket, invite-team."},"finished":{"type":"boolean","description":"True once you finished every step or skipped onboarding."}},"additionalProperties":false,"examples":[{"completedSteps":["install-plugin","sign-in"],"finished":false}]}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Marks one of your onboarding steps done, as Next does on the website. Finishing every step ends onboarding. Completing a finished step changes nothing.","summary":"Complete an onboarding step"}},"/v1/me/onboarding/skip":{"post":{"tags":["Profile"],"operationId":"profile.skipOnboarding","parameters":[],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["completedSteps","finished"],"properties":{"completedSteps":{"type":"array","items":{"type":"string","enum":["install-plugin","sign-in","create-ticket","invite-team"]},"description":"The onboarding steps you finished, in order: of install-plugin, sign-in, create-ticket, invite-team."},"finished":{"type":"boolean","description":"True once you finished every step or skipped onboarding."}},"additionalProperties":false,"examples":[{"completedSteps":["install-plugin","sign-in"],"finished":false}]}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Ends your onboarding early, as Skip does on the website, so the website stops showing it.","summary":"Skip onboarding"}},"/v1/api-keys":{"get":{"tags":["API keys"],"operationId":"apiKeys.list","parameters":[],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Your active API keys, newest first.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ApiKey"},"description":"Your active API keys, newest first."}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns your API keys that are not revoked, newest first. Account API keys cannot list keys.","summary":"List API keys"},"post":{"tags":["API keys"],"operationId":"apiKeys.create","parameters":[],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"An API key you just created, with its secret.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewApiKey"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Creates an API key that acts as you and returns its secret, which is shown only this once. You can have up to 20 active keys. Account API keys cannot create keys.","summary":"Create an API key","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","description":"A name that says where the key is used, 1 to 80 characters."}},"additionalProperties":false,"examples":[{"name":"CI deploys"}]}}},"required":true}}},"/v1/api-keys/{apiKeyId}/revoke":{"post":{"tags":["API keys"],"operationId":"apiKeys.revoke","parameters":[{"name":"apiKeyId","in":"path","schema":{"type":"string","description":"The API key's ID, such as Ak8TqW3nVr5L.","examples":["Ak8TqW3nVr5L"]},"required":true,"description":"The API key's ID, such as Ak8TqW3nVr5L."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"type":"boolean","enum":[true],"description":"Always true: the change was made."}},"additionalProperties":false}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Revokes one of your API keys, so requests with it fail with Unauthorized from then on. Fails with NotFound when the key is not yours or is already revoked.","summary":"Revoke an API key"}},"/v1/me/cli-sessions":{"get":{"tags":["CLI sign-ins"],"operationId":"cliSessions.list","parameters":[],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["sessions"],"properties":{"sessions":{"type":"array","items":{"$ref":"#/components/schemas/CliSession"},"description":"Your CLI sign-ins that have not ended."}},"additionalProperties":false}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns the computers where the `clanker` CLI is signed in as you. Account API keys have none.","summary":"List CLI sign-ins"}},"/v1/me/cli-sessions/{session}/revoke":{"post":{"tags":["CLI sign-ins"],"operationId":"cliSessions.revoke","parameters":[{"name":"session","in":"path","schema":{"type":"string","description":"The sign-in's ID, such as Cs8vN1qLm3Zx.","examples":["Cs8vN1qLm3Zx"]},"required":true,"description":"The sign-in's ID, such as Cs8vN1qLm3Zx."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"type":"boolean","enum":[true],"description":"Always true: the change was made."}},"additionalProperties":false}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Ends one of your CLI sign-ins, so the CLI on that computer must sign in again. Fails with NotFound when the sign-in is not yours or has already ended.","summary":"Revoke a CLI sign-in"}},"/v1/workspaces":{"get":{"tags":["Workspaces"],"operationId":"workspaces.list","parameters":[],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"The workspaces you belong to.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Workspace"},"description":"The workspaces you belong to."}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns the workspaces you are an active member of, with your role in each. An account API key sees only its own workspace.","summary":"List workspaces"},"post":{"tags":["Workspaces"],"operationId":"workspaces.create","parameters":[],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","workspace"],"properties":{"ok":{"type":"boolean","enum":[true],"description":"Always true: the workspace was created."},"workspace":{"type":"object","required":["id","name","slug","creatorUserId"],"properties":{"id":{"type":"string","description":"Unique ID of the workspace."},"name":{"type":"string","description":"The workspace's display name."},"slug":{"type":"string","description":"The workspace's URL name: 2 to 48 lowercase letters, digits and hyphens, such as acme."},"creatorUserId":{"type":"string","description":"Your user ID. You are the workspace's first owner."}},"additionalProperties":false,"description":"The new workspace."}},"additionalProperties":false,"examples":[{"ok":true,"workspace":{"id":"Wk7Qm2RtXa9L","name":"Acme","slug":"acme","creatorUserId":"Us3NfP8kLq2V"}}]}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Creates a workspace with you as its owner, plus the default ticket statuses and tags. Fails with Conflict when another workspace uses the slug. Account API keys cannot create workspaces.","summary":"Create a workspace","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["name","slug"],"properties":{"name":{"type":"string","description":"The workspace's display name. Surrounding spaces are removed."},"slug":{"type":"string","description":"The workspace's URL name: 2 to 48 lowercase letters, digits and hyphens, such as acme. It is trimmed and lowercased, and must be unused."}},"additionalProperties":false,"examples":[{"name":"Acme","slug":"acme"}]}}},"required":true}}},"/v1/slugs/{slug}":{"get":{"tags":["Workspaces"],"operationId":"workspaces.checkSlug","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The slug to check, such as acme.","examples":["acme"]},"required":true,"description":"The slug to check, such as acme."},{"name":"excludeWorkspaceId","in":"query","schema":{"type":"string","description":"A workspace ID, such as Wk7Qm2RtXa9L, whose own slug counts as free.","examples":["Wk7Qm2RtXa9L"]},"required":false,"description":"A workspace ID, such as Wk7Qm2RtXa9L, whose own slug counts as free."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["available"],"properties":{"available":{"type":"boolean","description":"Whether the slug is free to use."}},"additionalProperties":false,"examples":[{"available":true}]}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Tells whether any workspace uses the slug, ignoring case. It does not check that the slug is well formed.","summary":"Check a workspace slug"}},"/v1/workspaces/{slug}":{"get":{"tags":["Workspaces"],"operationId":"workspaces.get","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A workspace with its settings, and who is calling: your user ID or account API key and your role.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceAccess"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns the workspace with its allowed domains and your role in it. Fails with NotFound unless you are an active member, or the account API key belongs to the workspace.","summary":"Get a workspace"},"patch":{"tags":["Workspaces"],"operationId":"workspaces.update","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"type":"boolean","enum":[true],"description":"Always true: the change was made."}},"additionalProperties":false}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Sets the workspace's name, slug and allowed domains, and records a `workspace.updated` event. Send `name` and `slug` every time. Only owners and admins can update a workspace.","summary":"Update a workspace","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["name","slug"],"properties":{"name":{"type":"string","description":"The workspace's display name. Surrounding spaces are removed."},"slug":{"type":"string","description":"The workspace's URL name: 2 to 48 lowercase letters, digits and hyphens. It is trimmed and lowercased, and no other workspace may use it."},"allowedDomains":{"type":"string","description":"Email domains separated by commas, spaces or semicolons, such as acme.dev, acme.com. Leaving it out or sending an empty string clears the list."}},"additionalProperties":false,"examples":[{"name":"Acme","slug":"acme","allowedDomains":"acme.dev"}]}}},"required":true}}},"/v1/workspaces/{slug}/slug-availability":{"get":{"tags":["Workspaces"],"operationId":"workspaces.checkNewSlug","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"newSlug","in":"query","schema":{"type":"string","description":"The slug to check, such as acme-labs.","examples":["acme-labs"]},"required":true,"description":"The slug to check, such as acme-labs."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["available"],"properties":{"available":{"type":"boolean","description":"Whether the slug is free to use."}},"additionalProperties":false,"examples":[{"available":true}]}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Tells whether the workspace could change to the slug in `newSlug`, ignoring case. The workspace's own slug counts as free. Any member can check.","summary":"Check a new slug for a workspace"}},"/v1/workspaces/{slug}/icon":{"post":{"tags":["Workspaces"],"operationId":"workspaces.uploadIcon","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","iconUrl"],"properties":{"ok":{"type":"boolean","enum":[true],"description":"Always true: the icon was replaced."},"iconUrl":{"type":"string","description":"URL of the new icon image."}},"additionalProperties":false,"examples":[{"ok":true,"iconUrl":"https://images.clankership.com/workspaces/Wk7Qm2RtXa9L/icon-Ic5TfR2mWq8Z.png"}]}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Replaces the workspace's icon with a PNG, JPEG or WebP image under 256 KB, and records a `workspace.icon_updated` event. Only owners and admins can change the icon.","summary":"Upload a workspace icon","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["icon"],"properties":{"icon":{"type":"string","format":"binary","description":"A PNG, JPEG or WebP image under 256 KB for the workspace icon."}}}}}}}},"/v1/workspaces/{slug}/seeds":{"get":{"tags":["Workspaces"],"operationId":"workspaces.listSeeds","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"The seeded workspace, or nothing when this database does not have it.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SeedWorkspace"},"description":"The seeded workspace, or nothing when this database does not have it."}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns the seeded local development workspace when this database has it, and whether you have joined it. You must belong to the workspace in the path; it does not filter the results.","summary":"List seeded workspaces"}},"/v1/seeds/{workspaceId}/join":{"post":{"tags":["Workspaces"],"operationId":"workspaces.joinSeed","parameters":[{"name":"workspaceId","in":"path","schema":{"type":"string","description":"The seeded workspace's ID, such as localClanker.","examples":["localClanker"]},"required":true,"description":"The seeded workspace's ID, such as localClanker."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","slug"],"properties":{"ok":{"type":"boolean","enum":[true],"description":"Always true: you joined."},"slug":{"type":"string","description":"The seeded workspace's slug, such as clanker-ship."}},"additionalProperties":false,"examples":[{"ok":true,"slug":"clanker-ship"}]}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Makes you an owner of a seeded local development workspace. Fails with InvalidInput when the ID is not a seeded workspace or the workspace is missing from this database.","summary":"Join a seeded workspace"}},"/v1/workspaces/{slug}/members":{"get":{"tags":["Members"],"operationId":"members.list","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"The workspace's active members, sorted by name.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Member"},"description":"The workspace's active members, sorted by name."}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns the workspace's active members with their roles and teams, sorted by name. Any member can list members.","summary":"List members"}},"/v1/workspaces/{slug}/members/{userId}":{"patch":{"tags":["Members"],"operationId":"members.update","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"userId","in":"path","schema":{"type":"string","description":"The member's user ID, such as Us9DcT4wHn6R.","examples":["Us9DcT4wHn6R"]},"required":true,"description":"The member's user ID, such as Us9DcT4wHn6R."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"type":"boolean","enum":[true],"description":"Always true: the change was made."}},"additionalProperties":false}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Sets a member's role and records a `member.role_changed` event. Only owners and admins can change roles, and admins cannot change an owner's role or make anyone an owner. The last owner cannot be demoted.","summary":"Change a member's role","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["role"],"properties":{"role":{"type":"string","enum":["owner","admin","member","viewer"],"description":"The member's new role: owner, admin, member or viewer."}},"additionalProperties":false,"examples":[{"role":"admin"}]}}},"required":true}},"delete":{"tags":["Members"],"operationId":"members.remove","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"userId","in":"path","schema":{"type":"string","description":"The member's user ID, such as Us9DcT4wHn6R.","examples":["Us9DcT4wHn6R"]},"required":true,"description":"The member's user ID, such as Us9DcT4wHn6R."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"type":"boolean","enum":[true],"description":"Always true: the change was made."}},"additionalProperties":false}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Removes the person from the workspace and its teams, and records a `member.removed` event. Only owners and admins can remove members, and admins cannot remove owners. Nobody can remove themselves or the last owner.","summary":"Remove a member"}},"/v1/workspaces/{slug}/people":{"get":{"tags":["Members"],"operationId":"members.listWithRole","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["userId","role","members"],"properties":{"userId":{"type":"string","description":"Your user ID, or the account API key's ID."},"role":{"type":"string","enum":["owner","admin","member","viewer"],"description":"Your role in the workspace: owner, admin, member or viewer."},"members":{"type":"array","items":{"$ref":"#/components/schemas/Member"},"description":"The workspace's active members, sorted by name."}},"additionalProperties":false,"examples":[{"userId":"Us3NfP8kLq2V","role":"owner","members":[{"userId":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":"https://images.clankership.com/users/Us3NfP8kLq2V/profile-Ph8KcV2nRx4M.webp","role":"owner","joinedAt":"2026-10-01T16:20:00.000Z","teams":["Web"]}]}]}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns the workspace's active members, plus your ID and role, so a client can tell which members you may manage. Any member can call it.","summary":"List members with your role"}},"/v1/invites/{token}":{"get":{"tags":["Invites"],"operationId":"invites.get","parameters":[{"name":"token","in":"path","schema":{"type":"string","description":"The secret token from the invite link, the last part of /invite/{token}.","examples":["q8Fz3Kp1Lw9XcR2tV7bN4mJ6hY0sD5aE1uG3iO8kQwZ"]},"required":true,"description":"The secret token from the invite link, the last part of /invite/{token}."}],"security":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["invite"],"properties":{"invite":{"anyOf":[{"$ref":"#/components/schemas/InvitePreview"},{"type":"null"}],"description":"The invite the token belongs to, or null when there is none."}},"additionalProperties":false}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns the invite a link points to, including expired, revoked and accepted ones, so a person can see which workspace invited them. It needs no API key. Returns `invite: null` when no invite has the token.","summary":"Get an invite by token"}},"/v1/workspaces/{slug}/invites":{"get":{"tags":["Invites"],"operationId":"invites.list","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"The workspace's open invites.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Invite"},"description":"The workspace's open invites."}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns the workspace's open invites: those not accepted or revoked, including expired ones. Any member can list invites.","summary":"List invites"},"post":{"tags":["Invites"],"operationId":"invites.create","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["results"],"properties":{"results":{"type":"array","items":{"type":"object","required":["email","ok"],"properties":{"email":{"type":"string","description":"The address as it was sent in the request."},"ok":{"type":"boolean","enum":[true],"description":"Always true: the invite was sent."}},"additionalProperties":false,"description":"One invited address."},"description":"One entry per invited address, in request order."}},"additionalProperties":false,"examples":[{"results":[{"email":"lee@acme.dev","ok":true}]}]}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Invites each address with the same role and teams, queues an email with a link that expires in 7 days, and revokes any older open invite to that address. Only owners and admins can invite. Addresses are invited in order and the first failure stops the request, keeping the invites already made.","summary":"Create invites","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["emails","role","teamIds"],"properties":{"emails":{"type":"array","items":{"type":"string"},"description":"The email addresses to invite. An address repeated exactly is invited once."},"role":{"type":"string","enum":["owner","admin","member","viewer"],"description":"The role each person gets: admin, member or viewer. Owner is refused."},"teamIds":{"type":"array","items":{"type":"string"},"description":"IDs of teams each person joins on accepting. Send [] for none."}},"additionalProperties":false,"examples":[{"emails":["lee@acme.dev"],"role":"member","teamIds":["Tm6PzN3kWq1J"]}]}}},"required":true}}},"/v1/workspaces/{slug}/invites/{inviteId}/revoke":{"post":{"tags":["Invites"],"operationId":"invites.revoke","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"inviteId","in":"path","schema":{"type":"string","description":"The invite's ID, such as Iv6WqR3nTb8K.","examples":["Iv6WqR3nTb8K"]},"required":true,"description":"The invite's ID, such as Iv6WqR3nTb8K."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"type":"boolean","enum":[true],"description":"Always true: the change was made."}},"additionalProperties":false}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Cancels the invite so its link stops working, and records an `invite.revoked` event. Only owners and admins can revoke invites.","summary":"Revoke an invite"}},"/v1/workspaces/{slug}/invites/{inviteId}":{"patch":{"tags":["Invites"],"operationId":"invites.update","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"inviteId","in":"path","schema":{"type":"string","description":"The invite's ID, such as Iv6WqR3nTb8K.","examples":["Iv6WqR3nTb8K"]},"required":true,"description":"The invite's ID, such as Iv6WqR3nTb8K."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"type":"boolean","enum":[true],"description":"Always true: the change was made."}},"additionalProperties":false}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Sets the role an open invite grants and records an `invite.role_changed` event. Only owners and admins can change it.","summary":"Change an invite's role","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["role"],"properties":{"role":{"type":"string","enum":["owner","admin","member","viewer"],"description":"The role the person gets: admin, member or viewer. Owner is refused."}},"additionalProperties":false,"examples":[{"role":"viewer"}]}}},"required":true}}},"/v1/workspaces/{slug}/invites/{inviteId}/resend":{"post":{"tags":["Invites"],"operationId":"invites.resend","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"inviteId","in":"path","schema":{"type":"string","description":"The invite's ID, such as Iv6WqR3nTb8K.","examples":["Iv6WqR3nTb8K"]},"required":true,"description":"The invite's ID, such as Iv6WqR3nTb8K."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"type":"boolean","enum":[true],"description":"Always true: the change was made."}},"additionalProperties":false}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Queues a new email with a fresh link that expires in 7 days; the old link stops working. Records an `invite.resent` event. Only owners and admins can resend open invites.","summary":"Resend an invite"}},"/v1/invites/{token}/accept":{"post":{"tags":["Invites"],"operationId":"invites.accept","parameters":[{"name":"token","in":"path","schema":{"type":"string","description":"The secret token from the invite link, the last part of /invite/{token}.","examples":["q8Fz3Kp1Lw9XcR2tV7bN4mJ6hY0sD5aE1uG3iO8kQwZ"]},"required":true,"description":"The secret token from the invite link, the last part of /invite/{token}."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","workspaceSlug"],"properties":{"ok":{"type":"boolean","enum":[true],"description":"Always true: you joined the workspace."},"workspaceSlug":{"type":"string","description":"The slug of the workspace you joined, such as acme."}},"additionalProperties":false,"examples":[{"ok":true,"workspaceSlug":"acme"}]}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Adds you to the workspace with the invite's role and teams, and marks the invite accepted. Your email address must match the invite's. Fails with NotFound when the invite is expired, revoked or already accepted.","summary":"Accept an invite"}},"/v1/workspaces/{slug}/events":{"get":{"tags":["Events"],"operationId":"events.list","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"ticket","in":"query","schema":{"type":"string","description":"Only this ticket's activity, by its ID, such as WEB-31.","examples":["WEB-31"]},"required":false,"description":"Only this ticket's activity, by its ID, such as WEB-31."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"The latest events, newest first.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Event"},"description":"The latest events, newest first."}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns the 50 most recent events the caller can read, newest first, or one ticket's activity with `ticket`. Members and viewers get the workspace's own events and those about the teams, projects and tickets they can open; a personal view's events go only to its person. Owners, admins and account API keys get every event. A ticket the caller cannot read fails with NotFound.","summary":"List events"}},"/v1/workspaces/{slug}/account-api-keys":{"get":{"tags":["Account API keys"],"operationId":"accountApiKeys.list","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"The workspace's active account API keys.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AccountApiKey"},"description":"The workspace's active account API keys."}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns the workspace's account API keys without their values. Revoked keys are left out. Only admins and owners can list them.","summary":"List account API keys"},"post":{"tags":["Account API keys"],"operationId":"accountApiKeys.create","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A new account API key with its value, which is never shown again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatedAccountApiKey"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Creates a key that acts in this workspace with the given role. The response holds the key's value, which is never shown again. Only admins and owners can create account API keys, and only owners can grant the owner role.","summary":"Create an account API key","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["name","role"],"properties":{"name":{"type":"string","description":"A name for the key, 1 to 100 characters, such as Release CI."},"role":{"type":"string","enum":["owner","admin","member","viewer"],"description":"The role the key acts with. Only owners can choose owner."}},"additionalProperties":false,"examples":[{"name":"Release CI","role":"member"}]}}},"required":true}}},"/v1/workspaces/{slug}/account-api-keys/{id}":{"patch":{"tags":["Account API keys"],"operationId":"accountApiKeys.update","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"id","in":"path","schema":{"type":"string","description":"The account API key's ID, such as Ak2WqH9sDf5T.","examples":["Ak2WqH9sDf5T"]},"required":true,"description":"The account API key's ID, such as Ak2WqH9sDf5T."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"type":"boolean","enum":[true],"description":"Always true: the change was made."}},"additionalProperties":false}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Changes the key's name and role; its value stays the same. Only admins and owners can update account API keys, and only owners can change an owner key or grant the owner role.","summary":"Update an account API key","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["name","role"],"properties":{"name":{"type":"string","description":"A name for the key, 1 to 100 characters, such as Release CI."},"role":{"type":"string","enum":["owner","admin","member","viewer"],"description":"The role the key acts with. Only owners can choose owner."}},"additionalProperties":false,"examples":[{"name":"Release CI","role":"member"}]}}},"required":true}}},"/v1/workspaces/{slug}/account-api-keys/{id}/revoke":{"post":{"tags":["Account API keys"],"operationId":"accountApiKeys.revoke","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"id","in":"path","schema":{"type":"string","description":"The account API key's ID, such as Ak2WqH9sDf5T.","examples":["Ak2WqH9sDf5T"]},"required":true,"description":"The account API key's ID, such as Ak2WqH9sDf5T."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"type":"boolean","enum":[true],"description":"Always true: the change was made."}},"additionalProperties":false}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Revokes the key, so its next request fails with Unauthorized. Only admins and owners can revoke account API keys, and only owners can revoke an owner key.","summary":"Revoke an account API key"}},"/v1/workspaces/{slug}/pins":{"get":{"tags":["Pins"],"operationId":"pins.list","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"The caller's pins in their order.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PinList"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns the caller's pins in the workspace, in their order. Pins belong to a person, so a workspace API key gets Forbidden; use a personal API key.","summary":"List your pins"},"post":{"tags":["Pins"],"operationId":"pins.create","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"The caller's pins in their order.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PinList"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Pins a ticket, project, product, environment or team the caller can open, after their other pins, and returns their pins. Pinning something already pinned changes nothing. An archived entity gets Conflict. The caller's open website tabs show the pin at once. Pins belong to a person, so a workspace API key gets Forbidden; use a personal API key.","summary":"Pin something","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["kind","key"],"properties":{"kind":{"type":"string","enum":["ticket","project","product","environment","team"],"description":"What the pin points at: ticket, project, product, environment or team."},"key":{"type":"string","description":"The key its pages use: a ticket's ID such as WEB-31 (a former ID also works), a team's key such as WEB, or a project's, product's or environment's slug such as docs-launch."}},"additionalProperties":false,"examples":[{"kind":"ticket","key":"WEB-31"}]}}},"required":true}}},"/v1/workspaces/{slug}/pins/{kind}/{key}":{"delete":{"tags":["Pins"],"operationId":"pins.delete","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"kind","in":"path","schema":{"type":"string","description":"What the pin points at: ticket, project, product, environment or team.","examples":["ticket"]},"required":true,"description":"What the pin points at: ticket, project, product, environment or team."},{"name":"key","in":"path","schema":{"type":"string","description":"The key of what the pin points at, such as WEB-31, WEB or docs-launch.","examples":["WEB-31"]},"required":true,"description":"The key of what the pin points at, such as WEB-31, WEB or docs-launch."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"The caller's pins in their order.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PinList"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Removes one of the caller's pins and returns the rest. Something that is not pinned gets NotFound. Pins belong to a person, so a workspace API key gets Forbidden; use a personal API key.","summary":"Unpin something"}},"/v1/workspaces/{slug}/pins/{kind}/{key}/reorder":{"post":{"tags":["Pins"],"operationId":"pins.reorder","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"kind","in":"path","schema":{"type":"string","description":"What the pin points at: ticket, project, product, environment or team.","examples":["ticket"]},"required":true,"description":"What the pin points at: ticket, project, product, environment or team."},{"name":"key","in":"path","schema":{"type":"string","description":"The key of what the pin points at, such as WEB-31, WEB or docs-launch.","examples":["WEB-31"]},"required":true,"description":"The key of what the pin points at, such as WEB-31, WEB or docs-launch."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"The caller's pins in their order.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PinList"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Moves one of the caller's pins right before or right after another and returns them in the new order. Send `before` or `after`, not both. Pins belong to a person, so a workspace API key gets Forbidden; use a personal API key.","summary":"Reorder a pin","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":[],"properties":{"before":{"allOf":[{"$ref":"#/components/schemas/PinTarget"}],"description":"The pin to go right before."},"after":{"allOf":[{"$ref":"#/components/schemas/PinTarget"}],"description":"The pin to go right after."}},"additionalProperties":false,"examples":[{"before":{"kind":"project","key":"docs-launch"}}]}}},"required":true}}},"/v1/workspaces/{slug}/products":{"get":{"tags":["Products"],"operationId":"products.list","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"archived","in":"query","schema":{"type":"string","enum":["exclude","include","only"],"description":"Which archived objects to return: exclude (the default), include or only archived ones."},"required":false,"description":"Which archived objects to return: exclude (the default), include or only archived ones."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["products"],"properties":{"products":{"type":"array","items":{"$ref":"#/components/schemas/Product"},"description":"The products, sorted by name."}},"additionalProperties":false}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns the workspace's products with their active deployments. Archived products are left out unless `archived` asks for them.","summary":"List products"},"post":{"tags":["Products"],"operationId":"products.create","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"201":{"description":"Software the workspace builds and tests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Product"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Adds a product to the workspace. Viewers cannot create products, and the slug must be unused.","summary":"Create a product","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["slug","name","type"],"properties":{"slug":{"type":"string","description":"Lowercase letters, digits and hyphens, unique in the workspace, such as storefront."},"name":{"type":"string","description":"The product's display name."},"type":{"type":"string","enum":["website","api","cli","mobile_app","desktop_app","agent"],"description":"What kind of software this is."},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"A short description."},"repository":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The source repository as owner/name, such as acme/storefront."}},"additionalProperties":false,"examples":[{"slug":"storefront","name":"Storefront","type":"website","repository":"acme/storefront"}]}}},"required":true}}},"/v1/workspaces/{slug}/products/{product}":{"get":{"tags":["Products"],"operationId":"products.get","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"product","in":"path","schema":{"type":"string","description":"The product's slug or ID, such as storefront.","examples":["storefront"]},"required":true,"description":"The product's slug or ID, such as storefront."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Software the workspace builds and tests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Product"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns one product, archived or not, with its active deployments.","summary":"Get a product"},"patch":{"tags":["Products"],"operationId":"products.update","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"product","in":"path","schema":{"type":"string","description":"The product's slug or ID, such as storefront.","examples":["storefront"]},"required":true,"description":"The product's slug or ID, such as storefront."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Software the workspace builds and tests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Product"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Changes only the fields sent. A new slug must be unused in the workspace.","summary":"Update a product","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":[],"properties":{"slug":{"type":"string","description":"Lowercase letters, digits and hyphens, unique in the workspace, such as storefront."},"name":{"type":"string","description":"The product's display name."},"type":{"type":"string","enum":["website","api","cli","mobile_app","desktop_app","agent"],"description":"What kind of software this is."},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"A short description. `null` clears it."},"repository":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The source repository as owner/name, such as acme/storefront. `null` clears it."}},"additionalProperties":false,"examples":[{"name":"Storefront web","repository":"acme/storefront"}]}}},"required":true}}},"/v1/workspaces/{slug}/products/{product}/archive":{"post":{"tags":["Products"],"operationId":"products.archive","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"product","in":"path","schema":{"type":"string","description":"The product's slug or ID, such as storefront.","examples":["storefront"]},"required":true,"description":"The product's slug or ID, such as storefront."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Software the workspace builds and tests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Product"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Hides the product and refuses vault pulls for its deployments until it is restored. Archiving an archived product changes nothing.","summary":"Archive a product"}},"/v1/workspaces/{slug}/products/{product}/restore":{"post":{"tags":["Products"],"operationId":"products.restore","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"product","in":"path","schema":{"type":"string","description":"The product's slug or ID, such as storefront.","examples":["storefront"]},"required":true,"description":"The product's slug or ID, such as storefront."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Software the workspace builds and tests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Product"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Brings an archived product back with its deployments and secrets. Restoring an active product changes nothing.","summary":"Restore a product"}},"/v1/workspaces/{slug}/environments":{"get":{"tags":["Environments"],"operationId":"environments.list","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"archived","in":"query","schema":{"type":"string","enum":["exclude","include","only"],"description":"Which archived objects to return: exclude (the default), include or only archived ones."},"required":false,"description":"Which archived objects to return: exclude (the default), include or only archived ones."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["environments"],"properties":{"environments":{"type":"array","items":{"$ref":"#/components/schemas/Environment"},"description":"The environments, sorted by name."}},"additionalProperties":false}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns the workspace's environments with the deployments of active products.","summary":"List environments"},"post":{"tags":["Environments"],"operationId":"environments.create","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"201":{"description":"A place products run, shared by every product in the workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Environment"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Adds an environment every product in the workspace can deploy to. Viewers cannot create environments.","summary":"Create an environment","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["slug","name","class"],"properties":{"slug":{"type":"string","description":"Lowercase letters, digits and hyphens, unique in the workspace, such as staging."},"name":{"type":"string","description":"The environment's display name."},"class":{"type":"string","enum":["production","non-production"],"description":"Production holds real customer data. It cannot change once set."},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"A short description."},"emoji":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"One emoji shown beside the name."}},"additionalProperties":false,"examples":[{"slug":"staging","name":"Staging","class":"non-production","emoji":"🧪"}]}}},"required":true}}},"/v1/workspaces/{slug}/environments/{environment}":{"get":{"tags":["Environments"],"operationId":"environments.get","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"environment","in":"path","schema":{"type":"string","description":"The environment's slug or ID, such as staging.","examples":["staging"]},"required":true,"description":"The environment's slug or ID, such as staging."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A place products run, shared by every product in the workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Environment"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns one environment, archived or not, with the deployments of active products.","summary":"Get an environment"},"patch":{"tags":["Environments"],"operationId":"environments.update","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"environment","in":"path","schema":{"type":"string","description":"The environment's slug or ID, such as staging.","examples":["staging"]},"required":true,"description":"The environment's slug or ID, such as staging."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A place products run, shared by every product in the workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Environment"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Changes only the fields sent. The class cannot change; sending it fails with InvalidInput.","summary":"Update an environment","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":[],"properties":{"slug":{"type":"string","description":"Lowercase letters, digits and hyphens, unique in the workspace, such as staging."},"name":{"type":"string","description":"The environment's display name."},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"A short description. `null` clears it."},"emoji":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"One emoji shown beside the name. `null` clears it."},"class":{"type":"string","enum":["production","non-production"],"description":"Always rejected: an environment's class cannot change."}},"additionalProperties":false,"examples":[{"name":"Staging (EU)","emoji":"🇪🇺"}]}}},"required":true}}},"/v1/workspaces/{slug}/environments/{environment}/archive":{"post":{"tags":["Environments"],"operationId":"environments.archive","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"environment","in":"path","schema":{"type":"string","description":"The environment's slug or ID, such as staging.","examples":["staging"]},"required":true,"description":"The environment's slug or ID, such as staging."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A place products run, shared by every product in the workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Environment"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Hides the environment and refuses vault pulls for its deployments until it is restored. Archiving an archived environment changes nothing.","summary":"Archive an environment"}},"/v1/workspaces/{slug}/environments/{environment}/restore":{"post":{"tags":["Environments"],"operationId":"environments.restore","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"environment","in":"path","schema":{"type":"string","description":"The environment's slug or ID, such as staging.","examples":["staging"]},"required":true,"description":"The environment's slug or ID, such as staging."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A place products run, shared by every product in the workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Environment"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Brings an archived environment back with its deployments. Restoring an active environment changes nothing.","summary":"Restore an environment"}},"/v1/workspaces/{slug}/deployments":{"get":{"tags":["Deployments"],"operationId":"deployments.list","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"product","in":"query","schema":{"type":"string","description":"Only deployments of this product, by slug or ID.","examples":["storefront"]},"required":false,"description":"Only deployments of this product, by slug or ID."},{"name":"environment","in":"query","schema":{"type":"string","description":"Only deployments to this environment, by slug or ID.","examples":["staging"]},"required":false,"description":"Only deployments to this environment, by slug or ID."},{"name":"archived","in":"query","schema":{"type":"string","enum":["exclude","include","only"],"description":"Whether to include deployments whose product or environment is archived. Defaults to exclude."},"required":false,"description":"Whether to include deployments whose product or environment is archived. Defaults to exclude."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["deployments"],"properties":{"deployments":{"type":"array","items":{"$ref":"#/components/schemas/Deployment"},"description":"The deployments, sorted by product name and then environment name."}},"additionalProperties":false}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns the workspace's deployments, optionally for one product or one environment.","summary":"List deployments"},"post":{"tags":["Deployments"],"operationId":"deployments.create","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"201":{"description":"One product running in one environment.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Deployment"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Records that a product runs in an environment. A product has at most one deployment per environment.","summary":"Create a deployment","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["product","environment"],"properties":{"product":{"type":"string","description":"The product to deploy, by slug or ID."},"environment":{"type":"string","description":"The environment to deploy it to, by slug or ID."},"baseUrl":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The http(s) URL where the product answers. Required for website and API products."},"fixtureUrl":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The http(s) URL of the deployment's Fixture API, which test runs call to create and delete test data."},"version":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The build that is running, such as a git SHA."}},"additionalProperties":false,"examples":[{"product":"storefront","environment":"staging","baseUrl":"https://staging.acme.dev","fixtureUrl":"https://staging.acme.dev/fixtures","version":"9f2c41e"}]}}},"required":true}}},"/v1/workspaces/{slug}/deployments/{product}/{environment}":{"get":{"tags":["Deployments"],"operationId":"deployments.get","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"product","in":"path","schema":{"type":"string","description":"The product's slug or ID, such as storefront.","examples":["storefront"]},"required":true,"description":"The product's slug or ID, such as storefront."},{"name":"environment","in":"path","schema":{"type":"string","description":"The environment's slug or ID, such as staging.","examples":["staging"]},"required":true,"description":"The environment's slug or ID, such as staging."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"One product running in one environment.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Deployment"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns the deployment of one product to one environment.","summary":"Get a deployment"},"patch":{"tags":["Deployments"],"operationId":"deployments.update","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"product","in":"path","schema":{"type":"string","description":"The product's slug or ID, such as storefront.","examples":["storefront"]},"required":true,"description":"The product's slug or ID, such as storefront."},{"name":"environment","in":"path","schema":{"type":"string","description":"The environment's slug or ID, such as staging.","examples":["staging"]},"required":true,"description":"The environment's slug or ID, such as staging."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"One product running in one environment.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Deployment"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Changes only the fields sent. Send `version` after each deploy to record what is running.","summary":"Update a deployment","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":[],"properties":{"baseUrl":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The http(s) URL where the product answers. `null` clears it for products that do not need one."},"fixtureUrl":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The http(s) URL of the deployment's Fixture API. `null` clears it."},"version":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The build that is running, such as a git SHA. `null` clears it."}},"additionalProperties":false,"examples":[{"version":"4b7e0d2"}]}}},"required":true}},"delete":{"tags":["Deployments"],"operationId":"deployments.delete","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"product","in":"path","schema":{"type":"string","description":"The product's slug or ID, such as storefront.","examples":["storefront"]},"required":true,"description":"The product's slug or ID, such as storefront."},{"name":"environment","in":"path","schema":{"type":"string","description":"The environment's slug or ID, such as staging.","examples":["staging"]},"required":true,"description":"The environment's slug or ID, such as staging."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"204":{"description":"Success"},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Removes the deployment. Its secret values are kept and return if the product is deployed to the environment again.","summary":"Delete a deployment"}},"/v1/workspaces/{slug}/teams":{"get":{"tags":["Teams"],"operationId":"teams.list","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"archived","in":"query","schema":{"type":"string","enum":["exclude","include","only"],"description":"Which archived teams to return: exclude (the default), include or only archived ones."},"required":false,"description":"Which archived teams to return: exclude (the default), include or only archived ones."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["teams"],"properties":{"teams":{"type":"array","items":{"$ref":"#/components/schemas/Team"},"description":"The teams, sorted by name."}},"additionalProperties":false}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns open teams and the private teams the caller is in; owners, admins and account API keys see every team. Archived teams are left out unless `archived` asks for them.","summary":"List teams"},"post":{"tags":["Teams"],"operationId":"teams.create","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"201":{"description":"A group of workspace members that owns tickets and numbers them with its key, such as WEB-31.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Team"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Owners and admins create teams. The key and name must be unused in the workspace. The team copies the workspace's ticket status template, starts with the default views, and the person who creates it joins it.","summary":"Create a team","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["name","key"],"properties":{"name":{"type":"string","description":"The team's display name, up to 80 characters, unique in the workspace."},"key":{"type":"string","description":"2 to 5 letters that start the team's ticket IDs, such as WEB. Stored in capitals."},"visibility":{"type":"string","enum":["open","private"],"description":"`open` lists the team for everyone in the workspace; `private` only for its members and for owners and admins. Defaults to open."}},"additionalProperties":false,"examples":[{"name":"Web","key":"WEB","visibility":"open"}]}}},"required":true}}},"/v1/workspaces/{slug}/teams/{team}":{"get":{"tags":["Teams"],"operationId":"teams.get","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"team","in":"path","schema":{"type":"string","description":"The team's key, such as WEB.","examples":["WEB"]},"required":true,"description":"The team's key, such as WEB."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A group of workspace members that owns tickets and numbers them with its key, such as WEB-31.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Team"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns one team, archived or not, with its members. A caller who cannot see a private team gets NotFound.","summary":"Get a team"},"patch":{"tags":["Teams"],"operationId":"teams.update","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"team","in":"path","schema":{"type":"string","description":"The team's key, such as WEB.","examples":["WEB"]},"required":true,"description":"The team's key, such as WEB."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A group of workspace members that owns tickets and numbers them with its key, such as WEB-31.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Team"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Owners and admins change teams. Only the fields sent change. A new key or name must be unused, and the key changes only while the team has no tickets.","summary":"Update a team","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":[],"properties":{"name":{"type":"string","description":"The team's display name, up to 80 characters, unique in the workspace."},"key":{"type":"string","description":"2 to 5 letters that start the team's ticket IDs, such as WEB. Changes only while the team has no tickets."},"visibility":{"type":"string","enum":["open","private"],"description":"`open` lists the team for everyone in the workspace; `private` only for its members and for owners and admins."}},"additionalProperties":false,"examples":[{"name":"Web platform","visibility":"private"}]}}},"required":true}},"delete":{"tags":["Teams"],"operationId":"teams.delete","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"team","in":"path","schema":{"type":"string","description":"The team's key, such as WEB.","examples":["WEB"]},"required":true,"description":"The team's key, such as WEB."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"204":{"description":"Success"},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Owners and admins delete a team that has no tickets. A team with tickets fails with Conflict; archive it instead.","summary":"Delete a team"}},"/v1/workspaces/{slug}/teams/{team}/archive":{"post":{"tags":["Teams"],"operationId":"teams.archive","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"team","in":"path","schema":{"type":"string","description":"The team's key, such as WEB.","examples":["WEB"]},"required":true,"description":"The team's key, such as WEB."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A group of workspace members that owns tickets and numbers them with its key, such as WEB-31.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Team"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Owners and admins archive teams. The team leaves lists, and its tickets stay readable but take no changes until it is restored. Archiving an archived team changes nothing.","summary":"Archive a team"}},"/v1/workspaces/{slug}/teams/{team}/restore":{"post":{"tags":["Teams"],"operationId":"teams.restore","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"team","in":"path","schema":{"type":"string","description":"The team's key, such as WEB.","examples":["WEB"]},"required":true,"description":"The team's key, such as WEB."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A group of workspace members that owns tickets and numbers them with its key, such as WEB-31.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Team"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Owners and admins bring an archived team back, so its tickets take changes again. Restoring an active team changes nothing.","summary":"Restore a team"}},"/v1/workspaces/{slug}/teams/{team}/join":{"post":{"tags":["Teams"],"operationId":"teams.join","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"team","in":"path","schema":{"type":"string","description":"The team's key, such as WEB.","examples":["WEB"]},"required":true,"description":"The team's key, such as WEB."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A group of workspace members that owns tickets and numbers them with its key, such as WEB-31.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Team"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Adds the caller to an open team. Owners and admins can also join private teams, and an account API key cannot join any. Joining a team twice changes nothing.","summary":"Join a team"}},"/v1/workspaces/{slug}/teams/{team}/members":{"post":{"tags":["Teams"],"operationId":"teams.addMember","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"team","in":"path","schema":{"type":"string","description":"The team's key, such as WEB.","examples":["WEB"]},"required":true,"description":"The team's key, such as WEB."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A group of workspace members that owns tickets and numbers them with its key, such as WEB-31.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Team"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Adds a workspace member to the team, which is how private teams grow. The team's members and workspace owners and admins add people; viewers cannot. Adding a member twice changes nothing.","summary":"Add a team member","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["person"],"properties":{"person":{"type":"string","description":"The workspace member to add, by user ID or email address."}},"additionalProperties":false,"examples":[{"person":"sam@acme.dev"}]}}},"required":true}}},"/v1/workspaces/{slug}/teams/{team}/members/{person}":{"delete":{"tags":["Teams"],"operationId":"teams.removeMember","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"team","in":"path","schema":{"type":"string","description":"The team's key, such as WEB.","examples":["WEB"]},"required":true,"description":"The team's key, such as WEB."},{"name":"person","in":"path","schema":{"type":"string","description":"The member's user ID or email address, such as sam@acme.dev.","examples":["sam@acme.dev"]},"required":true,"description":"The member's user ID or email address, such as sam@acme.dev."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A group of workspace members that owns tickets and numbers them with its key, such as WEB-31.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Team"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Removes a person from the team. Anyone can leave a team; removing someone else takes a member of the team or a workspace owner or admin, and viewers cannot.","summary":"Remove a team member"}},"/v1/workspaces/{slug}/projects":{"get":{"tags":["Projects"],"operationId":"projects.list","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"team","in":"query","schema":{"type":"string","description":"Only projects linked to this team, by key, such as WEB.","examples":["WEB"]},"required":false,"description":"Only projects linked to this team, by key, such as WEB."},{"name":"product","in":"query","schema":{"type":"string","description":"Only projects linked to this product, by slug, such as storefront.","examples":["storefront"]},"required":false,"description":"Only projects linked to this product, by slug, such as storefront."},{"name":"archived","in":"query","schema":{"type":"string","enum":["exclude","include","only"],"description":"Which archived projects to return: exclude (the default), include or only archived ones."},"required":false,"description":"Which archived projects to return: exclude (the default), include or only archived ones."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["projects"],"properties":{"projects":{"type":"array","items":{"$ref":"#/components/schemas/ProjectListItem"},"description":"The projects in priority order."}},"additionalProperties":false}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns the projects the caller can open, in priority order and without their documents. A project opens for anyone who sees one of its teams. Archived projects are left out unless `archived` asks for them.","summary":"List projects"},"post":{"tags":["Projects"],"operationId":"projects.create","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"201":{"description":"A body of work with a goal. It links the teams whose tickets it holds and the products it changes, and has numbered milestones.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Project"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Adds a project at the end of the priority order, with the default views. Viewers cannot create projects, and the slug and name must be unused, archived projects included.","summary":"Create a project","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["name","slug","teams"],"properties":{"name":{"type":"string","description":"The project's display name, up to 100 characters, unique in the workspace."},"slug":{"type":"string","description":"Lowercase letters, digits and hyphens, unique in the workspace, such as docs-launch."},"summary":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"One line on what the project delivers, up to 200 characters."},"status":{"type":"string","enum":["planned","active","paused","completed","canceled"],"description":"Where the project stands. Defaults to planned."},"lead":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The member who leads the project, by user ID or email address."},"targetDate":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The date the project should be done, as YYYY-MM-DD."},"teams":{"type":"array","items":{"type":"string"},"description":"The teams whose tickets the project holds, by key. At least one, and each one the caller sees."},"products":{"type":"array","items":{"type":"string"},"description":"The products the project changes, by slug."},"document":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The project's document in Markdown."}},"additionalProperties":false,"examples":[{"name":"Docs launch","slug":"docs-launch","summary":"Ship the public docs site with search and the API reference.","status":"active","lead":"maya@acme.dev","targetDate":"2026-11-20","teams":["WEB"],"products":["storefront"]}]}}},"required":true}}},"/v1/workspaces/{slug}/projects/{project}":{"get":{"tags":["Projects"],"operationId":"projects.get","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"project","in":"path","schema":{"type":"string","description":"The project's slug, such as docs-launch.","examples":["docs-launch"]},"required":true,"description":"The project's slug, such as docs-launch."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A body of work with a goal. It links the teams whose tickets it holds and the products it changes, and has numbered milestones.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Project"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns one project, archived or not, with its document and milestones.","summary":"Get a project"},"patch":{"tags":["Projects"],"operationId":"projects.update","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"project","in":"path","schema":{"type":"string","description":"The project's slug, such as docs-launch.","examples":["docs-launch"]},"required":true,"description":"The project's slug, such as docs-launch."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A body of work with a goal. It links the teams whose tickets it holds and the products it changes, and has numbered milestones.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Project"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Changes only the fields sent. Viewers cannot change projects, and an archived project takes no changes until it is restored. A new slug or name must be unused.","summary":"Update a project","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":[],"properties":{"name":{"type":"string","description":"The project's display name, up to 100 characters, unique in the workspace."},"slug":{"type":"string","description":"Lowercase letters, digits and hyphens, unique in the workspace, such as docs-launch."},"summary":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"One line on what the project delivers, up to 200 characters. `null` clears it."},"status":{"type":"string","enum":["planned","active","paused","completed","canceled"],"description":"Where the project stands."},"lead":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The member who leads the project, by user ID or email address. `null` clears it."},"targetDate":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The date the project should be done, as YYYY-MM-DD. `null` clears it."},"teams":{"type":"array","items":{"type":"string"},"description":"Replaces the linked teams, by key. At least one; a team stays linked while the project holds its tickets."},"products":{"type":"array","items":{"type":"string"},"description":"Replaces the linked products, by slug. An empty list unlinks them all."},"document":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The project's document in Markdown. `null` clears it."}},"additionalProperties":false,"examples":[{"status":"active","targetDate":"2026-11-27"}]}}},"required":true}}},"/v1/workspaces/{slug}/projects/{project}/reorder":{"post":{"tags":["Projects"],"operationId":"projects.reorder","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"project","in":"path","schema":{"type":"string","description":"The project's slug, such as docs-launch.","examples":["docs-launch"]},"required":true,"description":"The project's slug, such as docs-launch."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A body of work with a goal. It links the teams whose tickets it holds and the products it changes, and has numbered milestones.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Project"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Moves the project in the workspace's priority order, right before or right after another project. Send `before` or `after`, not both. Viewers cannot reorder projects.","summary":"Reorder a project","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":[],"properties":{"before":{"type":"string","description":"The slug of the project to go right before."},"after":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The slug of the project to go right after, or null to go first."}},"additionalProperties":false,"examples":[{"before":"checkout-v2"}]}}},"required":true}}},"/v1/workspaces/{slug}/projects/{project}/archive":{"post":{"tags":["Projects"],"operationId":"projects.archive","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"project","in":"path","schema":{"type":"string","description":"The project's slug, such as docs-launch.","examples":["docs-launch"]},"required":true,"description":"The project's slug, such as docs-launch."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A body of work with a goal. It links the teams whose tickets it holds and the products it changes, and has numbered milestones.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Project"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Archived projects leave lists and take no changes; their tickets stay on their teams. Viewers cannot archive projects, and archiving an archived project changes nothing.","summary":"Archive a project"}},"/v1/workspaces/{slug}/projects/{project}/restore":{"post":{"tags":["Projects"],"operationId":"projects.restore","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"project","in":"path","schema":{"type":"string","description":"The project's slug, such as docs-launch.","examples":["docs-launch"]},"required":true,"description":"The project's slug, such as docs-launch."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A body of work with a goal. It links the teams whose tickets it holds and the products it changes, and has numbered milestones.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Project"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Brings an archived project back, so it takes changes again. Viewers cannot restore projects, and restoring an active project changes nothing.","summary":"Restore a project"}},"/v1/workspaces/{slug}/projects/{project}/milestones":{"post":{"tags":["Milestones"],"operationId":"milestones.create","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"project","in":"path","schema":{"type":"string","description":"The project's slug, such as docs-launch.","examples":["docs-launch"]},"required":true,"description":"The project's slug, such as docs-launch."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"201":{"description":"A checkpoint within a project, labeled M1, M2 and so on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Milestone"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Adds a milestone numbered one past the project's highest, such as M3 after M2. Viewers cannot add milestones, and an archived project takes none.","summary":"Create a milestone","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","description":"The milestone's name, up to 100 characters."},"summary":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"A short summary, up to 280 characters."}},"additionalProperties":false,"examples":[{"name":"Search","summary":"Readers find any page from the docs header."}]}}},"required":true}}},"/v1/workspaces/{slug}/projects/{project}/milestones/{milestone}":{"patch":{"tags":["Milestones"],"operationId":"milestones.update","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"project","in":"path","schema":{"type":"string","description":"The project's slug, such as docs-launch.","examples":["docs-launch"]},"required":true,"description":"The project's slug, such as docs-launch."},{"name":"milestone","in":"path","schema":{"type":"string","description":"The milestone's label or number within the project, such as M2 or 2.","examples":["M2"]},"required":true,"description":"The milestone's label or number within the project, such as M2 or 2."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A checkpoint within a project, labeled M1, M2 and so on.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Milestone"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Changes only the fields sent. Viewers cannot change milestones, and an archived project's milestones take no changes.","summary":"Update a milestone","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":[],"properties":{"name":{"type":"string","description":"The milestone's name, up to 100 characters."},"summary":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"A short summary, up to 280 characters. `null` clears it."}},"additionalProperties":false,"examples":[{"name":"Search and filters"}]}}},"required":true}},"delete":{"tags":["Milestones"],"operationId":"milestones.delete","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"project","in":"path","schema":{"type":"string","description":"The project's slug, such as docs-launch.","examples":["docs-launch"]},"required":true,"description":"The project's slug, such as docs-launch."},{"name":"milestone","in":"path","schema":{"type":"string","description":"The milestone's label or number within the project, such as M2 or 2.","examples":["M2"]},"required":true,"description":"The milestone's label or number within the project, such as M2 or 2."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"204":{"description":"Success"},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Deletes the milestone and takes it off its tickets, which stay in the project. Viewers cannot delete milestones, and an archived project keeps its milestones.","summary":"Delete a milestone"}},"/v1/workspaces/{slug}/tickets":{"get":{"tags":["Tickets"],"operationId":"tickets.list","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"team","in":"query","schema":{"type":"string","description":"Only this team's tickets, by key, such as WEB.","examples":["WEB"]},"required":false,"description":"Only this team's tickets, by key, such as WEB."},{"name":"project","in":"query","schema":{"type":"string","description":"Only this project's tickets, by slug, such as docs-launch.","examples":["docs-launch"]},"required":false,"description":"Only this project's tickets, by slug, such as docs-launch."},{"name":"owner","in":"query","schema":{"type":"string","description":"Only tickets this person owns, by user ID, or me for tickets the caller owns.","examples":["me"]},"required":false,"description":"Only tickets this person owns, by user ID, or me for tickets the caller owns."},{"name":"clanker","in":"query","schema":{"type":"string","description":"Only tickets this clanker works on, by clanker ID, or mine for tickets any of the caller's clankers work on.","examples":["Ag5HvB1mZr8K"]},"required":false,"description":"Only tickets this clanker works on, by clanker ID, or mine for tickets any of the caller's clankers work on."},{"name":"category","in":"query","schema":{"type":"string","description":"Only tickets whose status is in these categories, comma-separated, such as plan,build,review. The categories are backlog, plan, build, review, ship, done, canceled.","examples":["plan,build,review"]},"required":false,"description":"Only tickets whose status is in these categories, comma-separated, such as plan,build,review. The categories are backlog, plan, build, review, ship, done, canceled."},{"name":"query","in":"query","schema":{"type":"string","description":"Only tickets whose title or Scope holds these words, or whose ID starts with them.","examples":["docs search"]},"required":false,"description":"Only tickets whose title or Scope holds these words, or whose ID starts with them."},{"name":"needsHuman","in":"query","schema":{"type":"string","enum":["true"],"description":"`true` for only the tickets that wait on a person."},"required":false,"description":"`true` for only the tickets that wait on a person."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["tickets"],"properties":{"tickets":{"type":"array","items":{"$ref":"#/components/schemas/TicketListItem"},"description":"The tickets, sorted by status category, then status position, then rank, so open tickets come first."}},"additionalProperties":false}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns the tickets the caller can read, without their documents and checklists: tickets of the teams the caller sees, and tickets in the projects the caller can open.","summary":"List tickets"},"post":{"tags":["Tickets"],"operationId":"tickets.create","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"201":{"description":"One unit of work on a team, with its checklists and documents.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ticket"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Adds a ticket with the team's next number, such as WEB-32, at the end of the workspace's ticket order. Write its documents, such as its Scope, with Write a document. Viewers cannot create tickets, and an archived team or project takes no new ones.","summary":"Create a ticket","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["team","title"],"properties":{"team":{"type":"string","description":"The team's key, such as WEB."},"title":{"type":"string","description":"A short name for the work, up to 200 characters."},"status":{"type":"string","description":"A status of the team, by name, such as Plan. Defaults to the team's default status."},"owner":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The person accountable for the ticket: a member's user ID or email, or me for the caller's person."},"clankers":{"type":"array","items":{"type":"string"},"description":"The clankers working on the ticket, by clanker ID from List clankers; a clanker can add itself with me."},"project":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"A project linked to the team, by slug, such as docs-launch."},"milestone":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"A milestone of that project, such as M2."},"tags":{"type":"array","items":{"type":"string"},"description":"Tag names: workspace tags and the team's own."}},"additionalProperties":false,"examples":[{"team":"WEB","title":"Add docs search","status":"Plan","owner":"maya@acme.dev","clankers":["Ag5HvB1mZr8K"],"project":"docs-launch","milestone":"M2","tags":["feature"]}]}}},"required":true}}},"/v1/workspaces/{slug}/tickets/{ticket}":{"get":{"tags":["Tickets"],"operationId":"tickets.get","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"ticket","in":"path","schema":{"type":"string","description":"The ticket's ID, such as WEB-31. An ID the ticket had before it moved teams also finds it.","examples":["WEB-31"]},"required":true,"description":"The ticket's ID, such as WEB-31. An ID the ticket had before it moved teams also finds it."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"One unit of work on a team, with its checklists and documents.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ticket"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns one ticket with its checklists and the list of its documents, by its ID such as WEB-31. An ID the ticket had before it moved teams still finds it.","summary":"Get a ticket"},"patch":{"tags":["Tickets"],"operationId":"tickets.update","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"ticket","in":"path","schema":{"type":"string","description":"The ticket's ID, such as WEB-31. An ID the ticket had before it moved teams also finds it.","examples":["WEB-31"]},"required":true,"description":"The ticket's ID, such as WEB-31. An ID the ticket had before it moved teams also finds it."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"One unit of work on a team, with its checklists and documents.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ticket"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Changes only the fields sent. A new project clears the milestone unless `milestone` is sent too. Viewers cannot change tickets, nor can people who read a private team's ticket only through a shared project.","summary":"Update a ticket","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":[],"properties":{"title":{"type":"string","description":"A short name for the work, up to 200 characters."},"status":{"type":"string","description":"A status of the ticket's team, by name, such as Build."},"owner":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The person accountable for the ticket: a member's user ID or email, or me. `null` clears it."},"clankers":{"type":"array","items":{"type":"string"},"description":"Replaces the clankers working on the ticket, by clanker ID; a clanker can add itself with me. An empty list removes them all."},"project":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"A project linked to the ticket's team, by slug. `null` takes the ticket out of its project."},"milestone":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"A milestone of the ticket's project, such as M2. `null` clears it."},"tags":{"type":"array","items":{"type":"string"},"description":"Replaces the ticket's tags, by name: workspace tags and the team's own. An empty list removes them all."}},"additionalProperties":false,"examples":[{"status":"Review","owner":"me"}]}}},"required":true}}},"/v1/workspaces/{slug}/tickets/{ticket}/move":{"post":{"tags":["Tickets"],"operationId":"tickets.move","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"ticket","in":"path","schema":{"type":"string","description":"The ticket's ID, such as WEB-31. An ID the ticket had before it moved teams also finds it.","examples":["WEB-31"]},"required":true,"description":"The ticket's ID, such as WEB-31. An ID the ticket had before it moved teams also finds it."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"One unit of work on a team, with its checklists and documents.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ticket"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Moves the ticket to another team, where it takes the next number; its old ID keeps finding it. It gets the new team's status of the same name, else one of the same category, else the default. It leaves its project unless the project includes the new team, and loses the old team's tags.","summary":"Move a ticket","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["team"],"properties":{"team":{"type":"string","description":"The key of the team to move the ticket to, such as API."}},"additionalProperties":false,"examples":[{"team":"API"}]}}},"required":true}}},"/v1/workspaces/{slug}/tickets/{ticket}/reorder":{"post":{"tags":["Tickets"],"operationId":"tickets.reorder","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"ticket","in":"path","schema":{"type":"string","description":"The ticket's ID, such as WEB-31. An ID the ticket had before it moved teams also finds it.","examples":["WEB-31"]},"required":true,"description":"The ticket's ID, such as WEB-31. An ID the ticket had before it moved teams also finds it."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"One unit of work on a team, with its checklists and documents.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ticket"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Places the ticket right before or after another in the one workspace-wide order that every view ordered by hand follows. Send `before` or `after`, not both.","summary":"Reorder a ticket","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":[],"properties":{"before":{"type":"string","description":"The ID of the ticket to go right before, such as WEB-12."},"after":{"type":"string","description":"The ID of the ticket to go right after, such as WEB-12."}},"additionalProperties":false,"examples":[{"before":"WEB-12"}]}}},"required":true}}},"/v1/workspaces/{slug}/tickets/{ticket}/checklist":{"post":{"tags":["Tickets"],"operationId":"tickets.addChecklistItem","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"ticket","in":"path","schema":{"type":"string","description":"The ticket's ID, such as WEB-31. An ID the ticket had before it moved teams also finds it.","examples":["WEB-31"]},"required":true,"description":"The ticket's ID, such as WEB-31. An ID the ticket had before it moved teams also finds it."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"One unit of work on a team, with its checklists and documents.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ticket"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Adds items, in order, to the end of the ticket's checklist for a status: all of them, or none. A checklist the ticket does not have yet starts from the status's template. A checklist holds up to 30 items.","summary":"Add checklist items","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"type":"object","required":["title"],"properties":{"title":{"type":"string","description":"What has to be done, up to 120 characters, unique within the checklist."},"doer":{"type":"string","enum":["human","clanker"],"description":"Who does the item, human or clanker; clanker when left out."}},"additionalProperties":false},"description":"The items to add, in order."},"status":{"type":"string","description":"The status of the ticket's team whose checklist gets the items, by name, such as Build. Leave it out for the ticket's current status."}},"additionalProperties":false,"examples":[{"items":[{"title":"Index docs pages at build time"},{"title":"Design review","doer":"human"}],"status":"Build"}]}}},"required":true}}},"/v1/workspaces/{slug}/tickets/{ticket}/checklist/{item}":{"patch":{"tags":["Tickets"],"operationId":"tickets.updateChecklistItem","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"ticket","in":"path","schema":{"type":"string","description":"The ticket's ID, such as WEB-31. An ID the ticket had before it moved teams also finds it.","examples":["WEB-31"]},"required":true,"description":"The ticket's ID, such as WEB-31. An ID the ticket had before it moved teams also finds it."},{"name":"item","in":"path","schema":{"type":"string","description":"The checklist item's ID, or its title when only one of the ticket's checklists has that title.","examples":["Ci2SpG3nHv7Y"]},"required":true,"description":"The checklist item's ID, or its title when only one of the ticket's checklists has that title."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"One unit of work on a team, with its checklists and documents.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ticket"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Renames a ticket's checklist item, changes who does it, checks or clears it, or marks it in progress. Changes only the fields sent.","summary":"Update a checklist item","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":[],"properties":{"title":{"type":"string","description":"A new title, up to 120 characters."},"doer":{"type":"string","enum":["human","clanker"],"description":"Who does the item: `human` for a person, such as an approval, or `clanker`. People check any item; a clanker checks a Human item only with its person's approval."},"done":{"type":"boolean","description":"`true` checks the item and records who checked it and when; `false` clears it, back to not started."},"inProgress":{"type":"boolean","description":"`true` marks the item in progress and records who started it and when, clearing it if it was checked; `false` takes it back to not started. Send it or `done`, not both."}},"additionalProperties":false,"examples":[{"done":true},{"inProgress":true},{"doer":"human"}]}}},"required":true}},"delete":{"tags":["Tickets"],"operationId":"tickets.removeChecklistItem","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"ticket","in":"path","schema":{"type":"string","description":"The ticket's ID, such as WEB-31. An ID the ticket had before it moved teams also finds it.","examples":["WEB-31"]},"required":true,"description":"The ticket's ID, such as WEB-31. An ID the ticket had before it moved teams also finds it."},{"name":"item","in":"path","schema":{"type":"string","description":"The checklist item's ID, or its title when only one of the ticket's checklists has that title.","examples":["Ci2SpG3nHv7Y"]},"required":true,"description":"The checklist item's ID, or its title when only one of the ticket's checklists has that title."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"204":{"description":"Success"},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Removes an item from a ticket's checklist.","summary":"Remove a checklist item"}},"/v1/workspaces/{slug}/tickets/{ticket}/checklist/{item}/reorder":{"post":{"tags":["Tickets"],"operationId":"tickets.reorderChecklistItem","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"ticket","in":"path","schema":{"type":"string","description":"The ticket's ID, such as WEB-31. An ID the ticket had before it moved teams also finds it.","examples":["WEB-31"]},"required":true,"description":"The ticket's ID, such as WEB-31. An ID the ticket had before it moved teams also finds it."},{"name":"item","in":"path","schema":{"type":"string","description":"The checklist item's ID, or its title when only one of the ticket's checklists has that title.","examples":["Ci2SpG3nHv7Y"]},"required":true,"description":"The checklist item's ID, or its title when only one of the ticket's checklists has that title."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"One unit of work on a team, with its checklists and documents.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ticket"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Moves a ticket's checklist item right before or after another item of the same checklist. Send `before` or `after`, not both.","summary":"Reorder a checklist item","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":[],"properties":{"before":{"type":"string","description":"The ID or title of an item of the same checklist to go right before."},"after":{"type":"string","description":"The ID or title of an item of the same checklist to go right after."}},"additionalProperties":false,"examples":[{"before":"Ci1ImP8dRt4W"}]}}},"required":true}}},"/v1/workspaces/{slug}/tickets/{ticket}/question":{"post":{"tags":["Tickets"],"operationId":"tickets.askQuestion","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"ticket","in":"path","schema":{"type":"string","description":"The ticket's ID, such as WEB-31. An ID the ticket had before it moved teams also finds it.","examples":["WEB-31"]},"required":true,"description":"The ticket's ID, such as WEB-31. An ID the ticket had before it moved teams also finds it."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"One unit of work on a team, with its checklists and documents.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ticket"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Asks a question on a ticket, which then waits on a person until someone answers it; the ticket's owner is notified unless they asked. Asking again replaces the caller's own open question on the ticket. An account API key cannot ask.","summary":"Ask a question","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["question"],"properties":{"question":{"type":"string","description":"The question, up to 1,000 characters."},"choices":{"type":"array","items":{"type":"string"},"description":"Up to four answers to suggest, each up to 100 characters."}},"additionalProperties":false,"examples":[{"question":"Use a hosted search service, or build the index into the docs site? Hosted is faster to ship; built-in has no monthly cost.","choices":["Hosted service","Built-in index"]}]}}},"required":true}}},"/v1/workspaces/{slug}/tickets/{ticket}/question/answer":{"post":{"tags":["Tickets"],"operationId":"tickets.answerQuestion","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"ticket","in":"path","schema":{"type":"string","description":"The ticket's ID, such as WEB-31. An ID the ticket had before it moved teams also finds it.","examples":["WEB-31"]},"required":true,"description":"The ticket's ID, such as WEB-31. An ID the ticket had before it moved teams also finds it."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"One unit of work on a team, with its checklists and documents.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ticket"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Answers an open question on a ticket. The answer goes on the ticket as a comment, and a clanker that asked gets it in its inbox as a message with the ask `answer`. A ticket with several open questions needs the question's ID. An account API key cannot answer.","summary":"Answer a question","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["answer"],"properties":{"answer":{"type":"string","description":"The answer, up to 2,000 characters."},"question":{"type":"string","description":"The question's ID from the ticket's `needsHuman`. Leave it out when the ticket has one open question."}},"additionalProperties":false,"examples":[{"answer":"Built-in index. We do not want another bill."}]}}},"required":true}}},"/v1/workspaces/{slug}/tickets/{ticket}/branches":{"post":{"tags":["Tickets"],"operationId":"tickets.linkBranch","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"ticket","in":"path","schema":{"type":"string","description":"The ticket's ID, such as WEB-31. An ID the ticket had before it moved teams also finds it.","examples":["WEB-31"]},"required":true,"description":"The ticket's ID, such as WEB-31. An ID the ticket had before it moved teams also finds it."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"One unit of work on a team, with its checklists and documents.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ticket"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Links a ticket to a repository's branch it is worked on. The plugin's hook then names the ticket in sessions on that branch. Linking a branch the ticket already has changes nothing.","summary":"Link a branch","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["repository","branch"],"properties":{"repository":{"type":"string","description":"The repository as owner/name, such as acme/web, or its GitHub URL."},"branch":{"type":"string","description":"The git branch, such as web-31-docs-search."}},"additionalProperties":false,"examples":[{"repository":"acme/web","branch":"web-31-docs-search"}]}}},"required":true}},"delete":{"tags":["Tickets"],"operationId":"tickets.unlinkBranch","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"ticket","in":"path","schema":{"type":"string","description":"The ticket's ID, such as WEB-31. An ID the ticket had before it moved teams also finds it.","examples":["WEB-31"]},"required":true,"description":"The ticket's ID, such as WEB-31. An ID the ticket had before it moved teams also finds it."},{"name":"repository","in":"query","schema":{"type":"string","description":"The repository as owner/name, such as acme/web.","examples":["acme/web"]},"required":true,"description":"The repository as owner/name, such as acme/web."},{"name":"branch","in":"query","schema":{"type":"string","description":"The git branch, such as web-31-docs-search.","examples":["web-31-docs-search"]},"required":true,"description":"The git branch, such as web-31-docs-search."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"One unit of work on a team, with its checklists and documents.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ticket"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Unlinks a repository's branch from a ticket.","summary":"Unlink a branch"}},"/v1/workspaces/{slug}/tickets/{ticket}/pull-requests":{"post":{"tags":["Tickets"],"operationId":"tickets.linkPullRequest","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"ticket","in":"path","schema":{"type":"string","description":"The ticket's ID, such as WEB-31. An ID the ticket had before it moved teams also finds it.","examples":["WEB-31"]},"required":true,"description":"The ticket's ID, such as WEB-31. An ID the ticket had before it moved teams also finds it."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"One unit of work on a team, with its checklists and documents.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ticket"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Links a GitHub pull request to a ticket. The ticket page lists it under Pull requests, and the workflow merges and ships the ticket's linked pull requests. Linking one the ticket already has changes nothing. A ticket links up to 10.","summary":"Link a pull request","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["pullRequest"],"properties":{"pullRequest":{"type":"string","description":"A github.com pull request, by its link, such as https://github.com/acme/web/pull/142, or as owner/name#number, such as acme/web#142.","examples":["https://github.com/acme/web/pull/142","acme/web#142"]}},"additionalProperties":false,"examples":[{"pullRequest":"https://github.com/acme/web/pull/142"}]}}},"required":true}},"delete":{"tags":["Tickets"],"operationId":"tickets.unlinkPullRequest","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"ticket","in":"path","schema":{"type":"string","description":"The ticket's ID, such as WEB-31. An ID the ticket had before it moved teams also finds it.","examples":["WEB-31"]},"required":true,"description":"The ticket's ID, such as WEB-31. An ID the ticket had before it moved teams also finds it."},{"name":"pullRequest","in":"query","schema":{"type":"string","description":"A github.com pull request, by its link, such as https://github.com/acme/web/pull/142, or as owner/name#number, such as acme/web#142.","examples":["https://github.com/acme/web/pull/142","acme/web#142"]},"required":true,"description":"A github.com pull request, by its link, such as https://github.com/acme/web/pull/142, or as owner/name#number, such as acme/web#142."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"One unit of work on a team, with its checklists and documents.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ticket"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Unlinks a GitHub pull request from a ticket.","summary":"Unlink a pull request"}},"/v1/workspaces/{slug}/tickets/{ticket}/documents/{document}":{"get":{"tags":["Ticket documents"],"operationId":"ticketDocuments.get","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"ticket","in":"path","schema":{"type":"string","description":"The ticket's ID, such as WEB-31. An ID the ticket had before it moved teams also finds it.","examples":["WEB-31"]},"required":true,"description":"The ticket's ID, such as WEB-31. An ID the ticket had before it moved teams also finds it."},{"name":"document","in":"path","schema":{"type":"string","description":"The document's name or slug, such as plan or build-record.","examples":["plan"]},"required":true,"description":"The document's name or slug, such as plan or build-record."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A document a ticket keeps for one of its statuses, such as its Scope, Plan or Review.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TicketDocument"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns one of a ticket's documents in Markdown with its revision. A document nobody has written yet holds its status's template at revision 0.","summary":"Get a document"},"put":{"tags":["Ticket documents"],"operationId":"ticketDocuments.write","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"ticket","in":"path","schema":{"type":"string","description":"The ticket's ID, such as WEB-31. An ID the ticket had before it moved teams also finds it.","examples":["WEB-31"]},"required":true,"description":"The ticket's ID, such as WEB-31. An ID the ticket had before it moved teams also finds it."},{"name":"document","in":"path","schema":{"type":"string","description":"The document's name or slug, such as plan or build-record.","examples":["plan"]},"required":true,"description":"The document's name or slug, such as plan or build-record."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A document a ticket keeps for one of its statuses, such as its Scope, Plan or Review.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TicketDocument"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Replaces a document's Markdown as its next revision. A write from an older revision than the latest answers 409, so nobody overwrites a change they have not seen. Viewers cannot write documents.","summary":"Write a document","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["body","baseRevision"],"properties":{"body":{"type":"string","description":"The whole document in Markdown, up to 200,000 characters."},"baseRevision":{"type":"number","description":"The revision the change was made from: the `revision` you read, 0 for an unwritten document. A change from an older revision answers 409."}},"additionalProperties":false,"examples":[{"body":"## Approach\n1. Index every docs page at build time.\n2. Add a search box to the docs header that queries the index.","baseRevision":3}]}}},"required":true}},"patch":{"tags":["Ticket documents"],"operationId":"ticketDocuments.edit","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"ticket","in":"path","schema":{"type":"string","description":"The ticket's ID, such as WEB-31. An ID the ticket had before it moved teams also finds it.","examples":["WEB-31"]},"required":true,"description":"The ticket's ID, such as WEB-31. An ID the ticket had before it moved teams also finds it."},{"name":"document","in":"path","schema":{"type":"string","description":"The document's name or slug, such as plan or build-record.","examples":["plan"]},"required":true,"description":"The document's name or slug, such as plan or build-record."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A document a ticket keeps for one of its statuses, such as its Scope, Plan or Review.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TicketDocument"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Replaces exact passages of a document as its next revision, all or none. Each passage must appear exactly once in the revision the change was made from; a change from an older revision answers 409.","summary":"Edit a document","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["edits","baseRevision"],"properties":{"edits":{"type":"array","items":{"type":"object","required":["old","new"],"properties":{"old":{"type":"string","description":"A passage that appears exactly once in the document."},"new":{"type":"string","description":"What replaces it."}},"additionalProperties":false},"description":"The passages to change, up to 50, all or none."},"baseRevision":{"type":"number","description":"The revision the change was made from: the `revision` you read, 0 for an unwritten document. A change from an older revision answers 409."}},"additionalProperties":false,"examples":[{"edits":[{"old":"at build time","new":"at build time, skipping drafts"}],"baseRevision":3}]}}},"required":true}}},"/v1/workspaces/{slug}/tickets/{ticket}/documents/{document}/revisions":{"get":{"tags":["Ticket documents"],"operationId":"ticketDocuments.revisions","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"ticket","in":"path","schema":{"type":"string","description":"The ticket's ID, such as WEB-31. An ID the ticket had before it moved teams also finds it.","examples":["WEB-31"]},"required":true,"description":"The ticket's ID, such as WEB-31. An ID the ticket had before it moved teams also finds it."},{"name":"document","in":"path","schema":{"type":"string","description":"The document's name or slug, such as plan or build-record.","examples":["plan"]},"required":true,"description":"The document's name or slug, such as plan or build-record."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["revisions"],"properties":{"revisions":{"type":"array","items":{"$ref":"#/components/schemas/DocumentRevision"},"description":"The document's revisions, newest first. Empty until anyone writes it."}},"additionalProperties":false}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns every revision of a ticket's document, newest first.","summary":"List a document's revisions"}},"/v1/workspaces/{slug}/ticket-statuses":{"get":{"tags":["Ticket statuses"],"operationId":"ticketStatuses.list","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"team","in":"query","schema":{"type":"string","description":"A team's key, such as WEB. Leave it out for the workspace's template.","examples":["WEB"]},"required":false,"description":"A team's key, such as WEB. Leave it out for the workspace's template."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["statuses"],"properties":{"statuses":{"type":"array","items":{"$ref":"#/components/schemas/TicketStatusWithChecklist"},"description":"The statuses in board order: by category, then by position, each with its checklist template."}},"additionalProperties":false}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns a team's statuses or, without `team`, the workspace's template that new teams copy, with each status's checklist template and instructions.","summary":"List ticket statuses"},"post":{"tags":["Ticket statuses"],"operationId":"ticketStatuses.create","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"201":{"description":"A step in a team's workflow, such as Plan or Build.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TicketStatus"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Owners and admins add statuses. The new status goes last in its category and starts from its stage's checklist template and instructions; its document takes the stage's name, or the status's own when another status already keeps that one. A status added to the template reaches only teams created afterwards.","summary":"Create a ticket status","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["name","category"],"properties":{"team":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The key of the team to add the status to, such as WEB. Leave it out to add it to the workspace's template."},"name":{"type":"string","description":"The status's name, up to 40 characters, unique within the team."},"category":{"type":"string","enum":["backlog","plan","build","review","ship","done","canceled"],"description":"The status's category. It cannot change later."}},"additionalProperties":false,"examples":[{"team":"WEB","name":"In QA","category":"review"}]}}},"required":true}}},"/v1/workspaces/{slug}/ticket-statuses/{status}":{"patch":{"tags":["Ticket statuses"],"operationId":"ticketStatuses.update","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"status","in":"path","schema":{"type":"string","description":"The ticket status's ID.","examples":["St3BdV6nHs9D"]},"required":true,"description":"The ticket status's ID."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A step in a team's workflow, such as Plan or Build.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TicketStatus"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Owners and admins rename a status or make it the default. Saved view filters follow a new name.","summary":"Update a ticket status","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":[],"properties":{"name":{"type":"string","description":"The status's name, up to 40 characters, unique within the team."},"isDefault":{"type":"boolean","enum":[true],"description":"`true` makes this the status new tickets get when none is named. Only a backlog status can be the default."}},"additionalProperties":false,"examples":[{"name":"In development"},{"isDefault":true}]}}},"required":true}},"delete":{"tags":["Ticket statuses"],"operationId":"ticketStatuses.delete","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"status","in":"path","schema":{"type":"string","description":"The ticket status's ID.","examples":["St3BdV6nHs9D"]},"required":true,"description":"The ticket status's ID."},{"name":"moveTo","in":"query","schema":{"type":"string","description":"The ID of another status of the same team that takes this status's tickets. Required when tickets use the status.","examples":["St2PlN8mRc3K"]},"required":false,"description":"The ID of another status of the same team that takes this status's tickets. Required when tickets use the status."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"204":{"description":"Success"},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Owners and admins delete statuses. Every category keeps at least one status, and the default status cannot be deleted. Tickets that use the status move to `moveTo`, and tickets' checklists for the status join their checklists for `moveTo`.","summary":"Delete a ticket status"}},"/v1/workspaces/{slug}/ticket-statuses/{status}/reorder":{"post":{"tags":["Ticket statuses"],"operationId":"ticketStatuses.reorder","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"status","in":"path","schema":{"type":"string","description":"The ticket status's ID.","examples":["St3BdV6nHs9D"]},"required":true,"description":"The ticket status's ID."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["statuses"],"properties":{"statuses":{"type":"array","items":{"$ref":"#/components/schemas/TicketStatus"},"description":"Every status of the same team, or of the template, in board order: by category, then by position."}},"additionalProperties":false}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Moves a status right before or after another status of its category. Send `before` or `after`, not both. Owners and admins reorder statuses.","summary":"Reorder a ticket status","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":[],"properties":{"before":{"type":"string","description":"The ID of a status of the same category to go right before."},"after":{"type":"string","description":"The ID of a status of the same category to go right after."}},"additionalProperties":false,"examples":[{"after":"St4IrG2wZf5M"}]}}},"required":true}}},"/v1/workspaces/{slug}/ticket-statuses/{status}/checklist":{"post":{"tags":["Ticket statuses"],"operationId":"ticketStatuses.createChecklistItem","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"status","in":"path","schema":{"type":"string","description":"The ticket status's ID.","examples":["St3BdV6nHs9D"]},"required":true,"description":"The ticket status's ID."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"201":{"description":"A ticket status with its checklist template and instructions.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TicketStatusWithChecklist"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Adds an item to the end of a status's checklist template, which holds up to 30 items. Tickets that enter the status afterwards get it; tickets that already have the status's checklist keep theirs. A team's members change its statuses' templates; owners and admins change any, and the workspace's.","summary":"Add a checklist template item","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["title"],"properties":{"title":{"type":"string","description":"What has to be done, up to 120 characters, unique within the template."},"doer":{"type":"string","enum":["human","clanker"],"description":"Who does the item, human or clanker; clanker when left out."}},"additionalProperties":false,"examples":[{"title":"Design review","doer":"human"}]}}},"required":true}}},"/v1/workspaces/{slug}/ticket-statuses/{status}/checklist/{item}":{"patch":{"tags":["Ticket statuses"],"operationId":"ticketStatuses.updateChecklistItem","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"status","in":"path","schema":{"type":"string","description":"The ticket status's ID.","examples":["St3BdV6nHs9D"]},"required":true,"description":"The ticket status's ID."},{"name":"item","in":"path","schema":{"type":"string","description":"The template item's ID, or its title.","examples":["Ct2SpG7nKw3V"]},"required":true,"description":"The template item's ID, or its title."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A ticket status with its checklist template and instructions.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TicketStatusWithChecklist"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Renames an item of a status's checklist template, or changes who does it. Tickets that already have the status's checklist keep their copies. The people who add template items change them.","summary":"Update a checklist template item","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":[],"properties":{"title":{"type":"string","description":"The item's new title, up to 120 characters."},"doer":{"type":"string","enum":["human","clanker"],"description":"Who does the item: `human` for a person, such as an approval, or `clanker`. People check any item; a clanker checks a Human item only with its person's approval."}},"additionalProperties":false,"examples":[{"title":"Specs generated and passing"},{"doer":"human"}]}}},"required":true}},"delete":{"tags":["Ticket statuses"],"operationId":"ticketStatuses.deleteChecklistItem","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"status","in":"path","schema":{"type":"string","description":"The ticket status's ID.","examples":["St3BdV6nHs9D"]},"required":true,"description":"The ticket status's ID."},{"name":"item","in":"path","schema":{"type":"string","description":"The template item's ID, or its title.","examples":["Ct2SpG7nKw3V"]},"required":true,"description":"The template item's ID, or its title."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"204":{"description":"Success"},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Deletes an item from a status's checklist template. Tickets keep the copies they have. The people who add template items delete them.","summary":"Delete a checklist template item"}},"/v1/workspaces/{slug}/ticket-statuses/{status}/checklist/{item}/reorder":{"post":{"tags":["Ticket statuses"],"operationId":"ticketStatuses.reorderChecklistItem","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"status","in":"path","schema":{"type":"string","description":"The ticket status's ID.","examples":["St3BdV6nHs9D"]},"required":true,"description":"The ticket status's ID."},{"name":"item","in":"path","schema":{"type":"string","description":"The template item's ID, or its title.","examples":["Ct2SpG7nKw3V"]},"required":true,"description":"The template item's ID, or its title."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A ticket status with its checklist template and instructions.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TicketStatusWithChecklist"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Moves a template item right before or after another. Send `before` or `after`, not both. The people who add template items reorder them.","summary":"Reorder a checklist template item","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":[],"properties":{"before":{"type":"string","description":"The ID or title of a template item to go right before."},"after":{"type":"string","description":"The ID or title of a template item to go right after."}},"additionalProperties":false,"examples":[{"after":"Ct3CkP2sLx6T"}]}}},"required":true}}},"/v1/workspaces/{slug}/ticket-statuses/{status}/instructions":{"get":{"tags":["Ticket statuses"],"operationId":"ticketStatuses.getInstructions","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"status","in":"path","schema":{"type":"string","description":"The ticket status's ID.","examples":["St3BdV6nHs9D"]},"required":true,"description":"The ticket status's ID."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A status's instructions and the checklist they go with.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatusInstructionsDetail"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns what the status asks of a clanker, with its checklist template: the document its tickets keep there, the Markdown that document starts from, and how to work the status.","summary":"Get a status's instructions"},"put":{"tags":["Ticket statuses"],"operationId":"ticketStatuses.setInstructions","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"status","in":"path","schema":{"type":"string","description":"The ticket status's ID.","examples":["St3BdV6nHs9D"]},"required":true,"description":"The ticket status's ID."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A status's instructions and the checklist they go with.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatusInstructionsDetail"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Changes a status's instructions. Fields left out keep their values. A team's members change its statuses' instructions; owners and admins change any, and the workspace's. Tickets that already wrote the status's document keep it.","summary":"Set a status's instructions","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":[],"properties":{"document":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The name of the status's document, up to 40 characters, unique within the team. `null` or blank for no document."},"template":{"type":"string","description":"The Markdown the status's document starts from, up to 20,000 characters."},"guidance":{"type":"string","description":"How a clanker works the status, in Markdown, up to 20,000 characters."}},"additionalProperties":false,"examples":[{"document":"Build record","template":"## Progress\nOne entry per plan step: what was done, the files and commits.","guidance":"- Update the build record after every step. Never write it at the end."}]}}},"required":true}},"delete":{"tags":["Ticket statuses"],"operationId":"ticketStatuses.resetInstructions","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"status","in":"path","schema":{"type":"string","description":"The ticket status's ID.","examples":["St3BdV6nHs9D"]},"required":true,"description":"The ticket status's ID."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A status's instructions and the checklist they go with.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatusInstructionsDetail"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Puts a status's instructions back to Clanker Ship's for its stage and returns them. The people who set a status's instructions can reset them.","summary":"Reset a status's instructions"}},"/v1/workspaces/{slug}/tags":{"get":{"tags":["Tags"],"operationId":"tags.list","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"team","in":"query","schema":{"type":"string","description":"A team's key, such as WEB, for the tags that team's tickets can use.","examples":["WEB"]},"required":false,"description":"A team's key, such as WEB, for the tags that team's tickets can use."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["tags"],"properties":{"tags":{"type":"array","items":{"$ref":"#/components/schemas/Tag"},"description":"The tags, sorted by name."}},"additionalProperties":false}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns workspace tags and the team tags of every team the caller sees or, with `team`, workspace tags and that team's tags.","summary":"List tags"},"post":{"tags":["Tags"],"operationId":"tags.create","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"201":{"description":"A colored label on tickets. Workspace tags work on every ticket; team tags only on their team's tickets.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Tag"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Owners and admins create workspace tags, and a team's members also create its team tags; viewers cannot. A workspace tag's name must differ from every tag's, and a team tag's from the workspace tags and the team's own.","summary":"Create a tag","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["name","color"],"properties":{"name":{"type":"string","description":"The tag's name, up to 40 characters, such as bug."},"color":{"type":"string","enum":["gray","red","orange","amber","green","teal","cobalt","iris","pink"],"description":"The tag's color."},"team":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The key of the team a team tag belongs to, such as WEB. Leave it out for a workspace tag."}},"additionalProperties":false,"examples":[{"name":"search","color":"teal","team":"WEB"}]}}},"required":true}}},"/v1/workspaces/{slug}/tags/{tag}":{"patch":{"tags":["Tags"],"operationId":"tags.update","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"tag","in":"path","schema":{"type":"string","description":"The tag's ID.","examples":["Tg3FtR7nWq2K"]},"required":true,"description":"The tag's ID."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A colored label on tickets. Workspace tags work on every ticket; team tags only on their team's tickets.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Tag"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Renames or recolors a tag; only the fields sent change. Saved view filters follow a new name. The people who can create the tag can change it.","summary":"Update a tag","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":[],"properties":{"name":{"type":"string","description":"The tag's name, up to 40 characters."},"color":{"type":"string","enum":["gray","red","orange","amber","green","teal","cobalt","iris","pink"],"description":"The tag's color."}},"additionalProperties":false,"examples":[{"color":"iris"}]}}},"required":true}},"delete":{"tags":["Tags"],"operationId":"tags.delete","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"tag","in":"path","schema":{"type":"string","description":"The tag's ID.","examples":["Tg3FtR7nWq2K"]},"required":true,"description":"The tag's ID."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"204":{"description":"Success"},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Takes the tag off every ticket and out of saved view filters. The people who can create the tag can delete it.","summary":"Delete a tag"}},"/v1/workspaces/{slug}/me/views":{"get":{"tags":["Views"],"operationId":"views.listMine","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["views"],"properties":{"views":{"type":"array","items":{"$ref":"#/components/schemas/View"},"description":"The views in tab order, as people arranged them."}},"additionalProperties":false}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns the caller's own views, the tabs of their My work. Everyone starts with Work, List and Board, each showing the open tickets they own or their clankers work on; Work is the default. Only the caller sees them. An account API key has no person and gets InvalidInput.","summary":"List your views"},"post":{"tags":["Views"],"operationId":"views.createMine","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"201":{"description":"A saved way to look at a team's, a project's or a person's tickets: filters, grouping, order and layout.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/View"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Saves a view of the tickets the caller can read, across every team, as a My work tab only they see. Personal views group by status, category, owner, clanker, tag, project, team or none. Viewers can save their own views too.","summary":"Create one of your views","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","description":"The view's name, up to 60 characters, unique within its team, project or person."},"filters":{"$ref":"#/components/schemas/ViewFilters"},"groupBy":{"type":"string","enum":["status","category","owner","clanker","tag","project","team","none"],"description":"How the view groups tickets. Defaults to status."},"orderBy":{"type":"string","enum":["manual","created","updated"],"description":"`manual` follows the order people set by hand, `created` puts the newest first and `updated` the most recently changed. Defaults to manual."},"layout":{"type":"string","enum":["list","board","work"],"description":"A list, a board or the work layout. Defaults to list."}},"additionalProperties":false,"examples":[{"name":"My clankers","filters":{"categories":["plan","build","review"],"clankers":["mine"]},"groupBy":"status","layout":"board"}]}}},"required":true}}},"/v1/workspaces/{slug}/me/views/{view}":{"get":{"tags":["Views"],"operationId":"views.getMine","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"view","in":"path","schema":{"type":"string","description":"The view's slug, such as active.","examples":["active"]},"required":true,"description":"The view's slug, such as active."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A view with the tickets it shows.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ViewTickets"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns one of the caller's own views with the tickets it shows, in its order. Another member's view is NotFound.","summary":"Get one of your views"},"patch":{"tags":["Views"],"operationId":"views.updateMine","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"view","in":"path","schema":{"type":"string","description":"The view's slug, such as active.","examples":["active"]},"required":true,"description":"The view's slug, such as active."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A saved way to look at a team's, a project's or a person's tickets: filters, grouping, order and layout.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/View"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Changes only the settings sent; `filters` replaces the saved filters. `isDefault: true` makes it the view My work opens.","summary":"Update one of your views","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":[],"properties":{"name":{"type":"string","description":"The view's name, up to 60 characters, unique within its team, project or person. A new name gives the view a new slug."},"filters":{"$ref":"#/components/schemas/ViewFilters"},"groupBy":{"type":"string","enum":["status","category","owner","clanker","tag","project","team","none"],"description":"How the view groups tickets."},"orderBy":{"type":"string","enum":["manual","created","updated"],"description":"`manual` follows the order people set by hand, `created` puts the newest first and `updated` the most recently changed."},"layout":{"type":"string","enum":["list","board","work"],"description":"A list, a board or the work layout."},"isDefault":{"type":"boolean","enum":[true],"description":"`true` makes this the view the owner's page opens."}},"additionalProperties":false,"examples":[{"layout":"board","isDefault":true}]}}},"required":true}},"delete":{"tags":["Views"],"operationId":"views.deleteMine","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"view","in":"path","schema":{"type":"string","description":"The view's slug, such as active.","examples":["active"]},"required":true,"description":"The view's slug, such as active."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"204":{"description":"Success"},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Deletes the view; it does not come back. The default view stays until another view is the default.","summary":"Delete one of your views"}},"/v1/workspaces/{slug}/me/views/{view}/reorder":{"post":{"tags":["Views"],"operationId":"views.reorderMine","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"view","in":"path","schema":{"type":"string","description":"The view's slug, such as active.","examples":["active"]},"required":true,"description":"The view's slug, such as active."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A saved way to look at a team's, a project's or a person's tickets: filters, grouping, order and layout.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/View"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Moves the view right before or right after another of your views, changing the order of your My work tabs. Send `before` or `after`, not both. Viewers can reorder their own views.","summary":"Reorder one of your views","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":[],"properties":{"before":{"type":"string","description":"The slug of the view to go right before."},"after":{"type":"string","description":"The slug of the view to go right after."}},"additionalProperties":false,"examples":[{"before":"active"}]}}},"required":true}}},"/v1/workspaces/{slug}/teams/{team}/views":{"get":{"tags":["Views"],"operationId":"views.listForTeam","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"team","in":"path","schema":{"type":"string","description":"The team's key, such as WEB.","examples":["WEB"]},"required":true,"description":"The team's key, such as WEB."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["views"],"properties":{"views":{"type":"array","items":{"$ref":"#/components/schemas/View"},"description":"The views in tab order, as people arranged them."}},"additionalProperties":false}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns the team's saved views. Every team starts with All tickets, Active and Backlog.","summary":"List a team's views"},"post":{"tags":["Views"],"operationId":"views.createForTeam","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"team","in":"path","schema":{"type":"string","description":"The team's key, such as WEB.","examples":["WEB"]},"required":true,"description":"The team's key, such as WEB."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"201":{"description":"A saved way to look at a team's, a project's or a person's tickets: filters, grouping, order and layout.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/View"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Saves a view of the team's tickets, with a slug made from its name. Team views group by status, category, owner, clanker, tag, project or none. Members of the team and workspace owners and admins change its views; viewers cannot.","summary":"Create a team view","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","description":"The view's name, up to 60 characters, unique within its team, project or person."},"filters":{"$ref":"#/components/schemas/ViewFilters"},"groupBy":{"type":"string","enum":["status","category","owner","clanker","tag","project","none"],"description":"How the view groups tickets. Defaults to status."},"orderBy":{"type":"string","enum":["manual","created","updated"],"description":"`manual` follows the order people set by hand, `created` puts the newest first and `updated` the most recently changed. Defaults to manual."},"layout":{"type":"string","enum":["list","board","work"],"description":"A list, a board or the work layout. Defaults to list."}},"additionalProperties":false,"examples":[{"name":"Search work","filters":{"categories":["plan","build","review"],"tags":["feature"]},"groupBy":"clanker","layout":"board"}]}}},"required":true}}},"/v1/workspaces/{slug}/teams/{team}/views/{view}":{"get":{"tags":["Views"],"operationId":"views.getForTeam","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"team","in":"path","schema":{"type":"string","description":"The team's key, such as WEB.","examples":["WEB"]},"required":true,"description":"The team's key, such as WEB."},{"name":"view","in":"path","schema":{"type":"string","description":"The view's slug, such as active.","examples":["active"]},"required":true,"description":"The view's slug, such as active."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A view with the tickets it shows.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ViewTickets"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns the view with the tickets it shows, in its order, and the team's statuses for a status grouping's columns.","summary":"Get a team view"},"patch":{"tags":["Views"],"operationId":"views.updateForTeam","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"team","in":"path","schema":{"type":"string","description":"The team's key, such as WEB.","examples":["WEB"]},"required":true,"description":"The team's key, such as WEB."},{"name":"view","in":"path","schema":{"type":"string","description":"The view's slug, such as active.","examples":["active"]},"required":true,"description":"The view's slug, such as active."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A saved way to look at a team's, a project's or a person's tickets: filters, grouping, order and layout.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/View"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Changes only the settings sent, for everyone who opens the view; `filters` replaces the saved filters. Members of the team and workspace owners and admins change its views; viewers cannot.","summary":"Update a team view","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":[],"properties":{"name":{"type":"string","description":"The view's name, up to 60 characters, unique within its team, project or person. A new name gives the view a new slug."},"filters":{"$ref":"#/components/schemas/ViewFilters"},"groupBy":{"type":"string","enum":["status","category","owner","clanker","tag","project","none"],"description":"How the view groups tickets."},"orderBy":{"type":"string","enum":["manual","created","updated"],"description":"`manual` follows the order people set by hand, `created` puts the newest first and `updated` the most recently changed."},"layout":{"type":"string","enum":["list","board","work"],"description":"A list, a board or the work layout."},"isDefault":{"type":"boolean","enum":[true],"description":"`true` makes this the view the owner's page opens."}},"additionalProperties":false,"examples":[{"layout":"board","isDefault":true}]}}},"required":true}},"delete":{"tags":["Views"],"operationId":"views.deleteForTeam","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"team","in":"path","schema":{"type":"string","description":"The team's key, such as WEB.","examples":["WEB"]},"required":true,"description":"The team's key, such as WEB."},{"name":"view","in":"path","schema":{"type":"string","description":"The view's slug, such as active.","examples":["active"]},"required":true,"description":"The view's slug, such as active."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"204":{"description":"Success"},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Deletes the view. The default view stays until another view is the default. Members of the team and workspace owners and admins change its views; viewers cannot.","summary":"Delete a team view"}},"/v1/workspaces/{slug}/teams/{team}/views/{view}/reorder":{"post":{"tags":["Views"],"operationId":"views.reorderForTeam","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"team","in":"path","schema":{"type":"string","description":"The team's key, such as WEB.","examples":["WEB"]},"required":true,"description":"The team's key, such as WEB."},{"name":"view","in":"path","schema":{"type":"string","description":"The view's slug, such as active.","examples":["active"]},"required":true,"description":"The view's slug, such as active."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A saved way to look at a team's, a project's or a person's tickets: filters, grouping, order and layout.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/View"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Moves the view right before or right after another of the team's views, changing the order of its tabs for everyone. Send `before` or `after`, not both. Members of the team and workspace owners and admins change its views; viewers cannot.","summary":"Reorder a team view","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":[],"properties":{"before":{"type":"string","description":"The slug of the view to go right before."},"after":{"type":"string","description":"The slug of the view to go right after."}},"additionalProperties":false,"examples":[{"before":"active"}]}}},"required":true}}},"/v1/workspaces/{slug}/projects/{project}/views":{"get":{"tags":["Views"],"operationId":"views.listForProject","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"project","in":"path","schema":{"type":"string","description":"The project's slug, such as docs-launch.","examples":["docs-launch"]},"required":true,"description":"The project's slug, such as docs-launch."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["views"],"properties":{"views":{"type":"array","items":{"$ref":"#/components/schemas/View"},"description":"The views in tab order, as people arranged them."}},"additionalProperties":false}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns the project's saved views. Every project starts with Board, its default, and All tickets.","summary":"List a project's views"},"post":{"tags":["Views"],"operationId":"views.createForProject","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"project","in":"path","schema":{"type":"string","description":"The project's slug, such as docs-launch.","examples":["docs-launch"]},"required":true,"description":"The project's slug, such as docs-launch."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"201":{"description":"A saved way to look at a team's, a project's or a person's tickets: filters, grouping, order and layout.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/View"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Saves a view of the project's tickets, with a slug made from its name. Project views group by status, category, owner, clanker, tag, milestone, team or none. Members of the project's teams and workspace owners and admins change its views; viewers cannot.","summary":"Create a project view","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","description":"The view's name, up to 60 characters, unique within its team, project or person."},"filters":{"$ref":"#/components/schemas/ViewFilters"},"groupBy":{"type":"string","enum":["status","category","owner","clanker","tag","milestone","team","none"],"description":"How the view groups tickets. Defaults to status."},"orderBy":{"type":"string","enum":["manual","created","updated"],"description":"`manual` follows the order people set by hand, `created` puts the newest first and `updated` the most recently changed. Defaults to manual."},"layout":{"type":"string","enum":["list","board","work"],"description":"A list, a board or the work layout. Defaults to list."}},"additionalProperties":false,"examples":[{"name":"By milestone","filters":{"categories":["plan","build","review"]},"groupBy":"milestone"}]}}},"required":true}}},"/v1/workspaces/{slug}/projects/{project}/views/{view}":{"get":{"tags":["Views"],"operationId":"views.getForProject","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"project","in":"path","schema":{"type":"string","description":"The project's slug, such as docs-launch.","examples":["docs-launch"]},"required":true,"description":"The project's slug, such as docs-launch."},{"name":"view","in":"path","schema":{"type":"string","description":"The view's slug, such as active.","examples":["active"]},"required":true,"description":"The view's slug, such as active."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A view with the tickets it shows.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ViewTickets"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns the view with the tickets it shows, in its order. A status grouping uses the statuses the project's teams share as columns, or categories when their statuses differ.","summary":"Get a project view"},"patch":{"tags":["Views"],"operationId":"views.updateForProject","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"project","in":"path","schema":{"type":"string","description":"The project's slug, such as docs-launch.","examples":["docs-launch"]},"required":true,"description":"The project's slug, such as docs-launch."},{"name":"view","in":"path","schema":{"type":"string","description":"The view's slug, such as active.","examples":["active"]},"required":true,"description":"The view's slug, such as active."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A saved way to look at a team's, a project's or a person's tickets: filters, grouping, order and layout.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/View"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Changes only the settings sent, for everyone who opens the view; `filters` replaces the saved filters. Members of the project's teams and workspace owners and admins change its views; viewers cannot.","summary":"Update a project view","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":[],"properties":{"name":{"type":"string","description":"The view's name, up to 60 characters, unique within its team, project or person. A new name gives the view a new slug."},"filters":{"$ref":"#/components/schemas/ViewFilters"},"groupBy":{"type":"string","enum":["status","category","owner","clanker","tag","milestone","team","none"],"description":"How the view groups tickets."},"orderBy":{"type":"string","enum":["manual","created","updated"],"description":"`manual` follows the order people set by hand, `created` puts the newest first and `updated` the most recently changed."},"layout":{"type":"string","enum":["list","board","work"],"description":"A list, a board or the work layout."},"isDefault":{"type":"boolean","enum":[true],"description":"`true` makes this the view the owner's page opens."}},"additionalProperties":false,"examples":[{"layout":"board","isDefault":true}]}}},"required":true}},"delete":{"tags":["Views"],"operationId":"views.deleteForProject","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"project","in":"path","schema":{"type":"string","description":"The project's slug, such as docs-launch.","examples":["docs-launch"]},"required":true,"description":"The project's slug, such as docs-launch."},{"name":"view","in":"path","schema":{"type":"string","description":"The view's slug, such as active.","examples":["active"]},"required":true,"description":"The view's slug, such as active."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"204":{"description":"Success"},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Deletes the view. The default view stays until another view is the default. Members of the project's teams and workspace owners and admins change its views; viewers cannot.","summary":"Delete a project view"}},"/v1/workspaces/{slug}/projects/{project}/views/{view}/reorder":{"post":{"tags":["Views"],"operationId":"views.reorderForProject","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"project","in":"path","schema":{"type":"string","description":"The project's slug, such as docs-launch.","examples":["docs-launch"]},"required":true,"description":"The project's slug, such as docs-launch."},{"name":"view","in":"path","schema":{"type":"string","description":"The view's slug, such as active.","examples":["active"]},"required":true,"description":"The view's slug, such as active."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A saved way to look at a team's, a project's or a person's tickets: filters, grouping, order and layout.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/View"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Moves the view right before or right after another of the project's views, changing the order of its tabs for everyone. Send `before` or `after`, not both. Members of the project's teams and workspace owners and admins change its views; viewers cannot.","summary":"Reorder a project view","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":[],"properties":{"before":{"type":"string","description":"The slug of the view to go right before."},"after":{"type":"string","description":"The slug of the view to go right after."}},"additionalProperties":false,"examples":[{"before":"active"}]}}},"required":true}}},"/v1/workspaces/{slug}/clanker-instructions":{"get":{"tags":["Clanker instructions"],"operationId":"clankerInstructions.get","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"kind","in":"query","schema":{"type":"string","enum":["ticket","test-cases","test-code","fixtures","test-ci"],"description":"What the instructions shape: `ticket` for the defaults a clanker's new ticket gets, `test-cases` for test cases, `test-code` for specs, `fixtures` for a product's Fixture API and `test-ci` for the CI that runs tests."},"required":true,"description":"What the instructions shape: `ticket` for the defaults a clanker's new ticket gets, `test-cases` for test cases, `test-code` for specs, `fixtures` for a product's Fixture API and `test-ci` for the CI that runs tests."},{"name":"team","in":"query","schema":{"type":"string","description":"A team's key, such as WEB. Leave it out for the workspace's instructions.","examples":["WEB"]},"required":false,"description":"A team's key, such as WEB. Leave it out for the workspace's instructions."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"The instructions of one kind that a team's clankers follow, and where they come from.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClankerInstructions"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns the instructions a team's clankers follow: the team's own, else the workspace's, else Clanker Ship's defaults. Without `team`, returns the workspace's or Clanker Ship's. `source` says which.","summary":"Get clanker instructions"},"put":{"tags":["Clanker instructions"],"operationId":"clankerInstructions.set","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"The instructions of one kind that a team's clankers follow, and where they come from.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClankerInstructions"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Sets the workspace's or a team's own instructions. Fields left out keep their current values, so a team's first change copies what it inherits. Owners and admins set the workspace's, and a team's members also set the team's; viewers cannot. Only ticket instructions take `defaults`.","summary":"Set clanker instructions","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["kind"],"properties":{"kind":{"type":"string","enum":["ticket","test-cases","test-code","fixtures","test-ci"],"description":"What the instructions shape: `ticket` for the defaults a clanker's new ticket gets, `test-cases` for test cases, `test-code` for specs, `fixtures` for a product's Fixture API and `test-ci` for the CI that runs tests."},"team":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"A team's key, such as WEB. Leave it out for the workspace's instructions."},"templates":{"type":"array","items":{"$ref":"#/components/schemas/InstructionTemplate"},"description":"Replaces the templates: exactly one without a tag, and at most one more per tag, up to 20 in all. Not for ticket instructions."},"guidance":{"type":"string","description":"How the clanker should write, in Markdown, up to 20,000 characters. Not for ticket instructions."},"defaults":{"$ref":"#/components/schemas/TicketDefaults"}},"additionalProperties":false,"examples":[{"kind":"ticket","team":"WEB","defaults":{"status":"Plan","tags":[],"owner":"creator","clankers":"creator"}},{"kind":"test-cases","team":"WEB","templates":[{"tag":"bug","body":"## Steps to reproduce\n\n## Expected\n\n## Actual"}]}]}}},"required":true}},"delete":{"tags":["Clanker instructions"],"operationId":"clankerInstructions.reset","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"kind","in":"query","schema":{"type":"string","enum":["ticket","test-cases","test-code","fixtures","test-ci"],"description":"What the instructions shape: `ticket` for the defaults a clanker's new ticket gets, `test-cases` for test cases, `test-code` for specs, `fixtures` for a product's Fixture API and `test-ci` for the CI that runs tests."},"required":true,"description":"What the instructions shape: `ticket` for the defaults a clanker's new ticket gets, `test-cases` for test cases, `test-code` for specs, `fixtures` for a product's Fixture API and `test-ci` for the CI that runs tests."},{"name":"team","in":"query","schema":{"type":"string","description":"A team's key, such as WEB. Leave it out for the workspace's instructions.","examples":["WEB"]},"required":false,"description":"A team's key, such as WEB. Leave it out for the workspace's instructions."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"The instructions of one kind that a team's clankers follow, and where they come from.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClankerInstructions"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Removes the workspace's or a team's own instructions, so it follows what it inherits again, and returns the instructions that now apply. The people who can set the instructions can reset them.","summary":"Reset clanker instructions"}},"/v1/workspaces/{slug}/clankers":{"get":{"tags":["Clankers"],"operationId":"clankers.list","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"person","in":"query","schema":{"type":"string","description":"Only this member's clankers, by user ID, or `me` for your own.","examples":["me"]},"required":false,"description":"Only this member's clankers, by user ID, or `me` for your own."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["clankers"],"properties":{"clankers":{"type":"array","items":{"$ref":"#/components/schemas/Clanker"},"description":"The clankers, sorted by their member's name and then by client."}},"additionalProperties":false}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns the workspace's clankers with their computers and recent sessions. Revoked clankers and the clankers of inactive members are left out.","summary":"List clankers"}},"/v1/workspaces/{slug}/clankers/mine":{"get":{"tags":["Clankers"],"operationId":"clankers.mine","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["clankers"],"properties":{"clankers":{"type":"array","items":{"$ref":"#/components/schemas/ClankerWork"},"description":"Your clankers, sorted by client."}},"additionalProperties":false}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns your clankers, as My clankers shows them: each with its computers, recent sessions and whether it is live, and the open tickets it works on. A ticket two of your clankers work on is listed under each. Account API keys cannot list them, because clankers work for people.","summary":"List your clankers with their work"}},"/v1/workspaces/{slug}/clankers/register":{"post":{"tags":["Clankers"],"operationId":"clankers.register","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["clanker","computer","clientId","access_token","token_type","expires_in","refresh_token","scope"],"properties":{"clanker":{"$ref":"#/components/schemas/Clanker"},"computer":{"type":"object","required":["id","name"],"properties":{"id":{"type":"string","description":"Unique ID of the computer."},"name":{"type":"string","description":"The computer's name, such as maya-mbp."}},"additionalProperties":false,"description":"The computer this sign-in is for."},"clientId":{"type":"string","description":"The OAuth client ID to refresh the tokens with, such as clanker-cli:codex."},"access_token":{"type":"string","description":"The clanker's access token for this computer (`atk_…`). Send it as a bearer token to `/mcp` and `/clanker/v1`."},"token_type":{"type":"string","enum":["Bearer"],"description":"Always Bearer."},"expires_in":{"type":"number","description":"Seconds until the access token expires."},"refresh_token":{"type":"string","description":"The refresh token (`rtk_…`) that gets new tokens from `/oauth/token` for 30 days."},"scope":{"type":"string","description":"The sign-in's permissions: `read write`, or `read` for a viewer."}},"additionalProperties":false,"examples":[{"clanker":{"id":"Ag5HvB1mZr8K","name":"Codex","person":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null},"computers":[{"id":"Cp2LxW7nQd4S","name":"maya-mbp","lastSeenAt":"2026-10-14T09:31:20.000Z","live":true,"sessions":[{"id":"Ss1JtQ6wDm3X","repository":"acme/storefront","branch":"web-31-docs-search","ticket":{"id":"Tk7BnC5xLp9M","identifier":"WEB-31","title":"Add docs search","source":"linked"},"connected":true,"lastSeenAt":"2026-10-14T09:31:20.000Z","live":true}]}],"serverUrl":false,"live":true,"lastSeenAt":"2026-10-14T09:31:20.000Z","createdAt":"2026-10-01T16:20:00.000Z"},"computer":{"id":"Cp2LxW7nQd4S","name":"maya-mbp"},"clientId":"clanker-cli:codex","access_token":"atk_Jq3vX9mR2tLw8NcY5bKp1dHs7fZa4gUe6oTi0yBx","token_type":"Bearer","expires_in":900,"refresh_token":"rtk_Ve2nM8sQ4kWc1xRj6hTb9pLz3dFa7gYu5oNi0tCw","scope":"read write"}]}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Registers your clanker for a client on one computer, creating the clanker on first use, and returns that computer's own clanker sign-in. Registering the same computer name again ends its earlier sign-in. Account API keys cannot register clankers, because clankers work for people.","summary":"Register a clanker","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["client","computer"],"properties":{"client":{"type":"string","enum":["claude","codex","cursor"],"description":"The client the plugin runs in: claude for Claude Code, codex for Codex or cursor for Cursor."},"computer":{"type":"string","description":"The computer's name, such as maya-mbp. Only the first 100 characters are kept."}},"additionalProperties":false,"examples":[{"client":"codex","computer":"maya-mbp"}]}}},"required":true}}},"/v1/workspaces/{slug}/clankers/{clanker}/revoke":{"post":{"tags":["Clankers"],"operationId":"clankers.revoke","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"clanker","in":"path","schema":{"type":"string","description":"The clanker's ID.","examples":["Ag5HvB1mZr8K"]},"required":true,"description":"The clanker's ID."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["revoked","clanker","declined"],"properties":{"revoked":{"type":"boolean","enum":[true],"description":"Always true."},"clanker":{"type":"string","description":"The ID of the revoked clanker."},"declined":{"type":"number","description":"How many waiting messages were declined."}},"additionalProperties":false,"examples":[{"revoked":true,"clanker":"Ag5HvB1mZr8K","declined":1}]}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Ends every sign-in of the clanker at once and declines the messages waiting in its inbox, notifying each sender. Only the member the clanker works for can revoke it. Their next sign-in from that client registers a new clanker.","summary":"Revoke a clanker"}},"/v1/workspaces/{slug}/clankers/{clanker}/settings":{"get":{"tags":["Clankers"],"operationId":"clankers.getSettings","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"clanker","in":"path","schema":{"type":"string","description":"The clanker's ID.","examples":["Ag5HvB1mZr8K"]},"required":true,"description":"The clanker's ID."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A clanker's settings. Its person changes them; Codex shows them on the plugin's settings page.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClankerSettings"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns one of your clankers' settings, with the defaults for those you never changed. Another member's clanker fails with NotFound.","summary":"Get a clanker's settings"},"patch":{"tags":["Clankers"],"operationId":"clankers.updateSettings","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"clanker","in":"path","schema":{"type":"string","description":"The clanker's ID.","examples":["Ag5HvB1mZr8K"]},"required":true,"description":"The clanker's ID."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A clanker's settings. Its person changes them; Codex shows them on the plugin's settings page.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClankerSettings"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Changes the settings given and returns them all. A default team must be one of your teams. Another member's clanker fails with NotFound.","summary":"Change a clanker's settings","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":[],"properties":{"defaultTeam":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The key of one of your teams that new tickets go to when the clanker names none, such as WEB; null to use your first team."},"wakeIdleThreads":{"type":"boolean","description":"Whether the plugin hands each new message to an idle Codex thread."}},"additionalProperties":false,"examples":[{"defaultTeam":"WEB","wakeIdleThreads":false}]}}},"required":true}}},"/v1/workspaces/{slug}/clanker-sessions/{session}":{"get":{"tags":["Clanker sessions"],"operationId":"clankerSessions.get","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"session","in":"path","schema":{"type":"string","description":"The session's ID, from the sessions of your clankers' computers.","examples":["Ss1JtQ6wDm3X"]},"required":true,"description":"The session's ID, from the sessions of your clankers' computers."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"What Clanker Ship shows for a session: its ticket, where the ticket came from, the session's name and ticket line, and the person's other work. The Claude Code plugin draws its band and pane from it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionView"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns one of your clankers' sessions as Clanker Ship shows it: its ticket and where the ticket came from, its name and ticket line, and your other open tickets. A session of another member's clanker fails with Forbidden.","summary":"Get a session"},"put":{"tags":["Clanker sessions"],"operationId":"clankerSessions.setTicket","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"session","in":"path","schema":{"type":"string","description":"The session's ID, from the sessions of your clankers' computers.","examples":["Ss1JtQ6wDm3X"]},"required":true,"description":"The session's ID, from the sessions of your clankers' computers."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"What Clanker Ship shows for a session: its ticket, where the ticket came from, the session's name and ticket line, and the person's other work. The Claude Code plugin draws its band and pane from it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionView"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Makes the ticket the session's picked ticket. A pick wins over the ticket the session's clanker linked and the branch's ticket until you pick again, and the session's next prompt renames it after the ticket. A ticket you cannot see fails with NotFound; a session of another member's clanker fails with Forbidden.","summary":"Pick a session's ticket","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["ticket"],"properties":{"ticket":{"type":"string","description":"The ticket the session works on, by its ID, such as WEB-31."}},"additionalProperties":false,"examples":[{"ticket":"WEB-31"}]}}},"required":true}}},"/v1/workspaces/{slug}/clanker-messages":{"post":{"tags":["Messages"],"operationId":"messages.send","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"201":{"description":"A ticket sent to a clanker with an ask, or a mention of the clanker in a ticket comment.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClankerMessage"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Sends a ticket to a clanker with an ask. The message waits in the clanker's inbox, routed to one of its computers, and the clanker's member is notified unless they sent it. Viewers and account API keys cannot send messages, and a revoked clanker fails with Conflict.","summary":"Send a message","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["clanker","ticket","ask"],"properties":{"clanker":{"type":"string","description":"The clanker's ID."},"ticket":{"type":"string","description":"The ticket's ID, such as WEB-31."},"ask":{"type":"string","enum":["draft","refine","plan","build"],"description":"What the clanker should do with the ticket."},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"A note for the clanker, up to 2,000 characters."}},"additionalProperties":false,"examples":[{"clanker":"Ag5HvB1mZr8K","ticket":"WEB-31","ask":"plan","note":"Keep the search box in the header."}]}}},"required":true}}},"/v1/workspaces/{slug}/tickets/{ticket}/messages":{"get":{"tags":["Messages"],"operationId":"messages.list","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"ticket","in":"path","schema":{"type":"string","description":"The ticket's ID, such as WEB-31. A moved ticket's former ID also works.","examples":["WEB-31"]},"required":true,"description":"The ticket's ID, such as WEB-31. A moved ticket's former ID also works."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["messages"],"properties":{"messages":{"type":"array","items":{"$ref":"#/components/schemas/ClankerMessage"},"description":"The messages, newest first."}},"additionalProperties":false}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns every message sent about the ticket, with its status and the clanker's reply.","summary":"List a ticket's messages"}},"/v1/workspaces/{slug}/tickets/{ticket}/comments":{"get":{"tags":["Comments"],"operationId":"comments.list","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"ticket","in":"path","schema":{"type":"string","description":"The ticket's ID, such as WEB-31. A moved ticket's former ID also works.","examples":["WEB-31"]},"required":true,"description":"The ticket's ID, such as WEB-31. A moved ticket's former ID also works."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["comments"],"properties":{"comments":{"type":"array","items":{"$ref":"#/components/schemas/TicketComment"},"description":"The comments, oldest first."}},"additionalProperties":false}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns the ticket's comments, oldest first.","summary":"List a ticket's comments"},"post":{"tags":["Comments"],"operationId":"comments.create","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"ticket","in":"path","schema":{"type":"string","description":"The ticket's ID, such as WEB-31. A moved ticket's former ID also works.","examples":["WEB-31"]},"required":true,"description":"The ticket's ID, such as WEB-31. A moved ticket's former ID also works."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["comment","messages"],"properties":{"comment":{"$ref":"#/components/schemas/TicketComment"},"messages":{"type":"array","items":{"type":"object","required":["clanker","name"],"properties":{"clanker":{"type":"string","description":"The mentioned clanker's ID."},"name":{"type":"string","description":"The client, such as Codex."}},"additionalProperties":false},"description":"The clankers the comment sent a message to."}},"additionalProperties":false,"examples":[{"comment":{"id":"Cm8HrD2vNq5L","body":"Can you add a case for an empty query?","author":{"person":{"id":"Us9DcT4wHn6R","name":"Sam Okafor","email":"sam@acme.dev","image":null},"clanker":null},"createdAt":"2026-10-14T09:04:51.000Z"},"messages":[{"clanker":"Ag5HvB1mZr8K","name":"Codex"}]}]}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Adds a comment to the ticket and sends each mentioned clanker a message with the ask `mention`. Typed names reach your own clankers, and `mentions` adds any clanker by ID; a revoked clanker fails with Conflict. Viewers and account API keys cannot comment.","summary":"Create a comment","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["body"],"properties":{"body":{"type":"string","description":"The comment in Markdown, up to 10,000 characters. A typed name such as @Codex mentions your own clanker for that client."},"mentions":{"type":"array","items":{"type":"string"},"description":"IDs of clankers to mention, a teammate's included."}},"additionalProperties":false,"examples":[{"body":"Can you add a case for an empty query?","mentions":["Ag5HvB1mZr8K"]}]}}},"required":true}}},"/v1/workspaces/{slug}/notifications":{"get":{"tags":["Notifications"],"operationId":"notifications.list","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["notifications"],"properties":{"notifications":{"type":"array","items":{"$ref":"#/components/schemas/Notification"},"description":"Your 100 newest notifications, newest first."}},"additionalProperties":false}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns your notifications in the workspace, read and unread, each with its message. An account API key has none.","summary":"List notifications"}},"/v1/workspaces/{slug}/notifications/read":{"post":{"tags":["Notifications"],"operationId":"notifications.markRead","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["read"],"properties":{"read":{"type":"number","description":"How many unread notifications were marked read."}},"additionalProperties":false,"examples":[{"read":3}]}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Marks every unread notification you have in the workspace as read.","summary":"Mark notifications read"}},"/v1/workspaces/{slug}/test-runs":{"get":{"tags":["Test runs"],"operationId":"testRuns.list","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"product","in":"query","schema":{"type":"string","description":"Only runs of this product, by slug.","examples":["storefront"]},"required":false,"description":"Only runs of this product, by slug."},{"name":"environment","in":"query","schema":{"type":"string","description":"Only runs in this environment, by slug.","examples":["staging"]},"required":false,"description":"Only runs in this environment, by slug."},{"name":"result","in":"query","schema":{"type":"string","enum":["passed","failed","flaky"],"description":"Only runs that `passed` or `failed`, or `flaky` for runs with at least one flaky test."},"required":false,"description":"Only runs that `passed` or `failed`, or `flaky` for runs with at least one flaky test."},{"name":"q","in":"query","schema":{"type":"string","description":"Matches part of the branch or the commit subject, or the start of a commit SHA.","examples":["docs-search"]},"required":false,"description":"Matches part of the branch or the commit subject, or the start of a commit SHA."},{"name":"commit","in":"query","schema":{"type":"string","description":"Only runs of this full commit SHA.","examples":["9f2c41e7b8a3d5c6f1e0b2a4d6c8e0f1a3b5c7d9"]},"required":false,"description":"Only runs of this full commit SHA."},{"name":"mine","in":"query","schema":{"type":"string","enum":["true"],"description":"`true` for only the runs you published."},"required":false,"description":"`true` for only the runs you published."},{"name":"cursor","in":"query","schema":{"type":"string","description":"The `nextCursor` of the previous page.","examples":["1240"]},"required":false,"description":"The `nextCursor` of the previous page."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["runs","nextCursor"],"properties":{"runs":{"type":"array","items":{"$ref":"#/components/schemas/TestRunSummary"},"description":"Up to 50 runs, newest first."},"nextCursor":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"The `cursor` for the next page, or null on the last page."}},"additionalProperties":false}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns the workspace's runs, newest first, 50 per page. Send the response's `nextCursor` as `cursor` for the next page.","summary":"List test runs"},"post":{"tags":["Test runs"],"operationId":"testRuns.start","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["number","url","shard","fixture","semaphores"],"properties":{"number":{"type":"number","description":"The run's number in the workspace. Later calls name the run by it."},"url":{"type":"string","description":"The run's page on the website."},"shard":{"type":"object","required":["index","count"],"properties":{"index":{"type":"number","description":"This shard's index."},"count":{"type":"number","description":"How many shards the run has."}},"additionalProperties":false,"description":"The shard this machine started; 1 of 1 without one."},"fixture":{"anyOf":[{"$ref":"#/components/schemas/FixtureGrant"},{"type":"null"}],"description":"The shard's scope and fixture token, or null when the deployment has no Fixture API."},"semaphores":{"$ref":"#/components/schemas/SemaphoreGrant"}},"additionalProperties":false,"examples":[{"number":1289,"url":"https://clankership.com/w/acme/test-runs/1289","shard":{"index":2,"count":4},"fixture":{"scope":"scp_7h2k9q2m4x1a","token":"eyJhbGciOiJFZERTQSIsImtpZCI6ImZ4XzEifQ.eyJzY29wZSI6InNjcF83aDJrOXEybTR4MWEifQ.c2lnbmF0dXJl","url":"https://staging.acme.dev/fixtures","expiresAt":"2026-10-14T15:40:00.000Z"},"semaphores":{"url":"https://api.clankership.com/v1/workspaces/Wk7Qm2RtXa9L/semaphores","token":"eyJhbGciOiJFZERTQSIsImtpZCI6ImZ4XzEifQ.eyJraW5kIjoicnVuIiwicnVuIjoxMjg5fQ.c2lnbmF0dXJl","expiresAt":"2026-10-14T15:40:00.000Z"}}]}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Starts a shard of a `running` run of a product's deployment in an environment and records the deployment's URL and version. Without `shard` it starts a new run of one shard. With `shard`, the first request with its key starts a run of `count` shards and later ones join it; a shard that already started, another count or commit, another publisher or a run that is no longer running fails the request. When the deployment has a Fixture API, each shard gets a scope of its own and a fixture token to create its test data with. While it runs, its publisher uploads each file as the raw body of `PUT /v1/workspaces/{slug}/test-runs/{run}/files/{path}`, with `Content-Length` and at most 100 MB, deletes the scope, then finishes the shard. Viewers cannot publish runs, and an archived product or environment or a missing deployment fails the request.","summary":"Start a test run","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["product","environment","baseUrl","git","machine","selection"],"properties":{"product":{"type":"string","description":"The product to test, by slug, such as storefront."},"environment":{"type":"string","description":"The environment it is deployed to, by slug, such as staging."},"baseUrl":{"type":"string","description":"The URL the tests run against, usually the deployment's `baseUrl`."},"fixtureUrl":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Use this Fixture API instead of the deployment's, such as a local server on another port. The fixture token is only valid there."},"git":{"type":"object","required":["branch","sha","dirty","subject"],"properties":{"branch":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The checked-out branch, or null."},"sha":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The full commit SHA, or null outside a git checkout."},"dirty":{"type":"boolean","description":"Whether the checkout had uncommitted changes."},"subject":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The commit's subject line, or null."}},"additionalProperties":false,"description":"The commit being tested."},"machine":{"type":"object","required":["hostname","platform"],"properties":{"hostname":{"type":"string","description":"The computer's hostname, such as maya-mbp."},"platform":{"type":"string","description":"The operating system as Node.js names it, such as darwin, linux or win32."}},"additionalProperties":false,"description":"The computer running the tests."},"selection":{"type":"object","required":["coverage","folders","caseIds"],"properties":{"coverage":{"anyOf":[{"type":"string","enum":["critical","acceptance","regression","exhaustive"]},{"type":"null"}],"description":"The coverage level selected, or null for none."},"folders":{"type":"array","items":{"type":"string"},"description":"The spec folders the run is limited to, or empty for all."},"caseIds":{"type":"array","items":{"type":"string"},"description":"The case IDs the run is limited to, or empty for all."}},"additionalProperties":false,"description":"Which tests the run selects."},"shard":{"anyOf":[{"type":"object","required":["index","count","key"],"properties":{"index":{"type":"number","description":"This machine's shard, from 1 to `count`, as in `--shard 2/4`."},"count":{"type":"number","description":"How many shards the run has, 1 to 32. Every shard sends the same count."},"key":{"type":"string","description":"The run key every shard of the run sends, such as github-3905-1: 1 to 100 letters, digits, dots, underscores and hyphens, unique per product and environment."}},"additionalProperties":false},{"type":"null"}],"description":"This machine's share of a run split across machines. The first shard with a key starts the run; the others join it. Omit it for a run of one shard."}},"additionalProperties":false,"examples":[{"product":"storefront","environment":"staging","baseUrl":"https://staging.acme.dev","git":{"branch":"web-31-docs-search","sha":"9f2c41e7b8a3d5c6f1e0b2a4d6c8e0f1a3b5c7d9","dirty":false,"subject":"Add docs search"},"machine":{"hostname":"maya-mbp","platform":"darwin"},"selection":{"coverage":null,"folders":[],"caseIds":[]},"shard":{"index":2,"count":4,"key":"github-3905-1"}}]}}},"required":true}}},"/v1/workspaces/{slug}/test-runs/{run}":{"get":{"tags":["Test runs"],"operationId":"testRuns.get","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"run","in":"path","schema":{"type":"integer","description":"The run's number in the workspace, such as 1289.","examples":[1289]},"required":true,"description":"The run's number in the workspace, such as 1289."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A test run with its shards, its retries and every test with its attempts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestRun"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns one run with its shards, its retries and every test with its attempts. Download a stored file with `GET /v1/workspaces/{slug}/test-runs/{run}/files/{path}`, which accepts a `Range` header.","summary":"Get a test run"}},"/v1/workspaces/{slug}/test-runs/{run}/shards/{shard}/finish":{"post":{"tags":["Test runs"],"operationId":"testRuns.finishShard","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"run","in":"path","schema":{"type":"integer","description":"The run's number in the workspace, such as 1289.","examples":[1289]},"required":true,"description":"The run's number in the workspace, such as 1289."},{"name":"shard","in":"path","schema":{"type":"integer","description":"The shard's index in the run, such as 2; 1 for a run started without a shard.","examples":[1]},"required":true,"description":"The shard's index in the run, such as 2; 1 for a run started without a shard."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A test run without its retries and tests: what it tested, its state, result and counts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestRunSummary"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Records the shard's tests with their first attempts and closes the shard. The last shard to finish closes the run: it counts every shard's tests and ends the run `finished`, or `interrupted` when any shard was. Until then the run stays `running` and `finishedShards` counts up. Only the run's publisher can finish a shard, and only while it is running. A finished run with no tests gets the error `No tests ran.` and fails.","summary":"Finish a shard","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["interrupted","durationMs","tests"],"properties":{"interrupted":{"type":"boolean","description":"Whether the shard stopped early, such as on Ctrl-C. Its tests count, and the run ends `interrupted` with no result."},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"What Playwright reported outside the tests, such as a web server that did not start. It fails the run. Ignored when `interrupted` is true."},"durationMs":{"type":"number","description":"How long the shard took, in milliseconds."},"cleanup":{"anyOf":[{"$ref":"#/components/schemas/TestRunCleanupReport"},{"type":"null"}],"description":"What deleting the shard's scope reported. Required for a shard with a scope; a scope with no report counts as incomplete."},"tests":{"type":"array","items":{"type":"object","required":["caseId","title","file","coverage","testKind","priority","files","attempt"],"properties":{"caseId":{"type":"string","description":"The case ID: the spec's `@id` tag, or one derived from its file and title, such as checkout-applies-coupon."},"title":{"type":"string","description":"The test's title path as Playwright reports it, such as checkout › applies a coupon."},"file":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The spec file the test is in, such as checkout.spec.ts, or null."},"coverage":{"anyOf":[{"type":"string","enum":["critical","acceptance","regression","exhaustive"]},{"type":"null"}],"description":"The case's coverage level, or null when it has none."},"testKind":{"anyOf":[{"type":"string","enum":["behavior","journey"]},{"type":"null"}],"description":"Whether the case is a `behavior` or a `journey`, or null."},"priority":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The case's priority, such as P1, or null."},"files":{"type":"array","items":{"type":"string"},"description":"The case files uploaded to `results/{case}/`: case.md, spec.ts or both."},"attempt":{"type":"object","required":["status","durationMs","startedAt","errorMessage","errorStack","files"],"properties":{"status":{"type":"string","enum":["passed","failed","timed_out","interrupted","skipped"],"description":"How the attempt ended, as Playwright reported it."},"durationMs":{"type":"number","description":"How long the attempt took, in whole milliseconds."},"startedAt":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"When the attempt started, as an ISO 8601 timestamp, or null."},"errorMessage":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The error Playwright reported, or null. Only the first 4,000 characters are kept."},"errorStack":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The error's stack trace, or null. Only the first 20,000 characters are kept."},"files":{"type":"array","items":{"type":"string"},"description":"The evidence uploaded to `results/{case}/attempts/{n}/`: video.webm, trace.zip and screenshot-{k}.png."}},"additionalProperties":false,"description":"The test's attempt 1."}},"additionalProperties":false},"description":"Every test the shard ran, each with a `caseId` no other shard of the run reported. A run holds up to 5,000 tests."}},"additionalProperties":false,"examples":[{"interrupted":false,"error":null,"durationMs":151230,"cleanup":{"status":"complete","deleted":214,"remaining":0,"error":null},"tests":[{"caseId":"checkout-applies-coupon","title":"checkout › applies a coupon","file":"checkout.spec.ts","coverage":"critical","testKind":"behavior","priority":null,"files":["case.md","spec.ts"],"attempt":{"status":"failed","durationMs":30412,"startedAt":"2026-10-14T09:40:12.000Z","errorMessage":"Timed out 5000ms waiting for expect(locator).toHaveText(\"$45.00\")","errorStack":"Error: Timed out 5000ms waiting for expect(locator).toHaveText(\"$45.00\")\n    at checkout.spec.ts:24:41","files":["video.webm","trace.zip","screenshot-1.png"]}},{"caseId":"docs-search-finds-guides","title":"docs › search finds guides","file":"docs.spec.ts","coverage":"acceptance","testKind":"journey","priority":null,"files":["case.md","spec.ts"],"attempt":{"status":"passed","durationMs":6820,"startedAt":"2026-10-14T09:40:12.000Z","errorMessage":null,"errorStack":null,"files":[]}}]}]}}},"required":true}}},"/v1/workspaces/{slug}/test-runs/{run}/retries":{"post":{"tags":["Test runs"],"operationId":"testRuns.retry","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"run","in":"path","schema":{"type":"integer","description":"The run's number in the workspace, such as 1289.","examples":[1289]},"required":true,"description":"The run's number in the workspace, such as 1289."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["retry","requiredPasses","baseUrl","tests","environment","fixture","semaphores"],"properties":{"retry":{"type":"number","description":"The retry's number within the run."},"requiredPasses":{"type":"number","description":"How many passing attempts a failed test needs to count as flaky."},"baseUrl":{"type":"string","description":"The URL to test."},"tests":{"type":"array","items":{"type":"object","required":["caseId","title","file","nextAttempt"],"properties":{"caseId":{"type":"string","description":"The case ID: the spec's `@id` tag, or one derived from its file and title, such as checkout-applies-coupon."},"title":{"type":"string","description":"The test's title path as Playwright reports it, such as checkout › applies a coupon."},"file":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The spec file the test is in, such as checkout.spec.ts, or null."},"nextAttempt":{"type":"number","description":"The number of the test's first attempt in this retry. Upload each attempt's files under its number."}},"additionalProperties":false},"description":"The run's failed tests, to run again."},"environment":{"type":"object","required":["slug","class"],"properties":{"slug":{"type":"string","description":"The environment's slug, such as staging."},"class":{"type":"string","enum":["production","non-production"],"description":"Whether the environment is production."}},"additionalProperties":false,"description":"The environment the run tested."},"fixture":{"anyOf":[{"$ref":"#/components/schemas/FixtureGrant"},{"type":"null"}],"description":"A new scope and fixture token for the retry, or null when the run had no Fixture API."},"semaphores":{"$ref":"#/components/schemas/SemaphoreGrant"}},"additionalProperties":false,"examples":[{"retry":1,"requiredPasses":2,"baseUrl":"https://staging.acme.dev","tests":[{"caseId":"checkout-applies-coupon","title":"checkout › applies a coupon","file":"checkout.spec.ts","nextAttempt":2}],"environment":{"slug":"staging","class":"non-production"},"fixture":{"scope":"scp_7h2k9q2m4x1a","token":"eyJhbGciOiJFZERTQSIsImtpZCI6ImZ4XzEifQ.eyJzY29wZSI6InNjcF83aDJrOXEybTR4MWEifQ.c2lnbmF0dXJl","url":"https://staging.acme.dev/fixtures","expiresAt":"2026-10-14T15:40:00.000Z"},"semaphores":{"url":"https://api.clankership.com/v1/workspaces/Wk7Qm2RtXa9L/semaphores","token":"eyJhbGciOiJFZERTQSIsImtpZCI6ImZ4XzEifQ.eyJraW5kIjoicnVuIiwicnVuIjoxMjg5fQ.c2lnbmF0dXJl","expiresAt":"2026-10-14T15:40:00.000Z"}}]}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Starts a retry of a finished run's failed tests and returns them with the URL to test. The run must have no error, `git.sha` must match its commit and only one retry runs at a time, or the request fails with Conflict; viewers cannot retry runs. Its publisher uploads the retry's files like the run's, then finishes the retry.","summary":"Start a retry","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["passes","baseUrl","git","machine"],"properties":{"passes":{"type":"number","description":"How many passing attempts a failed test needs to count as flaky, 1 to 5."},"baseUrl":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The URL to test instead of the run's, or null for the run's."},"fixtureUrl":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Use this Fixture API instead of the deployment's, such as a local server on another port. The fixture token is only valid there."},"git":{"type":"object","required":["branch","sha","dirty","subject"],"properties":{"branch":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The checked-out branch, or null."},"sha":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The full commit SHA, or null outside a git checkout."},"dirty":{"type":"boolean","description":"Whether the checkout had uncommitted changes."},"subject":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The commit's subject line, or null."}},"additionalProperties":false,"description":"The commit being tested. `sha` must be the commit the run tested."},"machine":{"type":"object","required":["hostname","platform"],"properties":{"hostname":{"type":"string","description":"The computer's hostname, such as maya-mbp."},"platform":{"type":"string","description":"The operating system as Node.js names it, such as darwin, linux or win32."}},"additionalProperties":false,"description":"The computer running the tests."}},"additionalProperties":false,"examples":[{"passes":2,"baseUrl":null,"git":{"branch":"web-31-docs-search","sha":"9f2c41e7b8a3d5c6f1e0b2a4d6c8e0f1a3b5c7d9","dirty":false,"subject":"Add docs search"},"machine":{"hostname":"maya-mbp","platform":"darwin"}}]}}},"required":true}}},"/v1/workspaces/{slug}/test-runs/{run}/retries/{retry}/finish":{"post":{"tags":["Test runs"],"operationId":"testRuns.finishRetry","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"run","in":"path","schema":{"type":"integer","description":"The run's number in the workspace, such as 1289.","examples":[1289]},"required":true,"description":"The run's number in the workspace, such as 1289."},{"name":"retry","in":"path","schema":{"type":"integer","description":"The retry's number within the run, such as 1.","examples":[1]},"required":true,"description":"The retry's number within the run, such as 1."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A test run without its retries and tests: what it tested, its state, result and counts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestRunSummary"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Adds the retry's attempts to the run and recounts it. A failed test that ran at least `requiredPasses` times and passed every time becomes `flaky`. Only the retry's publisher can finish it, and only while it is running.","summary":"Finish a retry","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["interrupted","tests"],"properties":{"interrupted":{"type":"boolean","description":"Whether the retry stopped early. The attempts sent still count."},"cleanup":{"anyOf":[{"$ref":"#/components/schemas/TestRunCleanupReport"},{"type":"null"}],"description":"What deleting the retry's scope reported. Required for a retry with a scope."},"tests":{"type":"array","items":{"type":"object","required":["caseId","attempts"],"properties":{"caseId":{"type":"string","description":"The case ID of one of the run's failed tests."},"attempts":{"type":"array","items":{"type":"object","required":["status","durationMs","startedAt","errorMessage","errorStack","files"],"properties":{"status":{"type":"string","enum":["passed","failed","timed_out","interrupted","skipped"],"description":"How the attempt ended, as Playwright reported it."},"durationMs":{"type":"number","description":"How long the attempt took, in whole milliseconds."},"startedAt":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"When the attempt started, as an ISO 8601 timestamp, or null."},"errorMessage":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The error Playwright reported, or null. Only the first 4,000 characters are kept."},"errorStack":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The error's stack trace, or null. Only the first 20,000 characters are kept."},"files":{"type":"array","items":{"type":"string"},"description":"The evidence uploaded to `results/{case}/attempts/{n}/`: video.webm, trace.zip and screenshot-{k}.png."}},"additionalProperties":false},"description":"This retry's attempts of the test, in order. They are numbered from the test's `nextAttempt`."}},"additionalProperties":false},"description":"The tests this retry ran."}},"additionalProperties":false,"examples":[{"interrupted":false,"cleanup":{"status":"complete","deleted":12,"remaining":0,"error":null},"tests":[{"caseId":"checkout-applies-coupon","attempts":[{"status":"passed","durationMs":4210,"startedAt":"2026-10-14T09:44:07.000Z","errorMessage":null,"errorStack":null,"files":[]},{"status":"passed","durationMs":4105,"startedAt":"2026-10-14T09:44:13.000Z","errorMessage":null,"errorStack":null,"files":[]}]}]}]}}},"required":true}}},"/v1/workspaces/{slug}/semaphores":{"get":{"tags":["Semaphores"],"operationId":"semaphores.list","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["semaphores"],"properties":{"semaphores":{"type":"array","items":{"$ref":"#/components/schemas/Semaphore"},"description":"Every semaphore in the workspace, by name."}},"additionalProperties":false}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns each semaphore with its capacity and the leases held now.","summary":"List semaphores"}},"/v1/workspaces/{slug}/deployments/{product}/{environment}/fixture-tokens":{"post":{"tags":["Fixture tokens"],"operationId":"fixtureTokens.create","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"product","in":"path","schema":{"type":"string","description":"The product's slug, such as storefront.","examples":["storefront"]},"required":true,"description":"The product's slug, such as storefront."},{"name":"environment","in":"path","schema":{"type":"string","description":"The environment's slug, such as staging.","examples":["staging"]},"required":true,"description":"The environment's slug, such as staging."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"201":{"description":"A scope and the fixture token that lets a test run create and delete data in it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FixtureGrant"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns a new scope and fixture token for a deployment's Fixture API without starting a run, for unpublished runs and conformance checks. Viewers cannot create one, and a deployment without a Fixture API fails the request unless `fixtureUrl` names one.","summary":"Create a fixture token","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":[],"properties":{"lifetimeSeconds":{"type":"number","description":"How long the token and scope last, in whole seconds, from 5 to 21600 (six hours, the default)."},"fixtureUrl":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Use this Fixture API instead of the deployment's, such as a local server on another port. The fixture token is only valid there."}},"additionalProperties":false,"examples":[{"lifetimeSeconds":600}]}}},"required":true}}},"/v1/workspaces/{slug}/vault":{"get":{"tags":["Secrets"],"operationId":"secrets.listAll","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Every active product in the workspace.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/VaultProduct"},"description":"Every active product in the workspace."}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns each active product with the environments it is deployed to and each secret's current version there. Non-production values are included; production values never are.","summary":"List every product's secrets"}},"/v1/workspaces/{slug}/products/{productSlug}/secrets":{"get":{"tags":["Secrets"],"operationId":"secrets.list","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"productSlug","in":"path","schema":{"type":"string","description":"The product's slug, such as storefront.","examples":["storefront"]},"required":true,"description":"The product's slug, such as storefront."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"The product's secrets.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SecretSummary"},"description":"The product's secrets."}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns the product's secrets with their current version in each environment the product is deployed to. Non-production values are included; production values never are. Fails with NotFound when the product does not exist or is archived.","summary":"List a product's secrets"},"post":{"tags":["Secrets"],"operationId":"secrets.create","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"productSlug","in":"path","schema":{"type":"string","description":"The product's slug, such as storefront.","examples":["storefront"]},"required":true,"description":"The product's slug, such as storefront."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"One result per product and environment, sorted by product and then environment slug.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SecretWrite"},"description":"One result per product and environment, sorted by product and then environment slug."}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Adds a secret name to the product and sets any `values` sent, returning one result per value. Viewers cannot create secrets, a member's production values come back `skipped`, and a name already on the product fails with Conflict.","summary":"Create a secret","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","description":"Letters, digits and underscores, starting with a letter or underscore, at most 255 characters and unique on the product, such as DATABASE_URL."},"values":{"type":"object","required":[],"properties":{},"additionalProperties":{"anyOf":[{"type":"string"},{"type":"null"}]},"description":"First values keyed by environment slug, each at most 64 KiB. The product must be deployed to each environment. `null` or an empty string records it as unset."},"requestId":{"type":"string","description":"Your own ID for this request, up to 100 characters, stored with each first value. Unlike other secret writes, a retry fails with Conflict once the first attempt has created the name.","minLength":1,"maxLength":100}},"additionalProperties":false,"examples":[{"name":"DATABASE_URL","values":{"staging":"postgres://storefront@db.staging.acme.dev:5432/storefront"},"requestId":"5b0e8f3a-2c41-4d9e-9a7b-61f2c3d4e5a6"}]}}},"required":true}}},"/v1/workspaces/{slug}/products/{productSlug}/secrets/{name}":{"get":{"tags":["Secrets"],"operationId":"secrets.get","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"productSlug","in":"path","schema":{"type":"string","description":"The product's slug, such as storefront.","examples":["storefront"]},"required":true,"description":"The product's slug, such as storefront."},{"name":"name","in":"path","schema":{"type":"string","description":"The secret's name, such as DATABASE_URL.","examples":["DATABASE_URL"]},"required":true,"description":"The secret's name, such as DATABASE_URL."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A named value on a product with one version history per environment. Production values never appear.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Secret"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns the secret with its product, the environments the product is deployed to, and the current version in each. The plaintext value appears only for non-production environments. Fails with Conflict while the product is archived.","summary":"Get a secret"},"patch":{"tags":["Secrets"],"operationId":"secrets.update","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"productSlug","in":"path","schema":{"type":"string","description":"The product's slug, such as storefront.","examples":["storefront"]},"required":true,"description":"The product's slug, such as storefront."},{"name":"name","in":"path","schema":{"type":"string","description":"The secret's name, such as DATABASE_URL.","examples":["DATABASE_URL"]},"required":true,"description":"The secret's name, such as DATABASE_URL."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"One result per product and environment, sorted by product and then environment slug.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SecretWrite"},"description":"One result per product and environment, sorted by product and then environment slug."}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Renames the secret, sets or clears values, or both, in one transaction, and returns one result per value sent. Viewers cannot update secrets, and a member's production values come back `skipped`. A taken name, a stale `expectedVersions` entry or a `requestId` already used for a different write fails with Conflict, and nothing is saved.","summary":"Update a secret","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":[],"properties":{"newName":{"type":"string","description":"A new name for the secret, unique on the product."},"values":{"type":"object","required":[],"properties":{},"additionalProperties":{"anyOf":[{"type":"string"},{"type":"null"}]},"description":"New values keyed by environment slug, each at most 64 KiB. `null` or an empty string clears a value, and environments left out keep theirs."},"expectedVersions":{"type":"object","required":[],"properties":{},"additionalProperties":{"type":"integer","description":"a non-negative number","minimum":0},"description":"The version you last saw in each environment you are changing, keyed by environment slug, with 0 for one that has no version. If any has changed since, nothing is saved and the request fails with Conflict."},"requestId":{"type":"string","description":"Your own ID for this request, up to 100 characters. Sending the same ID again returns the first result instead of writing twice.","minLength":1,"maxLength":100}},"additionalProperties":false,"examples":[{"values":{"staging":"postgres://storefront@db-2.staging.acme.dev:5432/storefront"},"expectedVersions":{"staging":3},"requestId":"5b0e8f3a-2c41-4d9e-9a7b-61f2c3d4e5a6"}]}}},"required":true}},"delete":{"tags":["Secrets"],"operationId":"secrets.delete","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"productSlug","in":"path","schema":{"type":"string","description":"The product's slug, such as storefront.","examples":["storefront"]},"required":true,"description":"The product's slug, such as storefront."},{"name":"name","in":"path","schema":{"type":"string","description":"The secret's name, such as DATABASE_URL.","examples":["DATABASE_URL"]},"required":true,"description":"The secret's name, such as DATABASE_URL."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"type":"boolean","enum":[true],"description":"Always true: the change was made."}},"additionalProperties":false}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Deletes the secret and every version of it in every environment. Viewers cannot delete secrets, and only admins and owners can delete one that has a production value.","summary":"Delete a secret"}},"/v1/workspaces/{slug}/vault/assignments":{"post":{"tags":["Secrets"],"operationId":"secrets.assign","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"One result per product and environment, sorted by product and then environment slug.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SecretWrite"},"description":"One result per product and environment, sorted by product and then environment slug."}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Writes one value to every product and environment pair, up to 200 pairs, in one transaction, and creates the secret name on any product that lacks it. Every pair must be a deployment whose product and environment are active. Viewers cannot assign values, and a member's production pairs come back `skipped`.","summary":"Set a secret across products and environments","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["products","environments","name","value"],"properties":{"products":{"type":"array","items":{"type":"string"},"description":"Slugs of the products to write, such as storefront."},"environments":{"type":"array","items":{"type":"string"},"description":"Slugs of the environments to write, such as staging. Each product must be deployed to each of them."},"name":{"type":"string","description":"Letters, digits and underscores, starting with a letter or underscore, at most 255 characters and unique on the product, such as DATABASE_URL."},"value":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The value to set, at most 64 KiB. `null` or an empty string clears it."},"requestId":{"type":"string","description":"Your own ID for this request, up to 100 characters. Sending the same ID again returns the first result instead of writing twice.","minLength":1,"maxLength":100}},"additionalProperties":false,"examples":[{"products":["storefront"],"environments":["staging"],"name":"LOG_LEVEL","value":"debug","requestId":"5b0e8f3a-2c41-4d9e-9a7b-61f2c3d4e5a6"}]}}},"required":true}}},"/v1/workspaces/{slug}/vault/generations":{"post":{"tags":["Secrets"],"operationId":"secrets.generate","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"One result per product and environment, sorted by product and then environment slug.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SecretWrite"},"description":"One result per product and environment, sorted by product and then environment slug."}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Generates one value per environment on the server and writes it to every selected product there, so products share a value within an environment and no value crosses environments. Targets, limits and roles work as when setting a secret across products. Values come back only with `reveal: true`, and a retry with the same `requestId` returns the first versions without values.","summary":"Generate a secret value","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["products","environments","name","generator"],"properties":{"products":{"type":"array","items":{"type":"string"},"description":"Slugs of the products to write, such as storefront."},"environments":{"type":"array","items":{"type":"string"},"description":"Slugs of the environments to write, such as staging. Each product must be deployed to each of them."},"name":{"type":"string","description":"Letters, digits and underscores, starting with a letter or underscore, at most 255 characters and unique on the product, such as DATABASE_URL."},"generator":{"anyOf":[{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["token"],"description":"Random bytes."},"bytes":{"type":"integer","description":"How many random bytes, from 16 to 512. Defaults to 32.","minimum":16,"maximum":512},"encoding":{"type":"string","enum":["hex","base64","base64url"],"description":"How to write the bytes as text: hex (the default), base64 or base64url."}},"additionalProperties":false,"description":"A random token."},{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["password"],"description":"A random password."},"length":{"type":"integer","description":"How many characters, from 8 to 256. Defaults to 32.","minimum":8,"maximum":256},"lowercase":{"type":"boolean","description":"Whether to use a to z. Defaults to true; leave at least one class on."},"uppercase":{"type":"boolean","description":"Whether to use A to Z. Defaults to true; leave at least one class on."},"digits":{"type":"boolean","description":"Whether to use 0 to 9. Defaults to true; leave at least one class on."},"symbols":{"type":"boolean","description":"Whether to use the symbols -_.~+=, which need no quoting in shells or URLs. Defaults to true; leave at least one class on."}},"additionalProperties":false,"description":"A random password with at least one character from each class it uses."},{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["uuid"],"description":"A random version 4 UUID."}},"additionalProperties":false,"description":"A random version 4 UUID."},{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["ed25519"],"description":"An Ed25519 key pair: the value is the PKCS#8 PEM private key and the result's `publicKey` the SPKI PEM public key."}},"additionalProperties":false,"description":"An Ed25519 key pair."}],"description":"What to generate. Options left out use their defaults."},"reveal":{"type":"boolean","description":"Return each generated value in this response. Defaults to false."},"requestId":{"type":"string","description":"Your own ID for this request, up to 100 characters. Sending the same ID again returns the first result instead of writing twice.","minLength":1,"maxLength":100}},"additionalProperties":false,"examples":[{"products":["storefront"],"environments":["staging","production"],"name":"SESSION_SECRET","generator":{"type":"token","bytes":32},"requestId":"5b0e8f3a-2c41-4d9e-9a7b-61f2c3d4e5a6"}]}}},"required":true}}},"/v1/workspaces/{slug}/products/{productSlug}/secrets/{name}/environments/{environmentSlug}/versions":{"get":{"tags":["Secrets"],"operationId":"secrets.listVersions","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"productSlug","in":"path","schema":{"type":"string","description":"The product's slug, such as storefront.","examples":["storefront"]},"required":true,"description":"The product's slug, such as storefront."},{"name":"name","in":"path","schema":{"type":"string","description":"The secret's name, such as DATABASE_URL.","examples":["DATABASE_URL"]},"required":true,"description":"The secret's name, such as DATABASE_URL."},{"name":"environmentSlug","in":"path","schema":{"type":"string","description":"The environment's slug, such as staging.","examples":["staging"]},"required":true,"description":"The environment's slug, such as staging."},{"name":"values","in":"query","schema":{"type":"string","enum":["true","false"],"description":"`true` adds each version's plaintext value. Production environments refuse it."},"required":false,"description":"`true` adds each version's plaintext value. Production environments refuse it."},{"name":"before","in":"query","schema":{"type":"string","description":"Return only versions older than this version number, to fetch the next page.","examples":["3"]},"required":false,"description":"Return only versions older than this version number, to fetch the next page."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Up to 100 versions, newest first.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SecretVersion"},"description":"Up to 100 versions, newest first."}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns up to 100 versions of the secret in one environment, newest first, with who wrote each. Send the oldest `version` you have as `before` to get the next page. `values=true` fails with Forbidden for a production environment.","summary":"List a secret's versions"}},"/v1/workspaces/{slug}/products/{productSlug}/secrets/{name}/environments/{environmentSlug}/restore":{"post":{"tags":["Secrets"],"operationId":"secrets.restoreVersion","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"productSlug","in":"path","schema":{"type":"string","description":"The product's slug, such as storefront.","examples":["storefront"]},"required":true,"description":"The product's slug, such as storefront."},{"name":"name","in":"path","schema":{"type":"string","description":"The secret's name, such as DATABASE_URL.","examples":["DATABASE_URL"]},"required":true,"description":"The secret's name, such as DATABASE_URL."},{"name":"environmentSlug","in":"path","schema":{"type":"string","description":"The environment's slug, such as staging.","examples":["staging"]},"required":true,"description":"The environment's slug, such as staging."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"One result per product and environment, sorted by product and then environment slug.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SecretWrite"},"description":"One result per product and environment, sorted by product and then environment slug."}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Writes a new version with an earlier version's value, generator and public key, and records which version it restored. Restoring a version that cleared the value clears it again. Viewers cannot restore, and members cannot restore production versions.","summary":"Restore a secret version","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["version"],"properties":{"version":{"type":"integer","description":"The version to restore.","exclusiveMinimum":0},"requestId":{"type":"string","description":"Your own ID for this request, up to 100 characters. Sending the same ID again returns the first result instead of writing twice.","minLength":1,"maxLength":100}},"additionalProperties":false,"examples":[{"version":2,"requestId":"5b0e8f3a-2c41-4d9e-9a7b-61f2c3d4e5a6"}]}}},"required":true}}},"/v1/workspaces/{slug}/products/{productSlug}/environments/{environmentSlug}/secrets/pull":{"get":{"tags":["Secrets"],"operationId":"secrets.pull","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"productSlug","in":"path","schema":{"type":"string","description":"The product's slug, such as storefront.","examples":["storefront"]},"required":true,"description":"The product's slug, such as storefront."},{"name":"environmentSlug","in":"path","schema":{"type":"string","description":"The environment's slug, such as staging.","examples":["staging"]},"required":true,"description":"The environment's slug, such as staging."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Each set secret's current value, keyed by secret name. Unset secrets are left out.","content":{"application/json":{"schema":{"type":"object","required":[],"properties":{},"additionalProperties":{"type":"string"},"description":"Each set secret's current value, keyed by secret name. Unset secrets are left out.","examples":[{"DATABASE_URL":"postgres://storefront@db.staging.acme.dev:5432/storefront","LOG_LEVEL":"debug"}]}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns the current value of every set secret for one deployment, keyed by secret name; the product and environment must be active. Production pulls need a vault key (`ctvk_…`) scoped to the product and environment, and every attempt is recorded in the vault audit log. Non-production pulls take a user API key, account API key or CLI login for the workspace and refuse vault keys.","summary":"Pull an environment's secrets"}},"/v1/workspaces/{slug}/vault/keys":{"get":{"tags":["Vault keys"],"operationId":"vaultKeys.list","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"The active vault keys, newest first.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/VaultKey"},"description":"The active vault keys, newest first."}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Returns the workspace's vault keys without their values. Revoked keys are left out.","summary":"List vault keys"},"post":{"tags":["Vault keys"],"operationId":"vaultKeys.create","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"A new vault key with its value, which is never shown again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatedVaultKey"}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Creates a key that can pull production secrets for the chosen products and production environments. The response holds the key's value, which is never shown again. Only admins and owners can create vault keys.","summary":"Create a vault key","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["name","productIds","environmentIds"],"properties":{"name":{"type":"string","description":"A name for the key, 1 to 100 characters, such as Storefront runtime."},"productIds":{"type":"array","items":{"type":"string"},"description":"IDs of active products in the workspace whose secrets the key may pull. At least one."},"environmentIds":{"type":"array","items":{"type":"string"},"description":"IDs of active production environments the key may pull from. At least one."}},"additionalProperties":false,"examples":[{"name":"Storefront runtime","productIds":["Pr4GtY9sLm3B"],"environmentIds":["En1MwX6cTb7F"]}]}}},"required":true}}},"/v1/workspaces/{slug}/vault/keys/{id}":{"patch":{"tags":["Vault keys"],"operationId":"vaultKeys.update","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"id","in":"path","schema":{"type":"string","description":"The vault key's ID, such as Vk8MtR3pLx6N.","examples":["Vk8MtR3pLx6N"]},"required":true,"description":"The vault key's ID, such as Vk8MtR3pLx6N."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"The key's new name and scope.","content":{"application/json":{"schema":{"type":"object","required":["id","name","productIds","environmentIds"],"properties":{"id":{"type":"string","description":"Unique ID of the vault key."},"name":{"type":"string","description":"The key's name."},"productIds":{"type":"array","items":{"type":"string"},"description":"IDs of the products whose secrets the key can pull."},"environmentIds":{"type":"array","items":{"type":"string"},"description":"IDs of the production environments the key can pull from."}},"additionalProperties":false,"description":"The key's new name and scope.","examples":[{"id":"Vk8MtR3pLx6N","name":"Storefront runtime","productIds":["Pr4GtY9sLm3B"],"environmentIds":["En1MwX6cTb7F"]}]}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Replaces the key's name and scope; its value stays the same. Only admins and owners can update vault keys, and a revoked key fails with NotFound.","summary":"Update a vault key","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["name","productIds","environmentIds"],"properties":{"name":{"type":"string","description":"A name for the key, 1 to 100 characters, such as Storefront runtime."},"productIds":{"type":"array","items":{"type":"string"},"description":"IDs of active products in the workspace whose secrets the key may pull. At least one."},"environmentIds":{"type":"array","items":{"type":"string"},"description":"IDs of active production environments the key may pull from. At least one."}},"additionalProperties":false,"examples":[{"name":"Storefront runtime","productIds":["Pr4GtY9sLm3B"],"environmentIds":["En1MwX6cTb7F"]}]}}},"required":true}}},"/v1/workspaces/{slug}/vault/keys/{id}/revoke":{"post":{"tags":["Vault keys"],"operationId":"vaultKeys.revoke","parameters":[{"name":"slug","in":"path","schema":{"type":"string","description":"The workspace's slug or ID, such as acme.","examples":["acme"]},"required":true,"description":"The workspace's slug or ID, such as acme."},{"name":"id","in":"path","schema":{"type":"string","description":"The vault key's ID, such as Vk8MtR3pLx6N.","examples":["Vk8MtR3pLx6N"]},"required":true,"description":"The vault key's ID, such as Vk8MtR3pLx6N."}],"security":[{"apiKey":[]},{"bearer":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"type":"boolean","enum":[true],"description":"Always true: the change was made."}},"additionalProperties":false}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"401":{"description":"The request has no valid API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Unauthorized"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Revokes the key, so its next pull fails with Unauthorized. Only admins and owners can revoke vault keys.","summary":"Revoke a vault key"}},"/":{"get":{"tags":["Health"],"operationId":"system.ping","parameters":[],"security":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","service"],"properties":{"ok":{"type":"boolean","enum":[true],"description":"Always true: the API is up."},"service":{"type":"string","enum":["api"],"description":"The service that answered, always api."}},"additionalProperties":false,"examples":[{"ok":true,"service":"api"}]}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Answers at the API's root while it is up. It needs no API key and touches no data.","summary":"Ping the API"}},"/health":{"get":{"tags":["Health"],"operationId":"system.check","parameters":[],"security":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","service"],"properties":{"ok":{"type":"boolean","enum":[true],"description":"Always true: the API is up."},"service":{"type":"string","enum":["api"],"description":"The service that answered, always api."}},"additionalProperties":false,"examples":[{"ok":true,"service":"api"}]}}}},"400":{"description":"The request is malformed, or a value is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvalidInput"}}}},"403":{"description":"The key's user or role may not do this.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Forbidden"}}}},"404":{"description":"The workspace or object does not exist, or the caller cannot see it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotFound"}}}},"409":{"description":"The change conflicts with current data, such as a slug that is already in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conflict"}}}},"500":{"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Internal"}}}}},"description":"Answers while the API is up, for monitors and load balancers. It needs no API key and touches no data.","summary":"Check the API's health"}}},"components":{"schemas":{"User":{"type":"object","required":["id","name","email","image"],"properties":{"id":{"type":"string","description":"Unique ID of the user, or of the workspace API key that is calling."},"name":{"type":"string","description":"The user's display name, or the workspace API key's name."},"email":{"type":"string","description":"The user's email address; empty for a workspace API key."},"image":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"URL of the user's profile photo, or null. Always null for a workspace API key."},"accountWorkspaceId":{"type":"string","description":"Set when a workspace API key is calling: the workspace the key belongs to."},"accountRole":{"type":"string","enum":["owner","admin","member","viewer"],"description":"Set when a workspace API key is calling: the role the key acts with."}},"additionalProperties":false,"description":"The person, or the workspace API key, the request acts for.","examples":[{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":"https://images.clankership.com/users/Us3NfP8kLq2V/profile-Ph8KcV2nRx4M.webp"}]},"InvalidInput":{"type":"object","required":["message","_tag"],"properties":{"message":{"type":"string","description":"What went wrong, in a sentence a person can act on."},"_tag":{"type":"string","enum":["InvalidInput"]}},"additionalProperties":false,"description":"The request is malformed, or a value is not allowed."},"Unauthorized":{"type":"object","required":["message","_tag"],"properties":{"message":{"type":"string","description":"What went wrong, in a sentence a person can act on."},"_tag":{"type":"string","enum":["Unauthorized"]}},"additionalProperties":false,"description":"The request has no valid API key."},"Forbidden":{"type":"object","required":["message","_tag"],"properties":{"message":{"type":"string","description":"What went wrong, in a sentence a person can act on."},"_tag":{"type":"string","enum":["Forbidden"]}},"additionalProperties":false,"description":"The key's user or role may not do this."},"NotFound":{"type":"object","required":["message","_tag"],"properties":{"message":{"type":"string","description":"What went wrong, in a sentence a person can act on."},"_tag":{"type":"string","enum":["NotFound"]}},"additionalProperties":false,"description":"The workspace or object does not exist, or the caller cannot see it."},"Conflict":{"type":"object","required":["message","_tag"],"properties":{"message":{"type":"string","description":"What went wrong, in a sentence a person can act on."},"_tag":{"type":"string","enum":["Conflict"]}},"additionalProperties":false,"description":"The change conflicts with current data, such as a slug that is already in use."},"Internal":{"type":"object","required":["message","_tag"],"properties":{"message":{"type":"string","description":"What went wrong, in a sentence a person can act on."},"_tag":{"type":"string","enum":["Internal"]}},"additionalProperties":false,"description":"Clanker Ship failed to handle the request. Retry, or report the response's x-request-id."},"NotificationPreferences":{"type":"object","required":["userId","productUpdates","workspaceActivity"],"properties":{"userId":{"type":"string","description":"Your user ID."},"productUpdates":{"type":"boolean","description":"Whether to email you Clanker Ship product updates. Defaults to true."},"workspaceActivity":{"type":"boolean","description":"Whether to email you activity in your workspaces. Defaults to false."}},"additionalProperties":false,"description":"Which emails you want. A user who never saved preferences gets the defaults.","examples":[{"userId":"Us3NfP8kLq2V","productUpdates":true,"workspaceActivity":false}]},"Workspace":{"type":"object","required":["id","name","slug","iconUrl","role"],"properties":{"id":{"type":"string","description":"Unique ID of the workspace."},"name":{"type":"string","description":"The workspace's display name."},"slug":{"type":"string","description":"The workspace's URL name: 2 to 48 lowercase letters, digits and hyphens, such as acme."},"iconUrl":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"URL of the workspace's icon image, or null."},"role":{"type":"string","enum":["owner","admin","member","viewer"],"description":"Your role in the workspace: owner, admin, member or viewer."}},"additionalProperties":false,"description":"A workspace you belong to, with your role in it.","examples":[{"id":"Wk7Qm2RtXa9L","name":"Acme","slug":"acme","iconUrl":"https://images.clankership.com/workspaces/Wk7Qm2RtXa9L/icon-Ic5TfR2mWq8Z.png","role":"owner"}]},"ApiKey":{"type":"object","required":["id","name","tokenPrefix","lastFour","createdAt","lastUsedAt"],"properties":{"id":{"type":"string","description":"Unique ID of the API key."},"name":{"type":"string","description":"The name you gave the key, such as CI deploys."},"tokenPrefix":{"type":"string","description":"The secret's first 8 characters, such as ctk_9fQx, to recognize the key."},"lastFour":{"type":"string","description":"The secret's last 4 characters."},"createdAt":{"type":"string","format":"date-time","description":"When the key was created, as an ISO 8601 timestamp."},"lastUsedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When the key last authenticated a request, as an ISO 8601 timestamp; null if never."}},"additionalProperties":false,"description":"An API key that acts as you. The API shows only its first and last characters, never the full secret.","examples":[{"id":"Ak8TqW3nVr5L","name":"CI deploys","tokenPrefix":"ctk_9fQx","lastFour":"rVwA","createdAt":"2026-10-01T16:20:00.000Z","lastUsedAt":"2026-10-14T09:05:12.000Z"}]},"NewApiKey":{"type":"object","required":["id","name","tokenPrefix","lastFour","secret"],"properties":{"id":{"type":"string","description":"Unique ID of the API key."},"name":{"type":"string","description":"The name you gave the key, such as CI deploys."},"tokenPrefix":{"type":"string","description":"The secret's first 8 characters, such as ctk_9fQx, to recognize the key."},"lastFour":{"type":"string","description":"The secret's last 4 characters."},"secret":{"type":"string","description":"The full key, starting with ctk_. Store it now: the API never returns it again."}},"additionalProperties":false,"description":"An API key you just created, with its secret.","examples":[{"id":"Ak8TqW3nVr5L","name":"CI deploys","tokenPrefix":"ctk_9fQx","lastFour":"rVwA","secret":"ctk_9fQxR2mT7vLp4WnK8sDj3HcB6yZa1EuG5oNi0qXrVwA"}]},"CliSession":{"type":"object","required":["id","createdAt","expiresAt"],"properties":{"id":{"type":"string","description":"Unique ID of the CLI sign-in."},"createdAt":{"type":"string","format":"date-time","description":"When `clanker auth login` signed in, as an ISO 8601 timestamp."},"expiresAt":{"type":"string","format":"date-time","description":"When the sign-in ends unless the CLI is used again, as an ISO 8601 timestamp."}},"additionalProperties":false,"description":"One computer where the `clanker` CLI signed in as you.","examples":[{"id":"Cs8vN1qLm3Zx","createdAt":"2026-10-01T16:20:00.000Z","expiresAt":"2026-10-14T09:05:12.000Z"}]},"WorkspaceAccess":{"type":"object","required":["workspaceId","name","slug","iconUrl","allowedDomains","role","userId"],"properties":{"workspaceId":{"type":"string","description":"Unique ID of the workspace."},"name":{"type":"string","description":"The workspace's display name."},"slug":{"type":"string","description":"The workspace's URL name: 2 to 48 lowercase letters, digits and hyphens, such as acme."},"iconUrl":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"URL of the workspace's icon image, or null."},"allowedDomains":{"type":"array","items":{"type":"string"},"description":"Email domains, such as acme.dev, whose people join the workspace as members automatically. Invites must use one of them. Empty allows any address."},"role":{"type":"string","enum":["owner","admin","member","viewer"],"description":"Your role in the workspace: owner, admin, member or viewer."},"userId":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Your user ID, or null when an account API key is calling."},"accountApiKeyId":{"type":"string","description":"The account API key's ID. Present only when an account API key is calling."}},"additionalProperties":false,"description":"A workspace with its settings, and who is calling: your user ID or account API key and your role.","examples":[{"workspaceId":"Wk7Qm2RtXa9L","name":"Acme","slug":"acme","iconUrl":"https://images.clankership.com/workspaces/Wk7Qm2RtXa9L/icon-Ic5TfR2mWq8Z.png","allowedDomains":["acme.dev"],"role":"owner","userId":"Us3NfP8kLq2V"}]},"SeedWorkspace":{"type":"object","required":["id","name","slug","description","joined"],"properties":{"id":{"type":"string","description":"Unique ID of the seeded workspace."},"name":{"type":"string","description":"The workspace's display name."},"slug":{"type":"string","description":"The workspace's URL name: 2 to 48 lowercase letters, digits and hyphens, such as acme."},"description":{"type":"string","description":"What the seeded workspace is for."},"joined":{"type":"boolean","description":"Whether you are an active member of it."}},"additionalProperties":false,"description":"A workspace the local development seed creates, which any user can join as an owner.","examples":[{"id":"localClanker","name":"Clanker Ship","slug":"clanker-ship","description":"Clanker Ship's own products and environments, with sample teams, projects and tickets.","joined":false}]},"Member":{"type":"object","required":["userId","name","email","image","role","joinedAt","teams"],"properties":{"userId":{"type":"string","description":"The member's user ID."},"name":{"type":"string","description":"The member's display name."},"email":{"type":"string","description":"The member's email address."},"image":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"URL of the member's profile photo, or null."},"role":{"type":"string","enum":["owner","admin","member","viewer"],"description":"Owners and admins manage the workspace and its people, members do the work, and viewers only read."},"joinedAt":{"type":"string","format":"date-time","description":"When the person joined the workspace, as an ISO 8601 timestamp."},"teams":{"type":"array","items":{"type":"string"},"description":"Names of the teams the member is in, sorted alphabetically, such as Web."}},"additionalProperties":false,"description":"A person in the workspace and their role.","examples":[{"userId":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":"https://images.clankership.com/users/Us3NfP8kLq2V/profile-Ph8KcV2nRx4M.webp","role":"owner","joinedAt":"2026-10-01T16:20:00.000Z","teams":["Web"]}]},"InvitePreview":{"type":"object","required":["id","email","role","workspaceId","workspaceName","workspaceSlug","expiresAt","acceptedAt","revokedAt","teams"],"properties":{"id":{"type":"string","description":"Unique ID of the invite."},"email":{"type":"string","description":"The lowercased email address the invite was sent to."},"role":{"type":"string","enum":["owner","admin","member","viewer"],"description":"The role the person gets on accepting: admin, member or viewer."},"workspaceId":{"type":"string","description":"Unique ID of the workspace."},"workspaceName":{"type":"string","description":"The workspace's display name."},"workspaceSlug":{"type":"string","description":"The workspace's slug, such as acme."},"expiresAt":{"type":"string","format":"date-time","description":"When the invite link stops working, as an ISO 8601 timestamp: 7 days after it was sent."},"acceptedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When the invite was accepted, as an ISO 8601 timestamp; null until then."},"revokedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When the invite was revoked, as an ISO 8601 timestamp; null unless revoked."},"teams":{"type":"array","items":{"type":"object","required":["teamId","teamName"],"properties":{"teamId":{"type":"string","description":"Unique ID of the team."},"teamName":{"type":"string","description":"The team's name, such as Web."}},"additionalProperties":false,"description":"A team the person joins on accepting."},"description":"The teams the person joins on accepting."}},"additionalProperties":false,"description":"What an invite link shows before it is accepted: the workspace, the address it was sent to, the role and the teams.","examples":[{"id":"Iv6WqR3nTb8K","email":"lee@acme.dev","role":"member","workspaceId":"Wk7Qm2RtXa9L","workspaceName":"Acme","workspaceSlug":"acme","expiresAt":"2026-10-21T09:05:12.000Z","acceptedAt":null,"revokedAt":null,"teams":[{"teamId":"Tm6PzN3kWq1J","teamName":"Web"}]}]},"Invite":{"type":"object","required":["id","email","role","invitedByUserId","expiresAt","acceptedAt","revokedAt","createdAt","updatedAt","teams"],"properties":{"id":{"type":"string","description":"Unique ID of the invite."},"email":{"type":"string","description":"The lowercased email address the invite was sent to."},"role":{"type":"string","enum":["owner","admin","member","viewer"],"description":"The role the person gets on accepting: admin, member or viewer."},"invitedByUserId":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The user who sent the invite, or null when an account API key sent it."},"expiresAt":{"type":"string","format":"date-time","description":"When the invite link stops working, as an ISO 8601 timestamp: 7 days after it was sent."},"acceptedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When the invite was accepted, as an ISO 8601 timestamp; null until then."},"revokedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When the invite was revoked, as an ISO 8601 timestamp; null unless revoked."},"createdAt":{"type":"string","format":"date-time","description":"When the invite was created, as an ISO 8601 timestamp."},"updatedAt":{"type":"string","format":"date-time","description":"When the invite last changed, as an ISO 8601 timestamp."},"teams":{"type":"array","items":{"type":"object","required":["inviteId","teamId","teamName"],"properties":{"inviteId":{"type":"string","description":"Unique ID of the invite."},"teamId":{"type":"string","description":"Unique ID of the team."},"teamName":{"type":"string","description":"The team's name, such as Web."}},"additionalProperties":false,"description":"A team the person joins on accepting."},"description":"The teams the person joins on accepting."}},"additionalProperties":false,"description":"An invitation for one email address to join the workspace.","examples":[{"id":"Iv6WqR3nTb8K","email":"lee@acme.dev","role":"member","invitedByUserId":"Us3NfP8kLq2V","expiresAt":"2026-10-21T09:05:12.000Z","acceptedAt":null,"revokedAt":null,"createdAt":"2026-10-14T09:05:12.000Z","updatedAt":"2026-10-14T09:05:12.000Z","teams":[{"inviteId":"Iv6WqR3nTb8K","teamId":"Tm6PzN3kWq1J","teamName":"Web"}]}]},"Event":{"type":"object","required":["id","type","subjectType","subjectId","metadata","createdAt","actorUserId","actorAccountKeyId","actorClankerAuthorizationId","actorName","actorEmail","clankerName"],"properties":{"id":{"type":"string","description":"Unique ID of the event."},"type":{"type":"string","enum":["workspace.created","workspace.updated","workspace.icon_updated","member.role_changed","member.removed","member.auto_joined","invite.created","invite.role_changed","invite.resent","invite.revoked","invite.accepted","team.created","team.updated","team.member_added","team.member_removed","team.archived","team.restored","team.deleted","project.created","project.updated","project.archived","project.restored","project.reordered","milestone.created","milestone.updated","milestone.deleted","ticket.created","ticket.updated","ticket.moved","ticket.reordered","ticket.checklist_changed","ticket.checklist_item_checked","ticket.checklist_item_unchecked","ticket.checklist_item_started","ticket.checklist_item_stopped","ticket.document_written","ticket.question_asked","ticket.question_answered","ticket.branch_linked","ticket.branch_unlinked","ticket.pull_request_linked","ticket.pull_request_unlinked","tag.created","tag.updated","tag.deleted","ticket_status.created","ticket_status.updated","ticket_status.deleted","ticket_status.reordered","ticket_status.checklist_changed","ticket_status.instructions_changed","view.created","view.updated","view.deleted","view.reordered","clanker_instructions.updated","clanker_instructions.reset","clanker.registered","clanker.revoked","clanker_message.sent","clanker_message.delivered","clanker_message.completed","ticket.commented","product.created","product.updated","product.archived","product.restored","environment.created","environment.updated","environment.archived","environment.restored","deployment.created","deployment.updated","deployment.removed","profile.updated"],"description":"What happened, as subject.action, such as ticket.created."},"subjectType":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"What the event is about, such as user, invite, workspace or ticket, or null."},"subjectId":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The ID of what the event is about, or null."},"metadata":{"type":"object","additionalProperties":true,"description":"Details recorded with the event, such as the ticket's identifier and title. The fields depend on the type."},"createdAt":{"type":"string","format":"date-time","description":"When it happened, as an ISO 8601 timestamp."},"actorUserId":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The user ID of the person who made the change, or the person a clanker acted for. Null when an account API key made it."},"actorAccountKeyId":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The ID of the account API key that made the change, or null."},"actorClankerAuthorizationId":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The ID of the clanker that made the change for the person, or null."},"actorName":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The name of the person who made the change, or the person a clanker acted for. Null when an account API key made it."},"actorEmail":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"That person's email address, or null."},"clankerName":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The clanker that made the change for the person, such as Codex, or null."}},"additionalProperties":false,"description":"One change in the workspace and who made it.","examples":[{"id":"Ev4NpL7wQs2X","type":"ticket.created","subjectType":"ticket","subjectId":"Tk7BnC5xLp9M","metadata":{"identifier":"WEB-31","title":"Add docs search"},"createdAt":"2026-10-14T09:05:12.000Z","actorUserId":"Us3NfP8kLq2V","actorAccountKeyId":null,"actorClankerAuthorizationId":"Ag5HvB1mZr8K","actorName":"Maya Patel","actorEmail":"maya@acme.dev","clankerName":"Codex"}]},"AccountApiKey":{"type":"object","required":["id","name","role","lastFour","createdAt"],"properties":{"id":{"type":"string","description":"Unique ID of the account API key."},"name":{"type":"string","description":"The key's name, such as Release CI."},"role":{"type":"string","enum":["owner","admin","member","viewer"],"description":"The workspace role the key acts with."},"lastFour":{"type":"string","description":"The key's last four characters, to tell keys apart."},"createdAt":{"type":"string","format":"date-time","description":"When the key was created, as an ISO 8601 timestamp."}},"additionalProperties":false,"description":"A workspace's API key that acts with a role instead of as a person.","examples":[{"id":"Ak2WqH9sDf5T","name":"Release CI","role":"member","lastFour":"cZaE","createdAt":"2026-10-01T16:20:00.000Z"}]},"CreatedAccountApiKey":{"type":"object","required":["id","name","role","secret"],"properties":{"id":{"type":"string","description":"Unique ID of the account API key."},"name":{"type":"string","description":"The key's name."},"role":{"type":"string","enum":["owner","admin","member","viewer"],"description":"The workspace role the key acts with."},"secret":{"type":"string","description":"The key, starting with ctk_. It is shown only in this response."}},"additionalProperties":false,"description":"A new account API key with its value, which is never shown again.","examples":[{"id":"Ak2WqH9sDf5T","name":"Release CI","role":"member","secret":"ctk_4mT8vQ2xR7nL9pW3kS6dH1jF5bY0cZaE"}]},"PinList":{"type":"object","required":["pins"],"properties":{"pins":{"type":"array","items":{"$ref":"#/components/schemas/Pin"},"description":"The caller's pins in their order. Pins of archived entities, and of ones the caller no longer sees, are left out."}},"additionalProperties":false,"description":"The caller's pins in their order.","examples":[{"pins":[{"id":"Pn3HdT6wQa8K","kind":"project","key":"docs-launch","name":"Docs launch"},{"id":"Pn5MvB2xRc7L","kind":"ticket","key":"WEB-31","name":"Add docs search"}]}]},"Pin":{"type":"object","required":["id","kind","key","name"],"properties":{"id":{"type":"string","description":"Unique ID of the pin."},"kind":{"type":"string","enum":["ticket","project","product","environment","team"],"description":"What the pin points at: ticket, project, product, environment or team."},"key":{"type":"string","description":"The key its pages use: a ticket's ID such as WEB-31 (a former ID also works), a team's key such as WEB, or a project's, product's or environment's slug such as docs-launch."},"name":{"type":"string","description":"The ticket's title, or the project's, product's, environment's or team's name."}},"additionalProperties":false,"description":"One of the caller's pins: a shortcut to a ticket, project, product, environment or team, listed in the website's sidebar under Pinned.","examples":[{"id":"Pn5MvB2xRc7L","kind":"ticket","key":"WEB-31","name":"Add docs search"}]},"PinTarget":{"type":"object","required":["kind","key"],"properties":{"kind":{"type":"string","enum":["ticket","project","product","environment","team"],"description":"What the pin points at: ticket, project, product, environment or team."},"key":{"type":"string","description":"The key its pages use: a ticket's ID such as WEB-31 (a former ID also works), a team's key such as WEB, or a project's, product's or environment's slug such as docs-launch."}},"additionalProperties":false,"description":"The ticket, project, product, environment or team a pin points at.","examples":[{"kind":"ticket","key":"WEB-31"}]},"Product":{"type":"object","required":["id","slug","name","type","description","repository","archivedAt","createdAt","updatedAt","deployments"],"properties":{"id":{"type":"string","description":"Unique ID of the product."},"slug":{"type":"string","description":"Lowercase letters, digits and hyphens, unique in the workspace, such as storefront."},"name":{"type":"string","description":"The product's display name."},"type":{"type":"string","enum":["website","api","cli","mobile_app","desktop_app","agent"],"description":"What kind of software the product is."},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"A short description, or null."},"repository":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The source repository, such as acme/storefront, that clanker sessions report."},"archivedAt":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"When it was archived, as an ISO 8601 timestamp; null while active."},"createdAt":{"type":"string","description":"When it was created, as an ISO 8601 timestamp."},"updatedAt":{"type":"string","description":"When it last changed, as an ISO 8601 timestamp."},"deployments":{"type":"array","items":{"$ref":"#/components/schemas/Deployment"},"description":"Deployments whose environment is active."}},"additionalProperties":false,"description":"Software the workspace builds and tests.","examples":[{"id":"Pr4GtY9sLm3B","slug":"storefront","name":"Storefront","type":"website","description":"The customer-facing shop.","repository":"acme/storefront","archivedAt":null,"createdAt":"2026-10-01T16:20:00.000Z","updatedAt":"2026-10-14T09:05:12.000Z","deployments":[{"id":"Dp3FkR8wNv2T","product":{"id":"Pr4GtY9sLm3B","slug":"storefront","name":"Storefront","type":"website","archived":false},"environment":{"id":"En8RqZ2vKp5D","slug":"staging","name":"Staging","class":"non-production","emoji":"🧪","archived":false},"baseUrl":"https://staging.acme.dev","fixtureUrl":"https://staging.acme.dev/fixtures","version":"9f2c41e","versionUpdatedAt":"2026-10-14T09:05:12.000Z","active":true,"createdAt":"2026-10-01T16:20:00.000Z","updatedAt":"2026-10-14T09:05:12.000Z"}]}]},"Deployment":{"type":"object","required":["id","product","environment","baseUrl","fixtureUrl","version","versionUpdatedAt","active","createdAt","updatedAt"],"properties":{"id":{"type":"string","description":"Unique ID of the deployment."},"product":{"type":"object","required":["id","slug","name","type","archived"],"properties":{"id":{"type":"string","description":"Unique ID of the product."},"slug":{"type":"string","description":"Lowercase letters, digits and hyphens, unique in the workspace, such as storefront."},"name":{"type":"string","description":"The product's display name."},"type":{"type":"string","enum":["website","api","cli","mobile_app","desktop_app","agent"],"description":"What kind of software the product is."},"archived":{"type":"boolean","description":"Whether the product is archived."}},"additionalProperties":false,"description":"The product that is deployed."},"environment":{"type":"object","required":["id","slug","name","class","emoji","archived"],"properties":{"id":{"type":"string","description":"Unique ID of the environment."},"slug":{"type":"string","description":"Lowercase letters, digits and hyphens, unique in the workspace, such as staging."},"name":{"type":"string","description":"The environment's display name."},"class":{"type":"string","enum":["production","non-production"],"description":"Production holds real customer data; everything else is non-production."},"emoji":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"One emoji shown beside the environment's name, or null."},"archived":{"type":"boolean","description":"Whether the environment is archived."}},"additionalProperties":false,"description":"The environment it is deployed to."},"baseUrl":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The http(s) URL where the product answers in this environment. Required for website and API products."},"fixtureUrl":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The deployment's Fixture API, which test runs call to create and delete test data, or null when it has none."},"version":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The build that is running, such as a git SHA, or null when unknown."},"versionUpdatedAt":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"When `version` last changed, as an ISO 8601 timestamp."},"active":{"type":"boolean","description":"False while the product or the environment is archived."},"createdAt":{"type":"string","description":"When it was created, as an ISO 8601 timestamp."},"updatedAt":{"type":"string","description":"When it last changed, as an ISO 8601 timestamp."}},"additionalProperties":false,"description":"One product running in one environment.","examples":[{"id":"Dp3FkR8wNv2T","product":{"id":"Pr4GtY9sLm3B","slug":"storefront","name":"Storefront","type":"website","archived":false},"environment":{"id":"En8RqZ2vKp5D","slug":"staging","name":"Staging","class":"non-production","emoji":"🧪","archived":false},"baseUrl":"https://staging.acme.dev","fixtureUrl":"https://staging.acme.dev/fixtures","version":"9f2c41e","versionUpdatedAt":"2026-10-14T09:05:12.000Z","active":true,"createdAt":"2026-10-01T16:20:00.000Z","updatedAt":"2026-10-14T09:05:12.000Z"}]},"Environment":{"type":"object","required":["id","slug","name","class","description","emoji","archivedAt","createdAt","updatedAt","deployments"],"properties":{"id":{"type":"string","description":"Unique ID of the environment."},"slug":{"type":"string","description":"Lowercase letters, digits and hyphens, unique in the workspace, such as staging."},"name":{"type":"string","description":"The environment's display name."},"class":{"type":"string","enum":["production","non-production"],"description":"Production holds real customer data; everything else is non-production."},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"A short description, or null."},"emoji":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"One emoji shown beside the environment's name, or null."},"archivedAt":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"When it was archived, as an ISO 8601 timestamp; null while active."},"createdAt":{"type":"string","description":"When it was created, as an ISO 8601 timestamp."},"updatedAt":{"type":"string","description":"When it last changed, as an ISO 8601 timestamp."},"deployments":{"type":"array","items":{"$ref":"#/components/schemas/Deployment"},"description":"Deployments whose product is active."}},"additionalProperties":false,"description":"A place products run, shared by every product in the workspace.","examples":[{"id":"En8RqZ2vKp5D","slug":"staging","name":"Staging","class":"non-production","description":"Where each merge to main lands before production.","emoji":"🧪","archivedAt":null,"createdAt":"2026-10-01T16:20:00.000Z","updatedAt":"2026-10-14T09:05:12.000Z","deployments":[{"id":"Dp3FkR8wNv2T","product":{"id":"Pr4GtY9sLm3B","slug":"storefront","name":"Storefront","type":"website","archived":false},"environment":{"id":"En8RqZ2vKp5D","slug":"staging","name":"Staging","class":"non-production","emoji":"🧪","archived":false},"baseUrl":"https://staging.acme.dev","fixtureUrl":"https://staging.acme.dev/fixtures","version":"9f2c41e","versionUpdatedAt":"2026-10-14T09:05:12.000Z","active":true,"createdAt":"2026-10-01T16:20:00.000Z","updatedAt":"2026-10-14T09:05:12.000Z"}]}]},"Team":{"type":"object","required":["id","key","name","visibility","archivedAt","members","joined","createdAt","updatedAt"],"properties":{"id":{"type":"string","description":"Unique ID of the team."},"key":{"type":"string","description":"2 to 5 capital letters that start the team's ticket IDs, such as WEB."},"name":{"type":"string","description":"The team's display name."},"visibility":{"type":"string","enum":["open","private"],"description":"Who sees the team: open teams are listed for everyone in the workspace, private teams only for their members and for owners and admins."},"archivedAt":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"When it was archived, as an ISO 8601 timestamp; null while active."},"members":{"type":"array","items":{"$ref":"#/components/schemas/Person"},"description":"The team's members, sorted by name."},"joined":{"type":"boolean","description":"Whether the caller is a member. Always false for an account API key."},"createdAt":{"type":"string","description":"When it was created, as an ISO 8601 timestamp."},"updatedAt":{"type":"string","description":"When it last changed, as an ISO 8601 timestamp."}},"additionalProperties":false,"description":"A group of workspace members that owns tickets and numbers them with its key, such as WEB-31.","examples":[{"id":"Tm6PzN3kWq1J","key":"WEB","name":"Web","visibility":"open","archivedAt":null,"members":[{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null},{"id":"Us9DcT4wHn6R","name":"Sam Okafor","email":"sam@acme.dev","image":null}],"joined":true,"createdAt":"2026-10-01T16:20:00.000Z","updatedAt":"2026-10-14T09:05:12.000Z"}]},"Person":{"type":"object","required":["id","name","email","image"],"properties":{"id":{"type":"string","description":"The person's user ID."},"name":{"type":"string","description":"The person's display name."},"email":{"type":"string","description":"The person's email address."},"image":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The URL of the person's account photo, or null when they have none."}},"additionalProperties":false,"description":"A person in the workspace.","examples":[{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null}]},"ProjectListItem":{"type":"object","required":["id","slug","name","summary","status","lead","targetDate","teams","products","milestones","progress","archivedAt","createdAt","updatedAt"],"properties":{"id":{"type":"string","description":"Unique ID of the project."},"slug":{"type":"string","description":"Lowercase letters, digits and hyphens, unique in the workspace, such as docs-launch."},"name":{"type":"string","description":"The project's display name."},"summary":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"One line on what the project delivers, or null."},"status":{"type":"string","enum":["planned","active","paused","completed","canceled"],"description":"Where the project stands: planned, active, paused, completed or canceled."},"lead":{"anyOf":[{"$ref":"#/components/schemas/Person"},{"type":"null"}],"description":"The member who leads the project, or null."},"targetDate":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The date the project should be done, as YYYY-MM-DD, or null."},"teams":{"type":"array","items":{"$ref":"#/components/schemas/TeamRef"},"description":"The teams whose tickets the project holds, sorted by name."},"products":{"type":"array","items":{"type":"object","required":["id","slug","name"],"properties":{"id":{"type":"string","description":"Unique ID of the product."},"slug":{"type":"string","description":"The product's slug, such as storefront."},"name":{"type":"string","description":"The product's display name."}},"additionalProperties":false},"description":"The products the project changes, sorted by name."},"milestones":{"type":"array","items":{"$ref":"#/components/schemas/Milestone"},"description":"The project's milestones, in number order."},"progress":{"type":"object","required":["backlog","plan","build","review","ship","done","canceled"],"properties":{"backlog":{"type":"number","description":"How many of the project's tickets have a status in the backlog category."},"plan":{"type":"number","description":"How many of the project's tickets have a status in the plan category."},"build":{"type":"number","description":"How many of the project's tickets have a status in the build category."},"review":{"type":"number","description":"How many of the project's tickets have a status in the review category."},"ship":{"type":"number","description":"How many of the project's tickets have a status in the ship category."},"done":{"type":"number","description":"How many of the project's tickets have a status in the done category."},"canceled":{"type":"number","description":"How many of the project's tickets have a status in the canceled category."}},"additionalProperties":false,"description":"The project's tickets counted by stage."},"archivedAt":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"When it was archived, as an ISO 8601 timestamp; null while active."},"createdAt":{"type":"string","description":"When it was created, as an ISO 8601 timestamp."},"updatedAt":{"type":"string","description":"When it last changed, as an ISO 8601 timestamp."}},"additionalProperties":false,"description":"A project without its document, as lists return it.","examples":[{"id":"Pj2KsV8dRf4N","slug":"docs-launch","name":"Docs launch","summary":"Ship the public docs site with search and the API reference.","status":"active","lead":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null},"targetDate":"2026-11-20","teams":[{"id":"Tm6PzN3kWq1J","key":"WEB","name":"Web","visibility":"open"}],"products":[{"id":"Pr4GtY9sLm3B","slug":"storefront","name":"Storefront"}],"milestones":[{"id":"Ms1RfP5kXn8B","number":1,"name":"Reference pages","summary":"Every API resource has a generated page."},{"id":"Ms2SrC9vLm4D","number":2,"name":"Search","summary":"Readers find any page from the docs header."}],"progress":{"backlog":2,"plan":1,"build":2,"review":1,"ship":1,"done":5,"canceled":1},"archivedAt":null,"createdAt":"2026-10-01T16:20:00.000Z","updatedAt":"2026-10-14T09:05:12.000Z"}]},"TeamRef":{"type":"object","required":["id","key","name","visibility"],"properties":{"id":{"type":"string","description":"Unique ID of the team."},"key":{"type":"string","description":"2 to 5 capital letters that start the team's ticket IDs, such as WEB."},"name":{"type":"string","description":"The team's display name."},"visibility":{"type":"string","enum":["open","private"],"description":"Who sees the team: open teams are listed for everyone in the workspace, private teams only for their members and for owners and admins."}},"additionalProperties":false,"description":"A team as tickets and projects show it.","examples":[{"id":"Tm6PzN3kWq1J","key":"WEB","name":"Web","visibility":"open"}]},"Milestone":{"type":"object","required":["id","number","name","summary"],"properties":{"id":{"type":"string","description":"Unique ID of the milestone."},"number":{"type":"number","description":"The milestone's number within its project: 2 is M2."},"name":{"type":"string","description":"The milestone's name."},"summary":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"A short summary, or null."}},"additionalProperties":false,"description":"A checkpoint within a project, labeled M1, M2 and so on.","examples":[{"id":"Ms2SrC9vLm4D","number":2,"name":"Search","summary":"Readers find any page from the docs header."}]},"Project":{"type":"object","required":["id","slug","name","summary","status","lead","targetDate","teams","products","milestones","progress","archivedAt","createdAt","updatedAt","document"],"properties":{"id":{"type":"string","description":"Unique ID of the project."},"slug":{"type":"string","description":"Lowercase letters, digits and hyphens, unique in the workspace, such as docs-launch."},"name":{"type":"string","description":"The project's display name."},"summary":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"One line on what the project delivers, or null."},"status":{"type":"string","enum":["planned","active","paused","completed","canceled"],"description":"Where the project stands: planned, active, paused, completed or canceled."},"lead":{"anyOf":[{"$ref":"#/components/schemas/Person"},{"type":"null"}],"description":"The member who leads the project, or null."},"targetDate":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The date the project should be done, as YYYY-MM-DD, or null."},"teams":{"type":"array","items":{"$ref":"#/components/schemas/TeamRef"},"description":"The teams whose tickets the project holds, sorted by name."},"products":{"type":"array","items":{"type":"object","required":["id","slug","name"],"properties":{"id":{"type":"string","description":"Unique ID of the product."},"slug":{"type":"string","description":"The product's slug, such as storefront."},"name":{"type":"string","description":"The product's display name."}},"additionalProperties":false},"description":"The products the project changes, sorted by name."},"milestones":{"type":"array","items":{"$ref":"#/components/schemas/Milestone"},"description":"The project's milestones, in number order."},"progress":{"type":"object","required":["backlog","plan","build","review","ship","done","canceled"],"properties":{"backlog":{"type":"number","description":"How many of the project's tickets have a status in the backlog category."},"plan":{"type":"number","description":"How many of the project's tickets have a status in the plan category."},"build":{"type":"number","description":"How many of the project's tickets have a status in the build category."},"review":{"type":"number","description":"How many of the project's tickets have a status in the review category."},"ship":{"type":"number","description":"How many of the project's tickets have a status in the ship category."},"done":{"type":"number","description":"How many of the project's tickets have a status in the done category."},"canceled":{"type":"number","description":"How many of the project's tickets have a status in the canceled category."}},"additionalProperties":false,"description":"The project's tickets counted by stage."},"archivedAt":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"When it was archived, as an ISO 8601 timestamp; null while active."},"createdAt":{"type":"string","description":"When it was created, as an ISO 8601 timestamp."},"updatedAt":{"type":"string","description":"When it last changed, as an ISO 8601 timestamp."},"document":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The project's document in Markdown, or null."}},"additionalProperties":false,"description":"A body of work with a goal. It links the teams whose tickets it holds and the products it changes, and has numbered milestones.","examples":[{"id":"Pj2KsV8dRf4N","slug":"docs-launch","name":"Docs launch","summary":"Ship the public docs site with search and the API reference.","status":"active","lead":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null},"targetDate":"2026-11-20","teams":[{"id":"Tm6PzN3kWq1J","key":"WEB","name":"Web","visibility":"open"}],"products":[{"id":"Pr4GtY9sLm3B","slug":"storefront","name":"Storefront"}],"milestones":[{"id":"Ms1RfP5kXn8B","number":1,"name":"Reference pages","summary":"Every API resource has a generated page."},{"id":"Ms2SrC9vLm4D","number":2,"name":"Search","summary":"Readers find any page from the docs header."}],"progress":{"backlog":2,"plan":1,"build":2,"review":1,"ship":1,"done":5,"canceled":1},"archivedAt":null,"createdAt":"2026-10-01T16:20:00.000Z","updatedAt":"2026-10-14T09:05:12.000Z","document":"## Goal\nEvery Acme developer finds the answer in the docs before asking in chat.\n\n## Scope\nThe API reference, guides and search."}]},"TicketListItem":{"type":"object","required":["id","identifier","number","team","title","status","owner","clankers","project","milestone","tags","checklist","needsHuman","rank","createdAt","updatedAt"],"properties":{"id":{"type":"string","description":"Unique ID of the ticket."},"identifier":{"type":"string","description":"The team key and number, such as WEB-31. Paths take this ID."},"number":{"type":"number","description":"The ticket's number within its team."},"team":{"$ref":"#/components/schemas/TeamRef"},"title":{"type":"string","description":"A short name for the work."},"status":{"$ref":"#/components/schemas/TicketStatus"},"owner":{"anyOf":[{"$ref":"#/components/schemas/Person"},{"type":"null"}],"description":"The person accountable for the ticket, or null."},"clankers":{"type":"array","items":{"$ref":"#/components/schemas/Clanker"},"description":"The clankers working on the ticket, in the order they were added."},"project":{"anyOf":[{"type":"object","required":["id","slug","name"],"properties":{"id":{"type":"string","description":"Unique ID of the project."},"slug":{"type":"string","description":"Lowercase letters, digits and hyphens, unique in the workspace, such as docs-launch."},"name":{"type":"string","description":"The project's display name."}},"additionalProperties":false},{"type":"null"}],"description":"The project the ticket belongs to, or null."},"milestone":{"anyOf":[{"type":"object","required":["id","number","name"],"properties":{"id":{"type":"string","description":"Unique ID of the milestone."},"number":{"type":"number","description":"The milestone's number within the project: 2 is M2."},"name":{"type":"string","description":"The milestone's name."}},"additionalProperties":false},{"type":"null"}],"description":"The milestone of its project the ticket belongs to, or null."},"tags":{"type":"array","items":{"$ref":"#/components/schemas/Tag"},"description":"The ticket's tags, sorted by name."},"checklist":{"type":"object","required":["done","inProgress","total"],"properties":{"done":{"type":"number","description":"How many of those items are done."},"inProgress":{"type":"number","description":"How many of those items are in progress: started and not done."},"total":{"type":"number","description":"How many items there are."}},"additionalProperties":false,"description":"The ticket's checklist items for the statuses of its current stage, counted. The Work layout fills the stage's stretch of the track by this share."},"needsHuman":{"anyOf":[{"$ref":"#/components/schemas/NeedsHuman"},{"type":"null"}],"description":"Why the ticket waits on a person, or null when it does not."},"rank":{"type":"number","description":"The ticket's place in the one workspace-wide order that views ordered by hand follow; lower comes first."},"createdAt":{"type":"string","description":"When it was created, as an ISO 8601 timestamp."},"updatedAt":{"type":"string","description":"When it last changed, as an ISO 8601 timestamp."}},"additionalProperties":false,"description":"A ticket without its documents, checklists, creator and former IDs, as lists return it.","examples":[{"id":"Tk7BnC5xLp9M","identifier":"WEB-31","number":31,"team":{"id":"Tm6PzN3kWq1J","key":"WEB","name":"Web","visibility":"open"},"title":"Add docs search","status":{"id":"St3BdV6nHs9D","name":"Build","category":"build","position":2,"isDefault":false},"owner":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null},"clankers":[{"id":"Ag5HvB1mZr8K","name":"Codex","person":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null}}],"project":{"id":"Pj2KsV8dRf4N","slug":"docs-launch","name":"Docs launch"},"milestone":{"id":"Ms2SrC9vLm4D","number":2,"name":"Search"},"tags":[{"id":"Tg3FtR7nWq2K","name":"feature","color":"cobalt","team":null}],"checklist":{"done":1,"inProgress":1,"total":3},"needsHuman":null,"rank":31.5,"createdAt":"2026-10-01T16:20:00.000Z","updatedAt":"2026-10-14T09:05:12.000Z"}]},"TicketStatus":{"type":"object","required":["id","name","category","position","isDefault"],"properties":{"id":{"type":"string","description":"Unique ID of the ticket status."},"name":{"type":"string","description":"The status's name, unique within its team, such as Build."},"category":{"type":"string","enum":["backlog","plan","build","review","ship","done","canceled"],"description":"The fixed stage the status belongs to: backlog, plan, build, review, ship, done or canceled. It cannot change."},"position":{"type":"number","description":"Orders the status within its category; lower comes first."},"isDefault":{"type":"boolean","description":"Whether new tickets get this status when none is named."}},"additionalProperties":false,"description":"A step in a team's workflow, such as Plan or Build.","examples":[{"id":"St3BdV6nHs9D","name":"Build","category":"build","position":2,"isDefault":false}]},"Clanker":{"type":"object","required":["id","name","person"],"properties":{"id":{"type":"string","description":"Unique ID of the clanker."},"name":{"type":"string","description":"The clanker, such as Codex."},"person":{"$ref":"#/components/schemas/Person"}},"additionalProperties":false,"description":"A clanker: one clanker working for one workspace member. Clankers work on tickets as their clankers.","examples":[{"id":"Ag5HvB1mZr8K","name":"Codex","person":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null}}]},"Tag":{"type":"object","required":["id","name","color","team"],"properties":{"id":{"type":"string","description":"Unique ID of the tag."},"name":{"type":"string","description":"The tag's name, such as bug."},"color":{"type":"string","enum":["gray","red","orange","amber","green","teal","cobalt","iris","pink"],"description":"The tag's color."},"team":{"anyOf":[{"type":"object","required":["id","key"],"properties":{"id":{"type":"string","description":"Unique ID of the team."},"key":{"type":"string","description":"The team's key, such as WEB."}},"additionalProperties":false},{"type":"null"}],"description":"The team a team tag belongs to; null for a workspace tag."}},"additionalProperties":false,"description":"A colored label on tickets. Workspace tags work on every ticket; team tags only on their team's tickets.","examples":[{"id":"Tg3FtR7nWq2K","name":"feature","color":"cobalt","team":null}]},"NeedsHuman":{"type":"object","required":["reasons","items","questions","work"],"properties":{"reasons":{"type":"array","items":{"type":"string","enum":["human-items","question","work-returned"]},"description":"Why: `human-items` when only Human items are left on the current status's checklist in Plan, Build, Review or Ship; `question` while a question waits for an answer; `work-returned` when work sent to a clanker came back finished (a draft, refinement or plan) or declined."},"items":{"type":"array","items":{"type":"string"},"description":"The open Human items, for `human-items`; otherwise empty."},"questions":{"type":"array","items":{"$ref":"#/components/schemas/TicketQuestion"},"description":"The open questions, oldest first."},"work":{"anyOf":[{"type":"object","required":["clanker","ask","status","reply"],"properties":{"clanker":{"$ref":"#/components/schemas/Clanker"},"ask":{"type":"string","enum":["draft","refine","plan","build","mention","answer"],"description":"What was asked."},"status":{"type":"string","enum":["queued","delivered","completed","declined"],"description":"Where the work is: queued, delivered, completed or declined."},"reply":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"What the clanker said when it finished or declined, or null."}},"additionalProperties":false},{"type":"null"}],"description":"The work that came back, for `work-returned`; otherwise null."}},"additionalProperties":false,"description":"Why a ticket waits on a person. It is worked out from the ticket, so checking the last Human item, answering the question or sending new work clears it.","examples":[{"reasons":["human-items","question"],"items":["Plan approved"],"questions":[{"id":"Qn6TfB2wLp8R","question":"Use a hosted search service, or build the index into the docs site? Hosted is faster to ship; built-in has no monthly cost.","choices":["Hosted service","Built-in index"],"askedBy":{"person":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null},"clanker":{"id":"Ag5HvB1mZr8K","name":"Codex","person":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null}}},"askedAt":"2026-10-14T09:05:12.000Z"}],"work":null}]},"TicketQuestion":{"type":"object","required":["id","question","choices","askedBy","askedAt"],"properties":{"id":{"type":"string","description":"Unique ID of the question."},"question":{"type":"string","description":"The question, up to 1,000 characters."},"choices":{"type":"array","items":{"type":"string"},"description":"Up to four answers the asker suggests. Any answer will do."},"askedBy":{"type":"object","required":["person","clanker"],"properties":{"person":{"anyOf":[{"$ref":"#/components/schemas/Person"},{"type":"null"}],"description":"The person who acted, or the person the clanker works for; null for an account API key."},"clanker":{"anyOf":[{"$ref":"#/components/schemas/Clanker"},{"type":"null"}],"description":"The clanker that acted for the person, or null when the person acted directly."}},"additionalProperties":false,"description":"Who asked: a clanker for its person, or a person."},"askedAt":{"type":"string","description":"When, as an ISO 8601 timestamp."}},"additionalProperties":false,"description":"A question asked on a ticket, open until someone answers it.","examples":[{"id":"Qn6TfB2wLp8R","question":"Use a hosted search service, or build the index into the docs site? Hosted is faster to ship; built-in has no monthly cost.","choices":["Hosted service","Built-in index"],"askedBy":{"person":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null},"clanker":{"id":"Ag5HvB1mZr8K","name":"Codex","person":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null}}},"askedAt":"2026-10-14T09:05:12.000Z"}]},"Ticket":{"type":"object","required":["id","identifier","number","team","title","status","owner","clankers","project","milestone","tags","checklist","needsHuman","rank","createdAt","updatedAt","createdBy","formerIdentifiers","checklists","documents","branches","pullRequests","sessions"],"properties":{"id":{"type":"string","description":"Unique ID of the ticket."},"identifier":{"type":"string","description":"The team key and number, such as WEB-31. Paths take this ID."},"number":{"type":"number","description":"The ticket's number within its team."},"team":{"$ref":"#/components/schemas/TeamRef"},"title":{"type":"string","description":"A short name for the work."},"status":{"$ref":"#/components/schemas/TicketStatus"},"owner":{"anyOf":[{"$ref":"#/components/schemas/Person"},{"type":"null"}],"description":"The person accountable for the ticket, or null."},"clankers":{"type":"array","items":{"$ref":"#/components/schemas/Clanker"},"description":"The clankers working on the ticket, in the order they were added."},"project":{"anyOf":[{"type":"object","required":["id","slug","name"],"properties":{"id":{"type":"string","description":"Unique ID of the project."},"slug":{"type":"string","description":"Lowercase letters, digits and hyphens, unique in the workspace, such as docs-launch."},"name":{"type":"string","description":"The project's display name."}},"additionalProperties":false},{"type":"null"}],"description":"The project the ticket belongs to, or null."},"milestone":{"anyOf":[{"type":"object","required":["id","number","name"],"properties":{"id":{"type":"string","description":"Unique ID of the milestone."},"number":{"type":"number","description":"The milestone's number within the project: 2 is M2."},"name":{"type":"string","description":"The milestone's name."}},"additionalProperties":false},{"type":"null"}],"description":"The milestone of its project the ticket belongs to, or null."},"tags":{"type":"array","items":{"$ref":"#/components/schemas/Tag"},"description":"The ticket's tags, sorted by name."},"checklist":{"type":"object","required":["done","inProgress","total"],"properties":{"done":{"type":"number","description":"How many of those items are done."},"inProgress":{"type":"number","description":"How many of those items are in progress: started and not done."},"total":{"type":"number","description":"How many items there are."}},"additionalProperties":false,"description":"The ticket's checklist items for the statuses of its current stage, counted. The Work layout fills the stage's stretch of the track by this share."},"needsHuman":{"anyOf":[{"$ref":"#/components/schemas/NeedsHuman"},{"type":"null"}],"description":"Why the ticket waits on a person, or null when it does not."},"rank":{"type":"number","description":"The ticket's place in the one workspace-wide order that views ordered by hand follow; lower comes first."},"createdAt":{"type":"string","description":"When it was created, as an ISO 8601 timestamp."},"updatedAt":{"type":"string","description":"When it last changed, as an ISO 8601 timestamp."},"createdBy":{"type":"object","required":["person","clanker"],"properties":{"person":{"anyOf":[{"$ref":"#/components/schemas/Person"},{"type":"null"}],"description":"The person who acted, or the person the clanker works for; null for an account API key."},"clanker":{"anyOf":[{"$ref":"#/components/schemas/Clanker"},{"type":"null"}],"description":"The clanker that acted for the person, or null when the person acted directly."}},"additionalProperties":false,"description":"Who created the ticket."},"formerIdentifiers":{"type":"array","items":{"type":"string"},"description":"IDs the ticket had on other teams, oldest first. Each still finds it."},"checklists":{"type":"array","items":{"type":"object","required":["id","status","items"],"properties":{"id":{"type":"string","description":"Unique ID of the checklist."},"status":{"type":"object","required":["id","name","category","position","isDefault"],"properties":{"id":{"type":"string","description":"Unique ID of the ticket status."},"name":{"type":"string","description":"The status's name, unique within its team, such as Build."},"category":{"type":"string","enum":["backlog","plan","build","review","ship","done","canceled"],"description":"The fixed stage the status belongs to: backlog, plan, build, review, ship, done or canceled. It cannot change."},"position":{"type":"number","description":"Orders the status within its category; lower comes first."},"isDefault":{"type":"boolean","description":"Whether new tickets get this status when none is named."}},"additionalProperties":false,"description":"The status the checklist is for.","examples":[{"id":"St3BdV6nHs9D","name":"Build","category":"build","position":2,"isDefault":false}]},"items":{"type":"array","items":{"$ref":"#/components/schemas/ChecklistItem"},"description":"The checklist's items, in order."}},"additionalProperties":false},"description":"The ticket's own checklists, one per status of its team that has one, in board order. A ticket gets a status's checklist, copied from the status's template, when it first enters the status."},"documents":{"type":"array","items":{"$ref":"#/components/schemas/TicketDocumentRef"},"description":"The ticket's documents in workflow order: one for each of its team's statuses that keeps a document, written or not, then any it kept from statuses that are gone."},"branches":{"type":"array","items":{"$ref":"#/components/schemas/TicketBranch"},"description":"The repositories' branches the ticket is worked on, oldest link first."},"pullRequests":{"type":"array","items":{"$ref":"#/components/schemas/TicketPullRequest"},"description":"The GitHub pull requests the ticket links, oldest link first, up to 10."},"sessions":{"type":"array","items":{"$ref":"#/components/schemas/TicketSession"},"description":"The live sessions working on the ticket, most recently seen first."}},"additionalProperties":false,"description":"One unit of work on a team, with its checklists and documents.","examples":[{"id":"Tk7BnC5xLp9M","identifier":"WEB-31","number":31,"team":{"id":"Tm6PzN3kWq1J","key":"WEB","name":"Web","visibility":"open"},"title":"Add docs search","status":{"id":"St3BdV6nHs9D","name":"Build","category":"build","position":2,"isDefault":false},"owner":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null},"clankers":[{"id":"Ag5HvB1mZr8K","name":"Codex","person":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null}}],"project":{"id":"Pj2KsV8dRf4N","slug":"docs-launch","name":"Docs launch"},"milestone":{"id":"Ms2SrC9vLm4D","number":2,"name":"Search"},"tags":[{"id":"Tg3FtR7nWq2K","name":"feature","color":"cobalt","team":null}],"checklist":{"done":1,"inProgress":1,"total":3},"needsHuman":null,"rank":31.5,"createdAt":"2026-10-01T16:20:00.000Z","updatedAt":"2026-10-14T09:05:12.000Z","createdBy":{"person":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null},"clanker":{"id":"Ag5HvB1mZr8K","name":"Codex","person":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null}}},"formerIdentifiers":[],"checklists":[{"id":"Cl3BdV8nKt2P","status":{"id":"St3BdV6nHs9D","name":"Build","category":"build","position":2,"isDefault":false},"items":[{"id":"Ci1ImP8dRt4W","title":"Cases written","position":0,"doer":"clanker","done":true,"doneBy":{"person":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null},"clanker":{"id":"Ag5HvB1mZr8K","name":"Codex","person":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null}}},"doneAt":"2026-10-14T09:05:12.000Z","inProgress":false,"startedBy":null,"startedAt":null,"approval":null},{"id":"Ci2SpG3nHv7Y","title":"Specs generated","position":1,"doer":"clanker","done":false,"doneBy":null,"doneAt":null,"inProgress":true,"startedBy":{"person":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null},"clanker":{"id":"Ag5HvB1mZr8K","name":"Codex","person":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null}}},"startedAt":"2026-10-14T09:05:12.000Z","approval":null},{"id":"Ci3CkP6sMz2Q","title":"Tests pass","position":2,"doer":"clanker","done":false,"doneBy":null,"doneAt":null,"inProgress":false,"startedBy":null,"startedAt":null,"approval":null}]}],"documents":[{"name":"Plan","slug":"plan","stage":"plan","status":{"id":"St2PlN8mRc3K","name":"Plan","category":"plan","position":1,"isDefault":false},"revision":3,"updatedAt":"2026-10-14T09:05:12.000Z"}],"branches":[{"repository":"acme/web","branch":"web-31-docs-search","linkedBy":{"person":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null},"clanker":{"id":"Ag5HvB1mZr8K","name":"Codex","person":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null}}},"linkedAt":"2026-10-14T09:05:12.000Z"}],"pullRequests":[{"url":"https://github.com/acme/web/pull/142","repository":"acme/web","number":142,"linkedBy":{"person":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null},"clanker":{"id":"Ag5HvB1mZr8K","name":"Codex","person":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null}}},"linkedAt":"2026-10-14T09:05:12.000Z"}],"sessions":[{"id":"Ss1JtQ6wDm3X","client":"Claude Code","person":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null},"computer":"maya-mbp","repository":"acme/web","branch":"web-31-docs-search","source":"linked","connected":true,"lastSeenAt":"2026-10-14T09:05:12.000Z"}]}]},"ChecklistItem":{"type":"object","required":["id","title","position","doer","done","doneBy","doneAt","inProgress","startedBy","startedAt","approval"],"properties":{"id":{"type":"string","description":"Unique ID of the checklist item."},"title":{"type":"string","description":"What has to be done, up to 120 characters, unique within its checklist."},"position":{"type":"number","description":"Orders the item within its checklist, from 0."},"doer":{"type":"string","enum":["human","clanker"],"description":"Who does the item: `human` for a person, such as an approval, or `clanker`. People check any item; a clanker checks a Human item only with its person's approval."},"done":{"type":"boolean","description":"Whether the item is checked."},"doneBy":{"anyOf":[{"type":"object","required":["person","clanker"],"properties":{"person":{"anyOf":[{"$ref":"#/components/schemas/Person"},{"type":"null"}],"description":"The person who acted, or the person the clanker works for; null for an account API key."},"clanker":{"anyOf":[{"$ref":"#/components/schemas/Clanker"},{"type":"null"}],"description":"The clanker that acted for the person, or null when the person acted directly."}},"additionalProperties":false},{"type":"null"}],"description":"Who checked the item, or null while it is open."},"doneAt":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"When the item was checked, as an ISO 8601 timestamp, or null while it is open."},"inProgress":{"type":"boolean","description":"Whether someone is working the item: started and not checked yet."},"startedBy":{"anyOf":[{"type":"object","required":["person","clanker"],"properties":{"person":{"anyOf":[{"$ref":"#/components/schemas/Person"},{"type":"null"}],"description":"The person who acted, or the person the clanker works for; null for an account API key."},"clanker":{"anyOf":[{"$ref":"#/components/schemas/Clanker"},{"type":"null"}],"description":"The clanker that acted for the person, or null when the person acted directly."}},"additionalProperties":false},{"type":"null"}],"description":"Who started the item, or null unless it is in progress."},"startedAt":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"When the item was started, as an ISO 8601 timestamp, or null unless it is in progress."},"approval":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The person's words approving the item in a conversation with their clanker, when the clanker checked a Human item for them; null otherwise."}},"additionalProperties":false,"description":"One item of a ticket's checklist.","examples":[{"id":"Ci1ImP8dRt4W","title":"Cases written","position":0,"doer":"clanker","done":true,"doneBy":{"person":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null},"clanker":{"id":"Ag5HvB1mZr8K","name":"Codex","person":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null}}},"doneAt":"2026-10-14T09:05:12.000Z","inProgress":false,"startedBy":null,"startedAt":null,"approval":null}]},"TicketDocumentRef":{"type":"object","required":["name","slug","stage","status","revision","updatedAt"],"properties":{"name":{"type":"string","description":"The document's name, such as Plan."},"slug":{"type":"string","description":"The name as paths take it, such as build-record."},"stage":{"type":"string","enum":["backlog","plan","build","review","ship","done","canceled"],"description":"The fixed stage the status belongs to: backlog, plan, build, review, ship, done or canceled. It cannot change."},"status":{"anyOf":[{"$ref":"#/components/schemas/TicketStatus"},{"type":"null"}],"description":"The status that keeps the document; null once that status is gone."},"revision":{"type":"number","description":"The document's latest revision; 0 until anyone writes it."},"updatedAt":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"When the document was last written, as an ISO 8601 timestamp, or null."}},"additionalProperties":false,"description":"A ticket's document, as the ticket lists it.","examples":[{"name":"Plan","slug":"plan","stage":"plan","status":{"id":"St2PlN8mRc3K","name":"Plan","category":"plan","position":1,"isDefault":false},"revision":3,"updatedAt":"2026-10-14T09:05:12.000Z"}]},"TicketBranch":{"type":"object","required":["repository","branch","linkedBy","linkedAt"],"properties":{"repository":{"type":"string","description":"The repository as owner/name."},"branch":{"type":"string","description":"The branch, such as web-31-docs-search."},"linkedBy":{"type":"object","required":["person","clanker"],"properties":{"person":{"anyOf":[{"$ref":"#/components/schemas/Person"},{"type":"null"}],"description":"The person who acted, or the person the clanker works for; null for an account API key."},"clanker":{"anyOf":[{"$ref":"#/components/schemas/Clanker"},{"type":"null"}],"description":"The clanker that acted for the person, or null when the person acted directly."}},"additionalProperties":false,"description":"Who linked it."},"linkedAt":{"type":"string","description":"When, as an ISO 8601 timestamp."}},"additionalProperties":false,"description":"A repository's branch a ticket is worked on.","examples":[{"repository":"acme/web","branch":"web-31-docs-search","linkedBy":{"person":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null},"clanker":{"id":"Ag5HvB1mZr8K","name":"Codex","person":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null}}},"linkedAt":"2026-10-14T09:05:12.000Z"}]},"TicketPullRequest":{"type":"object","required":["url","repository","number","linkedBy","linkedAt"],"properties":{"url":{"type":"string","description":"The pull request's page on GitHub."},"repository":{"type":"string","description":"The repository as owner/name."},"number":{"type":"number","description":"The pull request's number, such as 142."},"linkedBy":{"type":"object","required":["person","clanker"],"properties":{"person":{"anyOf":[{"$ref":"#/components/schemas/Person"},{"type":"null"}],"description":"The person who acted, or the person the clanker works for; null for an account API key."},"clanker":{"anyOf":[{"$ref":"#/components/schemas/Clanker"},{"type":"null"}],"description":"The clanker that acted for the person, or null when the person acted directly."}},"additionalProperties":false,"description":"Who linked it."},"linkedAt":{"type":"string","description":"When, as an ISO 8601 timestamp."}},"additionalProperties":false,"description":"A GitHub pull request a ticket links, such as acme/web#142.","examples":[{"url":"https://github.com/acme/web/pull/142","repository":"acme/web","number":142,"linkedBy":{"person":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null},"clanker":{"id":"Ag5HvB1mZr8K","name":"Codex","person":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null}}},"linkedAt":"2026-10-14T09:05:12.000Z"}]},"TicketSession":{"type":"object","required":["id","client","person","computer","repository","branch","source","connected","lastSeenAt"],"properties":{"id":{"type":"string","description":"Unique ID of the session."},"client":{"type":"string","description":"The clanker client, such as Claude Code."},"person":{"$ref":"#/components/schemas/Person"},"computer":{"type":"string","description":"The name of the computer the session runs on, such as maya-mbp."},"repository":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The repository the session works in, as owner/name, or null outside one."},"branch":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The branch checked out in the session, or null."},"source":{"type":"string","enum":["picked","linked","branch","name"],"description":"Where the session's ticket came from, strongest first: `picked` by its person, `linked` by its clanker in the session, the ticket its branch is `branch`-linked to, or the ticket whose ID the branch's `name` carries."},"connected":{"type":"boolean","description":"Whether the session holds a connection to Clanker Ship, so it hears changes at once."},"lastSeenAt":{"type":"string","description":"When the session last reported, as an ISO 8601 timestamp."}},"additionalProperties":false,"description":"A live session working on a ticket: connected, or reported by the plugin's hooks in the last minute.","examples":[{"id":"Ss1JtQ6wDm3X","client":"Claude Code","person":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null},"computer":"maya-mbp","repository":"acme/web","branch":"web-31-docs-search","source":"linked","connected":true,"lastSeenAt":"2026-10-14T09:05:12.000Z"}]},"TicketDocument":{"type":"object","required":["ticket","name","slug","stage","status","revision","updatedAt","body","updatedBy"],"properties":{"ticket":{"type":"object","required":["id","identifier","title"],"properties":{"id":{"type":"string","description":"Unique ID of the ticket."},"identifier":{"type":"string","description":"The ticket's ID, such as WEB-31."},"title":{"type":"string","description":"The ticket's title."}},"additionalProperties":false,"description":"The ticket that keeps the document."},"name":{"type":"string","description":"The document's name, such as Plan."},"slug":{"type":"string","description":"The name as paths take it, such as build-record."},"stage":{"type":"string","enum":["backlog","plan","build","review","ship","done","canceled"],"description":"The fixed stage the status belongs to: backlog, plan, build, review, ship, done or canceled. It cannot change."},"status":{"anyOf":[{"$ref":"#/components/schemas/TicketStatus"},{"type":"null"}],"description":"The status that keeps the document; null once that status is gone."},"revision":{"type":"number","description":"The document's latest revision; 0 until anyone writes it."},"updatedAt":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"When the document was last written, as an ISO 8601 timestamp, or null."},"body":{"type":"string","description":"The document in Markdown. One nobody has written yet holds its status's template."},"updatedBy":{"anyOf":[{"type":"object","required":["person","clanker"],"properties":{"person":{"anyOf":[{"$ref":"#/components/schemas/Person"},{"type":"null"}],"description":"The person who acted, or the person the clanker works for; null for an account API key."},"clanker":{"anyOf":[{"$ref":"#/components/schemas/Clanker"},{"type":"null"}],"description":"The clanker that acted for the person, or null when the person acted directly."}},"additionalProperties":false},{"type":"null"}],"description":"Who wrote the latest revision; null until anyone writes it."}},"additionalProperties":false,"description":"A document a ticket keeps for one of its statuses, such as its Scope, Plan or Review.","examples":[{"ticket":{"id":"Tk7BnC5xLp9M","identifier":"WEB-31","title":"Add docs search"},"name":"Plan","slug":"plan","stage":"plan","status":{"id":"St2PlN8mRc3K","name":"Plan","category":"plan","position":1,"isDefault":false},"revision":3,"updatedAt":"2026-10-14T09:05:12.000Z","body":"## Approach\n1. Index every docs page at build time.\n2. Add a search box to the docs header that queries the index.","updatedBy":{"person":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null},"clanker":{"id":"Ag5HvB1mZr8K","name":"Codex","person":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null}}}}]},"DocumentRevision":{"type":"object","required":["revision","body","author","createdAt"],"properties":{"revision":{"type":"number","description":"The revision's number, from 1."},"body":{"type":"string","description":"The document as this revision wrote it."},"author":{"type":"object","required":["person","clanker"],"properties":{"person":{"anyOf":[{"$ref":"#/components/schemas/Person"},{"type":"null"}],"description":"The person who acted, or the person the clanker works for; null for an account API key."},"clanker":{"anyOf":[{"$ref":"#/components/schemas/Clanker"},{"type":"null"}],"description":"The clanker that acted for the person, or null when the person acted directly."}},"additionalProperties":false,"description":"Who wrote the revision."},"createdAt":{"type":"string","description":"When it was created, as an ISO 8601 timestamp."}},"additionalProperties":false,"description":"One write of a ticket's document.","examples":[{"revision":3,"body":"## Approach\n1. Index every docs page at build time.\n2. Add a search box to the docs header that queries the index.","author":{"person":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null},"clanker":{"id":"Ag5HvB1mZr8K","name":"Codex","person":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null}}},"createdAt":"2026-10-14T09:05:12.000Z"}]},"TicketStatusWithChecklist":{"type":"object","required":["id","name","category","position","isDefault","checklist","instructions"],"properties":{"id":{"type":"string","description":"Unique ID of the ticket status."},"name":{"type":"string","description":"The status's name, unique within its team, such as Build."},"category":{"type":"string","enum":["backlog","plan","build","review","ship","done","canceled"],"description":"The fixed stage the status belongs to: backlog, plan, build, review, ship, done or canceled. It cannot change."},"position":{"type":"number","description":"Orders the status within its category; lower comes first."},"isDefault":{"type":"boolean","description":"Whether new tickets get this status when none is named."},"checklist":{"type":"array","items":{"type":"object","required":["id","title","position","doer"],"properties":{"id":{"type":"string","description":"Unique ID of the checklist template item."},"title":{"type":"string","description":"What has to be done, up to 120 characters, unique within the template."},"position":{"type":"number","description":"Orders the item within the template, from 0."},"doer":{"type":"string","enum":["human","clanker"],"description":"Who does the item: `human` for a person, such as an approval, or `clanker`. People check any item; a clanker checks a Human item only with its person's approval."}},"additionalProperties":false},"description":"The status's checklist template, in order: the items a ticket's checklist starts with when the ticket first enters the status. Empty when the status has none."},"instructions":{"$ref":"#/components/schemas/StatusInstructions"}},"additionalProperties":false,"description":"A ticket status with its checklist template and instructions.","examples":[{"id":"St3BdV6nHs9D","name":"Build","category":"build","position":2,"isDefault":false,"checklist":[{"id":"Ct1ImP4dNq8R","title":"Cases written","position":0,"doer":"clanker"},{"id":"Ct2SpG7nKw3V","title":"Specs generated","position":1,"doer":"clanker"},{"id":"Ct3CkP2sLx6T","title":"Tests pass","position":2,"doer":"clanker"}],"instructions":{"document":"Build record","template":"## Progress\nOne entry per plan step: what was done, the files and commits.","guidance":"- Update the build record after every step. Never write it at the end."}}]},"StatusInstructions":{"type":"object","required":["document","template","guidance"],"properties":{"document":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The name of the document tickets keep in this status, such as Plan, unique within the team; null when the status keeps none."},"template":{"type":"string","description":"The Markdown the status's document starts from, up to 20,000 characters."},"guidance":{"type":"string","description":"How a clanker works the status, writes its document and moves on, in Markdown, up to 20,000 characters."}},"additionalProperties":false,"description":"What a status asks of a clanker: the document its tickets keep there, the Markdown that document starts from, and how to work the status.","examples":[{"document":"Build record","template":"## Progress\nOne entry per plan step: what was done, the files and commits.","guidance":"- Update the build record after every step. Never write it at the end."}]},"StatusInstructionsDetail":{"type":"object","required":["document","template","guidance","team","status","checklist","isStageDefault"],"properties":{"document":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The name of the document tickets keep in this status, such as Plan, unique within the team; null when the status keeps none."},"template":{"type":"string","description":"The Markdown the status's document starts from, up to 20,000 characters."},"guidance":{"type":"string","description":"How a clanker works the status, writes its document and moves on, in Markdown, up to 20,000 characters."},"team":{"anyOf":[{"type":"object","required":["id","key","name"],"properties":{"id":{"type":"string","description":"Unique ID of the team."},"key":{"type":"string","description":"2 to 5 capital letters that start the team's ticket IDs, such as WEB."},"name":{"type":"string","description":"The team's display name."}},"additionalProperties":false},{"type":"null"}],"description":"The team whose status this is, or null for the workspace's template."},"status":{"$ref":"#/components/schemas/TicketStatus"},"checklist":{"type":"array","items":{"type":"object","required":["id","title","position","doer"],"properties":{"id":{"type":"string","description":"Unique ID of the checklist template item."},"title":{"type":"string","description":"What has to be done, up to 120 characters, unique within the template."},"position":{"type":"number","description":"Orders the item within the template, from 0."},"doer":{"type":"string","enum":["human","clanker"],"description":"Who does the item: `human` for a person, such as an approval, or `clanker`. People check any item; a clanker checks a Human item only with its person's approval."}},"additionalProperties":false},"description":"The status's checklist template, in order."},"isStageDefault":{"type":"boolean","description":"Whether the instructions are still Clanker Ship's for the status: its stage's, with the document named after the status when another status of its set keeps the stage's."}},"additionalProperties":false,"description":"A status's instructions and the checklist they go with.","examples":[{"document":"Build record","template":"## Progress\nOne entry per plan step: what was done, the files and commits.","guidance":"- Update the build record after every step. Never write it at the end.","team":{"id":"Tm6PzN3kWq1J","key":"WEB","name":"Web"},"status":{"id":"St3BdV6nHs9D","name":"Build","category":"build","position":2,"isDefault":false},"checklist":[{"id":"Ct1ImP4dNq8R","title":"Cases written","position":0,"doer":"clanker"},{"id":"Ct2SpG7nKw3V","title":"Specs generated","position":1,"doer":"clanker"},{"id":"Ct3CkP2sLx6T","title":"Tests pass","position":2,"doer":"clanker"}],"isStageDefault":false}]},"View":{"type":"object","required":["id","slug","name","team","project","person","filters","groupBy","orderBy","layout","isDefault","createdAt","updatedAt"],"properties":{"id":{"type":"string","description":"Unique ID of the view."},"slug":{"type":"string","description":"Made from the view's name and unique within its team, project or person, such as active."},"name":{"type":"string","description":"The view's name, such as Active."},"team":{"anyOf":[{"type":"object","required":["id","key","name"],"properties":{"id":{"type":"string","description":"Unique ID of the team."},"key":{"type":"string","description":"2 to 5 capital letters that start the team's ticket IDs, such as WEB."},"name":{"type":"string","description":"The team's display name."}},"additionalProperties":false},{"type":"null"}],"description":"The team the view belongs to, or null."},"project":{"anyOf":[{"type":"object","required":["id","slug","name"],"properties":{"id":{"type":"string","description":"Unique ID of the project."},"slug":{"type":"string","description":"Lowercase letters, digits and hyphens, unique in the workspace, such as docs-launch."},"name":{"type":"string","description":"The project's display name."}},"additionalProperties":false},{"type":"null"}],"description":"The project the view belongs to, or null."},"person":{"anyOf":[{"$ref":"#/components/schemas/Person"},{"type":"null"}],"description":"The person whose own view this is, shown only to them on My work, or null."},"filters":{"$ref":"#/components/schemas/ViewFilters"},"groupBy":{"type":"string","enum":["status","category","owner","clanker","tag","project","milestone","team","none"],"description":"How the view groups tickets."},"orderBy":{"type":"string","enum":["manual","created","updated"],"description":"How the view orders tickets: manual follows the order people set by hand, created puts the newest first and updated the most recently changed."},"layout":{"type":"string","enum":["list","board","work"],"description":"How the view draws its tickets: a list, a board, or the work layout."},"isDefault":{"type":"boolean","description":"Whether the owner's page opens this view: its Tickets page, or My work."},"createdAt":{"type":"string","description":"When it was created, as an ISO 8601 timestamp."},"updatedAt":{"type":"string","description":"When it last changed, as an ISO 8601 timestamp."}},"additionalProperties":false,"description":"A saved way to look at a team's, a project's or a person's tickets: filters, grouping, order and layout.","examples":[{"id":"Vw4AcT8nRk2P","slug":"active","name":"Active","team":{"id":"Tm6PzN3kWq1J","key":"WEB","name":"Web"},"project":null,"person":null,"filters":{"categories":["plan","build","review"]},"groupBy":"status","orderBy":"manual","layout":"board","isDefault":false,"createdAt":"2026-10-01T16:20:00.000Z","updatedAt":"2026-10-14T09:05:12.000Z"}]},"ViewFilters":{"type":"object","required":[],"properties":{"statuses":{"type":"array","items":{"type":"string"},"description":"Only tickets with these statuses, by name."},"categories":{"type":"array","items":{"type":"string","enum":["backlog","plan","build","review","ship","done","canceled"],"description":"A status category."},"description":"Only tickets whose status is in these categories."},"tags":{"type":"array","items":{"type":"string"},"description":"Only tickets with any of these tags, by name."},"owners":{"type":"array","items":{"type":"string"},"description":"Only tickets these people own, by user ID; me matches the person reading the view, none tickets without an owner."},"clankers":{"type":"array","items":{"type":"string"},"description":"Only tickets any of these clankers works on, by clanker ID; mine matches the reader's clankers, none tickets without clankers."},"mine":{"type":"boolean","enum":[true],"description":"Only tickets the person reading the view owns or their clankers work on."},"projects":{"type":"array","items":{"type":"string"},"description":"Only tickets in these projects, by slug; none matches tickets without a project. Team and personal views."},"milestones":{"type":"array","items":{"type":"string"},"description":"Only tickets in these milestones, such as M1; none matches tickets without one. Project views only."},"teams":{"type":"array","items":{"type":"string"},"description":"Only tickets of these teams, by key. Project and personal views."},"needsHuman":{"type":"boolean","enum":[true],"description":"Only tickets that wait on a person, as their `needsHuman` says."}},"additionalProperties":false,"description":"Which tickets a view shows. Filters combine with and; the values within one filter with or.","examples":[{"categories":["plan","build","review"]}]},"ViewTickets":{"type":"object","required":["id","slug","name","team","project","person","filters","groupBy","orderBy","layout","isDefault","createdAt","updatedAt","tickets","statuses","work"],"properties":{"id":{"type":"string","description":"Unique ID of the view."},"slug":{"type":"string","description":"Made from the view's name and unique within its team, project or person, such as active."},"name":{"type":"string","description":"The view's name, such as Active."},"team":{"anyOf":[{"type":"object","required":["id","key","name"],"properties":{"id":{"type":"string","description":"Unique ID of the team."},"key":{"type":"string","description":"2 to 5 capital letters that start the team's ticket IDs, such as WEB."},"name":{"type":"string","description":"The team's display name."}},"additionalProperties":false},{"type":"null"}],"description":"The team the view belongs to, or null."},"project":{"anyOf":[{"type":"object","required":["id","slug","name"],"properties":{"id":{"type":"string","description":"Unique ID of the project."},"slug":{"type":"string","description":"Lowercase letters, digits and hyphens, unique in the workspace, such as docs-launch."},"name":{"type":"string","description":"The project's display name."}},"additionalProperties":false},{"type":"null"}],"description":"The project the view belongs to, or null."},"person":{"anyOf":[{"$ref":"#/components/schemas/Person"},{"type":"null"}],"description":"The person whose own view this is, shown only to them on My work, or null."},"filters":{"$ref":"#/components/schemas/ViewFilters"},"groupBy":{"type":"string","enum":["status","category","owner","clanker","tag","project","milestone","team","none"],"description":"How the view groups tickets."},"orderBy":{"type":"string","enum":["manual","created","updated"],"description":"How the view orders tickets: manual follows the order people set by hand, created puts the newest first and updated the most recently changed."},"layout":{"type":"string","enum":["list","board","work"],"description":"How the view draws its tickets: a list, a board, or the work layout."},"isDefault":{"type":"boolean","description":"Whether the owner's page opens this view: its Tickets page, or My work."},"createdAt":{"type":"string","description":"When it was created, as an ISO 8601 timestamp."},"updatedAt":{"type":"string","description":"When it last changed, as an ISO 8601 timestamp."},"tickets":{"type":"array","items":{"$ref":"#/components/schemas/TicketListItem"},"description":"The tickets the view shows, in its order."},"statuses":{"type":"array","items":{"type":"object","required":["id","name","category","position","isDefault","teams"],"properties":{"id":{"type":"string","description":"Unique ID of the ticket status."},"name":{"type":"string","description":"The status's name, unique within its team, such as Build."},"category":{"type":"string","enum":["backlog","plan","build","review","ship","done","canceled"],"description":"The fixed stage the status belongs to: backlog, plan, build, review, ship, done or canceled. It cannot change."},"position":{"type":"number","description":"Orders the status within its category; lower comes first."},"isDefault":{"type":"boolean","description":"Whether new tickets get this status when none is named."},"teams":{"type":"array","items":{"type":"string"},"description":"The keys of the teams with this status. A ticket moves into the column only when its team is one of them."}},"additionalProperties":false},"description":"Every status of the view's teams, empty ones and ones its filters leave out included: the team's statuses, the union across a project's teams, or for a personal view the union across every team the person sees. Matching names and categories share one entry. The website shows the ones the filters select and offers the others as drop targets."},"work":{"anyOf":[{"$ref":"#/components/schemas/ViewWork"},{"type":"null"}],"description":"For a view with the Work layout, its crew, lanes and log; otherwise null."}},"additionalProperties":false,"description":"A view with the tickets it shows.","examples":[{"id":"Vw4AcT8nRk2P","slug":"active","name":"Active","team":{"id":"Tm6PzN3kWq1J","key":"WEB","name":"Web"},"project":null,"person":null,"filters":{"categories":["plan","build","review"]},"groupBy":"status","orderBy":"manual","layout":"board","isDefault":false,"createdAt":"2026-10-01T16:20:00.000Z","updatedAt":"2026-10-14T09:05:12.000Z","tickets":[{"id":"Tk7BnC5xLp9M","identifier":"WEB-31","number":31,"team":{"id":"Tm6PzN3kWq1J","key":"WEB","name":"Web","visibility":"open"},"title":"Add docs search","status":{"id":"St3BdV6nHs9D","name":"Build","category":"build","position":2,"isDefault":false},"owner":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null},"clankers":[{"id":"Ag5HvB1mZr8K","name":"Codex","person":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null}}],"project":{"id":"Pj2KsV8dRf4N","slug":"docs-launch","name":"Docs launch"},"milestone":{"id":"Ms2SrC9vLm4D","number":2,"name":"Search"},"tags":[{"id":"Tg3FtR7nWq2K","name":"feature","color":"cobalt","team":null}],"checklist":{"done":1,"inProgress":1,"total":3},"needsHuman":null,"rank":31.5,"createdAt":"2026-10-01T16:20:00.000Z","updatedAt":"2026-10-14T09:05:12.000Z"}],"statuses":[{"id":"St1BkL4pQx7N","name":"Backlog","category":"backlog","position":0,"isDefault":true,"teams":["WEB"]},{"id":"St2PlN8mRc3K","name":"Plan","category":"plan","position":1,"isDefault":false,"teams":["WEB"]},{"id":"St3BdV6nHs9D","name":"Build","category":"build","position":2,"isDefault":false,"teams":["WEB"]},{"id":"St4IrG2wZf5M","name":"Review","category":"review","position":3,"isDefault":false,"teams":["WEB"]},{"id":"St5ShY7kPb1Q","name":"Ship","category":"ship","position":4,"isDefault":false,"teams":["WEB"]},{"id":"St6DnW4cRm9X","name":"Done","category":"done","position":5,"isDefault":false,"teams":["WEB"]},{"id":"St7CnJ3xTe8L","name":"Canceled","category":"canceled","position":6,"isDefault":false,"teams":["WEB"]},{"id":"St8DpR9vLw2H","name":"Duplicate","category":"canceled","position":7,"isDefault":false,"teams":["WEB"]}],"work":null}]},"ViewWork":{"type":"object","required":["crew","lanes","log"],"properties":{"crew":{"type":"number","description":"How many different clankers work on the view's tickets."},"lanes":{"type":"array","items":{"type":"object","required":["ticket","state","message"],"properties":{"ticket":{"type":"string","description":"Unique ID of the ticket."},"state":{"type":"string","enum":["live","needs-human","ready","idle","done","canceled"],"description":"Whose move it is: needs-human while the ticket waits on a person (see the ticket's needsHuman); live while a clanker has the newest work sent on it; ready when that work was a build the clanker finished; idle otherwise; done or canceled once the ticket is."},"message":{"anyOf":[{"type":"object","required":["clanker","ask","status","reply"],"properties":{"clanker":{"$ref":"#/components/schemas/Clanker"},"ask":{"type":"string","enum":["draft","refine","plan","build","mention","answer"],"description":"What was asked."},"status":{"type":"string","enum":["queued","delivered","completed","declined"],"description":"Where the work is: queued, delivered, completed or declined."},"reply":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"What the clanker said when it finished or declined, or null."}},"additionalProperties":false},{"type":"null"}],"description":"The newest work a person sent a clanker on the ticket, or null."}},"additionalProperties":false},"description":"One lane per ticket, in the view's order."},"log":{"type":"array","items":{"type":"object","required":["id","type","actor","subject","createdAt"],"properties":{"id":{"type":"string","description":"Unique ID of the event."},"type":{"type":"string","description":"The event's type, such as ticket.updated."},"actor":{"type":"string","description":"Who made the change, such as Maya Patel or Codex · Maya Patel."},"subject":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"What changed, such as WEB-31 Rate limits."},"createdAt":{"type":"string","description":"When, as an ISO 8601 time."}},"additionalProperties":false},"description":"The latest four changes to the view's tickets, newest first."}},"additionalProperties":false,"description":"What the Work layout shows: the crew, each ticket's state and the latest changes.","examples":[{"crew":1,"lanes":[{"ticket":"Tk7BnC5xLp9M","state":"needs-human","message":{"clanker":{"id":"Ag5HvB1mZr8K","name":"Codex","person":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null}},"ask":"plan","status":"completed","reply":"Cache per workspace. The plan is on the ticket."}}],"log":[{"id":"Ev7QmT2kWp9L","type":"clanker_message.completed","actor":"Codex · Maya Patel","subject":"Codex (WEB-31)","createdAt":"2026-10-14T09:31:20.000Z"}]}]},"ClankerInstructions":{"type":"object","required":["kind","source","team","templates","guidance","defaults","updatedAt","updatedBy"],"properties":{"kind":{"type":"string","enum":["ticket","test-cases","test-code","fixtures","test-ci"],"description":"What the instructions shape: `ticket` for the defaults a clanker's new ticket gets, `test-cases` for test cases, `test-code` for specs, `fixtures` for a product's Fixture API and `test-ci` for the CI that runs tests. Each status keeps its own instructions for its document and work."},"source":{"type":"string","enum":["team","workspace","default"],"description":"Where these come from: the team's own (team), the workspace's (workspace) or Clanker Ship's defaults (default)."},"team":{"anyOf":[{"type":"object","required":["id","key","name"],"properties":{"id":{"type":"string","description":"Unique ID of the team."},"key":{"type":"string","description":"2 to 5 capital letters that start the team's ticket IDs, such as WEB."},"name":{"type":"string","description":"The team's display name."}},"additionalProperties":false},{"type":"null"}],"description":"The team asked about, or null for the workspace's instructions."},"templates":{"type":"array","items":{"$ref":"#/components/schemas/InstructionTemplate"},"description":"One template for every ticket, and at most one more per tag; empty for ticket instructions."},"guidance":{"type":"string","description":"How the clanker should write, in Markdown; empty for ticket instructions."},"defaults":{"anyOf":[{"$ref":"#/components/schemas/TicketDefaults"},{"type":"null"}],"description":"What new tickets from clankers get; null for the test kinds."},"updatedAt":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"When these were last set, as an ISO 8601 timestamp; null for Clanker Ship's defaults."},"updatedBy":{"anyOf":[{"type":"object","required":["person","clanker"],"properties":{"person":{"anyOf":[{"$ref":"#/components/schemas/Person"},{"type":"null"}],"description":"The person who acted, or the person the clanker works for; null for an account API key."},"clanker":{"anyOf":[{"$ref":"#/components/schemas/Clanker"},{"type":"null"}],"description":"The clanker that acted for the person, or null when the person acted directly."}},"additionalProperties":false},{"type":"null"}],"description":"Who last set these; null for Clanker Ship's defaults or when an account API key set them."}},"additionalProperties":false,"description":"The instructions of one kind that a team's clankers follow, and where they come from.","examples":[{"kind":"ticket","source":"team","team":{"id":"Tm6PzN3kWq1J","key":"WEB","name":"Web"},"templates":[],"guidance":"","defaults":{"status":"Plan","tags":[],"owner":"creator","clankers":"creator"},"updatedAt":"2026-10-14T09:05:12.000Z","updatedBy":{"person":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null},"clanker":null}}]},"InstructionTemplate":{"type":"object","required":["tag","body"],"properties":{"tag":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The tag whose tickets start from this template, or null for the template every other ticket uses."},"body":{"type":"string","description":"The Markdown a test case, spec or setup starts from."}},"additionalProperties":false,"description":"The Markdown a test case, spec or setup starts from: the template of the ticket's first tag that has one, else the template without a tag.","examples":[{"tag":"bug","body":"## Steps to reproduce\n\n## Expected\n\n## Actual"}]},"TicketDefaults":{"type":"object","required":["status","tags","owner","clankers"],"properties":{"status":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The name of the status new tickets get, or null for the team's default status."},"tags":{"type":"array","items":{"type":"string"},"description":"The names of the tags new tickets get."},"owner":{"type":"string","enum":["creator","none"],"description":"`creator` makes the person the creating clanker works for the ticket's owner; `none` leaves the ticket without one."},"clankers":{"type":"string","enum":["creator","none"],"description":"`creator` makes the clanker that creates the ticket its one clanker; `none` leaves it without clankers."}},"additionalProperties":false,"description":"What a ticket a clanker creates gets for each of these fields the clanker leaves out.","examples":[{"status":"Plan","tags":[],"owner":"creator","clankers":"creator"}]},"ClankerWork":{"type":"object","required":["id","name","person","computers","serverUrl","live","lastSeenAt","createdAt","tickets"],"properties":{"id":{"type":"string","description":"Unique ID of the clanker."},"name":{"type":"string","description":"The clanker client, such as Codex or Claude Code."},"person":{"$ref":"#/components/schemas/Person"},"computers":{"type":"array","items":{"$ref":"#/components/schemas/ClankerComputer"},"description":"The computers it runs on, most recently seen first."},"serverUrl":{"type":"boolean","description":"Whether it has a sign-in made with the server URL instead of the plugin. That sign-in reads messages with the inbox tools only."},"live":{"type":"boolean","description":"Whether any of its computers is live."},"lastSeenAt":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"When it was last seen on any computer or sign-in, as an ISO 8601 timestamp, or null when never."},"createdAt":{"type":"string","description":"When the clanker was registered, as an ISO 8601 timestamp."},"tickets":{"type":"array","items":{"$ref":"#/components/schemas/TicketListItem"},"description":"The open tickets it works on that you can read, by status category, status and rank."}},"additionalProperties":false,"description":"One of your clankers with its presence and the open tickets it works on.","examples":[{"id":"Ag5HvB1mZr8K","name":"Codex","person":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null},"computers":[{"id":"Cp2LxW7nQd4S","name":"maya-mbp","lastSeenAt":"2026-10-14T09:31:20.000Z","live":true,"sessions":[{"id":"Ss1JtQ6wDm3X","repository":"acme/storefront","branch":"web-31-docs-search","ticket":{"id":"Tk7BnC5xLp9M","identifier":"WEB-31","title":"Add docs search","source":"linked"},"connected":true,"lastSeenAt":"2026-10-14T09:31:20.000Z","live":true}]}],"serverUrl":false,"live":true,"lastSeenAt":"2026-10-14T09:31:20.000Z","createdAt":"2026-10-01T16:20:00.000Z","tickets":[{"id":"Tk7BnC5xLp9M","identifier":"WEB-31","number":31,"team":{"id":"Tm6PzN3kWq1J","key":"WEB","name":"Web","visibility":"open"},"title":"Add docs search","status":{"id":"St3BdV6nHs9D","name":"Build","category":"build","position":2,"isDefault":false},"owner":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null},"clankers":[{"id":"Ag5HvB1mZr8K","name":"Codex","person":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null}}],"project":{"id":"Pj2KsV8dRf4N","slug":"docs-launch","name":"Docs launch"},"milestone":{"id":"Ms2SrC9vLm4D","number":2,"name":"Search"},"tags":[{"id":"Tg3FtR7nWq2K","name":"feature","color":"cobalt","team":null}],"checklist":{"done":1,"inProgress":1,"total":3},"needsHuman":null,"rank":31.5,"createdAt":"2026-10-01T16:20:00.000Z","updatedAt":"2026-10-14T09:05:12.000Z"}]}]},"ClankerComputer":{"type":"object","required":["id","name","lastSeenAt","live","sessions"],"properties":{"id":{"type":"string","description":"Unique ID of the computer."},"name":{"type":"string","description":"The computer's name as the plugin registered it, such as maya-mbp."},"lastSeenAt":{"type":"string","description":"When the computer was last seen, as an ISO 8601 timestamp."},"live":{"type":"boolean","description":"Whether the computer, or one of its sessions, was seen in the last minute."},"sessions":{"type":"array","items":{"$ref":"#/components/schemas/ClankerSession"},"description":"Its sessions seen in the last day, most recently seen first."}},"additionalProperties":false,"description":"A computer a clanker runs on, registered by the plugin's CLI by name.","examples":[{"id":"Cp2LxW7nQd4S","name":"maya-mbp","lastSeenAt":"2026-10-14T09:31:20.000Z","live":true,"sessions":[{"id":"Ss1JtQ6wDm3X","repository":"acme/storefront","branch":"web-31-docs-search","ticket":{"id":"Tk7BnC5xLp9M","identifier":"WEB-31","title":"Add docs search","source":"linked"},"connected":true,"lastSeenAt":"2026-10-14T09:31:20.000Z","live":true}]}]},"ClankerSession":{"type":"object","required":["id","repository","branch","ticket","connected","lastSeenAt","live"],"properties":{"id":{"type":"string","description":"Unique ID of the session."},"repository":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The repository the session works in, as owner/name, or null outside one."},"branch":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The branch checked out in the session, or null."},"ticket":{"anyOf":[{"$ref":"#/components/schemas/SessionTicketRef"},{"type":"null"}],"description":"The session's ticket, or null when it has none or you cannot see it. Change it with PUT /v1/workspaces/{slug}/clanker-sessions/{session}."},"connected":{"type":"boolean","description":"Whether the session holds a connection to Clanker Ship."},"lastSeenAt":{"type":"string","description":"When the session last reported, or its connection last closed, as an ISO 8601 timestamp."},"live":{"type":"boolean","description":"Whether the session is connected, or reported or disconnected in the last minute."}},"additionalProperties":false,"description":"One running clanker on a computer, with the repository and branch it works in and its ticket. The plugin's hooks report it, and the Claude Code plugin keeps it connected.","examples":[{"id":"Ss1JtQ6wDm3X","repository":"acme/storefront","branch":"web-31-docs-search","ticket":{"id":"Tk7BnC5xLp9M","identifier":"WEB-31","title":"Add docs search","source":"linked"},"connected":true,"lastSeenAt":"2026-10-14T09:31:20.000Z","live":true}]},"SessionTicketRef":{"type":"object","required":["id","identifier","title","source"],"properties":{"id":{"type":"string","description":"Unique ID of the ticket."},"identifier":{"type":"string","description":"The ticket's ID, such as WEB-31."},"title":{"type":"string","description":"The ticket's title."},"source":{"type":"string","enum":["picked","linked","branch","name"],"description":"Where the session's ticket came from, strongest first: `picked` by its person, `linked` by its clanker in the session, the ticket its branch is `branch`-linked to, or the ticket whose ID the branch's `name` carries."}},"additionalProperties":false,"description":"The ticket a session works on, and where it came from.","examples":[{"id":"Tk7BnC5xLp9M","identifier":"WEB-31","title":"Add docs search","source":"linked"}]},"ClankerSettings":{"type":"object","required":["defaultTeam","wakeIdleThreads"],"properties":{"defaultTeam":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The team key new tickets go to when the clanker names none, such as WEB; null for your first team."},"wakeIdleThreads":{"type":"boolean","description":"Whether the plugin hands each new message to an idle Codex thread."}},"additionalProperties":false,"description":"A clanker's settings. Its person changes them; Codex shows them on the plugin's settings page.","examples":[{"defaultTeam":"WEB","wakeIdleThreads":true}]},"SessionView":{"type":"object","required":["session","ticket","title","line","work"],"properties":{"session":{"type":"object","required":["id","key","client","computer","repository","branch","connected","live"],"properties":{"id":{"type":"string","description":"Unique ID of the session."},"key":{"type":"string","description":"The client's own ID for the session, such as a Claude Code session ID."},"client":{"type":"string","description":"The clanker client, such as Claude Code."},"computer":{"type":"string","description":"The computer it runs on."},"repository":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The repository the session works in, as owner/name, or null."},"branch":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The branch checked out in the session, or null."},"connected":{"type":"boolean","description":"Whether the session holds a connection to Clanker Ship."},"live":{"type":"boolean","description":"Whether the session is connected, or reported in the last minute."}},"additionalProperties":false,"description":"The session."},"ticket":{"anyOf":[{"$ref":"#/components/schemas/SessionTicket"},{"type":"null"}],"description":"The session's ticket, or null when it has none or you cannot see it."},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The session's name after its ticket, such as WEB-31: Add docs search, at most 36 characters; null without a ticket."},"line":{"type":"string","description":"The ticket line, at most 80 characters: the ticket, its stage and progress, and its next step or what it waits on you for, then how many of your other tickets need you. Without a ticket, the No ticket line."},"work":{"type":"object","required":["needsYou","url","tickets"],"properties":{"needsYou":{"type":"number","description":"How many of your other open tickets wait on you."},"url":{"type":"string","description":"Your My clankers page on the website, which the Claude Code band links its raised hand to."},"tickets":{"type":"array","items":{"$ref":"#/components/schemas/SessionWorkTicket"},"description":"Your open tickets: those that wait on you first, then the session's, then the rest by stage."}},"additionalProperties":false,"description":"A summary of the session's person's other work."}},"additionalProperties":false,"description":"What Clanker Ship shows for a session: its ticket, where the ticket came from, the session's name and ticket line, and the person's other work. The Claude Code plugin draws its band and pane from it.","examples":[{"session":{"id":"Ss1JtQ6wDm3X","key":"0199f3a2-7c41-7d2e-9b1a-5e8c4d2f6a10","client":"Claude Code","computer":"maya-mbp","repository":"acme/storefront","branch":"web-31-docs-search","connected":true,"live":true},"ticket":{"id":"Tk7BnC5xLp9M","identifier":"WEB-31","title":"Add docs search","source":"linked","url":"https://clankership.com/w/acme/tickets/WEB-31","status":{"id":"St3BdV6nHs9D","name":"Build","category":"build","position":2,"isDefault":false},"checklist":{"done":1,"inProgress":1,"total":3},"next":"Highlight matching headings","items":[{"id":"Ci4FqW8rLm2N","title":"Search box in the header","doer":"clanker","done":true,"inProgress":false},{"id":"Ci7HtX3vPn5R","title":"Highlight matching headings","doer":"clanker","done":false,"inProgress":true},{"id":"Ci2KdY6wQs9T","title":"Search result copy approved","doer":"human","done":false,"inProgress":false}],"needsHuman":null,"documents":[{"name":"Plan","slug":"plan","written":true},{"name":"Build record","slug":"build-record","written":true}]},"title":"WEB-31: Add docs search","line":"◆ WEB-31 Add docs search · Build 1/3 · next: Highlight matching headings · 1 more needs you","work":{"needsYou":1,"url":"https://clankership.com/w/acme/clankers","tickets":[{"id":"Tk3RmD8sVq1W","identifier":"WEB-28","title":"Fix login redirect","url":"https://clankership.com/w/acme/tickets/WEB-28","status":{"id":"St3BdV6nHs9D","name":"Build","category":"build","position":2,"isDefault":false},"checklist":{"done":4,"inProgress":0,"total":5},"needsYou":"Review approved","here":false,"sessions":[{"client":"Codex","computer":"maya-mbp"}]},{"id":"Tk7BnC5xLp9M","identifier":"WEB-31","title":"Add docs search","url":"https://clankership.com/w/acme/tickets/WEB-31","status":{"id":"St3BdV6nHs9D","name":"Build","category":"build","position":2,"isDefault":false},"checklist":{"done":1,"inProgress":1,"total":3},"needsYou":null,"here":true,"sessions":[]}]}}]},"SessionTicket":{"type":"object","required":["id","identifier","title","source","url","status","checklist","next","items","needsHuman","documents"],"properties":{"id":{"type":"string","description":"Unique ID of the ticket."},"identifier":{"type":"string","description":"The ticket's ID, such as WEB-31."},"title":{"type":"string","description":"The ticket's title."},"source":{"type":"string","enum":["picked","linked","branch","name"],"description":"Where the session's ticket came from, strongest first: `picked` by its person, `linked` by its clanker in the session, the ticket its branch is `branch`-linked to, or the ticket whose ID the branch's `name` carries."},"url":{"type":"string","description":"The ticket's page on the website."},"status":{"$ref":"#/components/schemas/TicketStatus"},"checklist":{"type":"object","required":["done","inProgress","total"],"properties":{"done":{"type":"number","description":"How many of the items are done."},"inProgress":{"type":"number","description":"How many of the items are in progress: started and not done."},"total":{"type":"number","description":"How many items there are."}},"additionalProperties":false,"description":"The ticket's checklist items for its current stage, counted."},"next":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The first open Clanker item on the current status's checklist, or null."},"items":{"type":"array","items":{"$ref":"#/components/schemas/SessionItem"},"description":"The checklist for the ticket's current status, in order."},"needsHuman":{"anyOf":[{"$ref":"#/components/schemas/NeedsHuman"},{"type":"null"}],"description":"Why the ticket waits on a person, or null when it does not."},"documents":{"type":"array","items":{"type":"object","required":["name","slug","written"],"properties":{"name":{"type":"string","description":"The document's name, such as Plan."},"slug":{"type":"string","description":"The name in URLs and commands, such as plan."},"written":{"type":"boolean","description":"Whether anyone has written it."}},"additionalProperties":false},"description":"The ticket's documents, in workflow order."}},"additionalProperties":false,"description":"The ticket a session works on, with what the Claude Code band and pane show.","examples":[{"id":"Tk7BnC5xLp9M","identifier":"WEB-31","title":"Add docs search","source":"linked","url":"https://clankership.com/w/acme/tickets/WEB-31","status":{"id":"St3BdV6nHs9D","name":"Build","category":"build","position":2,"isDefault":false},"checklist":{"done":1,"inProgress":1,"total":3},"next":"Highlight matching headings","items":[{"id":"Ci4FqW8rLm2N","title":"Search box in the header","doer":"clanker","done":true,"inProgress":false},{"id":"Ci7HtX3vPn5R","title":"Highlight matching headings","doer":"clanker","done":false,"inProgress":true},{"id":"Ci2KdY6wQs9T","title":"Search result copy approved","doer":"human","done":false,"inProgress":false}],"needsHuman":null,"documents":[{"name":"Plan","slug":"plan","written":true},{"name":"Build record","slug":"build-record","written":true}]}]},"SessionItem":{"type":"object","required":["id","title","doer","done","inProgress"],"properties":{"id":{"type":"string","description":"Unique ID of the checklist item."},"title":{"type":"string","description":"What the item asks for."},"doer":{"type":"string","enum":["human","clanker"],"description":"Who does it: a `human`, or the `clanker`."},"done":{"type":"boolean","description":"Whether it is checked."},"inProgress":{"type":"boolean","description":"Whether someone is working it: started, and not done yet."}},"additionalProperties":false,"description":"An item of the checklist for the ticket's current status.","examples":[{"id":"Ci4FqW8rLm2N","title":"Search box in the header","doer":"clanker","done":true,"inProgress":false}]},"SessionWorkTicket":{"type":"object","required":["id","identifier","title","url","status","checklist","needsYou","here","sessions"],"properties":{"id":{"type":"string","description":"Unique ID of the ticket."},"identifier":{"type":"string","description":"The ticket's ID, such as WEB-28."},"title":{"type":"string","description":"The ticket's title."},"url":{"type":"string","description":"The ticket's page on the website."},"status":{"$ref":"#/components/schemas/TicketStatus"},"checklist":{"type":"object","required":["done","inProgress","total"],"properties":{"done":{"type":"number","description":"How many of the items are done."},"inProgress":{"type":"number","description":"How many of the items are in progress: started and not done."},"total":{"type":"number","description":"How many items there are."}},"additionalProperties":false,"description":"The ticket's checklist items for its current stage, counted."},"needsYou":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"What the ticket waits on the session's person for, such as Review approved, or null when it does not."},"here":{"type":"boolean","description":"Whether it is this session's ticket."},"sessions":{"type":"array","items":{"type":"object","required":["client","computer"],"properties":{"client":{"type":"string","description":"The clanker client, such as Codex."},"computer":{"type":"string","description":"The computer it runs on."}},"additionalProperties":false},"description":"The other live sessions working on it."}},"additionalProperties":false,"description":"One of the session's person's open tickets, as the session's work summary lists it.","examples":[{"id":"Tk3RmD8sVq1W","identifier":"WEB-28","title":"Fix login redirect","url":"https://clankership.com/w/acme/tickets/WEB-28","status":{"id":"St3BdV6nHs9D","name":"Build","category":"build","position":2,"isDefault":false},"checklist":{"done":4,"inProgress":0,"total":5},"needsYou":"Review approved","here":false,"sessions":[{"client":"Codex","computer":"maya-mbp"}]}]},"ClankerMessage":{"type":"object","required":["id","clanker","computer","ticket","ask","note","commentId","sender","status","reply","createdAt","deliveredAt","completedAt","declinedAt"],"properties":{"id":{"type":"string","description":"Unique ID of the message."},"clanker":{"$ref":"#/components/schemas/Clanker"},"computer":{"anyOf":[{"type":"object","required":["id","name"],"properties":{"id":{"type":"string","description":"Unique ID of the computer."},"name":{"type":"string","description":"The computer's name, such as maya-mbp."}},"additionalProperties":false},{"type":"null"}],"description":"The computer routing chose when the message was sent, or null when the clanker had none."},"ticket":{"type":"object","required":["id","identifier","title"],"properties":{"id":{"type":"string","description":"Unique ID of the ticket."},"identifier":{"type":"string","description":"The ticket's ID, such as WEB-31."},"title":{"type":"string","description":"The ticket's title."}},"additionalProperties":false,"description":"The ticket the message is about."},"ask":{"type":"string","enum":["draft","refine","plan","build","mention","answer"],"description":"What the clanker should do: `draft`, `refine`, `plan` or `build` the ticket, or answer a `mention` in a comment."},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The sender's note, or for a mention the comment's first 2,000 characters. Null when there is none."},"commentId":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The ID of the comment a mention came from, or null."},"sender":{"type":"object","required":["person"],"properties":{"person":{"$ref":"#/components/schemas/Person"}},"additionalProperties":false,"description":"The member who sent the message."},"status":{"type":"string","enum":["queued","delivered","completed","declined"],"description":"`queued` until the plugin shows it to the clanker, then `delivered`, then `completed` when the clanker finishes it. `declined` when the clanker was revoked first."},"reply":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The clanker's reply when it completed the message, or why the message was declined. Null otherwise."},"createdAt":{"type":"string","description":"When the message was sent, as an ISO 8601 timestamp."},"deliveredAt":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"When it was delivered to the clanker, as an ISO 8601 timestamp, or null."},"completedAt":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"When the clanker completed it, as an ISO 8601 timestamp, or null."},"declinedAt":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"When it was declined, as an ISO 8601 timestamp, or null."}},"additionalProperties":false,"description":"A ticket sent to a clanker with an ask, or a mention of the clanker in a ticket comment.","examples":[{"id":"Mg4WzK7rTn2C","clanker":{"id":"Ag5HvB1mZr8K","name":"Codex","person":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null}},"computer":{"id":"Cp2LxW7nQd4S","name":"maya-mbp"},"ticket":{"id":"Tk7BnC5xLp9M","identifier":"WEB-31","title":"Add docs search"},"ask":"plan","note":"Keep the search box in the header.","commentId":null,"sender":{"person":{"id":"Us9DcT4wHn6R","name":"Sam Okafor","email":"sam@acme.dev","image":null}},"status":"completed","reply":"Wrote the plan: index the guides at build time and search them in the browser.","createdAt":"2026-10-14T09:05:12.000Z","deliveredAt":"2026-10-14T09:05:14.000Z","completedAt":"2026-10-14T09:18:03.000Z","declinedAt":null}]},"TicketComment":{"type":"object","required":["id","body","author","createdAt"],"properties":{"id":{"type":"string","description":"Unique ID of the comment."},"body":{"type":"string","description":"The comment, in Markdown."},"author":{"type":"object","required":["person","clanker"],"properties":{"person":{"$ref":"#/components/schemas/Person"},"clanker":{"anyOf":[{"type":"object","required":["id","name"],"properties":{"id":{"type":"string","description":"Unique ID of the clanker."},"name":{"type":"string","description":"The client, such as Codex."}},"additionalProperties":false},{"type":"null"}],"description":"The clanker that wrote it for the member, or null when the member wrote it."}},"additionalProperties":false,"description":"Who wrote the comment."},"createdAt":{"type":"string","description":"When it was created, as an ISO 8601 timestamp."}},"additionalProperties":false,"description":"A Markdown comment on a ticket, by a member or by a clanker working for one.","examples":[{"id":"Cm8HrD2vNq5L","body":"Can you add a case for an empty query?","author":{"person":{"id":"Us9DcT4wHn6R","name":"Sam Okafor","email":"sam@acme.dev","image":null},"clanker":null},"createdAt":"2026-10-14T09:04:51.000Z"}]},"Notification":{"type":"object","required":["id","kind","ticket","message","question","readAt","createdAt"],"properties":{"id":{"type":"string","description":"Unique ID of the notification."},"kind":{"type":"string","enum":["message_received","message_completed","message_declined","question_asked","ticket_needs_human"],"description":"`message_received` when someone sends a message to one of your clankers, `message_completed` when a clanker completes a message you sent, `message_declined` when a message you sent is declined, `question_asked` when someone asks a question on a ticket you own, and `ticket_needs_human` when only Human items are left on a ticket you own."},"ticket":{"type":"object","required":["id","identifier","title"],"properties":{"id":{"type":"string","description":"Unique ID of the ticket."},"identifier":{"type":"string","description":"The ticket's ID, such as WEB-31."},"title":{"type":"string","description":"The ticket's title."}},"additionalProperties":false,"description":"The ticket the notification is about."},"message":{"anyOf":[{"$ref":"#/components/schemas/ClankerMessage"},{"type":"null"}],"description":"The message, for the message kinds; otherwise null."},"question":{"anyOf":[{"$ref":"#/components/schemas/TicketQuestion"},{"type":"null"}],"description":"The question, for `question_asked`, while nobody has answered it; otherwise null."},"readAt":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"When you marked it read, as an ISO 8601 timestamp, or null while unread."},"createdAt":{"type":"string","description":"When it was created, as an ISO 8601 timestamp."}},"additionalProperties":false,"description":"Tells a member about a clanker message, a question on a ticket they own, or a ticket of theirs that waits on Human items.","examples":[{"id":"Nt3VpL9cWk6F","kind":"message_completed","ticket":{"id":"Tk7BnC5xLp9M","identifier":"WEB-31","title":"Add docs search"},"message":{"id":"Mg4WzK7rTn2C","clanker":{"id":"Ag5HvB1mZr8K","name":"Codex","person":{"id":"Us3NfP8kLq2V","name":"Maya Patel","email":"maya@acme.dev","image":null}},"computer":{"id":"Cp2LxW7nQd4S","name":"maya-mbp"},"ticket":{"id":"Tk7BnC5xLp9M","identifier":"WEB-31","title":"Add docs search"},"ask":"plan","note":"Keep the search box in the header.","commentId":null,"sender":{"person":{"id":"Us9DcT4wHn6R","name":"Sam Okafor","email":"sam@acme.dev","image":null}},"status":"completed","reply":"Wrote the plan: index the guides at build time and search them in the browser.","createdAt":"2026-10-14T09:05:12.000Z","deliveredAt":"2026-10-14T09:05:14.000Z","completedAt":"2026-10-14T09:18:03.000Z","declinedAt":null},"question":null,"readAt":null,"createdAt":"2026-10-14T09:18:03.000Z"}]},"TestRunSummary":{"type":"object","required":["id","number","url","state","result","counts","passRate","firstAttemptPassRate","error","product","environment","baseUrl","deploymentBaseUrl","deploymentVersion","git","coverage","shardCount","finishedShards","cleanup","publishedBy","startedAt","finishedAt","durationMs"],"properties":{"id":{"type":"string","description":"Unique ID of the test run."},"number":{"type":"number","description":"The run's number, counting up from 1 in each workspace, such as 1289."},"url":{"type":"string","description":"The run's page on the website."},"state":{"type":"string","enum":["running","finished","interrupted"],"description":"`running` until its last shard finishes, then `finished`, or `interrupted` when any shard was. One still running after 6 hours becomes `interrupted`."},"result":{"anyOf":[{"type":"string","enum":["passed","failed"]},{"type":"null"}],"description":"`passed` when the run has no error and no failed test, otherwise `failed`. Flaky tests count as passed. Null while running and for interrupted runs."},"counts":{"type":"object","required":["total","passed","flaky","failed","skipped"],"properties":{"total":{"type":"number","description":"Every test in the run."},"passed":{"type":"number","description":"Tests that passed on attempt 1."},"flaky":{"type":"number","description":"Tests that failed on attempt 1 and then passed every attempt of a retry."},"failed":{"type":"number","description":"Tests that are still failed."},"skipped":{"type":"number","description":"Tests that were skipped."}},"additionalProperties":false,"description":"How many tests have each status."},"passRate":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"(passed + flaky) ÷ (tests − skipped), from 0 to 1. Null while running or when no test counts."},"firstAttemptPassRate":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Tests that passed on attempt 1 ÷ (tests − skipped), from 0 to 1. Retries never change it. Null while running or when no test counts."},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"What failed outside the tests, such as a web server that did not start, or `No tests ran.` In a run with several shards, each shard's error starts with `Shard 2 of 4:`. A run with an error is failed and cannot be retried."},"product":{"type":"object","required":["slug","name"],"properties":{"slug":{"type":"string","description":"The product's slug, such as storefront."},"name":{"type":"string","description":"The product's display name."}},"additionalProperties":false,"description":"The product the run tested."},"environment":{"type":"object","required":["slug","name","class"],"properties":{"slug":{"type":"string","description":"The environment's slug, such as staging."},"name":{"type":"string","description":"The environment's display name."},"class":{"type":"string","description":"The environment's class: production or non-production."}},"additionalProperties":false,"description":"The environment the run tested."},"baseUrl":{"type":"string","description":"The URL the tests ran against."},"deploymentBaseUrl":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The deployment's URL when the run started, or null. It differs from `baseUrl` when `clanker run --base-url` overrode it."},"deploymentVersion":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The deployment's version when the run started, or null."},"git":{"type":"object","required":["branch","sha","dirty","subject"],"properties":{"branch":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The checked-out branch, or null."},"sha":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The full commit SHA, or null outside a git checkout."},"dirty":{"type":"boolean","description":"Whether the checkout had uncommitted changes."},"subject":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The commit's subject line, or null."}},"additionalProperties":false,"description":"The commit the run tested."},"coverage":{"anyOf":[{"type":"string","enum":["critical","acceptance","regression","exhaustive"]},{"type":"null"}],"description":"The coverage level the run selected, or null when it selected none."},"shardCount":{"type":"number","description":"How many shards the run is split into, 1 for a run started without one."},"finishedShards":{"type":"number","description":"How many of its shards have finished or been interrupted. The run finishes with its last."},"cleanup":{"anyOf":[{"$ref":"#/components/schemas/TestRunCleanupTotals"},{"type":"null"}],"description":"What deleting every shard's scope reported, or null when the deployment had no Fixture API."},"publishedBy":{"$ref":"#/components/schemas/TestRunPublisher"},"startedAt":{"type":"string","description":"When the run started, as an ISO 8601 timestamp."},"finishedAt":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"When the run finished or was marked interrupted, as an ISO 8601 timestamp, or null while running."},"durationMs":{"type":"number","description":"How long the run took, in milliseconds: its longest shard's duration, as reported. 0 while running."}},"additionalProperties":false,"description":"A test run without its retries and tests: what it tested, its state, result and counts.","examples":[{"id":"Tr8KcW3nPx5Q","number":1289,"url":"https://clankership.com/w/acme/test-runs/1289","state":"finished","result":"passed","counts":{"total":2,"passed":1,"flaky":1,"failed":0,"skipped":0},"passRate":1,"firstAttemptPassRate":0.5,"error":null,"product":{"slug":"storefront","name":"Storefront"},"environment":{"slug":"staging","name":"Staging","class":"non-production"},"baseUrl":"https://staging.acme.dev","deploymentBaseUrl":"https://staging.acme.dev","deploymentVersion":"9f2c41e","git":{"branch":"web-31-docs-search","sha":"9f2c41e7b8a3d5c6f1e0b2a4d6c8e0f1a3b5c7d9","dirty":false,"subject":"Add docs search"},"coverage":null,"shardCount":1,"finishedShards":1,"cleanup":{"scopes":["scp_7h2k9q2m4x1a"],"expiresAt":"2026-10-14T15:40:00.000Z","status":"complete","deleted":214,"remaining":0},"publishedBy":{"kind":"user","name":"Maya Patel","email":"maya@acme.dev"},"startedAt":"2026-10-14T09:40:00.000Z","finishedAt":"2026-10-14T09:42:31.000Z","durationMs":151230}]},"TestRunCleanupTotals":{"type":"object","required":["scopes","expiresAt","status","deleted","remaining"],"properties":{"scopes":{"type":"array","items":{"type":"string","description":"The scope's ID: `scp_` and 12 lowercase letters or digits, such as scp_7h2k9q2m4x1a."},"description":"Every shard's scope, in shard order."},"expiresAt":{"type":"string","description":"When the last of the scopes expires, as an ISO 8601 timestamp. A later teardown on the deployment deletes what is left."},"status":{"anyOf":[{"type":"string","enum":["complete","incomplete","kept"],"description":"`complete` when nothing is left, `incomplete` when records are left or the teardown did not answer, `kept` when the publisher kept the data to debug a non-production environment."},{"type":"null"}],"description":"`incomplete` when any shard's cleanup is, else `kept` when any is, else `complete`. Null until every shard reports."},"deleted":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Records deleted across the shards, or null when a teardown did not answer."},"remaining":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Records left across the shards, or null when a teardown did not answer."}},"additionalProperties":false,"description":"What became of a run's test data across the scopes of all its shards.","examples":[{"scopes":["scp_7h2k9q2m4x1a"],"expiresAt":"2026-10-14T15:40:00.000Z","status":"complete","deleted":214,"remaining":0}]},"TestRunPublisher":{"anyOf":[{"type":"object","required":["kind","name","email"],"properties":{"kind":{"type":"string","enum":["user"],"description":"A person published it."},"name":{"type":"string","description":"The person's name."},"email":{"type":"string","description":"The person's email address."}},"additionalProperties":false},{"type":"object","required":["kind","name"],"properties":{"kind":{"type":"string","enum":["account_key"],"description":"An account API key published it, such as one CI uses."},"name":{"type":"string","description":"The account API key's name."}},"additionalProperties":false},{"type":"object","required":["kind"],"properties":{"kind":{"type":"string","enum":["removed"],"description":"The person or account API key no longer exists."}},"additionalProperties":false}],"description":"Who published a run or a retry: a person, an account API key, or one since removed.","examples":[{"kind":"user","name":"Maya Patel","email":"maya@acme.dev"}]},"FixtureGrant":{"type":"object","required":["scope","token","url","expiresAt"],"properties":{"scope":{"type":"string","description":"The scope's ID: `scp_` and 12 lowercase letters or digits, such as scp_7h2k9q2m4x1a."},"token":{"type":"string","description":"The fixture token: an EdDSA JWT that only `url` accepts, for this scope only. Send it as `Authorization: Bearer …` to the Fixture API."},"url":{"type":"string","description":"The Fixture API to call."},"expiresAt":{"type":"string","description":"When the token and the scope expire, as an ISO 8601 timestamp."}},"additionalProperties":false,"description":"A scope and the fixture token that lets a test run create and delete data in it.","examples":[{"scope":"scp_7h2k9q2m4x1a","token":"eyJhbGciOiJFZERTQSIsImtpZCI6ImZ4XzEifQ.eyJzY29wZSI6InNjcF83aDJrOXEybTR4MWEifQ.c2lnbmF0dXJl","url":"https://staging.acme.dev/fixtures","expiresAt":"2026-10-14T15:40:00.000Z"}]},"SemaphoreGrant":{"type":"object","required":["url","token","expiresAt"],"properties":{"url":{"type":"string","description":"Where lease routes start: `{url}/{name}/leases`."},"token":{"type":"string","description":"The run token, which holds leases for this shard or retry. Only Clanker Ship accepts it."},"expiresAt":{"type":"string","description":"When the run token expires, six hours after it was issued."}},"additionalProperties":false,"description":"Where a shard or retry takes semaphore leases, and the run token it takes them with.","examples":[{"url":"https://api.clankership.com/v1/workspaces/Wk7Qm2RtXa9L/semaphores","token":"eyJhbGciOiJFZERTQSIsImtpZCI6ImZ4XzEifQ.eyJraW5kIjoicnVuIiwicnVuIjoxMjg5fQ.c2lnbmF0dXJl","expiresAt":"2026-10-14T15:40:00.000Z"}]},"TestRun":{"type":"object","required":["id","number","url","state","result","counts","passRate","firstAttemptPassRate","error","product","environment","baseUrl","deploymentBaseUrl","deploymentVersion","git","coverage","shardCount","finishedShards","cleanup","publishedBy","startedAt","finishedAt","durationMs","shards","retries","tests"],"properties":{"id":{"type":"string","description":"Unique ID of the test run."},"number":{"type":"number","description":"The run's number, counting up from 1 in each workspace, such as 1289."},"url":{"type":"string","description":"The run's page on the website."},"state":{"type":"string","enum":["running","finished","interrupted"],"description":"`running` until its last shard finishes, then `finished`, or `interrupted` when any shard was. One still running after 6 hours becomes `interrupted`."},"result":{"anyOf":[{"type":"string","enum":["passed","failed"]},{"type":"null"}],"description":"`passed` when the run has no error and no failed test, otherwise `failed`. Flaky tests count as passed. Null while running and for interrupted runs."},"counts":{"type":"object","required":["total","passed","flaky","failed","skipped"],"properties":{"total":{"type":"number","description":"Every test in the run."},"passed":{"type":"number","description":"Tests that passed on attempt 1."},"flaky":{"type":"number","description":"Tests that failed on attempt 1 and then passed every attempt of a retry."},"failed":{"type":"number","description":"Tests that are still failed."},"skipped":{"type":"number","description":"Tests that were skipped."}},"additionalProperties":false,"description":"How many tests have each status."},"passRate":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"(passed + flaky) ÷ (tests − skipped), from 0 to 1. Null while running or when no test counts."},"firstAttemptPassRate":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Tests that passed on attempt 1 ÷ (tests − skipped), from 0 to 1. Retries never change it. Null while running or when no test counts."},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"What failed outside the tests, such as a web server that did not start, or `No tests ran.` In a run with several shards, each shard's error starts with `Shard 2 of 4:`. A run with an error is failed and cannot be retried."},"product":{"type":"object","required":["slug","name"],"properties":{"slug":{"type":"string","description":"The product's slug, such as storefront."},"name":{"type":"string","description":"The product's display name."}},"additionalProperties":false,"description":"The product the run tested."},"environment":{"type":"object","required":["slug","name","class"],"properties":{"slug":{"type":"string","description":"The environment's slug, such as staging."},"name":{"type":"string","description":"The environment's display name."},"class":{"type":"string","description":"The environment's class: production or non-production."}},"additionalProperties":false,"description":"The environment the run tested."},"baseUrl":{"type":"string","description":"The URL the tests ran against."},"deploymentBaseUrl":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The deployment's URL when the run started, or null. It differs from `baseUrl` when `clanker run --base-url` overrode it."},"deploymentVersion":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The deployment's version when the run started, or null."},"git":{"type":"object","required":["branch","sha","dirty","subject"],"properties":{"branch":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The checked-out branch, or null."},"sha":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The full commit SHA, or null outside a git checkout."},"dirty":{"type":"boolean","description":"Whether the checkout had uncommitted changes."},"subject":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The commit's subject line, or null."}},"additionalProperties":false,"description":"The commit the run tested."},"coverage":{"anyOf":[{"type":"string","enum":["critical","acceptance","regression","exhaustive"]},{"type":"null"}],"description":"The coverage level the run selected, or null when it selected none."},"shardCount":{"type":"number","description":"How many shards the run is split into, 1 for a run started without one."},"finishedShards":{"type":"number","description":"How many of its shards have finished or been interrupted. The run finishes with its last."},"cleanup":{"anyOf":[{"$ref":"#/components/schemas/TestRunCleanupTotals"},{"type":"null"}],"description":"What deleting every shard's scope reported, or null when the deployment had no Fixture API."},"publishedBy":{"$ref":"#/components/schemas/TestRunPublisher"},"startedAt":{"type":"string","description":"When the run started, as an ISO 8601 timestamp."},"finishedAt":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"When the run finished or was marked interrupted, as an ISO 8601 timestamp, or null while running."},"durationMs":{"type":"number","description":"How long the run took, in milliseconds: its longest shard's duration, as reported. 0 while running."},"shards":{"type":"array","items":{"$ref":"#/components/schemas/TestRunShard"},"description":"The shards that have started, by index."},"retries":{"type":"array","items":{"$ref":"#/components/schemas/TestRunRetry"},"description":"The run's retries, oldest first."},"tests":{"type":"array","items":{"$ref":"#/components/schemas/TestResult"},"description":"Every test, failed first, then flaky, passed and skipped, by title."}},"additionalProperties":false,"description":"A test run with its shards, its retries and every test with its attempts.","examples":[{"id":"Tr8KcW3nPx5Q","number":1289,"url":"https://clankership.com/w/acme/test-runs/1289","state":"finished","result":"passed","counts":{"total":2,"passed":1,"flaky":1,"failed":0,"skipped":0},"passRate":1,"firstAttemptPassRate":0.5,"error":null,"product":{"slug":"storefront","name":"Storefront"},"environment":{"slug":"staging","name":"Staging","class":"non-production"},"baseUrl":"https://staging.acme.dev","deploymentBaseUrl":"https://staging.acme.dev","deploymentVersion":"9f2c41e","git":{"branch":"web-31-docs-search","sha":"9f2c41e7b8a3d5c6f1e0b2a4d6c8e0f1a3b5c7d9","dirty":false,"subject":"Add docs search"},"coverage":null,"shardCount":1,"finishedShards":1,"cleanup":{"scopes":["scp_7h2k9q2m4x1a"],"expiresAt":"2026-10-14T15:40:00.000Z","status":"complete","deleted":214,"remaining":0},"publishedBy":{"kind":"user","name":"Maya Patel","email":"maya@acme.dev"},"startedAt":"2026-10-14T09:40:00.000Z","finishedAt":"2026-10-14T09:42:31.000Z","durationMs":151230,"shards":[{"index":1,"state":"finished","machine":{"hostname":"maya-mbp","platform":"darwin"},"testCount":2,"error":null,"cleanup":{"scope":"scp_7h2k9q2m4x1a","expiresAt":"2026-10-14T15:40:00.000Z","status":"complete","deleted":214,"remaining":0},"durationMs":151230,"startedAt":"2026-10-14T09:40:00.000Z","finishedAt":"2026-10-14T09:42:31.000Z"}],"retries":[{"number":1,"state":"finished","requiredPasses":2,"testCount":1,"flakyCount":1,"baseUrl":"https://staging.acme.dev","gitSha":"9f2c41e7b8a3d5c6f1e0b2a4d6c8e0f1a3b5c7d9","cleanup":{"scope":"scp_q8w3e5r7t9y2","expiresAt":"2026-10-14T15:40:00.000Z","status":"complete","deleted":12,"remaining":0},"publishedBy":{"kind":"user","name":"Maya Patel","email":"maya@acme.dev"},"startedAt":"2026-10-14T09:44:05.000Z","finishedAt":"2026-10-14T09:44:22.000Z"}],"tests":[{"caseId":"checkout-applies-coupon","title":"checkout › applies a coupon","file":"checkout.spec.ts","coverage":"critical","testKind":"behavior","priority":null,"status":"flaky","durationMs":4105,"errorMessage":"Timed out 5000ms waiting for expect(locator).toHaveText(\"$45.00\")","files":["case.md","spec.ts"],"attempts":[{"number":1,"shard":1,"retry":null,"status":"failed","durationMs":30412,"startedAt":"2026-10-14T09:40:12.000Z","errorMessage":"Timed out 5000ms waiting for expect(locator).toHaveText(\"$45.00\")","errorStack":"Error: Timed out 5000ms waiting for expect(locator).toHaveText(\"$45.00\")\n    at checkout.spec.ts:24:41","files":["video.webm","trace.zip","screenshot-1.png"]},{"number":2,"shard":null,"retry":1,"status":"passed","durationMs":4210,"startedAt":"2026-10-14T09:44:07.000Z","errorMessage":null,"errorStack":null,"files":[]},{"number":3,"shard":null,"retry":1,"status":"passed","durationMs":4105,"startedAt":"2026-10-14T09:44:13.000Z","errorMessage":null,"errorStack":null,"files":[]}]},{"caseId":"docs-search-finds-guides","title":"docs › search finds guides","file":"docs.spec.ts","coverage":"acceptance","testKind":"journey","priority":null,"status":"passed","durationMs":6820,"errorMessage":null,"files":["case.md","spec.ts"],"attempts":[{"number":1,"shard":1,"retry":null,"status":"passed","durationMs":6820,"startedAt":"2026-10-14T09:40:12.000Z","errorMessage":null,"errorStack":null,"files":[]}]}]}]},"TestRunShard":{"type":"object","required":["index","state","machine","testCount","error","cleanup","durationMs","startedAt","finishedAt"],"properties":{"index":{"type":"number","description":"The shard's index in the run, from 1, as in `--shard 2/4`."},"state":{"type":"string","enum":["running","finished","interrupted"],"description":"`running` until its publisher finishes it as `finished` or `interrupted`. One still running after 6 hours becomes `interrupted`."},"machine":{"type":"object","required":["hostname","platform"],"properties":{"hostname":{"type":"string","description":"The computer's hostname, such as maya-mbp."},"platform":{"type":"string","description":"The operating system as Node.js names it, such as darwin, linux or win32."}},"additionalProperties":false,"description":"The computer that ran the shard."},"testCount":{"type":"number","description":"How many tests the shard reported."},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"What failed outside the shard's tests, or what its cleanup left behind, or null. It fails the run."},"cleanup":{"anyOf":[{"$ref":"#/components/schemas/TestRunCleanup"},{"type":"null"}],"description":"The shard's own scope and what deleting it reported, or null when the deployment had no Fixture API."},"durationMs":{"type":"number","description":"How long the shard took, in milliseconds, as reported. 0 while running."},"startedAt":{"type":"string","description":"When the shard started, as an ISO 8601 timestamp."},"finishedAt":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"When the shard finished or was marked interrupted, as an ISO 8601 timestamp, or null while running."}},"additionalProperties":false,"description":"One machine's share of a run: the tests Playwright's `--shard` gave it, its scope and what it reported. A run started without a shard has shard 1 only.","examples":[{"index":1,"state":"finished","machine":{"hostname":"maya-mbp","platform":"darwin"},"testCount":2,"error":null,"cleanup":{"scope":"scp_7h2k9q2m4x1a","expiresAt":"2026-10-14T15:40:00.000Z","status":"complete","deleted":214,"remaining":0},"durationMs":151230,"startedAt":"2026-10-14T09:40:00.000Z","finishedAt":"2026-10-14T09:42:31.000Z"}]},"TestRunCleanup":{"type":"object","required":["scope","expiresAt","status","deleted","remaining"],"properties":{"scope":{"type":"string","description":"The scope's ID: `scp_` and 12 lowercase letters or digits, such as scp_7h2k9q2m4x1a."},"expiresAt":{"type":"string","description":"When the scope expires, as an ISO 8601 timestamp. A later teardown on the deployment deletes what is left."},"status":{"anyOf":[{"type":"string","enum":["complete","incomplete","kept"],"description":"`complete` when nothing is left, `incomplete` when records are left or the teardown did not answer, `kept` when the publisher kept the data to debug a non-production environment."},{"type":"null"}],"description":"How the cleanup ended, or null until the run reports it."},"deleted":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"How many records the teardown deleted, or null when it did not answer."},"remaining":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"How many records are left in the scope, or null when the teardown did not answer."}},"additionalProperties":false,"description":"The scope a shard or retry made its test data in through the deployment's Fixture API, and what deleting it reported.","examples":[{"scope":"scp_7h2k9q2m4x1a","expiresAt":"2026-10-14T15:40:00.000Z","status":"complete","deleted":214,"remaining":0}]},"TestRunRetry":{"type":"object","required":["number","state","requiredPasses","testCount","flakyCount","baseUrl","gitSha","cleanup","publishedBy","startedAt","finishedAt"],"properties":{"number":{"type":"number","description":"The retry's number within the run, from 1."},"state":{"type":"string","enum":["running","finished","interrupted"],"description":"`running` until its publisher finishes it as `finished` or `interrupted`. One still running after 6 hours becomes `interrupted`."},"requiredPasses":{"type":"number","description":"How many passing attempts a failed test needed in this retry to count as flaky."},"testCount":{"type":"number","description":"How many failed tests it ran again."},"flakyCount":{"type":"number","description":"How many of them it turned flaky."},"baseUrl":{"type":"string","description":"The URL the retry ran against."},"gitSha":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The commit it ran on, which is always the run's commit."},"cleanup":{"anyOf":[{"$ref":"#/components/schemas/TestRunCleanup"},{"type":"null"}],"description":"The retry's own scope and what deleting it reported, or null when the run had no Fixture API."},"publishedBy":{"$ref":"#/components/schemas/TestRunPublisher"},"startedAt":{"type":"string","description":"When the retry started, as an ISO 8601 timestamp."},"finishedAt":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"When the retry finished or was marked interrupted, as an ISO 8601 timestamp, or null while running."}},"additionalProperties":false,"description":"One `clanker retry` of a run's failed tests, on the commit the run tested.","examples":[{"number":1,"state":"finished","requiredPasses":2,"testCount":1,"flakyCount":1,"baseUrl":"https://staging.acme.dev","gitSha":"9f2c41e7b8a3d5c6f1e0b2a4d6c8e0f1a3b5c7d9","cleanup":{"scope":"scp_q8w3e5r7t9y2","expiresAt":"2026-10-14T15:40:00.000Z","status":"complete","deleted":12,"remaining":0},"publishedBy":{"kind":"user","name":"Maya Patel","email":"maya@acme.dev"},"startedAt":"2026-10-14T09:44:05.000Z","finishedAt":"2026-10-14T09:44:22.000Z"}]},"TestResult":{"type":"object","required":["caseId","title","file","coverage","testKind","priority","status","durationMs","errorMessage","files","attempts"],"properties":{"caseId":{"type":"string","description":"The case ID: the spec's `@id` tag, or one derived from its file and title, such as checkout-applies-coupon."},"title":{"type":"string","description":"The test's title path as Playwright reports it, such as checkout › applies a coupon."},"file":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The spec file the test is in, such as checkout.spec.ts, or null."},"coverage":{"anyOf":[{"type":"string","enum":["critical","acceptance","regression","exhaustive"]},{"type":"null"}],"description":"The case's coverage level, or null when it has none."},"testKind":{"anyOf":[{"type":"string","enum":["behavior","journey"]},{"type":"null"}],"description":"Whether the case is a `behavior` or a `journey`, or null."},"priority":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The case's priority, such as P1, or null."},"status":{"type":"string","enum":["failed","flaky","passed","skipped"],"description":"Attempt 1 decides `passed`, `failed` or `skipped`. A failed test becomes `flaky` when one retry runs it at least `requiredPasses` times and every attempt passes."},"durationMs":{"type":"number","description":"How long its latest attempt took, in milliseconds."},"errorMessage":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The error of its latest failed attempt, or null."},"files":{"type":"array","items":{"type":"string"},"description":"The case files uploaded to `results/{case}/`: case.md, spec.ts or both."},"attempts":{"type":"array","items":{"$ref":"#/components/schemas/TestAttempt"},"description":"Every attempt in order: attempt 1 from the run, later ones from retries."}},"additionalProperties":false,"description":"One test's result in a run, with every attempt.","examples":[{"caseId":"checkout-applies-coupon","title":"checkout › applies a coupon","file":"checkout.spec.ts","coverage":"critical","testKind":"behavior","priority":null,"status":"flaky","durationMs":4105,"errorMessage":"Timed out 5000ms waiting for expect(locator).toHaveText(\"$45.00\")","files":["case.md","spec.ts"],"attempts":[{"number":1,"shard":1,"retry":null,"status":"failed","durationMs":30412,"startedAt":"2026-10-14T09:40:12.000Z","errorMessage":"Timed out 5000ms waiting for expect(locator).toHaveText(\"$45.00\")","errorStack":"Error: Timed out 5000ms waiting for expect(locator).toHaveText(\"$45.00\")\n    at checkout.spec.ts:24:41","files":["video.webm","trace.zip","screenshot-1.png"]},{"number":2,"shard":null,"retry":1,"status":"passed","durationMs":4210,"startedAt":"2026-10-14T09:44:07.000Z","errorMessage":null,"errorStack":null,"files":[]},{"number":3,"shard":null,"retry":1,"status":"passed","durationMs":4105,"startedAt":"2026-10-14T09:44:13.000Z","errorMessage":null,"errorStack":null,"files":[]}]}]},"TestAttempt":{"type":"object","required":["number","shard","retry","status","durationMs","startedAt","errorMessage","errorStack","files"],"properties":{"number":{"type":"number","description":"The attempt's number for its test, from 1. Attempt 1 comes from a shard of the run."},"shard":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"The index of the shard that ran attempt 1, or null for a retry's attempts."},"retry":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"The number of the retry that ran this attempt, or null for attempt 1."},"status":{"type":"string","enum":["passed","failed","timed_out","interrupted","skipped"],"description":"How the attempt ended, as Playwright reported it."},"durationMs":{"type":"number","description":"How long the attempt took, in milliseconds."},"startedAt":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"When the attempt started, as an ISO 8601 timestamp, or null."},"errorMessage":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The error Playwright reported, up to 4,000 characters, or null."},"errorStack":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The error's stack trace, up to 20,000 characters, or null."},"files":{"type":"array","items":{"type":"string"},"description":"The evidence uploaded to `results/{case}/attempts/{n}/`: video.webm, trace.zip and screenshot-{k}.png."}},"additionalProperties":false,"description":"One execution of a test, with its evidence. Attempts are never removed.","examples":[{"number":1,"shard":1,"retry":null,"status":"failed","durationMs":30412,"startedAt":"2026-10-14T09:40:12.000Z","errorMessage":"Timed out 5000ms waiting for expect(locator).toHaveText(\"$45.00\")","errorStack":"Error: Timed out 5000ms waiting for expect(locator).toHaveText(\"$45.00\")\n    at checkout.spec.ts:24:41","files":["video.webm","trace.zip","screenshot-1.png"]}]},"TestRunCleanupReport":{"type":"object","required":["status","deleted","remaining","error"],"properties":{"status":{"type":"string","enum":["complete","incomplete","kept"],"description":"`complete` when nothing is left, `incomplete` when records are left or the teardown did not answer, `kept` when the publisher kept the data to debug a non-production environment."},"deleted":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"How many records the teardown deleted, or null when it did not answer."},"remaining":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"How many records are left in the scope, or null when the teardown did not answer."},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Why the teardown could not finish, or null."}},"additionalProperties":false,"description":"What deleting the scope reported. `kept` is refused on production environments, `complete` with records left is refused, and a run whose cleanup is incomplete fails.","examples":[{"status":"complete","deleted":214,"remaining":0,"error":null}]},"Semaphore":{"type":"object","required":["name","capacity","holders"],"properties":{"name":{"type":"string","description":"The semaphore's name in the workspace, such as payments-sandbox."},"capacity":{"type":"number","description":"How many leases it allows at once, 1 to 100. The first lease sets it."},"holders":{"type":"array","items":{"type":"object","required":["lease","run","retry","test","since","expiresAt"],"properties":{"lease":{"type":"string","description":"The lease's ID."},"run":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"The number of the run that holds it, or null."},"retry":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"The number of the retry that holds it, or null when the run itself does."},"test":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The test that took it, as the run reported, or null."},"since":{"type":"string","description":"When the lease was taken, as an ISO 8601 timestamp."},"expiresAt":{"type":"string","description":"When the lease ends unless its holder renews it, as an ISO 8601 timestamp."}},"additionalProperties":false},"description":"The leases held now, oldest first."}},"additionalProperties":false,"description":"A named limit on how many tests may use a resource at once, with its holders.","examples":[{"name":"payments-sandbox","capacity":1,"holders":[{"lease":"Ls4TnV8qWm2C","run":1289,"retry":null,"test":"checkout › applies a coupon","since":"2026-10-14T09:40:20.000Z","expiresAt":"2026-10-14T09:41:20.000Z"}]}]},"VaultProduct":{"type":"object","required":["id","name","slug","type","description","repository","archivedAt","createdAt","updatedAt","environments","secrets"],"properties":{"id":{"type":"string","description":"Unique ID of the product."},"name":{"type":"string","description":"The product's display name."},"slug":{"type":"string","description":"The product's slug, such as storefront."},"type":{"type":"string","enum":["website","api","cli","mobile_app","desktop_app","agent"],"description":"What kind of software the product is."},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"A short description, or null."},"repository":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The source repository, such as acme/storefront, or null."},"archivedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Always null: the vault lists only active products."},"createdAt":{"type":"string","format":"date-time","description":"When the product was created, as an ISO 8601 timestamp."},"updatedAt":{"type":"string","format":"date-time","description":"When the product last changed, as an ISO 8601 timestamp."},"environments":{"type":"array","items":{"type":"object","required":["id","slug","name","class"],"properties":{"id":{"type":"string","description":"Unique ID of the environment."},"slug":{"type":"string","description":"The environment's slug, such as staging."},"name":{"type":"string","description":"The environment's display name."},"class":{"type":"string","enum":["production","non-production"],"description":"Production holds real customer data; everything else is non-production."}},"additionalProperties":false,"description":"An active environment the product is deployed to."},"description":"The active environments the product is deployed to, in the order it was deployed."},"secrets":{"type":"array","items":{"$ref":"#/components/schemas/SecretSummary"},"description":"The product's secrets."}},"additionalProperties":false,"description":"An active product with the environments it is deployed to and its secrets.","examples":[{"id":"Pr4GtY9sLm3B","name":"Storefront","slug":"storefront","type":"website","description":"The customer-facing shop.","repository":"acme/storefront","archivedAt":null,"createdAt":"2026-10-01T16:20:00.000Z","updatedAt":"2026-10-14T09:05:12.000Z","environments":[{"id":"En8RqZ2vKp5D","slug":"staging","name":"Staging","class":"non-production"},{"id":"En1MwX6cTb7F","slug":"production","name":"Production","class":"production"}],"secrets":[{"id":"Sc4VnJ7qTr2X","name":"DATABASE_URL","values":{"staging":{"isSet":true,"version":3,"value":"postgres://storefront@db.staging.acme.dev:5432/storefront"},"production":{"isSet":true,"version":2}}}]}]},"SecretSummary":{"type":"object","required":["id","name","values"],"properties":{"id":{"type":"string","description":"Unique ID of the secret."},"name":{"type":"string","description":"Letters, digits and underscores, starting with a letter or underscore, at most 255 characters and unique on the product, such as DATABASE_URL."},"values":{"type":"object","required":[],"properties":{},"additionalProperties":{"type":"object","required":["isSet","version"],"properties":{"isSet":{"type":"boolean","description":"Whether the environment has a value now."},"version":{"type":"integer","description":"The current version number, or 0 when the environment has no version yet."},"publicKey":{"type":"string","description":"The SPKI PEM public key, present when the value is a generated Ed25519 key pair."},"value":{"type":"string","description":"The plaintext value. Present only for a set value in a non-production environment."}},"additionalProperties":false,"description":"The secret's current version in one environment."},"description":"The current version in each environment the product is deployed to, keyed by environment slug."}},"additionalProperties":false,"description":"A secret's name and its current version in each environment.","examples":[{"id":"Sc4VnJ7qTr2X","name":"DATABASE_URL","values":{"staging":{"isSet":true,"version":3,"value":"postgres://storefront@db.staging.acme.dev:5432/storefront"},"production":{"isSet":true,"version":2}}}]},"SecretWrite":{"type":"object","required":["product","environment","status"],"properties":{"product":{"type":"string","description":"The product's slug, such as storefront."},"environment":{"type":"string","description":"The environment's slug, such as staging."},"status":{"type":"string","enum":["written","skipped"],"description":"`written` when the environment holds the value, or `skipped` when the caller's role may not write there, such as a member writing production."},"version":{"type":"integer","description":"The version that holds the value. A retry with the same `requestId` returns the first write's version. Absent when skipped."},"publicKey":{"type":"string","description":"The SPKI PEM public key, present when the value is an Ed25519 key pair."},"value":{"type":"string","description":"The generated value. Present only when a generation sends `reveal: true`, and never on a retry."}},"additionalProperties":false,"description":"What a write did to one product in one environment.","examples":[{"product":"storefront","environment":"staging","status":"written","version":4}]},"Secret":{"type":"object","required":["id","name","createdAt","product","environments","values"],"properties":{"id":{"type":"string","description":"Unique ID of the secret."},"name":{"type":"string","description":"Letters, digits and underscores, starting with a letter or underscore, at most 255 characters and unique on the product, such as DATABASE_URL."},"createdAt":{"type":"string","format":"date-time","description":"When the secret was created, as an ISO 8601 timestamp."},"product":{"type":"object","required":["id","slug","name","type"],"properties":{"id":{"type":"string","description":"Unique ID of the product."},"slug":{"type":"string","description":"The product's slug, such as storefront."},"name":{"type":"string","description":"The product's display name."},"type":{"type":"string","enum":["website","api","cli","mobile_app","desktop_app","agent"],"description":"What kind of software the product is."}},"additionalProperties":false,"description":"The product the secret belongs to."},"environments":{"type":"array","items":{"type":"object","required":["id","slug","name","class"],"properties":{"id":{"type":"string","description":"Unique ID of the environment."},"slug":{"type":"string","description":"The environment's slug, such as staging."},"name":{"type":"string","description":"The environment's display name."},"class":{"type":"string","enum":["production","non-production"],"description":"Production holds real customer data; everything else is non-production."}},"additionalProperties":false,"description":"An active environment the product is deployed to."},"description":"The active environments the product is deployed to, in the order it was deployed."},"values":{"type":"object","required":[],"properties":{},"additionalProperties":{"type":"object","required":["version","isSet"],"properties":{"version":{"type":"integer","description":"The current version number, or 0 when the environment has no version yet."},"isSet":{"type":"boolean","description":"Whether the environment has a value now."},"generator":{"anyOf":[{"$ref":"#/components/schemas/SecretGenerator"},{"type":"null"}],"description":"How the value was generated, or null when it was set by hand. Absent while the environment has no version."},"publicKey":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The SPKI PEM public key of a generated Ed25519 key pair, or null. Absent while the environment has no version."},"restoredFrom":{"anyOf":[{"type":"integer","description":"an integer"},{"type":"null"}],"description":"The earlier version the current version restored, or null. Absent while the environment has no version."},"createdAt":{"type":"string","format":"date-time","description":"When the current version was written, as an ISO 8601 timestamp. Absent while the environment has no version."},"actor":{"anyOf":[{"type":"object","required":["id","type","name"],"properties":{"id":{"type":"string","description":"Unique ID of the user or account API key."},"type":{"type":"string","enum":["user","accountApiKey"],"description":"Whether a user or an account API key wrote the version."},"name":{"type":"string","description":"The user's name, or their email when the name is empty, or the key's name."}},"additionalProperties":false,"description":"The user or account API key that wrote the version."},{"type":"null"}],"description":"Who wrote the current version, or null when they can no longer be found. Absent while the environment has no version."},"value":{"type":"string","description":"The plaintext value. Present only for a set value in a non-production environment."}},"additionalProperties":false,"description":"The current version of the secret in one environment."},"description":"The current version in each of those environments, keyed by environment slug."}},"additionalProperties":false,"description":"A named value on a product with one version history per environment. Production values never appear.","examples":[{"id":"Sc4VnJ7qTr2X","name":"DATABASE_URL","createdAt":"2026-10-01T16:20:00.000Z","product":{"id":"Pr4GtY9sLm3B","slug":"storefront","name":"Storefront","type":"website"},"environments":[{"id":"En8RqZ2vKp5D","slug":"staging","name":"Staging","class":"non-production"},{"id":"En1MwX6cTb7F","slug":"production","name":"Production","class":"production"}],"values":{"staging":{"version":3,"isSet":true,"generator":null,"publicKey":null,"restoredFrom":null,"createdAt":"2026-10-14T09:05:12.000Z","actor":{"id":"Us3NfP8kLq2V","type":"user","name":"Maya Patel"},"value":"postgres://storefront@db.staging.acme.dev:5432/storefront"},"production":{"version":2,"isSet":true,"generator":null,"publicKey":null,"restoredFrom":null,"createdAt":"2026-10-01T16:20:00.000Z","actor":{"id":"Us3NfP8kLq2V","type":"user","name":"Maya Patel"}}}}]},"SecretGenerator":{"anyOf":[{"type":"object","required":["type","bytes","encoding"],"properties":{"type":{"type":"string","enum":["token"],"description":"Random bytes."},"bytes":{"type":"integer","description":"How many random bytes, from 16 to 512."},"encoding":{"type":"string","enum":["hex","base64","base64url"],"description":"How the bytes are written as text."}},"additionalProperties":false,"description":"A random token."},{"type":"object","required":["type","length","lowercase","uppercase","digits","symbols"],"properties":{"type":{"type":"string","enum":["password"],"description":"A random password."},"length":{"type":"integer","description":"How many characters, from 8 to 256."},"lowercase":{"type":"boolean","description":"Whether it uses a to z."},"uppercase":{"type":"boolean","description":"Whether it uses A to Z."},"digits":{"type":"boolean","description":"Whether it uses 0 to 9."},"symbols":{"type":"boolean","description":"Whether it uses the symbols -_.~+=."}},"additionalProperties":false,"description":"A random password with at least one character from each class it uses."},{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["uuid"],"description":"A random version 4 UUID."}},"additionalProperties":false,"description":"A random version 4 UUID."},{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["ed25519"],"description":"An Ed25519 key pair."}},"additionalProperties":false,"description":"An Ed25519 key pair. The value is the PKCS#8 PEM private key, and `publicKey` holds the SPKI PEM public key."}],"description":"How a value was generated, with every option filled in.","examples":[{"type":"token","bytes":32,"encoding":"hex"}]},"SecretVersion":{"type":"object","required":["version","isSet","generator","publicKey","restoredFrom","createdAt","actor"],"properties":{"version":{"type":"integer","description":"The version number. Each write to an environment adds one, starting at 1."},"isSet":{"type":"boolean","description":"False when this version cleared the value."},"generator":{"anyOf":[{"$ref":"#/components/schemas/SecretGenerator"},{"type":"null"}],"description":"How the value was generated, or null when it was set by hand."},"publicKey":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The SPKI PEM public key of a generated Ed25519 key pair, or null. It is not secret, so production versions show it too."},"restoredFrom":{"anyOf":[{"type":"integer","description":"an integer"},{"type":"null"}],"description":"The earlier version this version restored, or null."},"createdAt":{"type":"string","format":"date-time","description":"When the version was written, as an ISO 8601 timestamp."},"actor":{"anyOf":[{"type":"object","required":["id","type","name"],"properties":{"id":{"type":"string","description":"Unique ID of the user or account API key."},"type":{"type":"string","enum":["user","accountApiKey"],"description":"Whether a user or an account API key wrote the version."},"name":{"type":"string","description":"The user's name, or their email when the name is empty, or the key's name."}},"additionalProperties":false,"description":"The user or account API key that wrote the version."},{"type":"null"}],"description":"Who wrote the version, or null when they can no longer be found."},"value":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The plaintext value, or null for a version that cleared it. Present only when the request sends `values=true`."}},"additionalProperties":false,"description":"One write to a secret in one environment.","examples":[{"version":3,"isSet":true,"generator":null,"publicKey":null,"restoredFrom":null,"createdAt":"2026-10-14T09:05:12.000Z","actor":{"id":"Us3NfP8kLq2V","type":"user","name":"Maya Patel"},"value":"postgres://storefront@db.staging.acme.dev:5432/storefront"}]},"VaultKey":{"type":"object","required":["id","name","productIds","environmentIds","createdAt"],"properties":{"id":{"type":"string","description":"Unique ID of the vault key."},"name":{"type":"string","description":"The key's name, such as Storefront runtime."},"productIds":{"type":"array","items":{"type":"string"},"description":"IDs of the products whose secrets the key can pull."},"environmentIds":{"type":"array","items":{"type":"string"},"description":"IDs of the production environments the key can pull from."},"createdAt":{"type":"string","format":"date-time","description":"When the key was created, as an ISO 8601 timestamp."}},"additionalProperties":false,"description":"A key that pulls production secrets for the products and environments it names.","examples":[{"id":"Vk8MtR3pLx6N","name":"Storefront runtime","productIds":["Pr4GtY9sLm3B"],"environmentIds":["En1MwX6cTb7F"],"createdAt":"2026-10-01T16:20:00.000Z"}]},"CreatedVaultKey":{"type":"object","required":["id","name","productIds","environmentIds","secret"],"properties":{"id":{"type":"string","description":"Unique ID of the vault key."},"name":{"type":"string","description":"The key's name."},"productIds":{"type":"array","items":{"type":"string"},"description":"IDs of the products whose secrets the key can pull."},"environmentIds":{"type":"array","items":{"type":"string"},"description":"IDs of the production environments the key can pull from."},"secret":{"type":"string","description":"The key, starting with ctvk_. It is shown only in this response."}},"additionalProperties":false,"description":"A new vault key with its value, which is never shown again.","examples":[{"id":"Vk8MtR3pLx6N","name":"Storefront runtime","productIds":["Pr4GtY9sLm3B"],"environmentIds":["En1MwX6cTb7F"],"secret":"ctvk_7HqP2mXv9LsR4tWc8NbK3dFj6YgZ1aQe"}]}},"securitySchemes":{"apiKey":{"description":"A user API key (`ctk_…`) or a workspace API key (`cwk_…`) in the `X-API-Key` header.","type":"apiKey","name":"x-api-key","in":"header"},"bearer":{"description":"The same API key as a bearer token, `Authorization: Bearer ctk_…`, or a CLI access token.","type":"http","scheme":"bearer"}}},"security":[],"tags":[{"name":"Profile","description":"Your profile is the user an API key acts for: name, email address and photo, plus which emails you want. Account API keys can read their own profile but not change one.","x-section":"Account","x-object":"User"},{"name":"API keys","description":"An API key lets scripts and tools call the API as you, with your role in each workspace. Send it as `Authorization: Bearer ctk_…` or `X-API-Key: ctk_…`. Its secret is shown once, when the key is created.","x-section":"Account","x-object":"ApiKey"},{"name":"CLI sign-ins","description":"A CLI sign-in is one computer where `clanker auth login` signed in as you. The website's Security settings list them too.","x-section":"Account","x-object":"CliSession"},{"name":"Workspaces","description":"A workspace holds a company's products, environments, planning, test runs and secrets, and the people who work on them. Every other resource belongs to one workspace, named in paths by its slug or ID.","x-section":"Workspaces","x-object":"Workspace"},{"name":"Members","description":"A member is a person in a workspace with one role: owner, admin, member or viewer. Owners and admins manage members and invites, members do the work, and viewers only read.","x-section":"Workspaces","x-object":"Member"},{"name":"Invites","description":"An invite asks one email address to join a workspace with a role and, optionally, teams. Its emailed link holds a secret token, and accepting it makes the person a member.","x-section":"Workspaces","x-object":"Invite"},{"name":"Events","description":"An event records one change in a workspace, such as a role change, a new invite or a ticket update, and who made it: a person, a clanker acting for a person, or an account API key.","x-section":"Workspaces","x-object":"Event"},{"name":"Account API keys","description":"An account API key (`ctk_…`) belongs to one workspace instead of a person, so CI and other automation can call the API. It acts in that workspace with the role it was given. Admins and owners manage account API keys, and only owners manage keys with the owner role.","x-section":"Workspaces","x-object":"AccountApiKey"},{"name":"Pins","description":"A pin is a person's own shortcut to a ticket, project, product, environment or team, listed in the website's sidebar under Pinned in their order. Each person sees only their own pins, and a clanker changes the pins of the person it works for.","x-section":"Workspaces","x-object":"Pin"},{"name":"Products","description":"A product is a piece of software the workspace builds and tests, such as a website, an API or a CLI. It runs in environments through deployments, and its test runs and secrets belong to it.","x-section":"Catalog","x-object":"Product"},{"name":"Environments","description":"An environment is a place products run, such as staging or production. Every product in the workspace can deploy to it, and its class decides whether production rules apply.","x-section":"Catalog","x-object":"Environment"},{"name":"Deployments","description":"A deployment says that one product runs in one environment, at which URL and which version. Test runs target a deployment, and vault pulls read the secrets of one.","x-section":"Catalog","x-object":"Deployment"},{"name":"Teams","description":"A team is a group of workspace members that owns tickets. Its key, such as WEB, starts the IDs of its tickets (WEB-31), and each team has its own ticket statuses and views. Open teams are listed for everyone; private teams only for their members and for owners and admins.","x-section":"Planning","x-object":"Team"},{"name":"Projects","description":"A project is a body of work with a goal, kept in one priority order per workspace. It links the teams whose tickets it holds and the products it changes, and splits into milestones (M1, M2). Anyone who sees one of its teams can open it.","x-section":"Planning","x-object":"Project"},{"name":"Milestones","description":"A milestone is a checkpoint within a project, numbered M1, M2 and so on. A ticket in the project can belong to one of its milestones. A project returns its milestones, so there is no separate list.","x-section":"Planning","x-object":"Milestone"},{"name":"Tickets","description":"A ticket is one unit of work on a team. Its ID is the team key and number, such as WEB-31. Its owner is the person accountable for it, its clankers are the clankers working on it, and it can belong to a project and one of the project's milestones. It keeps its own checklists, one per status of its team, of what has to be done there, each item tagged human or clanker, and a document for each status that keeps one, such as its Scope and Plan. Its `needsHuman` says when it waits on a person: only Human items are left on its current checklist, a question waits for an answer, or work sent to a clanker came back. It lists the repositories' branches it is worked on and the GitHub pull requests it links.","x-section":"Planning","x-object":"Ticket"},{"name":"Ticket documents","description":"A ticket keeps a document for each of its team's statuses that keeps one: by default its Scope in Backlog, Plan in Plan, Build record in Build, Review in Review and Ship report in Ship. Documents are Markdown, and every write makes a revision. Writes name the revision they were made from, so two writers never overwrite each other.","x-section":"Planning","x-object":"TicketDocument"},{"name":"Ticket statuses","description":"A ticket status is a step in a team's workflow, such as Plan or Build, in one of seven fixed categories, the stages every ticket moves through: backlog, plan, build, review, ship, done and canceled. Each team has its own statuses, copied from the workspace's template when the team is created. A status holds a checklist template, which a ticket copies into its own checklist when it first enters the status, and instructions: the document its tickets keep there and how a clanker works it. Owners and admins add, rename, move and delete statuses; a team's members also change its statuses' templates and instructions.","x-section":"Planning","x-object":"TicketStatus"},{"name":"Tags","description":"A tag is a colored label on tickets, such as bug. Workspace tags work on every ticket and belong to owners and admins; team tags work only on their team's tickets, and the team's members manage them too.","x-section":"Planning","x-object":"Tag"},{"name":"Views","description":"A view is a saved way to look at tickets: filters, grouping, order and layout. Each view belongs to one team, one project or one person. Anyone who sees a team or project can read its views, and changes apply for everyone; a person's own views are the tabs of their My work and only they see them. Filters can name the reader: owner me, clanker mine, and mine for tickets the reader owns or their clankers work on.","x-section":"Planning","x-object":"View"},{"name":"Clanker instructions","description":"Clanker instructions that no status holds: the defaults a clanker's new ticket gets, and how to write test cases, specs, a Fixture API and test CI. A workspace and each team can set their own; a team's replace the workspace's, which replace Clanker Ship's defaults. Each status keeps its own instructions for its document and work; see Ticket statuses.","x-section":"Planning","x-object":"ClankerInstructions"},{"name":"Clankers","description":"A clanker is one clanker client, such as Codex or Claude Code, working for one workspace member. The plugin registers each computer the clanker runs on, and its sessions report the repository and branch they work in. Clankers work on tickets and receive messages.","x-section":"Clankers","x-object":"Clanker"},{"name":"Clanker sessions","description":"A clanker session is one conversation in a clanker's app, such as a Claude Code session, on one of its computers. Each session works on one ticket: the one its person picked, else the one its clanker created or linked in it, else the one its branch is linked to, else the one its branch's name carries.","x-section":"Clankers","x-object":"SessionView"},{"name":"Messages","description":"A message is work for a clanker: a ticket with an ask, or a mention in a ticket comment. It goes to one of the clanker's computers, a live one first and one working in the ticket's repository when several are live, and waits in the clanker's inbox until the clanker completes it. Clankers read and complete their messages with the inbox tools at `/mcp`.","x-section":"Clankers","x-object":"ClankerMessage"},{"name":"Comments","description":"A comment is Markdown on a ticket, written by a member or by a clanker working for one. Mentioning a clanker in a comment sends it a message with the comment.","x-section":"Clankers","x-object":"TicketComment"},{"name":"Notifications","description":"A notification tells a member about a clanker message (one someone sent to their clanker, or the completion or decline of one they sent), a question someone asked on a ticket they own, or a ticket of theirs that only Human items hold up. Each member has their own in each workspace.","x-section":"Clankers","x-object":"Notification"},{"name":"Test runs","description":"A test run is one run of a product's Playwright tests against its deployment in an environment, numbered per workspace, on one machine or split into shards across several. Start a shard, upload each test's files, then finish the shard with every test's first attempt; the run finishes with its last shard. A retry runs the failed tests again on the same commit, and a failed test that passes every retry attempt counts as flaky.","x-section":"Testing","x-object":"TestRun"},{"name":"Semaphores","description":"A semaphore limits how many tests use one shared resource at a time, such as a sandbox account or a rate-limited vendor API, across every worker and every run in the workspace. Runs take, renew and release leases with the run token from starting a run or a retry, at `POST /v1/workspaces/{slug}/semaphores/{name}/leases`, `POST …/leases/{lease}/renew` and `DELETE …/leases/{lease}`. The first lease creates the semaphore with its capacity, and finishing a shard or a retry releases every lease it still holds.","x-section":"Testing","x-object":"Semaphore"},{"name":"Fixture tokens","description":"A fixture token lets a test run create and delete test data through a deployment's Fixture API: routes in the product that make the records its tests need. Clanker Ship signs each token as an EdDSA JWT for one scope and one Fixture API, which verifies it against `GET /.well-known/jwks.json`. Starting a run or a retry returns one; create one here to test without publishing a run.","x-section":"Testing","x-object":"FixtureGrant"},{"name":"Secrets","description":"A secret is a named value on a product, such as DATABASE_URL, with its own version history in each environment the product is deployed to. Reads return non-production values only. Production values reach a deployment through a pull with a vault key, or once in the response that generated them.","x-section":"Secrets","x-object":"Secret"},{"name":"Vault keys","description":"A vault key (`ctvk_…`) lets a running deployment pull its production secrets. Each key names the products and production environments it may pull, and it cannot pull non-production values. Admins and owners create, change and revoke vault keys.","x-section":"Secrets","x-object":"VaultKey"},{"name":"Health","description":"Liveness checks that answer without an API key, outside the `/v1` prefix. Use them to tell whether the API is up.","x-section":"System"}],"servers":[{"url":"https://api.clankership.com","description":"Production"},{"url":"https://api.qa.clankership.net","description":"QA"},{"url":"http://127.0.0.1:3200","description":"Localhost"}],"x-tagGroups":[{"name":"Account","tags":["Profile","API keys","CLI sign-ins"]},{"name":"Workspaces","tags":["Workspaces","Members","Invites","Events","Account API keys","Pins"]},{"name":"Catalog","tags":["Products","Environments","Deployments"]},{"name":"Planning","tags":["Teams","Projects","Milestones","Tickets","Ticket documents","Ticket statuses","Tags","Views","Clanker instructions"]},{"name":"Clankers","tags":["Clankers","Clanker sessions","Messages","Comments","Notifications"]},{"name":"Testing","tags":["Test runs","Semaphores","Fixture tokens"]},{"name":"Secrets","tags":["Secrets","Vault keys"]},{"name":"System","tags":["Health"]}]}