Build a form by pasting JSON
Create or replace a form's questions in one step by pasting a JSON document.
A JSON document describes every page, question, choice and follow-up rule of a form, and pasting it builds the whole form at once. Copy this article with the button above or below and use the format to prepare the document outside the editor, or use Copy the prompt under the paste box to have an assistant write it.
- On Create form, choose Paste JSON as the starting point, paste the document and choose Create form. It builds a new draft form, the same as choosing a starting point does.
- In the editor, Import JSON in the More menu, then Import, replaces the current draft's pages and questions entirely with what's in the pasted document: anything in the draft that isn't in the JSON is gone. A form you've already published is unaffected until you publish again; respondents keep seeing the last published version until then.
Either way, the document is checked in full before anything is saved. If any part of it doesn't fit the format below, nothing is created or changed, and the specific problem is reported.
The document
{
"title": "Volunteer sign-up",
"schema": { "description": "...", "pages": [] }
}
title is optional, up to 150 characters. Leave it out and the title typed
into the page's own title field is used instead; replacing a form in the
editor keeps its current title.
schema holds the form itself. description is optional intro text under the
title (1000 characters). completion is optional: { "heading": "...", "message": "..." }, shown after a response is submitted. payment is
optional too; leave it out unless the form should charge for a response, which
still needs Stripe connected before the form can be published (see
Require payment for a Form response). pages is required, and needs at least one page:
{ "title": "...", "blocks": [] }.
A page's blocks run in order, and are one of four kinds: { "type": "heading", "text": "..." }, { "type": "paragraph", "text": "..." }, { "type": "divider" }, or a question: { "type": "field", "field": { ... } }.
Questions
{
"key": "attending",
"type": "yes_no",
"label": "Will you attend?",
"required": true
}
label is the question text, required, up to 500 characters. description is
optional help text shown underneath it. required is true or false,
defaulting to false. key is a short made-up name for this question. It
isn't part of the finished form, and only matters if a later question follows
up on this one, covered below.
options lists the choices offered, and is required, with at least one entry, for
radio, checkboxes, and select; leave it out for every other type.
| Type | Answer | |
|---|---|---|
text |
one line | |
textarea |
multiple lines | |
email |
an email address | checked as valid |
phone |
one line | not checked |
url |
a web address | checked as valid |
number |
one line | not range-checked |
radio |
one of several choices | needs options |
checkboxes |
any of several choices | needs options |
select |
one choice, as a dropdown | needs options |
yes_no |
Yes or No | built in, so do not set options |
date |
a date | |
time |
a time | |
rating |
1 to 5 | built in, so do not set options |
scale |
a number from 0 or 1 to 5 or 10 | set scaleMin (0 or 1) and scaleMax (5 or 10), 0 to 10 if left out, and the words for each end in scaleLow and scaleHigh |
file |
one uploaded file |
Follow-up questions
Give an earlier question a key, then point a later question's visibility
at it with fieldKey:
{
"key": "has_guests",
"type": "yes_no",
"label": "Bringing any guests?",
"required": true
},
{
"key": "guest_names",
"type": "textarea",
"label": "Guest names",
"visibility": [
{ "fieldKey": "has_guests", "operator": "equals", "value": "Yes" }
]
}
This is the same conditional visibility the editor's own Conditional
visibility panel offers (see Build, publish, and share a form). Every
fieldKey must match a key used elsewhere in the document, or the import is
rejected. operator is equals, not_equals, contains, answered, or
not_answered. A question can list more than one rule; add
"visibilityMode": "any" alongside visibility when matching one of
them should be enough, instead of requiring all of them.
A complete example
{
"title": "Team retreat RSVP",
"schema": {
"description": "Let us know if you're joining this year's retreat.",
"completion": { "heading": "Thank you.", "message": "We'll follow up with details closer to the date." },
"pages": [{
"title": "",
"blocks": [
{ "type": "field", "field": { "key": "name", "type": "text", "label": "Full name", "required": true } },
{ "type": "field", "field": { "key": "email", "type": "email", "label": "Email", "required": true } },
{ "type": "field", "field": { "key": "attending", "type": "yes_no", "label": "Will you attend?", "required": true } },
{ "type": "field", "field": {
"key": "diet",
"type": "select",
"label": "Dietary preference",
"required": true,
"options": ["No restrictions", "Vegetarian", "Vegan", "Other"],
"visibility": [{ "fieldKey": "attending", "operator": "equals", "value": "Yes" }]
} }
]
}]
}
}
If an import is rejected for a reason you can't work out, Contact support.
Demander à l’assistance Magpie
Envoyez à l’équipe Magpie une question sur tout ce que cet article n’explique pas.