Managing templates via the API
The Flow Templates API lets you manage page and ballot templates programmatically — list, create, update, clone, and more — without using the UI.
All examples below use cURL. Replace YOUR_API_TOKEN with your API key and https://app.example.com with your instance URL.
How fields work
Fields are the core of what makes a template reusable. A template's body_html contains Liquid tags like {{ template.heading }}, and the fields array defines what those tags are — their type, label, default value, and how they appear in the page builder.
When someone creates a page from your template, each field becomes an editable input. The values they enter get substituted into the HTML via Liquid at render time.
Example: a template with fields
Here's a complete template that has a heading, an intro paragraph, and an optional hero image:
Body HTML:
<div class="header">
<h1>{{ template.heading }}</h1>
</div>
<div class="content">
{% if template.heroImage != blank %}
<div class="hero">{{ template.heroImage }}</div>
{% endif %}
<p class="intro">{{ template.introText }}</p>
<surveyform></surveyform>
</div>Fields:
[
{
"slug": "heading",
"label": "Page Heading",
"questionType": "text",
"wysiwyg": true,
"defaultValue": "Take our survey",
"translatable": true,
"showInWizard": true
},
{
"slug": "heroImage",
"label": "Hero Image",
"questionType": "image",
"image": true,
"required": false,
"showInWizard": true
},
{
"slug": "introText",
"label": "Introduction",
"questionType": "paragraph",
"wysiwyg": true,
"defaultValue": "Thanks for taking the time to fill out our survey.",
"translatable": true
}
]Notice how each field's slug matches a {{ template.slug }} tag in the HTML. The heading field has wysiwyg: true so it can be edited inline in the page builder preview. The heroImage field is optional (required: false) and the HTML uses a Liquid {% if %} block to hide it when empty.
Field properties
Each field requires:
slug— unique identifier, must be camelCase (this is what you reference in HTML as{{ template.slug }})label— display name shown when editingquestionType— one of:text,url,paragraph,select,checkbox,image
Common optional properties:
defaultValue— pre-filled value when a page is created from this templatewysiwyg— iftrue, the field is editable directly in the page builder previewsetup— iftrue, shown in the page builder's setup tab instead of the editorshowInWizard— iftrue, shown in the initial page creation wizardtranslatable— iftrue, the value can differ across languagesrequired— whether the field must be filled in (default:true)image— iftrue, the value is rendered as an imagedescription— help text shown when editing the fieldoptions— forselectfields, an array of{ "value": "...", "label": "..." }choices
Field types
| Type | Description | Example use |
|---|---|---|
text | Single-line text input | Headings, button labels |
url | Single-line URL input | Links, redirect URLs |
paragraph | Multi-line text input | Intro copy, descriptions |
select | Dropdown with options | Theme picker, layout variants |
checkbox | Boolean toggle | Show/hide optional sections |
image | Image uploader | Hero images, logos |
Using fields in HTML with Liquid
Reference a field value: {{ template.fieldSlug }}
Conditionally show content based on a checkbox or optional field:
{% if template.showDisclaimer != blank %}
<div class="disclaimer">Terms and conditions apply.</div>
{% endif %}Branch on a select field value:
{% if template.layout == 'wide' %}
<div class="content-wide">...</div>
{% else %}
<div class="content-narrow">...</div>
{% endif %}See the Building page and ballot templates guide for the full HTML/CSS/Liquid reference.
API endpoints
Fetching a template
curl -H "Authorization: Token YOUR_API_TOKEN" \
"https://app.example.com/api/flow_templates/42"Returns the full template including body_html, styles_css, head_html, and fields.
Searching templates
curl -H "Authorization: Token YOUR_API_TOKEN" \
"https://app.example.com/api/flow_templates/search?query=survey"Creating a template
curl -X POST \
-H "Authorization: Token YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
"https://app.example.com/api/flow_templates"Creates a blank template. Use the update endpoint to add content.
Updating a template
This is the main endpoint for setting HTML, CSS, and fields:
curl -X PUT \
-H "Authorization: Token YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"flow_template": {
"name": "Branded Survey",
"styles_css": ".template-body { font-family: Arial; } .header { background: #2c3e50; color: white; padding: 2rem; text-align: center; }",
"body_html": "<div class=\"header\"><h1>{{ template.heading }}</h1></div><div class=\"content\"><surveyform></surveyform></div>",
"fields": [
{
"slug": "heading",
"label": "Page Heading",
"questionType": "text",
"wysiwyg": true,
"defaultValue": "Take our survey",
"translatable": true
}
]
}
}' \
"https://app.example.com/api/flow_templates/42"Other endpoints are available for cloning, archiving, restoring, and deleting templates — see the API reference for details.
Updated 13 days ago
