Agent-authored definition JSON
Preserve reviewed question text, answer types, and branches by submitting a canonical form definition.
Use --definition when the agent writes the questions. Pollaris validates and saves this definition instead of generating new questions from a prompt. The form title is passed separately with --title.
Complete example
Save this as definition.json. It asks a required 1–5 rating followed by an optional comment, then ends:
{
"start": "00000000-0000-0000-0000-000000000001",
"questions": [
{
"id": "00000000-0000-0000-0000-000000000001",
"key": "visit_rating",
"type": "rating",
"prompt": "How would you rate your visit?",
"config": {
"scale": {
"min": 1,
"max": 5
}
},
"required": true,
"next_id": "00000000-0000-0000-0000-000000000002"
},
{
"id": "00000000-0000-0000-0000-000000000002",
"key": "comments",
"type": "text",
"prompt": "What could we improve?",
"config": {
"validation": {
"max_length": 500
}
},
"required": false,
"next_id": null
}
],
"edges": [
{
"id": "00000000-0000-0000-0000-000000000003",
"source": "00000000-0000-0000-0000-000000000001",
"target": "00000000-0000-0000-0000-000000000002",
"condition": null,
"priority": 0
},
{
"id": "00000000-0000-0000-0000-000000000004",
"source": "00000000-0000-0000-0000-000000000002",
"target": null,
"condition": null,
"priority": 0
}
]
}Definition fields
| Field | Meaning |
|---|---|
start | UUID of the first question |
questions | Questions in display order |
edges | Runtime routes between questions, including the final route to END |
Every question has a unique UUID id, type, and prompt. Optional fields are key (a unique stable name matching [a-z][a-z0-9_]{0,63}), config, required (defaults to false), next_id (next question in display order), and ui (canvas coordinates). Generate fresh UUIDs for a new form; retain IDs when updating existing questions.
Supported types: yesno, single, multi, rating, nps, text, star, contact, date, time. Choice questions use config.options, an array of strings. Rating/star questions use config.scale with min and max; NPS uses 0–10. Text limits use config.validation.max_length.
Every edge has its own UUID id, source question UUID, and target question UUID or null for END. condition: null is a fallback route. Conditional edges use condition: {"op": "equals", "value": "Yes"} or operators not_equals, answered, gte, and lte. Lower priority values are evaluated first; put conditional routes before the fallback. Include outgoing edges explicitly; next_id is display order and does not replace runtime edges.
All questions must be reachable from start, all edge endpoints must exist, and paths must terminate without loops. Include a fallback route so answers cannot get stuck. Validate before saving; resolve errors and review warnings.
Review and submit
Show the user the exact questions, types, options, required fields, and branching behavior before writing to Pollaris. After authorization, validate without saving:
pollaris forms validate --definition definition.json --wait --jsonThen create a draft:
pollaris forms create --definition definition.json --title "Library feedback" --draft-only --wait --jsonFor publication already authorized by the user, replace --draft-only with --publish. Creation publishes by default. With MCP, pass the same object to validate_form_definition, then to create_form as definition with a separate title, idempotency_key, and publish value.
The MCP create_form tool takes a request object and a separate idempotency key:
create_form({
"request": {
"title": "Library feedback",
"definition": <the canonical JSON object above>,
"publish": false
},
"idempotency_key": "<a fresh UUID for this creation>"
})Limits: at most 100 questions and 500 edges; question prompts at most 2,000 characters; choice options at most 50, each a unique non-blank string of at most 500 characters.
See Create forms for authorization and retry handling.