POST /v1/forms/generate turns a plain-language prompt into a form and stores it as an ordinary draft. The call is synchronous: a successful 201 contains the form resource, its complete Draft Document under draft, and that draft’s ETag in the response header. There is no job to poll.
Nothing is published automatically. Read, edit, validate, and publish the result through the same form operations you use for a form created from a Form Blueprint.
Send a prompt
Section titled “Send a prompt”Send JSON with a prompt and, when you want a Private Template, is_template: true:
curl -s -X POST "https://platform.fomr.io/v1/forms/generate" \ -H "Authorization: Bearer $FOMR_TOKEN" \ -H "Content-Type: application/json" \ -d '{"prompt":"Create a two-page customer feedback form. Ask for the customer name, then ask what we could improve."}'| Field | Required | What it does |
|---|---|---|
prompt | Yes | Describes the form to create. Leading and trailing whitespace is removed; the remaining text must be 1 to 5,000 characters. |
is_template | No | Set to true to create a Private Template. It defaults to false. |
workspace_public_id | No | The workspace to create the form in. Left out, the form lands in the Default Workspace. |
Be specific about the audience, questions, answer types, number of pages, and any wording that must appear.
- Size. The generated form has at most 10 pages, endings included.
- Logic. It may include Conditional logic and Calculated values.
- Endings. On Pro the generator can add several endings; on Free it produces one.
- Readiness. The result always passes the Form Blueprint’s structural rules, but it may still need content changes before it is ready to publish.
Do not put API keys, access tokens, passwords, or unnecessary personal data in a prompt. Fomr sends the prompt to its AI provider and keeps the prompt and the generated blueprint in its AI generation logs, under Fomr’s data-retention controls.
Generation usually takes a few seconds. If the AI provider has not finished after 30 seconds, the call stops with 503 AI_SERVICE_UNAVAILABLE, nothing is created, and no credits are spent.
The result
Section titled “The result”The response is the same resource-plus-draft shape returned by POST /v1/forms. Page and node public IDs are already assigned, so you can store them and address those items without another read.
{ "public_id": "AiFeedbk01", "name": "Customer feedback", "is_template": false, "status": "draft", "has_unpublished_changes": true, "published_version": null, "published_at": null, "source_template_public_id": null, "workspace_public_id": "Mn1w", "access": { "is_closed": false, "close_at": null, "open_at": null, "accepting_submissions": false, "duplicate_response_rule": null }, "submissions": { "completed_count": 0, "partial_count": 0 }, "urls": { "editor": "https://fomr.io/app/s/AiFeedbk01/_/editor", "share": null }, "domain": null, "preview_image_url": null, "created_at": "2026-10-01T09:00:00.000Z", "updated_at": "2026-10-01T09:00:00.000Z", "draft": { "public_id": "AiFeedbk01", "name": "Customer feedback", "is_template": false, "hidden_values": [], "logic_rules": [], "calculated_values": [], "pages": [ { "public_id": "pQ01", "name": "About you", "type": "normal", "is_hidden": false, "is_entrypoint": true, "is_auto_jump_next_page": false, "nodes": [ { "public_id": "nNam", "parent_node_id": null, "column_index": null, "sort_order": 1, "is_hidden": false, "type": "text_input_short", "meta": { "question": "<span>What is your name?</span>", "placeholder": "Jane Doe", "validation": { "required": true } } } ] }, { "public_id": "pQ02", "name": "Your feedback", "type": "normal", "is_hidden": false, "is_entrypoint": false, "is_auto_jump_next_page": false, "nodes": [ { "public_id": "nFdb", "parent_node_id": null, "column_index": null, "sort_order": 1, "is_hidden": false, "type": "text_input_long", "meta": { "question": "<span>What could we improve?</span>", "placeholder": "Tell us what would make your experience better", "validation": { "required": false } } } ] }, { "public_id": "pFn1", "name": "Thank you", "type": "final", "is_hidden": false, "is_entrypoint": false, "is_auto_jump_next_page": false, "nodes": [ { "public_id": "nThx", "parent_node_id": null, "column_index": null, "sort_order": 1, "is_hidden": false, "type": "thank_you", "meta": { "thank_you_title": "<h1 style=\"text-align: center\">Thanks for your feedback!</h1>", "thank_you_description": "<p style=\"text-align: center\">Your response helps us improve.</p>", "thank_you_icon": "check_animated" } } ] } ], "settings": { "email_notifications_enabled_owner": 1, "email_notifications_enabled_respondent": 0, "email_notifications_recipients_owner": [ ], "email_notifications_recipient_respondent": null }, "properties": { "show_branding": 1, "auto_jump_next_page": 0, "allow_back_navigation": 1, "meta_title": null, "meta_description": null, "meta_index": 1, "meta_favicon_url": null, "meta_ogimage_url": null, "partial_response_capture_enabled": 0 }, "access": { "is_closed": 0, "close_at": null, "open_at": null, "duplicate_response_rule": null }, "styles": { "theme_id": null, "override_properties": { "page_actions_show_back_button": 1 } } }}Generated Thank You content is centered. A form with more than one non-ending page shows a Back button, set through styles.override_properties.page_actions_show_back_button, unless the generator chose otherwise.
The form is a draft with has_unpublished_changes: true, no published version, no share URL, and no submissions. The form lifecycle starts from there.
Permissions and plan checks
Section titled “Permissions and plan checks”These checks run before the AI provider is contacted:
- Permission. The member needs
forms:write, ortemplates:writewhenis_templateistrue. Otherwise the call is403 FORBIDDENnaming the missing permission. - Form limit. A generated form counts against the plan’s form limit, so an organization at its limit gets
402 PLAN_LIMIT_REACHED. Forms in Trash count until they are permanently deleted. Private Templates do not count.
The generated draft then goes through the same plan checks as a create. If it uses a feature the plan does not include, the call is 402 PRO_FEATURE_REQUIRED and nothing is created.
Cost and rate limits
Section titled “Cost and rate limits”Generation costs 10 credits on every plan, against 1 for an ordinary call. The organization needs 10 credits available in both its API Burst and its API Minute Cap; with fewer, the call is refused with 429 (API_COOLDOWN during a cooldown, TOO_MANY_REQUESTS otherwise) and generation does not start. If generation fails for any reason, including a provider outage, a timeout, or a draft the plan does not allow, the 10 credits are returned and the call costs nothing.
Separately, each IP address can send five generation requests per minute. A request over that limit is 429 with Retry-After.
Rate limits and plans has the budgets, the RateLimit response headers, and the retry rules.
When generation is unavailable
Section titled “When generation is unavailable”503 AI_SERVICE_UNAVAILABLE means the AI provider could not complete the generation. The body’s retry_after_seconds and the Retry-After header give the delay, currently 5 seconds. Nothing was created and no credits were spent. Treat it as transient: wait, add a little jitter, and send the request again. Cap your retries so a provider outage cannot become an endless loop.
503 SERVICE_UNAVAILABLE means Fomr is briefly unable to accept writes. It also carries a retry delay; wait and send the same request again.
Errors
Section titled “Errors”| Status | Code | When |
|---|---|---|
400 | INVALID_INPUT | The prompt is empty or longer than 5,000 characters, a field has the wrong type, the workspace is unknown, or the body has an unknown field. An issue with code ai_generation_failed at path ["prompt"] means the AI could not turn this prompt into a valid form; rephrase it before trying again. |
402 | PLAN_LIMIT_REACHED | A generated form would pass the plan’s form limit. The provider is not contacted. |
402 | PRO_FEATURE_REQUIRED | The generated draft uses a field the organization’s plan does not include. |
403 | FORBIDDEN | The member lacks forms:write, or templates:write for a Private Template. The provider is not contacted. |
429 | TOO_MANY_REQUESTS | The organization lacks 10 available credits, its minute cap was hit, or the originating IP exceeded five generation requests per minute (per-IP limit). |
429 | API_COOLDOWN | The organization’s burst pool is empty until its cooldown ends. |
503 | AI_SERVICE_UNAVAILABLE | The AI provider could not complete generation. Retry-After says when to try again. |
503 | SERVICE_UNAVAILABLE | Fomr is briefly unable to accept writes. Retry-After says when to try again. |
The complete error catalog and the fields each variant carries are on Errors.