Skip to main content

Template Documents

A template document is a whole Template written as one JSON object: its settings, tags, permissions, parameters, tasks, the fields on each task, the conditional logic rules that show and hide them and the custom notifications it sends. It is the only way to say what a template's tasks are through the API. You send one to create a template or publish a new version, you get one back when you export a template, and a draft holds one while it is being written.

This page is the reference for the format itself. The routes that accept and return documents are documented on Templates and Drafts, and the discovery routes that describe the format to a program — including an AI agent — are on Schema and Authoring Guide.

A field, in the document, is one of a task's controls — the Short Text box, the Dropdown, the Text block of instructions. The API calls them fields throughout. See Control Types for what each one does in the product.

Where Documents Are Used​

MethodPathWhat it does with a documentMCP tool
POST/v3/templatesCreates a template from a document.create_template
POST/v3/templates/{key}/versionsPublishes a document as the next version of a template.create_template_version
GET/v3/templates/{key}/documentExports a template as a document.export_template
POST/v3/templates/validateReports what is wrong with a document without saving anything.validate_template
POST/v3/draftsStarts a draft, which holds a document that may still be invalid.create_template_draft
POST/v3/drafts/{key}/commitChecks the draft's document and publishes it.commit_template

All of these read and write the same shape. Everything an export returns, create and versions accept.

The Shape of a Document​

{
"name": "Invoice Review",
"description": "Checking a supplier invoice, getting it approved and scheduling the payment.",
"settings": { "timeZone": "Europe/London" },
"tags": ["q3-audit"],
"permissions": [],
"parameters": [],
"tasks": [],
"conditions": [],
"notifications": []
}
PropertyTypeRequiredDescription
namestringYesThe template's name as the library lists it. At most 100 characters.
descriptionstringNoWhat the library shows under the name. There is no per-task description — see Tasks and Headings.
settingsobjectNoTime zone, display formats and feature switches. Leave it out for the defaults. See Settings.
tagsstring[]NoThe template's own tags, by name. See Tags.
permissionsobject[]NoWho may run and see checklists made from the template. See Permissions.
parametersobject[]NoValues asked for when a checklist is started. See Parameters.
tasksobject[]NoThe tasks and headings, in order. See Tasks and Headings.
conditionsobject[]NoThe conditional logic rules. See Conditional Logic.
notificationsobject[]NoThe custom notifications. See Custom Notifications.

Only name is required. A template with no tasks is valid, though of little use.

Rules That Apply Everywhere​

  • Array position is order. Tasks appear in the order they are listed, and fields in the order they are listed on their task. There is no order property.
  • The document carries no key and no version. The template's key is in the URL of every route that has one, and the version number is worked out when you publish.
  • Everything that can be pointed at has a ref. Tasks, fields, parameters, conditions and notifications each carry your own short name, and every cross-reference in the document is one of those refs. See Refs and Ids.
  • People, tags, templates and Data Sets are named, not keyed. A member is named by display name or email address, a group or tag by its name. Names are resolved against the workspace when the document is read, and a name that matches two things is refused rather than guessed at. GET /v3/workspace returns the names a document can use.
  • A document is a whole template, not an amendment. Publishing a version replaces everything, including the template's permissions and tags. See Changing an Existing Template.
  • Problems are collected, not reported one at a time. A refused document comes back with every violation found, each with a path into the document. See Violations.
  • Field types are spelled exactly. DropDown is a type and Drop Down is not. Case is forgiven.
warning

An unrecognised property on a field is refused with unknown_property, usually with a suggestion for what you meant. Elsewhere in the document — on a task, a due date or the document itself — an unrecognised property is currently ignored, so a misspelling such as hidenByDefault on a task is dropped without a word. Check those objects against the document schema.

Working With Documents​

To write a new template:

  1. Read GET /v3/workspace for the member, group, tag and template names you can use.
  2. Read GET /v3/schema/document for the envelope and GET /v3/schema/content-types for the field types.
  3. When you choose a field type, read GET /v3/schema/content-types/{type} for its properties and a ready-made example.
  4. Compose the document and send it to POST /v3/templates/validate until valid is true, reading any warnings as well.
  5. Send it to POST /v3/templates, or build it in a draft if it is large.

To change a template that already exists, export it, change what you need and publish the result as a version. Do not compose a version document from scratch. See Changing an Existing Template.

A Complete Example​

The document below creates an Invoice Review template. It uses a heading with instructions, template parameters, a Dropdown whose answer shows a hidden approval task and a hidden field, an approval task assigned from a parameter with a due date counted back from the payment date, a halt, a calendar due date, a date-control due date and two custom notifications.

{
"name": "Invoice Review",
"description": "Checking a supplier invoice, getting it approved and scheduling the payment.",
"settings": { "timeZone": "Europe/London", "libraryFolder": "Finance" },
"tags": ["q3-audit"],
"permissions": [
{ "type": "Group", "name": "Finance Team", "permission": "RunAndView" },
{ "type": "AllUsers", "permission": "ViewOnly" }
],
"parameters": [
{ "ref": "invoice_number", "name": "Invoice number", "type": "string" },
{ "ref": "payment_due", "name": "Payment due date", "type": "datetime" },
{ "ref": "approver", "name": "Who approves this invoice", "type": "member_or_group" }
],
"tasks": [
{
"ref": "before_you_start",
"name": "Before you start",
"isHeading": true,
"fields": [
{
"ref": "how_this_works",
"type": "Text",
"html": "<p>Have the PDF of the invoice and the purchase order number to hand.</p>"
}
]
},
{
"ref": "capture",
"name": "Capture the invoice",
"assignTo": [{ "type": "Group", "name": "Finance Team" }],
"tags": ["urgent"],
"dueDate": { "rule": "checklist-start-date", "offset": { "days": 1 } },
"fields": [
{
"ref": "invoice_ref",
"type": "ShortText",
"label": "Invoice number",
"isRequired": true,
"regex": "^INV-[0-9]{4}$",
"regexMessage": "An invoice number is INV- followed by four digits.",
"valueFrom": { "parameter": "invoice_number" }
},
{
"ref": "invoice_type",
"type": "DropDown",
"label": "What kind of spend is this",
"isRequired": true,
"items": [
{ "ref": "operating", "text": "Operating expense" },
{ "ref": "capex", "text": "Capital expenditure" },
{ "ref": "other", "text": "Something else" }
]
},
{
"ref": "other_explanation",
"type": "LongText",
"label": "What is it for",
"isRequired": true,
"hiddenByDefault": true
},
{
"ref": "invoice_pdf",
"type": "FileUpload",
"label": "Upload the invoice",
"minFiles": 1,
"maxFiles": 3
}
]
},
{
"ref": "po_check",
"name": "Check against the purchase order",
"halt": "task",
"dueDate": { "rule": "previous-task-completed", "offset": { "days": 1 } },
"fields": [
{
"ref": "po_checks",
"type": "SubTasks",
"label": "Checks",
"isRequired": true,
"items": [
{ "ref": "po_exists", "text": "The purchase order exists and is open" },
{ "ref": "amounts_match", "text": "The amounts match" },
{ "ref": "goods_received", "text": "The goods or services have been received" }
]
}
]
},
{
"ref": "approve_capex",
"name": "Approve the capital spend",
"hiddenByDefault": true,
"assignFrom": [{ "parameter": "approver" }],
"dueDate": { "rule": "task-completed", "anchorRef": "capture", "offset": { "days": 2 } },
"fields": [
{ "ref": "capex_note", "type": "LongText", "label": "Asset register reference", "isRequired": true }
]
},
{
"ref": "approve",
"name": "Approve the invoice",
"halt": "task-and-preceding",
"assignFrom": [{ "parameter": "approver" }],
"dueDate": {
"rule": "parameter",
"anchorRef": "payment_due",
"direction": "before",
"offset": { "days": 3 }
},
"fields": [
{
"ref": "decision",
"type": "DropDown",
"label": "Decision",
"isRequired": true,
"items": [
{ "ref": "approved", "text": "Approved" },
{ "ref": "rejected", "text": "Rejected" }
]
},
{
"ref": "rejection_reason",
"type": "LongText",
"label": "Why was it rejected",
"isRequired": true,
"hiddenByDefault": true
}
]
},
{
"ref": "schedule_payment",
"name": "Schedule the payment",
"dueDate": { "scenario": "next-friday", "scenarioTime": "15:00" },
"fields": [
{ "ref": "payment_date", "type": "Date", "label": "Payment date", "isRequired": true, "mode": "date" }
]
},
{
"ref": "confirm_payment",
"name": "Confirm the payment has left",
"dueDate": {
"rule": "date-control",
"anchorRef": "payment_date",
"direction": "after",
"offset": { "days": 1 }
},
"fields": [
{
"ref": "remittance_sent",
"type": "SubTasks",
"label": "Done",
"items": [{ "ref": "remittance", "text": "Remittance advice sent to the supplier" }]
}
]
}
],
"conditions": [
{
"ref": "reset_invoice_type",
"when": { "fieldRef": "invoice_type", "operator": "has-any-value" },
"then": { "effect": "hide", "tasks": ["approve_capex"], "fields": ["other_explanation"] }
},
{
"ref": "clear_invoice_type",
"when": { "fieldRef": "invoice_type", "operator": "has-no-value" },
"then": { "effect": "hide", "tasks": ["approve_capex"], "fields": ["other_explanation"] }
},
{
"ref": "capex_needs_approval",
"when": { "fieldRef": "invoice_type", "operator": "is", "value": "capex" },
"then": { "effect": "show", "tasks": ["approve_capex"] }
},
{
"ref": "explain_other",
"when": { "fieldRef": "invoice_type", "operator": "is", "value": "other" },
"then": { "effect": "show", "fields": ["other_explanation"] }
},
{
"ref": "reset_decision",
"when": { "fieldRef": "decision", "operator": "has-any-value" },
"then": { "effect": "hide", "fields": ["rejection_reason"] }
},
{
"ref": "explain_rejection",
"when": { "fieldRef": "decision", "operator": "is", "value": "rejected" },
"then": { "effect": "show", "fields": ["rejection_reason"] }
}
],
"notifications": [
{
"ref": "approval_overdue",
"event": "overdue-by",
"on": { "tasks": ["approve"] },
"offset": { "days": 1 },
"notify": [{ "type": "Group", "name": "Finance Team" }]
},
{
"ref": "invoice_done",
"event": "completed",
"on": { "checklist": true },
"notify": [{ "email": "accounts@acme.example" }]
}
]
}

What each part does:

  • The heading before_you_start groups nothing and completes nothing; its Text field carries the instructions, because a task has no description.
  • invoice_ref is filled from the invoice_number parameter when the checklist starts, and must match the regular expression.
  • The rules on invoice_type start with two resets — one for any answer, one for a cleared answer — that hide everything the later rules show. Then capex shows the approval task and other shows the explanation field. See Order and Resets for why the resets come first.
  • approve_capex starts hidden and is assigned to whoever the approver parameter names. It falls due two days after capture is completed.
  • approve is assigned from the same parameter and falls due three days before the payment_due date given when the checklist starts. Its task-and-preceding halt stops anything after it being completed until it and every task before it are done.
  • schedule_payment falls due at 15:00 on the next Friday after the checklist starts, in the template's time zone.
  • confirm_payment falls due one day after the date entered in payment_date.
  • The notifications tell the Finance Team group when the approval is a day overdue, and email an outside address when the checklist is completed.

Sent to POST /v3/templates/validate in a workspace that has a Finance Team group, this document comes back valid with no warnings:

{
"valid": true,
"errorCount": 0,
"warningCount": 0,
"violations": []
}

Refs and Ids​

Refs​

A ref is your own name for a node in the document — capture, invoice_type, approver. Every cross-reference is a ref: a condition names the field it tests and the tasks and fields it affects by ref, a due date names its anchor by ref, a binding names its source by ref.

  • A ref matches ^[a-z0-9][a-z0-9_-]{0,63}$: lower-case letters, digits, underscores and hyphens, at most 64 characters, starting with a letter or a digit. A capital letter is refused, not folded.
  • Refs are unique across the whole document, not within a kind or a task. That is what lets every reference be one bare token — a condition says "other_explanation", never "capture.other_explanation". The cost is that two tasks cannot both have a field with the ref notes.
  • Every task, field, parameter, condition and notification needs a ref. A missing ref is refused with invalid_ref, and the hint suggests one made from the node's name.
  • Dropdown, Multi-Choice and Sub-Tasks items carry a ref too. An item's ref only needs to be unique among that field's items, and it is what a condition's value names. An item with no ref cannot be tested by a condition.
  • Refs exist only inside the document. They are not stored, and an export invents fresh ones from the names. When you commit a draft, the commit status carries a refMap from your refs to the keys that were created.

Ids​

Every task, field, choice item, parameter, condition and notification may also carry an id — its real key, a GUID. Export writes one on every node.

RouteWhat an id does
POST /v3/templatesRefused with id_not_allowed. A new template gets new keys throughout. To duplicate a template, use POST /v3/templates/{key}/copy, which also copies the files a document cannot carry.
POST /v3/templates/{key}/versionsKept. A task or field that keeps its id stays the same task or field, so answers already given against it and running checklists that refer to it stay attached.
POST /v3/templates/validateRefused, unless you pass the template's key in the forTemplate query parameter to validate the document as a version of that template.

Leave id out when you write a node yourself. An id that is not a GUID is refused with invalid_id.

What Points at What​

PropertyMust name
conditions[].when.fieldRefA field of one of the eight testable types, not on a heading
conditions[].then.tasks[]A task or heading, other than the one the tested field is on
conditions[].then.fields[]A field on any task
tasks[].dueDate.anchorRefA task for task-completed, a Date field for date-control, a datetime parameter for parameter
tasks[].assignFrom[].parameterA member_or_group parameter
tasks[].assignFrom[].fieldA Members field on any task
fields[].valueFrom.parameterA parameter
fields[].valueFrom.fieldAnother field
notifications[].on.tasks[]A task that is not a heading
SendEmail attachments[]A FileUpload field on any task
LinkedChecklist linkedControls[].fieldA field in this document

A ref that names nothing is refused with unknown_ref, with a suggestion drawn from refs of the right kind when one is close. A ref that names the wrong kind of node is told so — "'capture' is a task, not a field."

Settings​

settings is optional, and every property in it has a default matching what the template editor gives a new template.

PropertyTypeDefaultDescription
timeZonestringThe request's time zoneThe zone the template's dates are read in, as an IANA name (Europe/London) or a Windows name (GMT Standard Time). An unknown zone is refused with invalid_time_zone.
dateFormatIdinteger1How dates are displayed, from 1 to 9.
timeFormatIdinteger1How times are displayed, from 0 to 2.
displayCommentsbooleantrueWhether checklists show the comment box.
displayTaskTagsbooleantrueWhether task tags are shown on the checklist.
isNotApplicableEnabledbooleantrueWhether a task can be marked not applicable.
isShareEmbedEnabledbooleantrueWhether a checklist can be shared or embedded.
isAttachedTasksEnabledbooleantrueWhether standalone tasks can be attached to a checklist.
libraryFolderstringThe rootThe library folder to file the template under, by name. At most 50 characters.

Left out, timeZone is the time zone the request acts in: the X-CF-Timezone header if you send one, otherwise the time zone of the member the API key acts as. See Conventions.

Tags​

tags is a list of tag names for the template itself. Tasks carry their own tags list in the same form.

  • A name the workspace has not used before creates a new tag when the template is saved. Read the workspace's tags first rather than coining near-duplicates.
  • Names are matched without regard to case, and a name repeated on the same template or task is read once.
  • A tag name is at most 100 characters.
  • A refused document creates no tags.

See Tags for the tag routes.

Permissions​

permissions says who may run and see the checklists made from the template. It is a complete set: what you send replaces what is stored. Permissions are held once per template, not per version, so a version document that leaves them out removes them from the template altogether.

"permissions": [
{ "type": "Group", "name": "Finance Team", "permission": "RunAndView" },
{ "type": "TeamMember", "id": 1042, "permission": "RunAndViewAssigned" },
{ "type": "AllUsers", "permission": "ViewOnly" }
]
PropertyTypeRequiredDescription
typestringYes, with idAllUsers, TeamMember or Group. AllUsers is the whole workspace and takes no id and no name.
idintegerOne of id or nameThe member's or group's id.
namestringOne of id or nameA member's display name or email address, or a group's name. Ignored when id is given.
permissionstringYesWhat they may do — see below.
permissionMeaning
RunAndViewCan start checklists from the template and see them.
ViewOnlyCan see checklists from the template but not start them.
RunAndViewAssignedCan start checklists, and see only the ones they have a task assigned in.
ViewAssignedOnlyCan see only the checklists they have a task assigned in.

One assigned task anywhere in a checklist opens the whole checklist to the two Assigned variants. None of the four grants editing — editing templates is a matter of the member's role and permissions, not of the template. The same member or group named twice is refused with duplicate_assignee. See Templates for the permission routes and Template Permissions for the product concept.

Parameters​

Template parameters are values asked for when a checklist is started. A parameter does nothing on its own: a field's valueFrom fills the field from it, a task's assignFrom assigns the task from it, and a due date's parameter rule counts from it. See Template Parameters.

"parameters": [
{ "ref": "invoice_number", "name": "Invoice number", "type": "string" },
{ "ref": "payment_due", "name": "Payment due date", "type": "datetime" },
{ "ref": "approver", "name": "Who approves this invoice", "type": "member_or_group" }
]
PropertyTypeRequiredDescription
refstringYesYour name for the parameter.
idstringNoThe parameter's key. Written by export; keep it on a version, leave it out otherwise.
namestringYesWhat whoever starts the checklist is asked for. At most 100 characters.
typestringYesstring, datetime or member_or_group.
defaultValuestringNoThe value offered when a checklist is started.
typeCan fillCan assign a taskCan anchor a due date
stringAny field that takes valueFrom, except a DateNoNo
datetimeA Date fieldNoYes
member_or_groupA Members fieldYesNo

Tasks and Headings​

A task is one piece of work. A heading is a divider in the task list that nothing ever completes.

note

There is no task description. A task that needs explaining carries a Text field — a block of HTML the checklist shows and nobody answers. Put the instructions there.

{
"ref": "capture",
"name": "Capture the invoice",
"halt": "none",
"hiddenByDefault": false,
"assignTo": [{ "type": "Group", "name": "Finance Team" }],
"assignFrom": [],
"assignedExclusively": false,
"tags": ["urgent"],
"dueDate": { "rule": "checklist-start-date", "offset": { "days": 1 } },
"fields": []
}
PropertyTypeRequiredDescription
refstringYesYour name for the task.
idstringNoThe task's key. Written by export; keep it on a version.
namestringYesThe task's name. At most 100 characters.
isHeadingbooleanNotrue for a heading. Default false.
haltstringNoWhether the checklist stops here until the task is done. See Halts. Default none.
hiddenByDefaultbooleanNotrue to start hidden until a condition shows the task. Default false.
assignToobject[]NoMembers and groups assigned when a checklist is started. See Assignees.
assignFromobject[]NoWhere more assignees come from at run time. See Assignees.
assignedExclusivelybooleanNotrue to let only the assignees open, change or reassign the task. Has no effect while the task has no assignees. Default false.
tagsstring[]NoThe task's tags, by name.
dueDateobjectNoWhen the task falls due. Leave it out for no due date. See Due Dates.
fieldsobject[]NoThe task's fields, in order. See Fields.

See Create, Edit and Delete Tasks for tasks in the template editor.

Headings​

A heading sets "isHeading": true and takes only ref, id, name, tags and fields. A heading that also carries halt (other than none), hiddenByDefault, assignTo, assignFrom, assignedExclusively or dueDate is refused with one conflicting_properties violation listing them.

A heading may carry fields, and a condition may show or hide a heading. Three things may not point at one:

  • A condition may not be triggered by a field on a heading.
  • A task-completed due date may not be anchored to a heading, because nothing completes one.
  • A notification may not name a heading.

Halts​

halt is how a template enforces task order. See Enforce Task Order.

haltEffect
noneThe checklist runs past this task. The default.
taskNothing after this task can be completed until it is.
task-and-precedingNothing after this task can be completed until it and every task before it are.

Assignees​

A task's assignees come from two lists, and a task may use both. See Template Task Assignments and Dynamic Task Assignments for the product concepts.

Static Assignees​

assignTo names members and groups who are assigned when a checklist is started.

"assignTo": [
{ "type": "TeamMember", "id": 1042 },
{ "name": "priya.patel@acme.example" },
{ "type": "Group", "name": "Finance Team" }
]
PropertyTypeDescription
typestringTeamMember or Group. Required with id.
idintegerThe member's or group's id, from GET /v3/workspace.
namestringA member's display name or email address, or a group's name, matched without regard to case. Used when id is absent.

Each entry gives type and id, or name. An email address is always unique, so it is the safest way to name a member by name. The same person or group named twice on one task is refused with duplicate_assignee.

Dynamic Assignees​

assignFrom adds assignees that are resolved when the checklist runs rather than named now. Each entry names exactly one source.

"assignFrom": [
{ "parameter": "approver" },
{ "field": "reviewer" }
]
PropertyDescription
parameterThe ref of a member_or_group parameter. Whoever it is answered with when the checklist is started is assigned the task.
fieldThe ref of a Members field on this task or any other. Whoever is chosen in it is assigned the task as the choice is made.

An entry with both properties is refused with conflicting_properties, and an entry with neither with property_required. A parameter of another type, or a field that is not Members, is refused with property_out_of_range.

How Names Are Resolved​

The same rules apply wherever a document names somebody — assignTo, permissions, a notification's notify, a Members field's exclude and a condition testing a Members field.

ResultViolation
Nobody in the workspace matchesassignee_not_found
More than one member or group matchesambiguous_assignee, with the candidates' type and id in the hint
An id with no type, or a type that is not TeamMember or Groupproperty_out_of_range
Neither id nor nameproperty_required

Due Dates​

A task's dueDate says when it falls due in one of two ways: a rule with an offset, or a calendar scenario. A due date carrying both rule and scenario is refused with conflicting_properties. See Dynamic Task Due Dates for the product concept.

PropertyTypeDescription
rulestringWhat the offset is counted from. See the table below.
anchorRefstringThe ref of what the rule counts from, for the three rules that need one.
directionstringbefore or after. Only date-control and parameter accept before. Default after.
offsetobjectHow far from the anchor: months, days, hours and minutes. Leave it out to fall due on the anchor itself.
scenariostringA recurring moment in the calendar, instead of rule.
scenarioTimestringThe time of day a scenario falls due, as HH:mm. Default 00:00.
scenarioTimeZonestringThe zone scenarioTime is read in. Defaults to the template's timeZone.

Rules​

ruleCounts fromanchorRefdirection
checklist-start-dateWhen the checklist is started.Not allowedafter only
previous-task-completedWhen the task before this one is completed.Not allowedafter only
task-completedWhen a named task is completed.A task's ref — not a heading, not this taskafter only
date-controlThe date entered in a Date field.A Date field's refbefore or after
parameterThe date given for a template parameter when the checklist is started.A datetime parameter's refbefore or after

previous-task-completed names no task, because the task it means is worked out while the checklist runs: the last task before this one that is neither a heading nor hidden.

A checklist started without an answer for a parameter anchor gets no due date from it.

Offsets​

PropertyDescription
monthsWhole months, landing on the same day of a later month.
daysDays.
hoursHours.
minutesMinutes.

Every part defaults to 0 and must not be negative — the direction is direction's job, not the sign's. The schema advertises upper bounds of 120 months, 3650 days, 23 hours and 59 minutes.

Scenarios​

A scenario is always worked out from the day the checklist starts, so it takes no anchorRef, direction or offset — sending any of them is refused with conflicting_properties. The twenty scenarios are:

WeekMonthQuarterYear
next-weekdayfirst-day-of-next-monthlast-day-of-quarterlast-day-of-current-year
next-mondayfirst-weekday-of-next-monthlast-weekday-of-quarterlast-weekday-of-current-year
next-tuesdaylast-day-of-monthfirst-day-of-next-quarterfirst-day-of-next-year
next-wednesdaylast-weekday-of-monthfirst-weekday-of-next-quarterfirst-weekday-of-next-year
next-thursday
next-friday
next-saturday
next-sunday

scenarioTime is a wall-clock time rather than an instant: 09:00 means 09:00 in scenarioTimeZone whatever the time of year. GET /v3/schema/due-dates returns the same list.

Due Date Examples​

{ "rule": "checklist-start-date", "offset": { "days": 1 } }

One day after the checklist is started.

{ "rule": "previous-task-completed", "offset": { "days": 2, "hours": 4 } }

Two days and four hours after the previous visible task is completed.

{ "rule": "task-completed", "anchorRef": "capture", "offset": { "days": 2 } }

Two days after the task capture is completed.

{ "rule": "date-control", "anchorRef": "payment_date", "direction": "before", "offset": { "days": 5 } }

Five days before the date entered in the payment_date field.

{ "rule": "parameter", "anchorRef": "payment_due", "direction": "before", "offset": { "days": 3 } }

Three days before the date given for the payment_due parameter.

{ "rule": "date-control", "anchorRef": "payment_date" }

On the date entered in payment_date.

{ "scenario": "first-weekday-of-next-month", "scenarioTime": "09:00", "scenarioTimeZone": "Europe/London" }

09:00 London time on the first weekday of the month after the checklist starts.

What Is Refused​

MistakeViolation
Both rule and scenarioconflicting_properties
Neither rule nor scenarioproperty_required on rule — leave dueDate out for no due date
A rule or scenario not in the lists aboveproperty_out_of_range, with the nearest word as a hint
anchorRef missing on a rule that needs oneproperty_required
anchorRef on checklist-start-date or previous-task-completedconflicting_properties
anchorRef naming a heading, this task, a non-Date field or a non-datetime parameterproperty_out_of_range
direction: "before" on a rule that only counts forwardconflicting_properties
A negative offset partproperty_out_of_range
scenarioTime that is not a time of dayproperty_out_of_range
dueDate on a headingconflicting_properties

Fields​

A field is one control on a task. Every field has five properties in common; everything else belongs to its type and is written flat beside them, never nested under a config key.

{
"ref": "invoice_ref",
"type": "ShortText",
"hiddenByDefault": false,
"tooltip": "It is printed at the top right of the invoice.",
"label": "Invoice number",
"isRequired": true,
"regex": "^INV-[0-9]{4}$"
}
PropertyTypeRequiredDescription
refstringYesYour name for the field.
idstringNoThe field's key. Written by export; keep it on a version to keep the answers already given to the field.
typestringYesWhich control this is. See the table below.
hiddenByDefaultbooleanNotrue to start hidden until a condition shows the field. Default false.
tooltipstringNoHelp text behind the question mark beside the label. At most 1,200 characters.

A property the type does not have is refused with unknown_property, usually with the property you meant as a hint — required is refused with "Did you mean 'isRequired'?".

Field Types​

typeControlAnswered in the checklistTestable by a condition
TextTextNoNo
ShortTextShort TextYesYes
LongTextLong TextYesYes
EmailInputE-MailYesYes
WebsiteWebsiteYesYes
FileUploadFile UploadYesNo
DateDate & TimeYesYes
DropDownDropdownYesYes
MultiChoiceMulti-ChoiceYesYes
SubTasksSub-TasksYesNo
ImageImageNoNo
VideoVideoNoNo
FileFileNoNo
SendEmailMail-ToNoNo
SeparatorSeparatorNoNo
EmbedEmbedNoNo
MembersMembersYesYes
TableTableYesNo
LinkedChecklistLinked ChecklistNoNo

Three pairs are easy to confuse. File hands the user files and FileUpload asks them for files. Embed shows a page the author chose and Website asks the user for an address. Text tells the user something and LongText asks them something.

GET /v3/schema/content-types/{type} returns each type's full JSON Schema and an example. The tables below summarise the same properties.

Text​

PropertyTypeRequiredDescription
htmlstringYesThe prose, as HTML. Rendered as formatting, and may carry dynamic values.
{ "ref": "read_this_first", "type": "Text", "html": "<p>Check the invoice total against the purchase order <b>before</b> you approve.</p>" }

ShortText, LongText, EmailInput and Website​

These four share label, isRequired and valueFrom.

PropertyTypesTypeDescription
labelAll fourstringThe question shown above the box. Required.
isRequiredAll fourbooleanWhether the task cannot be completed until this is answered. Default false.
regexShortTextstringA .NET regular expression the answer must match. At most 1,000 characters; one that does not compile is refused with invalid_regex.
regexMessageShortTextstringWhat to show when the answer does not match. At most 400 characters.
heightLongTextintegerThe box's height in pixels, 1 to 2000. Default 100.
valueFromAll fourobjectWhere the value is filled in from. See Filling a Field In.

EmailInput checks the answer is an email address; Website takes an address the user types.

{ "ref": "supplier_email", "type": "EmailInput", "label": "Supplier's accounts email", "isRequired": true }

Date​

PropertyTypeDescription
labelstringThe question shown above the picker. Required.
isRequiredbooleanDefault false.
modestringdate, time or date-and-time. Default date.
valueFromobjectSee Filling a Field In.

A Date field is the only field a date-control due date can be anchored to, and the only type with the four ordering operators.

A DropDown takes exactly one answer, a MultiChoice any number, and SubTasks is a list of steps ticked off as the user goes.

PropertyTypeDescription
labelstringThe question shown above the list. Required.
isRequiredbooleanDefault false.
itemsobject[]The choices, in order. At least one, unless dataSet is given.
dataSetobjectWhere the choices come from instead of items. See Data Set Links.
valueFromobjectSee Filling a Field In.

Each item:

PropertyTypeDescription
refstringYour name for the choice, unique within the field. What a condition's value names.
idstringThe choice's key. Written by export; keep it on a version.
textstringWhat the choice says. Required. At most 500 characters, or 2,000 for SubTasks.

A choice field with neither items nor dataSet, or with an empty items, is refused with items_required. One with both is refused with conflicting_properties.

FileUpload​

PropertyTypeDescription
labelstringThe prompt shown above the upload box. Required.
minFilesintegerHow many files the task cannot be completed without, 0 to 100. 0 means no minimum.
maxFilesintegerHow many files may be uploaded, 0 to 100. 0 means no limit; otherwise at least minFiles.
{ "ref": "receipts", "type": "FileUpload", "label": "Upload the receipts", "minFiles": 1, "maxFiles": 10 }

Image, Video and File​

A document carries no files, so these three are limited in what a document can create.

TypeWritable propertiesRead-only propertiesCreatable from a document
ImagecaptionfileNameNo
Videourl, description, valueFromfileNameOnly with a url
Filelabelfiles (each with name and description)No
  • A new Image, a new File, or a new Video with no url is refused with binary_required. Add them in the template editor, then keep the field's id on later versions to keep the file.
  • A Video url must be an absolute http or https address, at most 2,000 characters.
  • Export writes the read-only properties. Sending them back is accepted with a property_not_writable warning and has no effect.

SendEmail​

An email the checklist sends, written when the template is. Nothing in it is answered by the checklist's user. See Mail-To.

PropertyTypeDescription
labelstringA name for the field. Never shown to the user.
tostringWho the email goes to. May carry dynamic values.
ccstringWho is copied in.
bccstringWho is blind copied in.
fromstringWho the email comes from. Needs a verified sending domain on the workspace.
replyTostringWhere replies go, when not to the sender.
subjectstringThe subject line. May carry dynamic values.
bodystringThe message; HTML under the rich and html body modes.
bodyModestringplain, rich or html. Default plain.
sendModestringmanual, manual-required or automatic. Default manual.
attachmentsstring[]The refs of FileUpload fields, on any task, whose uploaded files are attached.
  • plain opens the reader's own mail client, so CheckFlow never sends the message and from, replyTo, sendMode and attachments have no effect. plain with a sendMode other than manual is refused with conflicting_properties.
  • manual sends on a button press, manual-required on a button press the task cannot be completed without, and automatic when the task is completed.
  • An email with no to or no subject is accepted with a never_sent warning, because nothing will send it.
{
"ref": "tell_the_supplier",
"type": "SendEmail",
"label": "Tell the supplier it has been paid",
"to": "billing@northwind.example",
"subject": "Payment for {{checklist.name}}",
"body": "<p>The payment has left our account today.</p>",
"bodyMode": "rich",
"sendMode": "manual-required"
}

Separator and Embed​

A Separator takes no properties of its own. An Embed shows another page inside the task:

PropertyTypeDescription
urlstringThe page to show. Required, absolute, http or https.
heightintegerThe frame's height in pixels, 1 to 4000. Default 500.
valueFromobjectSee Filling a Field In.

Members​

People picked from the workspace by the checklist's user.

PropertyTypeDescription
labelstringThe question shown above the picker. Required.
isRequiredbooleanDefault false.
selectionModestringsingle or multiple. Default multiple.
excludeobject[]Members and groups the picker does not offer, each named by type and id or by name, as in Static Assignees.
valueFromobjectSee Filling a Field In.

A Members field can assign its task or any other task through assignFrom — see Dynamic Assignees.

Table​

A grid of cells. Cells the author fills in and marks read-only act as headings; the rest are answered in the checklist.

PropertyTypeDescription
labelstringWords shown above the grid. Optional.
rowsintegerHow many rows the grid starts with, 1 to 50. Default 4.
columnsintegerHow many columns, 1 to 50. Default 4.
allowAddRemoveRowsbooleanWhether the user may add and remove rows. Default true.
cellsobject[]The cells that are not empty and editable. The rest of the grid is built empty.
dataSetobjectRows filled from a Data Set. See Data Set Links.

Each cell:

PropertyTypeDescription
rowintegerThe row, from 1. Required.
columnintegerThe column, from 1. Required.
valuestringThe cell's content. Export writes it only for read-only cells.
readOnlybooleanWhether the checklist shows the cell rather than asking for it.
requiredbooleanWhether the task cannot be completed while the cell is empty.
backgroundstringwhite, red, orange, yellow, green, blue or grey.
formatstringplain-text, number, percent, date, time or date-time.

A cell outside the grid, or the same cell given twice, is refused.

{
"ref": "line_items",
"type": "Table",
"label": "Line items",
"rows": 3,
"columns": 2,
"cells": [
{ "row": 1, "column": 1, "value": "Item", "readOnly": true, "background": "grey" },
{ "row": 1, "column": 2, "value": "Amount", "readOnly": true, "background": "grey" },
{ "row": 2, "column": 2, "required": true, "format": "number" }
]
}

LinkedChecklist​

Starts a second checklist from another template, as a sub-process. See Linked Checklists.

Filling a Field In​

valueFrom fills a field for the user from one source. It is accepted by ShortText, LongText, EmailInput, Website, Date, DropDown, MultiChoice, SubTasks, Members, Video and Embed. Give exactly one of parameter, field or dynamicValue; dataSetField goes with field.

PropertyDescription
parameterThe ref of a parameter, filled when the checklist starts. See the table in Parameters for which type fills which field.
fieldThe ref of another field, copied in whenever it changes.
dataSetFieldWith field: a field of the record that field selected from its Data Set, by name or key.
dynamicValueA global dynamic value as its token, such as {{checklist.name}}, {{current_user.email}} or {{current_date}}.

What a field source can fill:

TargetCan be filled from
DateA Date field
DropDownA DropDown field
EmailInputAn EmailInput field
Website, Video, EmbedA Website field
ShortText, LongTextAny answerable field
  • A field that reads its choices from a Data Set holds a record rather than a value, so a field copying from it must say which record field with dataSetField. A Date takes a date field of the record, an EmailInput an email field, a Website a URL field, and ShortText or LongText any field. A MultiChoice or SubTasks source selects several records and fills only ShortText and LongText.
  • Which dynamic values a field takes depends on its type: a Date takes the date-valued ones, a DropDown takes none, and text fields take any. See Dynamic Values.
  • A field cannot be filled from itself. A mismatched source is refused with property_out_of_range, naming what the target accepts.
{ "ref": "supplier_region", "type": "ShortText", "label": "Region",
"valueFrom": { "field": "supplier", "dataSetField": "Region" } }

A DropDown, MultiChoice or SubTasks field can take its choices from a Data Set view instead of items, and a Table can start each checklist with a row per record. Write dataSet on the field and leave items out. See Linking a Data Set to a Control.

{
"ref": "supplier",
"type": "DropDown",
"label": "Which supplier sent the invoice",
"isRequired": true,
"dataSet": { "name": "Suppliers", "view": "Active suppliers", "displayField": "Supplier name" }
}
PropertyTypeDescription
keystringThe Data Set's key, or a built-in Data Set's slug such as system-countries. Exact; wins when both key and name are given.
namestringThe Data Set's name. Refused when two Data Sets share it. At most 200 characters.
viewstringThe view, by name or key. Left out, the default view — every record.
displayFieldstringChoice fields only. The field whose value each choice shows, by name or key. Left out, the first text field.
prePopulateRowsbooleanTable only. Whether a checklist starts with one row per record of the view, mapped cells filled in and read-only. The view may hold at most 500 records.
columnsobject[]Table only, required. Which Data Set field fills which column: field (name or key) and column (from 1). Between 1 and 20 entries.

A Table keeps its own rows, columns and header cells; the link only says what fills them.

A link naming a Data Set, view or field the workspace does not have is refused with unknown_data_set, unknown_data_set_view or unknown_data_set_field, and a name matching more than one with the matching ambiguous_ code. A link the Data Set service still refuses — a pre-populating table reading a view of more than 500 records — is refused with data_set_link_invalid. GET /v3/data-sets lists the Data Sets you can name, and GET /v3/data-sets/{dataSetKey} gives one Data Set's views and fields.

Export writes each link back by name, so a linked template round-trips like any other. On a version, a field that keeps its id but drops its dataSet becomes a fixed list again, and the answer carries a data_set_link_removed warning.

Linked Checklists​

A LinkedChecklist field starts a checklist from another template. See Linked Checklist.

PropertyTypeDescription
templateKeystringThe linked template's key. Exact; wins when both are given.
templateNamestringThe linked template's name. Refused when two templates share it.
namestringWhat the new checklist is called. Defaults to the template's name; may carry dynamic values.
createAutomaticallybooleanWhether the checklist starts as soon as the task is reached rather than when somebody presses the button. Default false.
linkedControlsobject[]Values copied into the linked checklist. See below.

One of templateKey or templateName is required. An archived template can be linked. A link to the template it is on with createAutomatically set is refused with circular_reference, because each checklist would start another.

linkedControls copies values from fields in this document into controls of the linked template, when the checklist is started and again whenever the parent's value changes:

PropertyTypeDescription
fieldstringThe ref of the field here whose value is copied. Required.
childFieldstringThe label, or the key, of the control in the linked template. Required.
childTaskstringThe name of the task in the linked template that the control is on. Needed only when two tasks there use the same label. Export always writes it.
defaultValuestringWhat the child control gets when the parent has no value.

Values can be copied from Date, DropDown, EmailInput, FileUpload, LongText, Members, MultiChoice, ShortText, SubTasks and Website fields, into Date, DropDown, EmailInput, Embed, LongText, Members, MultiChoice, ShortText, SubTasks, Text, Video and Website controls. A label that matches no control of the linked template is refused with unknown_linked_control, and one matching several with ambiguous_linked_control. GET /v3/templates/{key} on the linked template lists its tasks and fields.

{
"ref": "onboard_supplier",
"type": "LinkedChecklist",
"templateName": "Supplier Onboarding",
"name": "Onboarding for {{checklist.name}}",
"createAutomatically": true,
"linkedControls": [
{ "field": "supplier_email", "childTask": "Collect their details", "childField": "Accounts email" },
{ "field": "payment_date", "childField": "First payment date", "defaultValue": "2026-10-01" }
]
}

Conditional Logic​

A condition shows or hides tasks and fields when a field's answer passes a test. Conditions live in the document's own conditions array, not on a task: the rule is attached to the task holding the field it tests. See Conditional Logic for the product concept.

{
"ref": "capex_needs_approval",
"when": { "fieldRef": "invoice_type", "operator": "is", "value": "capex" },
"then": { "effect": "show", "tasks": ["approve_capex"], "fields": [] }
}
PropertyTypeRequiredDescription
refstringYesYour name for the rule.
idstringNoThe rule's key. Written by export.
when.fieldRefstringYesThe ref of the field tested — the conditional logic trigger.
when.operatorstringYesThe test. See Operators.
when.valuevariesDepends on the operatorWhat the answer is compared with. See Values.
then.effectstringYesshow or hide.
then.tasksstring[]One of tasks or fieldsThe refs of tasks or headings to show or hide.
then.fieldsstring[]One of tasks or fieldsThe refs of fields to show or hide, on any task.
  • Only eight types can be tested: Date, DropDown, MultiChoice, EmailInput, LongText, ShortText, Website and Members. Design the fields a template's logic depends on around this before writing the tasks.
  • A rule must name at least one task or field in then, or it is refused with property_required.
  • A rule may not show or hide the task its own tested field is on — hiding it would hide the question. It may show or hide other tasks, and fields on any task including its own. The mistake is refused with conflicting_properties.
  • A field on a heading cannot be tested.
  • A task or field named twice in one rule is affected once.

Operators​

operatorTakes a valueAvailable on
isYesAll eight testable types
is-notYesAll eight testable types
has-no-valueNoAll eight testable types
has-any-valueNoAll eight testable types
is-greater-thanYesDate only
is-greater-than-or-equal-toYesDate only
is-less-thanYesDate only
is-less-than-or-equal-toYesDate only

A value sent with has-no-value or has-any-value is refused with conflicting_properties rather than ignored. An ordering operator on any type but Date is refused with property_out_of_range. GET /v3/schema/condition-operators returns the same table.

Values​

The shape of value follows the type of the field tested.

Field testedvalueExample
DropDown, MultiChoice with itemsThe ref of one of that field's items"capex"
DropDown, MultiChoice with dataSetA record of the view: { "recordKey": "..." }, or { "record": "..." } with the words the choice shows{ "record": "Northwind Traders" }
DateAn ISO date, or a date and time, with no offset"2026-10-01", "2026-10-01T09:00"
MembersA member or group, named as in Static Assignees{ "type": "Group", "name": "Finance Team" }
ShortText, LongText, EmailInput, WebsiteText compared exactly as written, at most 500 characters"N/A"
  • A Date value is accepted as yyyy-MM-dd, yyyy-MM-ddTHH:mm or yyyy-MM-ddTHH:mm:ss, and nothing else.
  • A number or boolean given for a text field is read as its text.
  • A record named by its words must match exactly one record of the view, compared without regard to case; otherwise unknown_data_set_record or ambiguous_data_set_record. Export writes recordKey.
  • An item ref the field does not have is refused with unknown_ref, with the nearest item ref as a hint.

Order and Resets​

When an answer changes, the checklist takes the rules on that field in the order they appear in conditions and applies each one that fires. A rule that does not fire changes nothing, nothing goes back to hiddenByDefault on its own, and the last rule to fire wins. So a lone show rule is a one-way door:

{ "ref": "explain_other", "when": { "fieldRef": "invoice_type", "operator": "is", "value": "other" },
"then": { "effect": "show", "fields": ["other_explanation"] } }

Choose Something else and the field appears. Change the answer to Operating expense and it stays, because no rule fired to hide it.

The fix is a reset, first among the rules on the same field, that puts back everything the later rules move:

{ "ref": "reset_invoice_type", "when": { "fieldRef": "invoice_type", "operator": "has-any-value" },
"then": { "effect": "hide", "tasks": ["approve_capex"], "fields": ["other_explanation"] } },
{ "ref": "capex_needs_approval", "when": { "fieldRef": "invoice_type", "operator": "is", "value": "capex" },
"then": { "effect": "show", "tasks": ["approve_capex"] } },
{ "ref": "explain_other", "when": { "fieldRef": "invoice_type", "operator": "is", "value": "other" },
"then": { "effect": "show", "fields": ["other_explanation"] } }
  • The reset goes first. Placed after the show rules, it fires every time they do and undoes them.
  • It is on the same field. A field's rules run only when that field is answered.
  • It names every target of the rules after it, with the opposite effect: a hide reset for rules that show things hidden by default, a show reset for rules that hide things visible by default.
  • Add a has-no-value reset when the answer can be cleared. has-any-value does not fire when a Dropdown, Multi-Choice or Members answer is emptied.
  • A matching is-not rule works for a single value only. With two or more show values, each is-not rule fires for the other value and undoes it.

Validation warns with never_restored when a rule has no way back, or when a reset comes after the rule it undoes. It warns with never_shown when a task or field starts hidden and no rule shows it — a legitimate way to park something, and an easy mistake.

Custom Notifications​

A custom notification tells people when something happens to the checklist or some of its tasks. Notifications live in the document's own notifications array, because one may be about the checklist and several tasks at once. See Custom Notifications for the product concept.

{
"ref": "approval_overdue",
"event": "overdue-by",
"on": { "tasks": ["approve"] },
"offset": { "days": 1 },
"notify": [
{ "type": "Group", "name": "Finance Team" },
{ "email": "controller@acme.example" }
]
}
PropertyTypeRequiredDescription
refstringYesYour name for the notification.
idstringNoThe notification's key. Written by export; keep it on a version.
eventstringYesThe notification trigger. See the table below.
on.checklistbooleanOne of checklist or taskstrue when the notification is about the checklist itself.
on.tasksstring[]One of checklist or tasksThe refs of the tasks it is about. Not headings.
offsetobjectFor due-in and overdue-by onlyHow far from the task's due date: months, days, hours, minutes, at least one above zero.
notifyobject[]Yes, at least oneWho is told.
eventSent whenoffsetAbout the checklist
status-changedThe checklist or task is completed, uncompleted or marked not applicable.RefusedAllowed
completedIt is completed.RefusedAllowed
uncompletedIt is uncompleted.RefusedAllowed
not-applicableIt is marked not applicable.RefusedAllowed
due-inThe offset before a task's due date.RequiredRefused
overdue-byThe offset after a task's due date.RequiredRefused

Each notify entry is a member or group of the workspace, named by type and id or by name as in Static Assignees, or { "email": "..." } for anybody outside it. An entry with both an email and a name is refused with conflicting_properties, and the same recipient twice with duplicate_assignee.

Limits​

Each of these is the size the storage keeps. A longer value is refused with property_out_of_range rather than stored cut short.

WhatLongest
A ref64 characters
Template name100 characters
Task name100 characters
Parameter name100 characters
A tag name100 characters
settings.libraryFolder50 characters
A field's tooltip1,200 characters
ShortText regex1,000 characters
ShortText regexMessage400 characters
A DropDown or MultiChoice item's text500 characters
A SubTasks item's text2,000 characters
A Video url2,000 characters
A condition's text value500 characters
A Data Set link's name200 characters

Numeric ranges — LongText height, Embed height, Table rows and columns, FileUpload minFiles and maxFiles, dateFormatId and timeFormatId — are given with each property above and in GET /v3/schema/content-types/{type}. Labels, descriptions, html, email bodies and Embed addresses have no length limit.

Violations​

Every problem found in a document is a violation. They are collected rather than raised one at a time, so a document with four problems is refused once with all four.

The Violation Object​

{
"path": "$.conditions[2].when.fieldRef",
"code": "unknown_ref",
"message": "No field with ref 'invoice_typ' exists in this document.",
"hint": "Did you mean 'invoice_type'?",
"severity": "error"
}
FieldTypeDescription
pathstringA JSONPath into the document as you sent it, such as $.tasks[2].fields[1].regex. A problem with a whole node points at the node, such as $.tasks[0].fields[0].
codestringWhat kind of problem it is. Stable — branch on this, not on the message. See Violation Codes.
messagestringWhat is wrong, in a sentence. The wording may change.
hintstringWhat to do about it, often the value you probably meant. Absent when there is nothing useful to suggest.
severitystringerror refuses the document; warning does not.

Where Violations Appear​

  • POST /v3/templates/validate (and POST /v3/drafts/{key}/validate) answers 200 OK whatever it finds, with valid, errorCount, warningCount and violations. valid is false only when there are errors. This is the only way to see warnings on a document that would be accepted.
  • POST /v3/templates, POST /v3/templates/{key}/versions and a draft commit refuse a document with errors with 422 Unprocessable Entity and the code TEMPLATE_INVALID. The error's violations carries every violation found, warnings included, and the message counts only the errors. Nothing is written — not even new tags. A document with only warnings is accepted and the warnings are not reported.
HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json; charset=utf-8
X-Request-Id: req_7d2e41c9a0b84f5f9e6c3a1b2d7f8e90
{
"error": {
"code": "TEMPLATE_INVALID",
"message": "The template document has 2 problems.",
"requestId": "req_7d2e41c9a0b84f5f9e6c3a1b2d7f8e90",
"violations": [
{
"path": "$.tasks[1].fields[0].required",
"code": "unknown_property",
"message": "'required' is not a property of a ShortText field.",
"hint": "Did you mean 'isRequired'?",
"severity": "error"
},
{
"path": "$.conditions[0].when.fieldRef",
"code": "unknown_ref",
"message": "No field with ref 'invoice_typ' exists in this document.",
"hint": "Did you mean 'invoice_type'?",
"severity": "error"
}
]
}
}

See Errors for the error body.

Violation Codes​

Errors:

CodeMeaning
unknown_content_typeA field's type is not one of the nineteen. The hint names the nearest.
unknown_propertyA field carries a property its type does not have — usually a misspelling.
property_type_mismatchA property is the wrong kind of JSON value, such as a string where an object belongs.
property_requiredA property that cannot be left out was left out.
property_out_of_rangeA value the storage cannot hold or the product does not recognise: an unknown word, a number outside its range, a string too long, an anchor of the wrong kind.
invalid_refA ref is missing or does not match the ref grammar. The hint suggests one made from the name.
invalid_idAn id (or a recordKey or templateKey) is not a GUID.
id_not_allowedAn id on a route that creates a template.
duplicate_refTwo nodes claim one ref. The second is reported, with a numbered alternative as the hint.
unknown_refA ref names nothing, or names the wrong kind of node, or a condition names an item the field does not have.
invalid_regexA regex does not compile.
invalid_urlA URL is not an absolute http or https address.
invalid_time_zoneA time zone the server does not know.
items_requiredA choice field has no items and no Data Set link.
binary_requiredAn Image, File, or Video with no url, that has no existing file to keep. Create it in the template editor.
assignee_not_foundA named member or group is not in the workspace.
ambiguous_assigneeA name matches more than one member or group.
duplicate_assigneeThe same member, group or email address named twice where once is the only sense.
conflicting_propertiesTwo properties that cannot both be meant, such as rule and scenario, or a property a heading cannot have.
unknown_templateA linked template does not exist in the workspace.
ambiguous_templateA linked template's name matches more than one template.
unknown_linked_controlA linked control names a task or control the linked template does not have.
ambiguous_linked_controlA linked control's label matches more than one control.
unknown_data_setA dataSet names a Data Set the workspace does not have.
ambiguous_data_setA Data Set name matches more than one Data Set.
unknown_data_set_viewA dataSet.view names no view of the Data Set.
ambiguous_data_set_viewA view name matches more than one view.
unknown_data_set_fieldA display field, mapped column or dataSetField names no field of the Data Set.
unknown_data_set_recordA condition names a record the view does not have.
ambiguous_data_set_recordA record's words match more than one record.
data_set_link_invalidThe Data Set service refused a link, such as a pre-populating table reading a view of more than 500 records.
circular_referenceA LinkedChecklist links to the template it is on and is set to create automatically.

Warnings:

CodeMeaning
never_shownA task or field starts hidden and no rule shows it.
never_restoredA rule moves something off how it starts and no rule on the same field moves it back, or the reset comes after the rule it undoes.
never_sentA SendEmail field has no to or no subject, so nothing will send it.
property_not_writableA read-only property, such as an Image's fileName, was sent. It is ignored.
data_set_link_removedOn a version, a field that read from a Data Set no longer does.

Changing an Existing Template​

Publish changes by round trip, not by writing a version document from scratch:

  1. Export the template with GET /v3/templates/{key}/document.
  2. Change the part that is wrong.
  3. Send the whole result to POST /v3/templates/{key}/versions, or start a draft from the template with fromTemplateKey — see Drafts.

The round trip matters for three reasons:

  • id on every task and field. A version document that drops one describes a new task or field, and the answers already given against the old one do not follow it.
  • Permissions and tags are stored once per template. A version document that leaves them out removes them from every version, including ones somebody else published.
  • A dataSet is part of the field. A version that keeps a field's id and drops its link turns it back into a fixed list.

An export also writes name beside id for permissions, invents refs from the names (numbered _2, _3 when two names slug alike), writes Data Set links and linked templates by name, and writes the read-only properties of Image, Video and File fields. Publishing a version never changes an older one; see Template Versioning and Templates for moving running checklists onto a new version.

warning

Posting an exported document to POST /v3/templates is refused with id_not_allowed. To duplicate a template, use POST /v3/templates/{key}/copy, which copies the files behind Image, Video and File fields that a document cannot carry and repoints every internal reference at the copy.

  • Templates — the routes that create, export, validate and version templates from documents.
  • Drafts — building a large document step by step and committing it.
  • Schema and Authoring Guide — the discovery routes that describe this format to a program.
  • Errors — the error body that carries violations.
  • Conditional Logic — how show and hide rules behave in the product.