Skip to main content
All ticketing routes live under a Project on the management API. Set these before running the examples:
For concepts, see Ticketing overview. For the workflow and form spec, see Workflows and Forms.

Authentication

Every route requires: Form and workflow bodies (POST/PATCH on ticket-forms and ticket-workflows, plus /validate) also accept YAML. Send Content-Type: application/yaml (or text/yaml, application/x-yaml) and keep the same top-level key (form: or workflow:).

Idempotency

Send an Idempotency-Key header to make retries safe on these routes: create, update, and delete ticket; transition; assign; unassign; remove tag; instantiate template. A retry with the same key while the first request is still running returns 409 in progress.

Permissions

Transitions also check the transition’s permit list in the workflow. A Project member who does not match any permit gets 403 transition permit denied. See Workflows for permit values.

Rate limits

Back off on 429.

Response envelopes

Paginated lists accept page (default 1), limit (default 10, max 200), and offset (used only when page is absent). meta contains:

Forms

Forms are versioned by name. POST with a name that already exists, or PATCH on any version, writes the next version. Older versions stay intact. A workflow require_form without a version uses the latest version.

List forms

Permission: Project read
Response: data.items[] of form items plus data.meta.

Get form

Permission: Project read form_id is the id of one form version.
Response: data.item — a form item. 404 form not found if the id is not in this Project.

Create form

Permission: Project manage workflows Request body: writes_to.kind is tag (needs tag_kind) or metadata (needs metadata_path, dotted paths allowed).
Response:
A missing name or schema, or a bad binding, returns 400.

Update form

Permission: Project manage workflows Request body: same as create. form.name must match the existing form (400 spec name must match existing form name).
Response: data.item — the new version, with a new id and version incremented by one.

Delete form

Permission: Project manage workflows Deletes that one version.
Response: {"ok": 1}

Workflows

A workflow has a stable definition (workflow_def_id, one per name) and immutable versions (id). Creating or patching writes a new version that is inactive. Activate a version before you create tickets against the definition. Only one version per definition is active.

List workflow versions

Permission: Project read
Response: data.items[] of workflow version items plus data.meta.

Get workflow version

Permission: Project read workflow_id is a version id.
Response: data.item — a workflow version item.

List state labels

Permission: Project read Returns the state labels of one workflow version, sorted by label key. Use the label value as to_label when you transition.
Response: data.items[] of state label items. Not paginated.

Validate a workflow

Permission: Project member Dry-runs validation. Nothing is saved. Request body: {"workflow": {…}} — same as create.
Response data fields:
A body that does not parse, or a spec missing name or initial, returns 400 invalid workflow instead of a report.

Create workflow

Permission: Project manage workflows Request body: {"workflow": {…}}. Top-level spec fields: Full field reference: Workflows and Automation. maintenance-request.json:
Response:
Create saves the version even when validation fails. Check validation_report.ok — a version with ok: false cannot be activated. Call validate first to see structured errors.

Update workflow

Permission: Project manage workflows Writes a new, inactive version on the same definition. workflow_id is any existing version id. workflow.name must match the definition (400 workflow yaml name must match existing workflow). Request body: {"workflow": {…}} — full spec, as in create.
Response: data.item — the new workflow version item.

Activate workflow version

Permission: Project manage workflows Makes this version the active one for its definition and deactivates the previous one. Existing tickets keep the version they were created on.
Response: data.item with is_active: true. 400 workflow validation failed if the version’s validation_report.ok is false.

Delete workflow version

Permission: Project manage workflows
Response: {"ok": 1} Returns 409 when the version is active (cannot delete active workflow version), when tickets use it (workflow version is referenced by tickets), or when it has pending actions (workflow version has pending actions).

Workflow templates

Templates are platform-provided workflows (with their forms) that you install into a Project as your own editable copy. The catalog is the same for every Project.

List templates

Permission: Project read
Response: data.items[], not paginated:

Instantiate template

Permission: Project manage assets Installs the template’s forms and workflow into this Project and activates the workflow. Calling it again is safe: it returns already_installed: true and re-creates any forms you deleted.
Response:
404 for an unknown template_key. 409 when a workflow or form you authored already uses the template’s name.

Tickets

List tickets

Permission: Project read Results are sorted newest first. fields accepts: id, org_id, project_id, workflow_version_id, state_label_id, system_class, title, body, assigned_to, assigned_group_id, opened_at, closed_at, due_at, metadata, created_by, created_at, updated_at, number, tags, state_label. An unknown name returns 400 unknown field: …. tags and state_label are only available through fields:
  • tags — [{ id, ticket_id, kind, value, label, metadata, created_at }], oldest first
  • state_label — a state label item
Response:
Without fields, list items are full Ticket objects and metadata is a base64-encoded JSON string. With fields that include metadata, it is a decoded JSON object. Single-ticket responses (get, create, patch) also return base64 metadata.

Get ticket

Permission: Project read
Response: data.item — a Ticket. 404 ticket not found.

Create ticket

Permission: Project member Request body: Set at most one of assigned_user_id and assigned_group_id. Unknown body fields return 400.
Response:
Common failures:

Update ticket

Permission: Project member Request body (at least one field): State, assignment, and tags have their own routes. Unknown fields return 400.
Response: data.item — the updated Ticket.

Delete ticket

Permission: Project member
Response: {"ok": 1}

Transitions

Transition a ticket

Permission: Project member, plus a matching permit on the transition Request body: The workflow must declare a transition from the current label to to_label.
Response:
Re-read the ticket to see the new state_label_id and system_class. Moving to a terminal label sets closed_at.
The sub-ticket check only counts children linked by a subticket tag on the parent (value = child ticket id). The Console links sub-tickets through metadata.parent_ticket_id, which this check does not read.

List transition history

Permission: Project read Newest first.
Response: data.items[] of transition records plus data.meta.

Assignment

A ticket has one user assignee (assigned_to) or one group assignee (assigned_group_id). Assigning a group clears assigned_to.

Assign a ticket

Permission: Project member Request body (exactly one):
Response: {"ok": 1, "data": {"ok": true}} 400 when both or neither field is set, when the user is not a Project member, or when the group is not in this Organization.

Unassign a ticket

Permission: Project member Request body:
Response: {"ok": 1, "data": {"ok": true}} → Notifications for assignment changes: Assignment and notifications

Tags

Tags link a ticket to entities (device, asset, user, subticket, …) or carry scalar values (priority, severity, …). Entity tags must reference something that exists in the Project; a user tag must be a Project member. Read tags with GET …/tickets?fields=id,tags.

Add a tag

Permission: Project member Request body:
Response:
400 for an unknown kind or a value that fails validation. 404 if the ticket does not exist.

Remove a tag

Permission: Project member
Response: {"ok": 1}. 404 ticket tag if the tag is not on this ticket.

Object reference

Ticket

The Console’s Due date field writes metadata.due_at, not the top-level due_at. Only the top-level due_at drives due_policy timers.

Workflow version item

Form item

State label item

Transition record


Error codes