Workflows & schema

List and read workflows, read a published version's tree and its JSON Schema, update workflow-level settings, and import or export the portable template.

View this page as Markdown

Operations: Workflows endpoints.

A workflow is a template; runs are started from its published version. The builder owns the tree (sections, tasks, fields, rules); the API reads it, describes it as JSON Schema, moves it between workspaces as a portable template, and changes the workflow-level settings around it.

Summary and detail

GET /v1/workflows lists the workflows the key may see (its allowlist applied; trashed workflows absent), by name, 50 per page up to 200. Each item is the library header:

{
  "id": "3c1d9e2a-…", "name": "Order fulfillment", "description": "Every order from payment to shipment.",
  "status": "active", "icon": "package", "color": "#2563eb",
  "folder": { "id": "f0f1…", "name": "Operations" },
  "keyDateFieldKey": "ship_date", "kickoffFormEnabled": false,
  "publishedVersion": { "id": "a0b1…", "number": 4, "publishedAt": "2026-09-30T21:10:00.000Z" },
  "taskCount": 9,
  "createdAt": "2026-06-26T15:00:00.000Z", "updatedAt": "2026-09-30T21:10:00.000Z"
}
  • publishedVersion is null until the workflow is published — such a workflow cannot start runs and has no schema.
  • updatedAt moves on every change to the header, folder, status or published pointer; updatedSince turns the list into an incremental sync.
  • status is active or archived; an archived workflow is hidden from the Run menu while its runs stay.

GET /v1/workflows/{id} adds the published version's tree: sections[] → tasks[] → fields[] plus rules[] — every task key and field key a run will carry. A task carries its kind, isStop, defaultVisibility, dueRule, assignment (by ids: users, groups, roles, the run starter, a Members field, a guest) and guestConfig; a field its type, label, help, required, options (choices, items, file multiple), formatConfig, validation, a static defaultValue, formula, inKickoff, kickoffPosition and readOnly (formula, file and Display Text fields, and any field carrying a formula, are read-only through the API). An unpublished workflow answers with publishedVersion: null and no sections; a workflow in Trash is a 404.

JSON Schema

GET /v1/workflows/{id}/schema returns two JSON Schema (2020-12) documents generated from the published version:

{
  "workflowId": "3c1d9e2a-…", "versionId": "a0b1…", "versionNumber": 4,
  "start":  { "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "Start a run", "type": "object", "properties": { "workflowId": …, "name": …, "fields": { … }, "priority": …, "labels": …, "dueAt": … }, "required": ["workflowId", "name", "fields"] },
  "fields": { "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "Set field values", "type": "object", "properties": { … }, "minProperties": 1, "maxProperties": 200 }
}

This example's workflow has a required kickoff field, so start.required lists fields; for a workflow without one it is ["workflowId", "name"] and fields may be omitted — the per-workflow form of the reference, where fields is optional.

  • start describes the POST /v1/runs body: every writable field under fields, with required naming only the required kickoff fields no rule can hide (a required field a rule may hide is described as "required at start unless a rule hides it"); a required checkbox is const: true.
  • fields describes the PATCH /v1/runs/{id}/fields body: every writable field.
  • Each property carries the field's title, its JSON type per the typing rules, enum for dropdown choices / multi-choice entries / subtask keys, minimum / maximum bounds, format (date, email, uri), and the annotations x-processcart-type, x-processcart-format, x-task and x-section. Hidden fields are writable and marked so (never shown in the app, not secret).
  • versionId is the published version; runs pin the version they started on, so an older run may carry fields this schema no longer lists.
  • An unpublished workflow is a 409 workflow_not_published.

Updating a workflow

PATCH /v1/workflows/{id} changes workflow-level settings — never the tree, which stays the builder's:

{ "name": "Order fulfillment (US)", "description": "…", "folderId": "f0f1…", "keyDateFieldKey": "ship_date", "status": "active" }

Any subset. folderId must be a folder of your workspace (null for the main Workflows page; a key restricted to folders may only move within its folders) — any other id is a 422 (errors[].code unknown_folder); keyDateFieldKey must name a date-typed field of the published version — of the draft while the workflow has never been published (null clears it; a key the version lacks is unknown_field, a field that is not date-typed not_a_date_field) — and re-derives every live run's Key Date; status: "archived" hides the workflow from the Run menu. The answer is the summary. Audited.

Template export and import

The portable template (specs §10.6) is the buildable workflow as JSON — sections, tasks, fields, formulas, rules, due rules and assignments by group or role name — with no ids, no people, no workspace settings, no secrets and no embedded images. Its envelope carries formatVersion and engineVersion, exportedAt and source (the workspace slug).

  • GET /v1/workflows/{id}/template exports the published version (409 workflow_not_published otherwise). Keep it in version control, or feed it to another workspace — the sandbox flow.
  • POST /v1/workflows creates a workflow from one:
{ "template": { "formatVersion": 1, "engineVersion": 1, "workflow": { … } },
  "name": "Order fulfillment", "description": "…", "folderId": "f0f1…", "publish": true }

The flow, in order: the envelope's versions are checked (a template from a newer build is a 422, errors[].code unsupported_version); the template is validated and sanitized; group assignments are matched to your workspace's groups by name, case-insensitively (an unknown group clears that assignment — counted in clearedAssignments); when publish is true (the default) the publish gate runs before anything is written, so a 422 creates nothing (a template that fails validation answers invalid_template entries in errors[], one that fails the gate publish_gate entries, one that repeats a section, task or field key duplicate_key, and a folderId outside your workspace unknown_folder); then the workflow is created, published, and answered as 201 Created with Location, the detail resource, an import report (errors — always empty on a 201 —, warnings, counts, clearedAssignments, flaggedEmails — static recipient addresses kept from the template, worth a review) and publishWarnings (the gate's non-blocking notes). publish: false leaves a draft to finish in the builder. A key restricted to workflows cannot create one; a key restricted to folders must pass a folderId among its folders.

Workflows cannot be moved to Trash or restored through the API in v1; run-start restrictions by group (folder restrictions in the app) are replaced, for keys, by the key's allowlist.