Skip to main content

Templates

A Template is the reusable definition a checklist is started from: its tasks, the fields on each task, the conditions that show and hide them, due date rules, assignments and custom notifications. Fields are the task's input controls — see Control Types for what each kind does.

Templates are versioned. Every change to a template publishes a new version under the same key, and the key names the template rather than any one version of it: reading a template by key gives you the latest version unless you ask for another. A checklist keeps the version it was started from, so publishing a version never changes work in progress — upgrades are how running checklists are moved on. See Template Versioning for the concept.

There is no route that edits part of a template, renames one or deletes one. You change a template by publishing a new version of the whole thing (a template's name and description belong to a version too), and you retire one by archiving it, which is reversible.

Every request acts as the member the API key acts as — see Authentication. What a key may do depends on who that is:

  • A key acting as an Administrator may do everything on this page, for any template.
  • A key acting as the workspace may do the same, archiving and unarchiving included.
  • A key acting as a Member needs the permissions below. They combine the Member's Template.Creator permission with their permission on the Library folder the template is filed in (see Template Permissions).
OperationWhat a Member needs
List templatesNothing. The list is not filtered by folder permission: it names every template in the workspace.
Read one template — get it, list its versions, export it, list its permissions, validate a document forTemplate itAny folder permission except Deny.
Create a templateTemplate.Creator.
Create a version, set its permissionsTemplate.Creator, and Edit on the template's folder.
Copy a templateTemplate.Creator, and Edit on the template's folder, as the app's Duplicate needs.
List checklist upgrades, upgrade checklistsEdit on the template's folder.
Archive or unarchive a templateCannot. Archiving is limited to Administrators.

A template in no folder has no folder rule to fail, and neither does an archived one: where the table asks for Edit or refuses Deny, such a template passes. Likewise a folder that has no rule naming the Member counts as passing, as it does in the app.

A refusal is 403 FORBIDDEN, and its message says what is missing. It comes after the template is looked up, so another workspace's template is still 404 TEMPLATE_NOT_FOUND. A write refused for permission is refused before the document is read, so a Member who may not save a template gets the 403 rather than a 422.

Every write on this page accepts an Idempotency-Key header (see Idempotency), and every route on this page is charged to the standard rate limit budget.

Authoring a Template​

A template is written as a template document: one JSON object holding the whole template, in which tasks, fields, conditions and notifications carry a ref — a name you choose — that other parts of the document point at. Members, groups, tags, linked templates and Data Sets are named rather than numbered and are resolved against your workspace. The format is described in full on Template Documents, and the JSON Schema, the per-field-type schemas and the authoring guide are served by the schema routes.

There are two ways to write one:

  • In one request. Send the finished document to POST /v3/templates. Nothing is saved unless all of it can be; a document with any error is refused whole with 422 TEMPLATE_INVALID and a list of every problem.
  • As a draft. Build the document up over several requests in a draft, which is stored but not yet a template, then commit it. A draft can start empty or from an existing template, and can be validated at any point. Use a draft when the document is too large to send at once, or is being assembled step by step.

Whichever you choose, the working loop is the same:

  1. Compose the document, looking up each field type's properties with GET /v3/schema/content-types/{type}.
  2. Send it to POST /v3/templates/validate, fix what it reports, and validate again. Validation is the only place warnings are reported — the routes that write a template accept a document with warnings and do not mention them.
  3. Create the template.

To change a template afterwards:

  1. Export it as a document.
  2. Change the part that is wrong, keeping every id the export wrote.
  3. Validate it with forTemplate set to the template's key.
  4. Publish it as a new version.
  5. If running checklists should follow, upgrade them.

To roll a template back, export the older version and publish it as a new version. To duplicate a template, copy it — posting an exported document to POST /v3/templates is refused, because the ids in it describe a template that already exists.

Endpoints​

MethodPathDescriptionMCP tool
GET/v3/templatesList templateslist_templates
GET/v3/templates/{key}Get a templateget_template
POST/v3/templatesCreate a templatecreate_template
POST/v3/templates/validateValidate a template documentvalidate_template
GET/v3/templates/{key}/documentExport a template documentexport_template
POST/v3/templates/{key}/versionsCreate a template versioncreate_template_version
GET/v3/templates/{key}/versionsList template versionslist_template_versions
POST/v3/templates/{key}/copyCopy a templatecopy_template
POST/v3/templates/{key}/archiveArchive a templateset_template_archived
DELETE/v3/templates/{key}/archiveUnarchive a templateset_template_archived
GET/v3/templates/{key}/permissionsList template permissionslist_template_permissions
PUT/v3/templates/{key}/permissionsSet template permissionsset_template_permissions
GET/v3/templates/{key}/upgradesList checklist upgradeslist_checklist_upgrades
POST/v3/templates/{key}/upgradesUpgrade checklistsupgrade_checklists

The Template Object​

One row of the template list. It describes one version of a template — the latest, unless you asked for every version — and carries no tasks.

FieldTypeDescription
keystringThe template's key (GUID). Every version of a template has the same key.
namestringThe template's name, as of this version.
descriptionstringThe template's description, as of this version. Absent when it has none.
versionintegerThe version this row describes. The first version is 1.
isArchivedbooleanWhether the template is archived. Always false unless you asked for archived templates.
urlstringThe template in the CheckFlow app.
createdDateTimestringWhen this version was published.
createdByobjectWho published this version: name and email. Absent when that person has left the workspace.
{
"key": "3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14",
"name": "Invoice Review",
"description": "Check, approve and pay a supplier invoice.",
"version": 1,
"isArchived": false,
"url": "https://app.checkflow.io/Template/Index?templateKey=3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14",
"createdDateTime": "2026-09-14T09:12:44.107Z",
"createdBy": {
"name": "Sarah Chen",
"email": "sarah.chen@acme.example"
}
}

The Template Detail Object​

A template with its tasks and fields, as Get a Template and every route that creates or changes a template return it. This is the shape a checklist is started against — the task and field keys here are the ones Checklist Tasks and Task Fields take. It is not the shape a template is authored in: a field's full configuration (its drop-down items, file limits, conditions and so on) is only in the exported document.

FieldTypeDescription
keystringThe template's key (GUID).
namestringThe template's name, as of this version.
descriptionstringThe template's description. Absent when it has none.
versionintegerThe version this object describes.
latestVersionintegerThe template's highest version number — what the key on its own resolves to.
isLatestbooleanWhether version is the latest version.
isArchivedbooleanWhether the template is archived.
urlstringThis version in the CheckFlow app. The latest version is linked by key and an older one by its own id, so an older version's link opens that version.
createdDateTimestringWhen this version was published.
createdByobjectWho published this version: name and email. Absent when that person has left the workspace.
tasksarrayThe tasks and headings, in order. See Task.

Task​

FieldTypeDescription
keystringThe task's key (GUID).
namestringThe task's name.
isHeadingbooleantrue for a heading — a divider that is never completed.
orderintegerThe task's position, starting at 1.
fieldsarrayThe task's fields, in order. See Field.

Field​

FieldTypeDescription
keystringThe field's key (GUID). Keys survive a new version when the version document keeps the field's id.
namestringThe field's label. A field with no label is named after its type and position, for example Text Content at Position 1.
typestringThe content type, for example ShortText, DropDown, Date or Members. The full list is on Template Documents.
isRequiredbooleanWhether the task cannot be completed until the field is answered.
modestringDate fields only: date, time or date-and-time — what the picker asks for.
regexstringShortText fields with a pattern only. Answers that do not match are refused. Reported exactly as the template stores it, which may include the slashes the editor wraps a pattern in; the API trims them before applying the pattern, and you should too.
regexMessagestringThe template's message for an answer that does not match regex. Absent when there is no pattern or no message.
selectionModestringMembers fields only: single or multiple. A single field refuses a value naming two people.
dataSetobjectDropDown, MultiChoice, SubTasks and Table fields that read from a Data Set only. See Data Set Link.

A field linked to a Data Set is answered with a record of the linked view rather than with an option's text, so the link is reported on the field.

FieldTypeDescription
keystringThe Data Set's key.
namestringThe Data Set's name.
viewKeystringThe view whose records are the choices.
viewNamestringThe view's name.
displayFieldKeystringThe Data Set field whose value each choice shows. Absent on a Table.
displayFieldNamestringThat field's name.
prePopulateRowsbooleanTable only: whether a checklist starts with one row per record. Always present, and false on the other three types.
columnsarrayTable only: fieldKey, fieldName and column (the table column the field fills).
{
"key": "8d70632a-e08f-4afc-8939-6fd6f30f81cf",
"name": "Supplier",
"type": "DropDown",
"isRequired": true,
"dataSet": {
"key": "7abef6d5-0ab6-4b97-b868-e9126993a8b2",
"name": "Suppliers",
"viewKey": "92d9a6c9-0481-469c-9802-2b815219d6e8",
"viewName": "Active suppliers",
"displayFieldKey": "18a00c98-128f-450a-84fa-8b5b29a457e0",
"displayFieldName": "Supplier name",
"prePopulateRows": false
}
}

Example​

{
"key": "3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14",
"name": "Invoice Review",
"description": "Check, approve and pay a supplier invoice.",
"version": 1,
"latestVersion": 1,
"isLatest": true,
"isArchived": false,
"url": "https://app.checkflow.io/Template/Index?templateKey=3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14",
"createdDateTime": "2026-09-14T09:12:44.107Z",
"createdBy": {
"name": "Sarah Chen",
"email": "sarah.chen@acme.example"
},
"tasks": [
{
"key": "3c99f258-45bb-4997-9d81-f97468e5ae9f",
"name": "Check the invoice",
"isHeading": false,
"order": 1,
"fields": [
{
"key": "9b71b832-a195-4d33-877e-3e1017fcd406",
"name": "Invoice number",
"type": "ShortText",
"isRequired": true,
"regex": "^INV-[0-9]{4}$",
"regexMessage": "An invoice number is INV- followed by four digits."
},
{
"key": "c1715bff-2066-4b2c-af25-3c37749df4b5",
"name": "Invoice amount",
"type": "DropDown",
"isRequired": true
}
]
},
{
"key": "c1cb7d14-0fa9-4a5e-8e08-77e93d29102c",
"name": "Get director approval",
"isHeading": false,
"order": 2,
"fields": []
},
{
"key": "f997d478-cb52-4efc-bfc2-3e318decadf2",
"name": "Pay the invoice",
"isHeading": false,
"order": 3,
"fields": []
}
]
}

The Template Version Object​

One row of a template's version history.

FieldTypeDescription
keystringThe template's key — the same on every row.
versionintegerThe version number. Pass it as version to the read routes.
isLatestbooleanWhether this is the latest version.
namestringThe template's name in this version.
descriptionstringThe template's description in this version. Absent when it had none.
createdDateTimestringWhen this version was published.
createdByobjectWho published it: name and email. Absent when that person has left the workspace.
urlstringThis version in the CheckFlow app.
{
"key": "ae72d986-884f-4c87-abeb-669e0543b59c",
"version": 2,
"isLatest": true,
"name": "Supplier Onboarding",
"description": "Set up a new supplier before their first invoice is paid.",
"createdDateTime": "2026-09-21T14:05:31.62Z",
"createdBy": {
"name": "James Okafor",
"email": "james.okafor@acme.example"
},
"url": "https://app.checkflow.io/Template/Index?templateId=48214"
}

The Template Permission Object​

One rule about who can see and run the checklists made from a template. In the app these are the template's Checklist Permissions. They are about checklists, not about the template: none of them lets anyone edit the template.

FieldTypeDescription
assigneeTypestringAllUsers (the whole workspace), TeamMember or Group.
assigneeIdintegerThe member's or group's id. Absent for AllUsers.
namestringThe member's or group's name, or All Users. Ignored when you send a rule.
permissionstringRunAndView, ViewOnly, RunAndViewAssigned or ViewAssignedOnly. The two Assigned values limit the rule to checklists in which the assignee has at least one task, and one such task opens the whole checklist to them.
{
"assigneeType": "Group",
"assigneeId": 87,
"name": "Finance Team",
"permission": "RunAndView"
}

The Validation Result Object​

What Validate a Template Document returns.

FieldTypeDescription
validbooleanWhether the document would be accepted. Warnings do not make it false.
errorCountintegerHow many violations would refuse the document.
warningCountintegerHow many violations are worth knowing about and would not refuse it.
violationsarrayEvery violation found, errors and warnings together, in the order the document was read. See Violation.

Violation​

The same object appears in the violations array of a 422 TEMPLATE_INVALID error.

FieldTypeDescription
pathstringA JSONPath into the document as you sent it, for example $.tasks[0].fields[1].regex.
codestringWhat kind of problem it is, for example unknown_ref or assignee_not_found. Branch on this rather than on message, which may be reworded. The codes are listed on Template Documents.
messagestringWhat is wrong, in a sentence.
hintstringWhat was probably meant, or what to do about it. Absent when there is nothing useful to suggest.
severitystringerror refuses the document; warning does not.

Warnings describe documents that can be stored but probably do not do what you meant — for example never_shown (something starts hidden and no rule ever shows it), never_restored (a rule shows or hides something and nothing ever puts it back), never_sent (an email with no recipient), circular_reference (a template that starts a copy of itself automatically) and data_set_link_removed (a field that read from a Data Set in the version before and does not in this one).

{
"path": "$.conditions[1].when.fieldRef",
"code": "unknown_ref",
"message": "No field with ref 'amount_bnad' exists in this document.",
"hint": "Did you mean 'amount_band'?",
"severity": "error"
}

The Upgrade Candidate Object​

A running checklist that is not on the version an upgrade would move it to.

FieldTypeDescription
keystringThe checklist's key.
namestringThe checklist's name.
urlstringThe checklist in the CheckFlow app.
statusstringScheduled, InProgress or Complete.
startDateTimestringWhen the checklist started, or is due to start. Absent when it has no start date.
versionintegerThe version of the template the checklist is on now.
targetVersionintegerThe version an upgrade would move it to.
{
"key": "9db5bb2e-020c-480f-999a-f5ad1426583f",
"name": "Supplier Onboarding — Northwind Supplies",
"url": "https://app.checkflow.io/Checklist/Index?checklistKey=9db5bb2e-020c-480f-999a-f5ad1426583f",
"status": "InProgress",
"startDateTime": "2026-09-18T08:00:00Z",
"version": 1,
"targetVersion": 2
}

The Upgrade Result Object​

What Upgrade Checklists returns: what was handed to the background worker, and what was left where it was.

FieldTypeDescription
templateKeystringThe template's key.
templateNamestringThe template's name in the target version.
versionintegerThe version the queued checklists are being moved to.
queuedintegerHow many checklists were queued.
checklistKeysarrayThe keys of the queued checklists. Empty when none were queued.
skippedarrayThe checklists you named that were not queued, each with checklistKey and reason. Empty when every named checklist was queued, and always empty when you sent all: true.
{
"templateKey": "ae72d986-884f-4c87-abeb-669e0543b59c",
"templateName": "Supplier Onboarding",
"version": 2,
"queued": 1,
"checklistKeys": [
"9db5bb2e-020c-480f-999a-f5ad1426583f"
],
"skipped": [
{
"checklistKey": "e7d714ea-f3f4-4cd7-bf56-fdcc5be6f56c",
"reason": "already on version 2"
}
]
}

List Templates​

Returns the workspace's templates, one row per template at its latest version, leaving archived templates out. Use it to find a template's key before starting a checklist or schedule from it.

The list is not filtered by the acting member's permissions. A key that acts as a Member lists every template, including one in a Library folder where the Member has Deny — though reading that template by its key is refused with 403.

GET /v3/templates

Parameters​

NameInTypeRequiredDescription
includeAllVersionsquerybooleanNotrue returns a row for every version of every template instead of one per template. Default false. For one template's history, List Template Versions is the better call.
includeArchivedquerybooleanNotrue includes archived templates, marked isArchived: true. Default false. This is how you find an archived template's key to unarchive it.

Only the value true (in any letter case) switches either option on; any other value is read as false.

This list is not paged: every template comes back in one response, with hasMore always false and total the number of rows. It takes no pageSize, after or sort.

Example​

GET https://api.checkflow.io/v3/templates
X-API-KEY: your-api-key-here
HTTP/1.1 200 OK
{
"items": [
{
"key": "7279c5ac-30a3-40be-babd-b0e3566e7d01",
"name": "Employee Onboarding",
"description": "Everything a new starter needs in their first week.",
"version": 4,
"isArchived": false,
"url": "https://app.checkflow.io/Template/Index?templateKey=7279c5ac-30a3-40be-babd-b0e3566e7d01",
"createdDateTime": "2026-06-02T11:47:09.3Z"
},
{
"key": "3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14",
"name": "Invoice Review",
"description": "Check, approve and pay a supplier invoice.",
"version": 1,
"isArchived": false,
"url": "https://app.checkflow.io/Template/Index?templateKey=3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14",
"createdDateTime": "2026-09-14T09:12:44.107Z",
"createdBy": {
"name": "Sarah Chen",
"email": "sarah.chen@acme.example"
}
},
{
"key": "ae72d986-884f-4c87-abeb-669e0543b59c",
"name": "Supplier Onboarding",
"description": "Set up a new supplier before their first invoice is paid.",
"version": 2,
"isArchived": false,
"url": "https://app.checkflow.io/Template/Index?templateKey=ae72d986-884f-4c87-abeb-669e0543b59c",
"createdDateTime": "2026-09-21T14:05:31.62Z",
"createdBy": {
"name": "James Okafor",
"email": "james.okafor@acme.example"
}
}
],
"hasMore": false,
"total": 3
}

The first row has no createdBy because the member who published that version has since left the workspace. The template is still listed.

Responses​

StatusCodeWhen
200—The templates.

Get a Template​

Returns one template with its tasks and fields, at the latest version or at the version you name. Use it to find the task and field keys a checklist will have; use Export a Template Document when you need the template's full configuration.

GET /v3/templates/{key}

Parameters​

NameInTypeRequiredDescription
keypathstringYesThe template's key.
versionqueryintegerNoThe version to read, 1 or greater. Omit for the latest. Version numbers come from List Template Versions.

A version that is not a whole number, or is 0 or less, is refused rather than read as "the latest".

Example​

GET https://api.checkflow.io/v3/templates/ae72d986-884f-4c87-abeb-669e0543b59c?version=1
X-API-KEY: your-api-key-here
HTTP/1.1 200 OK
{
"key": "ae72d986-884f-4c87-abeb-669e0543b59c",
"name": "Supplier Onboarding",
"description": "Set up a new supplier before their first invoice is paid.",
"version": 1,
"latestVersion": 2,
"isLatest": false,
"isArchived": false,
"url": "https://app.checkflow.io/Template/Index?templateId=48213",
"createdDateTime": "2026-08-03T10:20:15.8Z",
"createdBy": {
"name": "Sarah Chen",
"email": "sarah.chen@acme.example"
},
"tasks": [
{
"key": "9ecc4a77-4f3d-4cda-af7e-c16b9c967cc9",
"name": "Collect supplier details",
"isHeading": false,
"order": 1,
"fields": [
{
"key": "37a08a2f-33de-4465-ae20-c94b07050e5c",
"name": "Supplier name",
"type": "ShortText",
"isRequired": true
}
]
}
]
}

Returns a Template Detail object. isLatest: false and latestVersion: 2 say that a newer version exists.

Responses​

StatusCodeWhen
200—The template.
400VALIDATION_ERRORkey is not a GUID (field: key), or version is not a whole number of 1 or more (field: version).
403FORBIDDENThe key acts as a Member whose permission on the Library folder the template is in is Deny.
404TEMPLATE_NOT_FOUNDNo template in this workspace has that key, or the template has no such version. The message says which.

Notes​

  • An archived template is still returned, with isArchived: true.

Create a Template​

Creates a template from a template document — the whole template, tasks, fields, conditions, due dates and custom notifications included — in one request. The new template is at version 1.

POST /v3/templates

Parameters​

This endpoint takes no parameters.

Request Body​

The body is a template document. Only name is required; a document with nothing but a name creates an empty template. The document below creates a three-task invoice review: the invoice number must match a pattern, a director's approval task is shown only for large invoices, and payment falls due two days after the invoice is checked.

{
"name": "Invoice Review",
"description": "Check, approve and pay a supplier invoice.",
"tags": ["q3-audit"],
"permissions": [
{ "type": "Group", "name": "Finance Team", "permission": "RunAndView" }
],
"tasks": [
{
"ref": "check_invoice",
"name": "Check the invoice",
"assignTo": [{ "name": "James Okafor" }],
"fields": [
{
"ref": "invoice_number",
"type": "ShortText",
"label": "Invoice number",
"isRequired": true,
"regex": "^INV-[0-9]{4}$",
"regexMessage": "An invoice number is INV- followed by four digits."
},
{
"ref": "amount_band",
"type": "DropDown",
"label": "Invoice amount",
"isRequired": true,
"items": [
{ "ref": "under_5k", "text": "Under 5,000" },
{ "ref": "over_5k", "text": "5,000 or more" }
]
}
]
},
{
"ref": "director_approval",
"name": "Get director approval",
"hiddenByDefault": true,
"fields": []
},
{
"ref": "pay_invoice",
"name": "Pay the invoice",
"halt": "task",
"dueDate": {
"rule": "task-completed",
"anchorRef": "check_invoice",
"offset": { "days": 2 }
},
"fields": []
}
],
"conditions": [
{
"ref": "reset_approval",
"when": { "fieldRef": "amount_band", "operator": "has-any-value" },
"then": { "effect": "hide", "tasks": ["director_approval"] }
},
{
"ref": "large_invoice",
"when": { "fieldRef": "amount_band", "operator": "is", "value": "over_5k" },
"then": { "effect": "show", "tasks": ["director_approval"] }
}
]
}

The first condition is a reset: whenever the amount is answered it hides the approval task, and the rule after it shows the task again only for a large invoice. Without it, changing the answer from 5,000 or more back to Under 5,000 would leave the task showing, and validation would warn never_restored.

The top-level properties are summarised below. Tasks, fields, conditions, due dates and notifications are described on Template Documents, and each field type's own properties (label, regex, items and the rest) by GET /v3/schema/content-types/{type}.

FieldTypeRequiredDescription
namestringYesThe template's name, at most 100 characters.
descriptionstringNoThe template's description.
settingsobjectNoTime zone, date and time formats, the feature switches and the Library folder. Every setting has the default a new template gets in the app.
tagsarrayNoThe template's tags, by name. A tag that does not exist yet is created.
permissionsarrayNoWho can see and run the template's checklists: type (AllUsers, TeamMember or Group) with an id or a name, and a permission.
parametersarrayNoValues asked for when a checklist is started.
tasksarrayNoThe tasks and headings, in display order, each with its fields.
conditionsarrayNoRules that show and hide tasks and fields.
notificationsarrayNoCustom notifications.

Leave every id out. An id on a task, field, parameter or condition is refused with the violation code id_not_allowed: ids only come from an export, and a document carrying them describes a template that already exists. Copy that template instead, or publish the document as a new version of it.

Example​

POST https://api.checkflow.io/v3/templates
X-API-KEY: your-api-key-here
Content-Type: application/json

{
"name": "Invoice Review",
"description": "Check, approve and pay a supplier invoice.",
"tags": ["q3-audit"],
"permissions": [
{ "type": "Group", "name": "Finance Team", "permission": "RunAndView" }
],
"tasks": [
{
"ref": "check_invoice",
"name": "Check the invoice",
"assignTo": [{ "name": "James Okafor" }],
"fields": [
{
"ref": "invoice_number",
"type": "ShortText",
"label": "Invoice number",
"isRequired": true,
"regex": "^INV-[0-9]{4}$",
"regexMessage": "An invoice number is INV- followed by four digits."
},
{
"ref": "amount_band",
"type": "DropDown",
"label": "Invoice amount",
"isRequired": true,
"items": [
{ "ref": "under_5k", "text": "Under 5,000" },
{ "ref": "over_5k", "text": "5,000 or more" }
]
}
]
},
{
"ref": "director_approval",
"name": "Get director approval",
"hiddenByDefault": true,
"fields": []
},
{
"ref": "pay_invoice",
"name": "Pay the invoice",
"halt": "task",
"dueDate": {
"rule": "task-completed",
"anchorRef": "check_invoice",
"offset": { "days": 2 }
},
"fields": []
}
],
"conditions": [
{
"ref": "reset_approval",
"when": { "fieldRef": "amount_band", "operator": "has-any-value" },
"then": { "effect": "hide", "tasks": ["director_approval"] }
},
{
"ref": "large_invoice",
"when": { "fieldRef": "amount_band", "operator": "is", "value": "over_5k" },
"then": { "effect": "show", "tasks": ["director_approval"] }
}
]
}
HTTP/1.1 201 Created
{
"key": "3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14",
"name": "Invoice Review",
"description": "Check, approve and pay a supplier invoice.",
"version": 1,
"latestVersion": 1,
"isLatest": true,
"isArchived": false,
"url": "https://app.checkflow.io/Template/Index?templateKey=3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14",
"createdDateTime": "2026-09-14T09:12:44.107Z",
"createdBy": {
"name": "Sarah Chen",
"email": "sarah.chen@acme.example"
},
"tasks": [
{
"key": "3c99f258-45bb-4997-9d81-f97468e5ae9f",
"name": "Check the invoice",
"isHeading": false,
"order": 1,
"fields": [
{
"key": "9b71b832-a195-4d33-877e-3e1017fcd406",
"name": "Invoice number",
"type": "ShortText",
"isRequired": true,
"regex": "^INV-[0-9]{4}$",
"regexMessage": "An invoice number is INV- followed by four digits."
},
{
"key": "c1715bff-2066-4b2c-af25-3c37749df4b5",
"name": "Invoice amount",
"type": "DropDown",
"isRequired": true
}
]
},
{
"key": "c1cb7d14-0fa9-4a5e-8e08-77e93d29102c",
"name": "Get director approval",
"isHeading": false,
"order": 2,
"fields": []
},
{
"key": "f997d478-cb52-4efc-bfc2-3e318decadf2",
"name": "Pay the invoice",
"isHeading": false,
"order": 3,
"fields": []
}
]
}

Returns a Template Detail object describing the template as it was stored. The keys in it are the ones checklists started from this version will have.

Responses​

StatusCodeWhen
201—The template was created at version 1.
400VALIDATION_ERRORThe body is not valid JSON, or is empty.
403FORBIDDENThe key acts as a Member without Template.Creator.
422TEMPLATE_INVALIDThe document was read and cannot be stored. violations lists every problem. Nothing was written, not even new tags.

Refused Documents​

A document with any error is refused whole with 422 and the code TEMPLATE_INVALID. The error body carries a violations array in addition to the usual fields, listing every problem found in one pass — errors and any warnings — so one round trip is enough to see everything that needs fixing. The message counts only the errors.

If the second condition above named the field amount_bnad by mistake, the answer would be:

HTTP/1.1 422 Unprocessable Entity
{
"error": {
"code": "TEMPLATE_INVALID",
"message": "The template document has 1 problem.",
"requestId": "req_4b8e2f1a9c3d47e6b0a5d9c2e7f18a36",
"violations": [
{
"path": "$.conditions[1].when.fieldRef",
"code": "unknown_ref",
"message": "No field with ref 'amount_bnad' exists in this document.",
"hint": "Did you mean 'amount_band'?",
"severity": "error"
},
{
"path": "$.tasks[1].hiddenByDefault",
"code": "never_shown",
"message": "The task 'director_approval' starts hidden and no rule shows it, so it will never appear.",
"hint": "Add a rule with an effect of 'show' naming 'director_approval' in 'then.tasks', or take 'hiddenByDefault' off.",
"severity": "warning"
}
]
}
}

See The Violation Object and Errors.

Notes​

  • Everyone in the workspace except you is notified that you created the template, in the same words the template editor uses.
  • A document that is accepted with warnings is created without mentioning them. Run it through validation first to see them.
  • Array order is display order, for tasks and for the fields within a task.

Validate a Template Document​

Reads a template document and reports everything wrong with it, without creating or changing anything. It applies the same rules as creating a template and publishing a version, so a document it calls valid is one those routes will accept.

POST /v3/templates/validate

Parameters​

NameInTypeRequiredDescription
forTemplatequerystringNoThe key of the template this document will become a new version of. Omit it to check the document as a new template.

forTemplate changes the answer, so send it whenever the document is headed for Create a Template Version. With it, the id values in the document are read against that template, and a field that has dropped its dataSet since that version is warned about with data_set_link_removed. The answer can differ: an Image field needs a stored picture that a document cannot carry, so it is accepted when it keeps its id in a version of the template it came from, and refused as part of a new template.

Request Body​

A template document, the same shape Create a Template takes.

Example​

POST https://api.checkflow.io/v3/templates/validate
X-API-KEY: your-api-key-here
Content-Type: application/json

{
"name": "Invoice Review",
"tasks": [
{
"ref": "check_invoice",
"name": "Check the invoice",
"fields": [
{
"ref": "amount_band",
"type": "DropDown",
"label": "Invoice amount",
"isRequired": true,
"items": [
{ "ref": "under_5k", "text": "Under 5,000" },
{ "ref": "over_5k", "text": "5,000 or more" }
]
}
]
},
{ "ref": "director_approval", "name": "Get director approval", "hiddenByDefault": true, "fields": [] }
],
"conditions": [
{
"ref": "large_invoice",
"when": { "fieldRef": "amount_band", "operator": "is", "value": "over_5k" },
"then": { "effect": "show", "tasks": ["director_approval"] }
}
]
}
HTTP/1.1 200 OK
{
"valid": true,
"errorCount": 0,
"warningCount": 1,
"violations": [
{
"path": "$.conditions[0].then",
"code": "never_restored",
"message": "This rule will show 'director_approval', and no rule on 'amount_band' will hide it again. The checklist only applies the rules that fire when an answer changes and never goes back to 'hiddenByDefault' by itself, so changing the answer afterwards leaves 'director_approval' as this rule left it.",
"hint": "Make the first rule on 'amount_band' a reset -- when 'has-any-value', hide 'director_approval' -- so every change starts from how the checklist began and the rules after it decide. If the answer can also be cleared, add the same reset for 'has-no-value'.",
"severity": "warning"
}
]
}

Returns a Validation Result object.

Responses​

StatusCodeWhen
200—The document was read. Check valid — a document with errors is still a 200 here.
400VALIDATION_ERRORforTemplate is not a GUID (field: forTemplate), or the body is not valid JSON or is empty.
403FORBIDDENforTemplate names a template in a Library folder where the Member the key acts as has Deny.
404TEMPLATE_NOT_FOUNDforTemplate names no template in this workspace.

Notes​

  • Validation writes nothing — not even the tags a document names.
  • Validating is the only way to see warnings on a document that has no errors. Creating a template or publishing a version accepts it and does not report them.

Export a Template Document​

Returns a template as a template document: the shape Create a Template and Create a Template Version accept. Use it to see a template's full configuration, and as the starting point for every new version.

GET /v3/templates/{key}/document

Parameters​

NameInTypeRequiredDescription
keypathstringYesThe template's key.
versionqueryintegerNoThe version to export, 1 or greater. Omit for the latest.

Example​

GET https://api.checkflow.io/v3/templates/ae72d986-884f-4c87-abeb-669e0543b59c/document
X-API-KEY: your-api-key-here
HTTP/1.1 200 OK
{
"name": "Supplier Onboarding",
"description": "Set up a new supplier before their first invoice is paid.",
"settings": {
"dateFormatId": 1,
"timeFormatId": 1,
"displayComments": true,
"displayTaskTags": true,
"isNotApplicableEnabled": true,
"isShareEmbedEnabled": true,
"isAttachedTasksEnabled": true
},
"tags": ["q3-audit"],
"permissions": [
{ "type": "Group", "id": 87, "name": "Finance Team", "permission": "RunAndView" }
],
"parameters": [],
"tasks": [
{
"ref": "collect_supplier_details",
"id": "9ecc4a77-4f3d-4cda-af7e-c16b9c967cc9",
"name": "Collect supplier details",
"isHeading": false,
"halt": "none",
"hiddenByDefault": false,
"assignTo": [
{ "type": "TeamMember", "id": 1051, "name": "Priya Patel" }
],
"assignFrom": [],
"assignedExclusively": false,
"tags": [],
"fields": [
{
"ref": "supplier_name",
"id": "37a08a2f-33de-4465-ae20-c94b07050e5c",
"type": "ShortText",
"hiddenByDefault": false,
"label": "Supplier name",
"isRequired": true
}
]
}
],
"conditions": [],
"notifications": []
}

Responses​

StatusCodeWhen
200—The template as a document.
400VALIDATION_ERRORkey is not a GUID (field: key), or version is not a whole number of 1 or more (field: version).
403FORBIDDENThe key acts as a Member whose permission on the Library folder the template is in is Deny.
404TEMPLATE_NOT_FOUNDNo template in this workspace has that key, or the template has no such version.

Notes​

  • Refs are invented from names. A template stores no refs, so the export makes one for every task, field and choice from its name or label (Collect supplier details becomes collect_supplier_details), numbering duplicates. Conditions and notifications have no name, so they get condition, condition_2, notification, notification_2 and so on.
  • Every node carries its id. Keep them when you publish the document as a new version: the ids are what keep answers already given on running checklists attached to the same tasks and fields. Remove them, or use Copy a Template, to make a separate template.
  • Members, groups and linked templates are written with their names beside their ids, and a field linked to a Data Set is written with a dataSet naming the Data Set, view and display field, and no items.
  • The document carries no key and no version — it describes a template rather than identifying one.
  • An Image, Video or read-only File field is exported without the stored file behind it. It keeps that file only when the document goes back to the same template as a new version.

Create a Template Version​

Publishes a new version of an existing template from a template document. The new version becomes the latest and is what new checklists are started from; running checklists stay on the version they were started from until you upgrade them.

POST /v3/templates/{key}/versions

Parameters​

NameInTypeRequiredDescription
keypathstringYesThe template's key. The new version is added under it.

Request Body​

The template document, describing the whole template as it should be from this version on. Only name is required. Start from an export and keep its id values: a task or field that keeps its id is the same task or field as before, and one without an id is new.

warning

A document is the whole template, not a change to it. A template's permissions and tags belong to the template rather than to one version, so a version document that leaves out permissions or tags removes them from the template altogether — including from the versions before it. Likewise a field that keeps its id and leaves out its dataSet goes back to being a fixed list. Export the template and edit what comes back, and all of these are kept.

The version number is assigned by CheckFlow — the next one after the current latest — and cannot be chosen. Read it from the response.

Example​

This adds a VAT number field to the exported document above. The existing task and field keep their id; the new field has none.

POST https://api.checkflow.io/v3/templates/ae72d986-884f-4c87-abeb-669e0543b59c/versions
X-API-KEY: your-api-key-here
Content-Type: application/json

{
"name": "Supplier Onboarding",
"description": "Set up a new supplier before their first invoice is paid.",
"tags": ["q3-audit"],
"permissions": [
{ "type": "Group", "id": 87, "name": "Finance Team", "permission": "RunAndView" }
],
"tasks": [
{
"ref": "collect_supplier_details",
"id": "9ecc4a77-4f3d-4cda-af7e-c16b9c967cc9",
"name": "Collect supplier details",
"assignTo": [
{ "type": "TeamMember", "id": 1051, "name": "Priya Patel" }
],
"fields": [
{
"ref": "supplier_name",
"id": "37a08a2f-33de-4465-ae20-c94b07050e5c",
"type": "ShortText",
"label": "Supplier name",
"isRequired": true
},
{
"ref": "vat_number",
"type": "ShortText",
"label": "VAT number",
"isRequired": true,
"regex": "^GB[0-9]{9}$",
"regexMessage": "A UK VAT number is GB followed by nine digits."
}
]
}
]
}
HTTP/1.1 201 Created
{
"key": "ae72d986-884f-4c87-abeb-669e0543b59c",
"name": "Supplier Onboarding",
"description": "Set up a new supplier before their first invoice is paid.",
"version": 2,
"latestVersion": 2,
"isLatest": true,
"isArchived": false,
"url": "https://app.checkflow.io/Template/Index?templateKey=ae72d986-884f-4c87-abeb-669e0543b59c",
"createdDateTime": "2026-09-21T14:05:31.62Z",
"createdBy": {
"name": "James Okafor",
"email": "james.okafor@acme.example"
},
"tasks": [
{
"key": "9ecc4a77-4f3d-4cda-af7e-c16b9c967cc9",
"name": "Collect supplier details",
"isHeading": false,
"order": 1,
"fields": [
{
"key": "37a08a2f-33de-4465-ae20-c94b07050e5c",
"name": "Supplier name",
"type": "ShortText",
"isRequired": true
},
{
"key": "e12b7d01-7423-45b8-b293-54221f667ed2",
"name": "VAT number",
"type": "ShortText",
"isRequired": true,
"regex": "^GB[0-9]{9}$",
"regexMessage": "A UK VAT number is GB followed by nine digits."
}
]
}
]
}

Returns a Template Detail object at the new version.

Responses​

StatusCodeWhen
201—The version was published.
400VALIDATION_ERRORkey is not a GUID (field: key), or the body is not valid JSON or is empty.
403FORBIDDENThe key acts as a Member without Template.Creator, or whose permission on the Library folder the template is in is only View or Deny.
404TEMPLATE_NOT_FOUNDNo template in this workspace has that key.
409CONFLICTThe template is archived. Unarchive it first.
422TEMPLATE_INVALIDThe document cannot be stored. violations lists every problem, and the template stays at its current version. See Refused Documents.

Notes​

  • Everyone in the workspace except you is notified that you modified the template.
  • The response does not report warnings, including data_set_link_removed. Validate the document with forTemplate first to see them.
  • To rename a template, publish a version with the new name.

List Template Versions​

Returns every version of a template, newest first, with who published each. This is the only route that shows which versions exist.

GET /v3/templates/{key}/versions

Parameters​

NameInTypeRequiredDescription
keypathstringYesThe template's key.

The list is not paged: every version comes back in one response, with hasMore always false.

Example​

GET https://api.checkflow.io/v3/templates/ae72d986-884f-4c87-abeb-669e0543b59c/versions
X-API-KEY: your-api-key-here
HTTP/1.1 200 OK
{
"items": [
{
"key": "ae72d986-884f-4c87-abeb-669e0543b59c",
"version": 2,
"isLatest": true,
"name": "Supplier Onboarding",
"description": "Set up a new supplier before their first invoice is paid.",
"createdDateTime": "2026-09-21T14:05:31.62Z",
"createdBy": {
"name": "James Okafor",
"email": "james.okafor@acme.example"
},
"url": "https://app.checkflow.io/Template/Index?templateId=48214"
},
{
"key": "ae72d986-884f-4c87-abeb-669e0543b59c",
"version": 1,
"isLatest": false,
"name": "Supplier Onboarding",
"description": "Set up a new supplier before their first invoice is paid.",
"createdDateTime": "2026-08-03T10:20:15.8Z",
"createdBy": {
"name": "Sarah Chen",
"email": "sarah.chen@acme.example"
},
"url": "https://app.checkflow.io/Template/Index?templateId=48213"
}
],
"hasMore": false,
"total": 2
}

Each item is a Template Version object.

Responses​

StatusCodeWhen
200—The versions, newest first.
400VALIDATION_ERRORkey is not a GUID (field: key).
403FORBIDDENThe key acts as a Member whose permission on the Library folder the template is in is Deny.
404TEMPLATE_NOT_FOUNDNo template in this workspace has that key.

Notes​

  • An archived template's versions are still listed.

Copy a Template​

Copies a template, and everything in it, into a new template of its own at version 1. This is the way to duplicate a template — it is the same copy the app's Duplicate button makes.

POST /v3/templates/{key}/copy

Parameters​

NameInTypeRequiredDescription
keypathstringYesThe key of the template to copy. The copy is made from its latest version.

Request Body​

{
"name": "Supplier Onboarding — EU",
"description": "Set up a new EU supplier before their first invoice is paid."
}
FieldTypeRequiredDescription
namestringYesThe copy's name, at most 100 characters. It may be the same as the original's.
descriptionstringNoThe copy's description. Omit it to keep the original's; send "" to give the copy none.

Example​

POST https://api.checkflow.io/v3/templates/ae72d986-884f-4c87-abeb-669e0543b59c/copy
X-API-KEY: your-api-key-here
Content-Type: application/json

{
"name": "Supplier Onboarding — EU",
"description": "Set up a new EU supplier before their first invoice is paid."
}
HTTP/1.1 201 Created
{
"key": "99d0227d-d5a9-42da-9317-ddda5cdf74eb",
"name": "Supplier Onboarding — EU",
"description": "Set up a new EU supplier before their first invoice is paid.",
"version": 1,
"latestVersion": 1,
"isLatest": true,
"isArchived": false,
"url": "https://app.checkflow.io/Template/Index?templateKey=99d0227d-d5a9-42da-9317-ddda5cdf74eb",
"createdDateTime": "2026-09-22T08:41:02.513Z",
"createdBy": {
"name": "Sarah Chen",
"email": "sarah.chen@acme.example"
},
"tasks": [
{
"key": "54489054-80f5-4127-b5bb-7990c5fa291e",
"name": "Collect supplier details",
"isHeading": false,
"order": 1,
"fields": [
{
"key": "9bd1844f-b751-43a7-a95a-9602fae94f7d",
"name": "Supplier name",
"type": "ShortText",
"isRequired": true
},
{
"key": "49be1345-d50b-4df4-9d5b-06792b5a15cc",
"name": "VAT number",
"type": "ShortText",
"isRequired": true,
"regex": "^GB[0-9]{9}$",
"regexMessage": "A UK VAT number is GB followed by nine digits."
}
]
}
]
}

Returns a Template Detail object for the copy.

Responses​

StatusCodeWhen
201—The copy was created.
400VALIDATION_ERRORkey is not a GUID (field: key), or name is missing, blank or longer than 100 characters (field: name).
403FORBIDDENThe key acts as a Member without Template.Creator, or whose permission on the Library folder the template is in is only View or Deny.
404TEMPLATE_NOT_FOUNDNo template in this workspace has that key.

Notes​

  • The copy has its own key, and so does every task, field, parameter and rule in it. Everything inside that pointed at one of those — conditions, due date anchors, task tags, dynamic assignments, parameter bindings, Data Set links, valueFrom bindings, SendEmail attachments and {{content.x}} tokens — is repointed at the copy's own, so nothing in the copy reaches back into the original.
  • Images, videos and read-only files are shared with the original rather than duplicated. This is what exporting a document and creating a template from it cannot do, because a document carries no files.
  • An archived template can be copied, and the copy is not archived.

Archive a Template​

Moves a template into the Library's archive. An archived template is left out of List Templates unless you ask for archived templates, and cannot be used to start new checklists; checklists already running from it are unaffected. Archiving applies to every version and is reversible — there is no route that deletes a template.

POST /v3/templates/{key}/archive

Parameters​

NameInTypeRequiredDescription
keypathstringYesThe template's key.

Request Body​

This endpoint takes no request body.

Example​

POST https://api.checkflow.io/v3/templates/ae72d986-884f-4c87-abeb-669e0543b59c/archive
X-API-KEY: your-api-key-here
HTTP/1.1 200 OK
{
"key": "ae72d986-884f-4c87-abeb-669e0543b59c",
"name": "Supplier Onboarding",
"description": "Set up a new supplier before their first invoice is paid.",
"version": 2,
"latestVersion": 2,
"isLatest": true,
"isArchived": true,
"url": "https://app.checkflow.io/Template/Index?templateKey=ae72d986-884f-4c87-abeb-669e0543b59c",
"createdDateTime": "2026-09-21T14:05:31.62Z",
"createdBy": {
"name": "James Okafor",
"email": "james.okafor@acme.example"
},
"tasks": [
{
"key": "9ecc4a77-4f3d-4cda-af7e-c16b9c967cc9",
"name": "Collect supplier details",
"isHeading": false,
"order": 1,
"fields": [
{
"key": "37a08a2f-33de-4465-ae20-c94b07050e5c",
"name": "Supplier name",
"type": "ShortText",
"isRequired": true
},
{
"key": "e12b7d01-7423-45b8-b293-54221f667ed2",
"name": "VAT number",
"type": "ShortText",
"isRequired": true,
"regex": "^GB[0-9]{9}$",
"regexMessage": "A UK VAT number is GB followed by nine digits."
}
]
}
]
}

Returns the Template Detail object at its latest version, with isArchived: true.

Responses​

StatusCodeWhen
200—The template is archived. Archiving a template that is already archived also answers 200 and changes nothing.
400VALIDATION_ERRORkey is not a GUID (field: key).
403FORBIDDENThe key acts as a Member. Archiving and unarchiving are limited to Administrators.
404TEMPLATE_NOT_FOUNDNo template in this workspace has that key.

Notes​

  • An archived template can still be read, exported, listed by version and copied, but a new version cannot be published until it is unarchived.

Unarchive a Template​

Takes a template back out of the Library's archive, restoring every version of it.

DELETE /v3/templates/{key}/archive

Parameters​

NameInTypeRequiredDescription
keypathstringYesThe template's key. To find an archived template's key, list templates with includeArchived=true.

Request Body​

This endpoint takes no request body.

Example​

DELETE https://api.checkflow.io/v3/templates/ae72d986-884f-4c87-abeb-669e0543b59c/archive
X-API-KEY: your-api-key-here
HTTP/1.1 200 OK
{
"key": "ae72d986-884f-4c87-abeb-669e0543b59c",
"name": "Supplier Onboarding",
"description": "Set up a new supplier before their first invoice is paid.",
"version": 2,
"latestVersion": 2,
"isLatest": true,
"isArchived": false,
"url": "https://app.checkflow.io/Template/Index?templateKey=ae72d986-884f-4c87-abeb-669e0543b59c",
"createdDateTime": "2026-09-21T14:05:31.62Z",
"createdBy": {
"name": "James Okafor",
"email": "james.okafor@acme.example"
},
"tasks": [
{
"key": "9ecc4a77-4f3d-4cda-af7e-c16b9c967cc9",
"name": "Collect supplier details",
"isHeading": false,
"order": 1,
"fields": [
{
"key": "37a08a2f-33de-4465-ae20-c94b07050e5c",
"name": "Supplier name",
"type": "ShortText",
"isRequired": true
},
{
"key": "e12b7d01-7423-45b8-b293-54221f667ed2",
"name": "VAT number",
"type": "ShortText",
"isRequired": true,
"regex": "^GB[0-9]{9}$",
"regexMessage": "A UK VAT number is GB followed by nine digits."
}
]
}
]
}

Returns the Template Detail object at its latest version, with isArchived: false.

Responses​

StatusCodeWhen
200—The template is live. Unarchiving a template that is not archived also answers 200 and changes nothing.
400VALIDATION_ERRORkey is not a GUID (field: key).
403FORBIDDENThe key acts as a Member. Archiving and unarchiving are limited to Administrators.
404TEMPLATE_NOT_FOUNDNo template in this workspace has that key.

List Template Permissions​

Returns who can see and run the checklists made from a template — the template's Checklist Permissions in the app.

GET /v3/templates/{key}/permissions

Parameters​

NameInTypeRequiredDescription
keypathstringYesThe template's key.

The list is not paged.

Example​

GET https://api.checkflow.io/v3/templates/3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14/permissions
X-API-KEY: your-api-key-here
HTTP/1.1 200 OK
{
"items": [
{
"assigneeType": "Group",
"assigneeId": 87,
"name": "Finance Team",
"permission": "RunAndView"
}
],
"hasMore": false,
"total": 1
}

Each item is a Template Permission object.

Responses​

StatusCodeWhen
200—The template's permissions.
400VALIDATION_ERRORkey is not a GUID (field: key).
403FORBIDDENThe key acts as a Member whose permission on the Library folder the template is in is Deny.
404TEMPLATE_NOT_FOUNDNo template in this workspace has that key.

Notes​

  • An empty list is a real answer: only Administrators can see the template's checklists. A member named by no rule can still see the tasks they are assigned.

Set Template Permissions​

Replaces a template's whole set of checklist permissions. A permission has no identity of its own, so there is nothing to change one at a time: send every rule you want the template to have, including the ones you are keeping.

PUT /v3/templates/{key}/permissions

Parameters​

NameInTypeRequiredDescription
keypathstringYesThe template's key.

Request Body​

{
"permissions": [
{ "assigneeType": "Group", "assigneeId": 87, "permission": "RunAndView" },
{ "assigneeType": "TeamMember", "assigneeId": 1051, "permission": "ViewAssignedOnly" }
]
}
FieldTypeRequiredDescription
permissionsarrayYesThe complete set of rules. An empty array removes every rule, leaving the checklists visible to Administrators only.
permissions[].assigneeTypestringYesAllUsers, TeamMember or Group.
permissions[].assigneeIdintegerFor TeamMember and GroupThe member's or group's id, from Team. Not allowed with AllUsers.
permissions[].permissionstringYesRunAndView, ViewOnly, RunAndViewAssigned or ViewAssignedOnly.
permissions[].namestringNoIgnored. The rule is about the id.

This route names assignees with assigneeType and assigneeId. The permissions array in a template document names them with type and id (or name) instead.

Example​

PUT https://api.checkflow.io/v3/templates/3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14/permissions
X-API-KEY: your-api-key-here
Content-Type: application/json

{
"permissions": [
{ "assigneeType": "Group", "assigneeId": 87, "permission": "RunAndView" },
{ "assigneeType": "TeamMember", "assigneeId": 1051, "permission": "ViewAssignedOnly" }
]
}
HTTP/1.1 200 OK
{
"items": [
{
"assigneeType": "Group",
"assigneeId": 87,
"name": "Finance Team",
"permission": "RunAndView"
},
{
"assigneeType": "TeamMember",
"assigneeId": 1051,
"name": "Priya Patel",
"permission": "ViewAssignedOnly"
}
],
"hasMore": false,
"total": 2
}

Returns the permissions as installed.

Responses​

StatusCodeWhen
200—The permissions were replaced.
400VALIDATION_ERRORkey is not a GUID; permissions is missing (field: permissions); or a rule is invalid — an unknown assigneeType or permission, a missing assigneeId, an assigneeId sent with AllUsers, an id that is not a member or group of this workspace or the same assignee named twice. field points at the rule, for example permissions[1].assigneeId.
403FORBIDDENThe key acts as a Member without Template.Creator, or whose permission on the Library folder the template is in is only View or Deny.
404TEMPLATE_NOT_FOUNDNo template in this workspace has that key. Nothing is written.

Notes​

  • Every rule is checked before anything is written, so a request with one bad rule changes nothing.
  • Permissions apply to the template as a whole, not to one version, and changing them does not publish a version.

List Checklist Upgrades​

Returns the running checklists of a template that are not on a given version — the latest, unless you name another — newest first, each with the version it is on beside the target. These are the checklists Upgrade Checklists would move, and the list is also how you watch an upgrade finish: a checklist leaves it as soon as its rebuild is done.

GET /v3/templates/{key}/upgrades

Parameters​

NameInTypeRequiredDescription
keypathstringYesThe template's key.
versionqueryintegerNoThe target version, 1 or greater. Omit for the latest. Name an older version to see what a rollback would touch.
pageSizequeryintegerNoHow many to return, 1 to 100. Default 50; a value outside that range, or not a number, is also read as 50.
afterquerystringNoThe nextCursor from the previous page. A cursor is only valid with the same version and pageSize it was issued under.

The order is fixed — newest start date first — and there is no sort parameter. total is the number of candidates in all. See Pagination.

Example​

GET https://api.checkflow.io/v3/templates/ae72d986-884f-4c87-abeb-669e0543b59c/upgrades?pageSize=2
X-API-KEY: your-api-key-here
HTTP/1.1 200 OK
{
"items": [
{
"key": "9db5bb2e-020c-480f-999a-f5ad1426583f",
"name": "Supplier Onboarding — Northwind Supplies",
"url": "https://app.checkflow.io/Checklist/Index?checklistKey=9db5bb2e-020c-480f-999a-f5ad1426583f",
"status": "InProgress",
"startDateTime": "2026-09-18T08:00:00Z",
"version": 1,
"targetVersion": 2
},
{
"key": "9584a35a-1f92-43da-b54e-94db1c245d85",
"name": "Supplier Onboarding — Harbour Freight",
"url": "https://app.checkflow.io/Checklist/Index?checklistKey=9584a35a-1f92-43da-b54e-94db1c245d85",
"status": "Complete",
"startDateTime": "2026-09-02T09:30:00Z",
"version": 1,
"targetVersion": 2
}
],
"nextCursor": "Q2hLdTdQeWZ4b0x3N2ZtVjJ6UXNL",
"hasMore": true,
"total": 3
}

Each item is an Upgrade Candidate object.

Responses​

StatusCodeWhen
200—The candidates.
400VALIDATION_ERRORkey is not a GUID (field: key); version is not a whole number of 1 or more (field: version); or after is not a valid cursor, or was issued for a different version or pageSize (field: after).
403FORBIDDENThe key acts as a Member whose permission on the Library folder the template is in is only View or Deny.
404TEMPLATE_NOT_FOUNDNo template in this workspace has that key, or the template has no such version.

Notes​

  • Candidates are compared for difference, not order: a checklist on a newer version than the target is a candidate too, which is how a rollback is found.
  • Archived checklists are left out. So is a checklist the background worker is part-way through rebuilding, which is on neither version until it finishes.
  • Completed checklists are included. They are running checklists that have not been archived, and an upgrade with all: true rebuilds them too.
  • If you publish another version while paging, the cursor no longer matches the latest version; start again from the first page.

Upgrade Checklists​

Queues running checklists to be rebuilt on a version of their template — the latest, unless you name another — carrying across every answer that still has somewhere to go. This is the same queue and background worker as the app's option to update open checklists when a template is saved. The worker can take minutes for a template with many checklists, so the route answers 202 Accepted with what it queued, and List Checklist Upgrades is how you watch it land.

POST /v3/templates/{key}/upgrades

Parameters​

NameInTypeRequiredDescription
keypathstringYesThe template's key.

Request Body​

{
"checklistKeys": [
"9db5bb2e-020c-480f-999a-f5ad1426583f",
"e7d714ea-f3f4-4cd7-bf56-fdcc5be6f56c"
]
}
FieldTypeRequiredDescription
checklistKeysarrayOne of the twoThe checklists to upgrade, by key — at most 500. Duplicates are ignored.
allbooleanOne of the twotrue to upgrade every checklist List Checklist Upgrades would return for the target version.
versionintegerNoThe version to move them to, 1 or greater. Omit for the latest. An older version is accepted, which is how a rollout is undone.

Send checklistKeys or all: true, not both.

Example​

POST https://api.checkflow.io/v3/templates/ae72d986-884f-4c87-abeb-669e0543b59c/upgrades
X-API-KEY: your-api-key-here
Content-Type: application/json

{
"checklistKeys": [
"9db5bb2e-020c-480f-999a-f5ad1426583f",
"e7d714ea-f3f4-4cd7-bf56-fdcc5be6f56c"
]
}
HTTP/1.1 202 Accepted
Location: /v3/templates/ae72d986-884f-4c87-abeb-669e0543b59c/upgrades
Retry-After: 60
{
"templateKey": "ae72d986-884f-4c87-abeb-669e0543b59c",
"templateName": "Supplier Onboarding",
"version": 2,
"queued": 1,
"checklistKeys": [
"9db5bb2e-020c-480f-999a-f5ad1426583f"
],
"skipped": [
{
"checklistKey": "e7d714ea-f3f4-4cd7-bf56-fdcc5be6f56c",
"reason": "already on version 2"
}
]
}

Returns an Upgrade Result object. Location is the candidates list and Retry-After is how many seconds to give the worker before reading it.

Responses​

StatusCodeWhen
202—At least one checklist was queued.
200—Nothing was queued: every named checklist was skipped, or there were no candidates. The body has the same shape, with queued: 0.
400VALIDATION_ERRORSee What Is Refused.
403FORBIDDENThe key acts as a Member whose permission on the Library folder the template is in is only View or Deny.
404TEMPLATE_NOT_FOUNDNo template in this workspace has that key, or the template has no such version.
404CHECKLIST_NOT_FOUNDA named checklist is not in this workspace.

What Is Refused​

A refusal refuses the whole request: nothing is queued, even for the checklists that were valid.

ProblemAnswerfield
No body400 VALIDATION_ERROR—
Both checklistKeys and all: true400 VALIDATION_ERRORall
Neither checklistKeys nor all: true400 VALIDATION_ERRORchecklistKeys
More than 500 keys400 VALIDATION_ERRORchecklistKeys
A key that is not a GUID400 VALIDATION_ERRORchecklistKeys[n]
version below 1400 VALIDATION_ERRORversion
A template or version that does not exist404 TEMPLATE_NOT_FOUND—
A key without permission to edit the template403 FORBIDDEN—
A named checklist that is not in this workspace404 CHECKLIST_NOT_FOUND—
A named checklist started from a different template400 VALIDATION_ERRORchecklistKeys

What Is Skipped​

A named checklist in one of these states is left where it is and reported under skipped, and the rest of the request goes ahead:

Statereason
Archivedarchived, and an archived checklist is not running
Already on the target versionalready on version N, with the version number

What an Upgrade Carries Across​

The worker builds each checklist afresh from the target version and moves the old checklist's work onto it. Tasks are matched by task key and fields by field key — which is why a version document must keep the id of every task and field that is meant to stay the same. The rebuilt checklist keeps its key, name and start date, and replaces the old one.

WhatCarried across
Short Text, Long Text, E-Mail, Website, Video, EmbedThe value.
Date & TimeThe date, when one was given.
Dropdown, Multi-ChoiceThe selection, matched by option key. When the field's Data Set link has changed — newly linked, pointed at a different view or unlinked — the selection is matched by the words the option showed.
Sub-TasksWhich items were ticked, matched the same way.
MembersSelections that the new version still offers and does not exclude.
File UploadThe uploaded files.
TableEntered cell values and added rows, adjusted for columns the new version adds or removes.
Linked ChecklistThe link to the child checklist, when the field still links to the same template.
Task statusCompleted and not-applicable tasks keep their status, who set it and when. A completed task that has an unanswered required field in the new version is made incomplete.
CommentsAll task comments.
AssigneesAssignees added to or removed from a task on the checklist, relative to the template.
Due datesA due date changed on the checklist is kept when the task's due date rule has not changed.
Custom notificationsNotifications added to the checklist itself, rather than inherited from the template.

A Dropdown, Multi-Choice or Sub-Tasks choice that the new version no longer offers is recorded in the checklist's activity feed as an answer that could no longer be selected. An answer to a task or field that the new version does not have at all is not carried across and is not recorded. A field that the new version fills from a new or changed valueFrom binding is filled from that binding, replacing the carried-across value.

Notes​

  • A checklist whose rebuild fails is left as it was, on its old version, and stays on the candidates list. Nothing in the response reports the failure — check the candidates list after the Retry-After interval.
  • The worker handles one template at a time. A second upgrade of the same template waits until the first has finished.
  • Upgrading cannot be undone except by another upgrade. Read List Checklist Upgrades before sending all: true.
  • The app offers the upgrade to Administrators only. The API also lets a key acting as a Member upgrade, when the Member's permission on the template's Library folder is not View or Deny.