Forms API
https://api.airogelcms.com/v1/accounts/:account_id/forms
A form collects submissions from site visitors. Each form points at a collection, where every submission is stored as an entry, and at a blueprint, which defines the form's fields. You render the form in a template with the form_for Liquid tag.
Operations
- GET
/v1/accounts/:account_id/forms- List forms - GET
/v1/accounts/:account_id/forms/:id- Get one form - POST
/v1/accounts/:account_id/forms- Create a form - PUT / PATCH
/v1/accounts/:account_id/forms/:id- Update a form - DELETE
/v1/accounts/:account_id/forms/:id- Delete a form (returns204)
:id is the form's form_ ID or handle.
Writable fields
| Field | Type | Required | Description |
|---|---|---|---|
title | string | yes | Display name |
handle | string | no | Generated from the title if you leave it out (for example contact-form). Must be unique. |
collection_handle | string | yes | Collection that stores submissions (handle or clctn_ ID) |
blueprint_handle | string | yes | Blueprint that defines the fields (handle or blprt_ ID). It must belong to that collection. |
redirect_url | string | no | Where to send the visitor after a successful submission |
success_message | string | no | Message shown after a successful submission |
honeypot_enabled | boolean | no | Add a hidden honeypot field to catch spam bots |
spam_check_enabled | boolean | no | Run automatic spam checking on submissions |
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
account_id
|
string | Required |
Path. Your account prefix ID (acct_...).
|
id
|
string | Optional |
Path, for show/update/delete. Form form_ ID or handle.
|
handle
|
string | Optional | Query, list only. Return only the record with exactly this handle. |
page
|
integer | Optional | Query, list only. Page number, starting at 1. The page size is fixed at 20. |
title
|
string | Required | Body. Display name. |
handle
|
string | Optional | Body. Generated from the title if omitted. Duplicate handles return 422. |
collection_handle
|
string | Required | Body. Collection that stores submissions. Unknown value returns 422. |
blueprint_handle
|
string | Required | Body. Blueprint defining the fields. Must belong to the collection. |
redirect_url
|
string | Optional | Body. Redirect after a successful submission. |
success_message
|
string | Optional | Body. Message shown after submission. |
honeypot_enabled
|
boolean | Optional | Body. Enable the honeypot field. |
spam_check_enabled
|
boolean | Optional | Body. Enable automatic spam checking. |
Request Example
# Create a form
curl -X POST "https://api.airogelcms.com/v1/accounts/$ACCOUNT_ID/forms" \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Contact Form",
"handle": "contact",
"collection_handle": "submissions",
"blueprint_handle": "contact_form",
"redirect_url": "/thank-you",
"success_message": "Thanks for your message!",
"honeypot_enabled": true,
"spam_check_enabled": true
}'
# Update a form
curl -X PATCH "https://api.airogelcms.com/v1/accounts/$ACCOUNT_ID/forms/contact" \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"success_message": "Thanks! We will reply within a day."}'
Response Example
// Single form (show, create, update)
{
"id": "form_1aZx7Cv",
"handle": "contact",
"title": "Contact Form",
"collection_handle": "submissions",
"blueprint_handle": "contact_form",
"redirect_url": "/thank-you",
"success_message": "Thanks for your message!",
"honeypot_enabled": true,
"notification_enabled": false,
"notification_emails": null,
"spam_check_enabled": true,
"fields": [
{ "handle": "name", "display": "Your Name", "type": "text", "position": 0, "options": { "required": true } },
{ "handle": "email", "display": "Email Address", "type": "text", "position": 1, "options": { "required": true, "input_type": "email" } },
{ "handle": "message", "display": "Message", "type": "text", "position": 2, "options": {} }
],
"template_usage": {
"description": "Use the form_for Liquid tag to render this form. ...",
"important": "Input names must use the fields[] namespace ...",
"example": "{% form_for form: \"contact\", class: \"your-form-class\" %} ... {% endform_for %}",
"manual_field_example": "...",
"available_field_properties": ["field.handle - Field identifier", "..."]
},
"created_at": "2026-09-14T16:00:00Z",
"updated_at": "2026-09-14T16:00:00Z"
}
// List
{
"data": [ { "id": "form_1aZx7Cv", "handle": "contact", "title": "Contact Form", "...": "same fields as above" } ],
"pagination": {
"page": 1,
"per_page": 20,
"total": 1,
"total_pages": 1,
"next_page": null,
"prev_page": null
}
}
// 422 - unknown collection
{
"error": "Validation failed",
"details": [
{ "path": "collection_handle", "message": "Collection 'submisions' not found" }
]
}
Additional Notes
Configuration only. This API manages form settings. It does not accept submissions. Visitors submit forms on the site itself, to POST /cms/:handle/submit on the site's own domain, and each submission becomes an entry in the form's collection. Read submissions with the Entries API on that collection.
Fields come from the form's blueprint and are read-only here. Edit them through Blueprints. Options such as required, placeholder, help_text and input_type control how form_for renders each input. The internal spam-status field is not listed.
template_usage is generated Liquid showing how to render this form with its actual field handles. Use it as a starting point for your template.
Notifications. notification_enabled and notification_emails appear in responses but are set in the dashboard or through MCP, not through REST.
Not idempotent. Unlike most resources, POST always creates. A handle that already exists returns 422. Use PUT/PATCH to change an existing form.
Honeypot. When enabled, form_for adds a hidden field with a per-form name. Submissions that fill it in are discarded without being saved, and the bot is shown the normal success response.