Skip to main content

Forms API

Manage forms and process submissions programmatically.

Try it — API Explorer

API Explorer
This endpoint requires an API key
Show cURL
curl \
  "https://your-site.clearcms.app/api/v1/forms"

Authentication

All endpoints except form submission require your API key:

Authorization: Bearer YOUR_API_KEY

The submission endpoint (POST /api/v1/forms/{id}/submissions) is public -- no API key needed.


Forms

List forms

GET /api/v1/forms

cURL:

curl -H "Authorization: Bearer YOUR_API_KEY" \
https://your-site.clearcms.app/api/v1/forms

Response:

{
"data": [
{
"id": "form_abc123",
"slug": "contact",
"name": "Contact Form",
"description": "Main contact form",
"status": "published",
"fields": [...],
"settings": {...},
"createdAt": "2026-03-01T10:00:00Z",
"updatedAt": "2026-03-15T09:30:00Z"
}
],
"total": 3
}

Get a form

GET /api/v1/forms/{id}

Returns a single form with all fields and settings.

Create a form

POST /api/v1/forms

Request body:

{
"name": "Feedback Form",
"slug": "feedback",
"description": "Collect visitor feedback",
"fields": [
{
"type": "email",
"name": "email",
"label": "Your email",
"required": true,
"width": "full"
},
{
"type": "select",
"name": "rating",
"label": "How would you rate us?",
"required": true,
"width": "full",
"options": [
{ "label": "Excellent", "value": "5" },
{ "label": "Good", "value": "4" },
{ "label": "Average", "value": "3" },
{ "label": "Poor", "value": "2" },
{ "label": "Terrible", "value": "1" }
]
},
{
"type": "textarea",
"name": "comments",
"label": "Comments",
"placeholder": "Tell us more...",
"required": false,
"width": "full"
}
],
"settings": {
"submitButtonText": "Send Feedback",
"successMessage": "Thanks for your feedback!"
}
}

You can also create a form from a template by passing templateId instead of fields.

Update a form

PUT /api/v1/forms/{id}

Pass any combination of name, description, fields, settings, or status.

Delete a form

DELETE /api/v1/forms/{id}

Deletes the form and all its submissions. Cannot be undone.


Field types

Each field in the fields array supports these properties:

PropertyTypeRequiredDescription
typestringYesOne of the 18 field types (see below)
namestringYesSubmission key (no spaces)
labelstringYesDisplay label
placeholderstringNoInput placeholder text
helpTextstringNoHelp text below the field
requiredbooleanYesWhether the field must be filled in
widthstringNofull or half. Default: full
optionsarrayNoFor select, radio, and checkbox group fields
validationobjectNo{ minLength, maxLength, min, max, pattern, patternMessage }
acceptedTypesarrayNoFor file fields: ["image/*", ".pdf"]
maxFileSizenumberNoMax file size in bytes

Available types: text, email, phone, url, number, textarea, select, multiselect, radio, checkbox, checkboxGroup, date, time, datetime, file, hidden, heading, paragraph


Submissions

Submit a form (public)

POST /api/v1/forms/{id}/submissions

cURL:

curl -X POST \
-H "Content-Type: application/json" \
-d '{"data":{"email":"test@example.com","message":"Hello"}}' \
https://your-site.clearcms.app/api/v1/forms/{id}/submissions

No API key required. The form must have published status.

Request body:

{
"data": {
"email": "visitor@example.com",
"rating": "5",
"comments": "Love it!"
}
}

For file upload fields, include file references:

{
"data": {
"name": "Jane Smith",
"resume": null
},
"files": [
{
"fieldName": "resume",
"mediaId": "media_xyz789",
"filename": "resume.pdf"
}
]
}

Response:

{
"success": true,
"message": "Thank you for your submission!",
"redirect": "https://example.com/thank-you"
}

message and redirect come from the form's settings. redirect is only present if configured.

If the honeypot catches a bot, the endpoint returns a success response without saving the submission.

List submissions

GET /api/v1/forms/{id}/submissions

Query parameters:

ParameterTypeDescription
statusstringFilter by status: new, read, replied, archived, spam
limitintegerResults per page. Default: 50. Max: 200
offsetintegerPagination offset

Response:

{
"data": [
{
"id": "sub_def456",
"formId": "form_abc123",
"data": {
"email": "visitor@example.com",
"rating": "5",
"comments": "Love it!"
},
"submittedAt": "2026-03-26T14:20:00Z",
"submitterEmail": "visitor@example.com",
"status": "new"
}
],
"total": 42
}

Update submission status

PUT /api/v1/forms/{id}/submissions

Request body:

{
"submissionId": "sub_def456",
"status": "read"
}

Status values: new, read, replied, archived, spam


Form settings reference

The settings object supports:

{
"submitButtonText": "Submit",
"submitButtonStyle": "primary",
"successMessage": "Thank you for your submission!",
"successRedirect": "https://example.com/thank-you",
"honeypotEnabled": true,
"captchaType": "none",
"notifyEmails": ["admin@example.com"],
"sendConfirmation": false,
"confirmationSubject": "We received your message",
"confirmationMessage": "Thanks for reaching out. We'll reply within 24 hours.",
"addToNewsletter": false,
"newsletterListId": "list_abc",
"webhookUrl": "https://hooks.example.com/form-submit",
"requireAuth": false,
"allowMultiple": true
}

All settings are optional. Omitted fields use defaults.


Webhook payloads

When a form has a webhookUrl, ClearCMS sends a POST request to that URL on each submission:

{
"event": "form.submission",
"formId": "form_abc123",
"formSlug": "contact",
"submission": {
"id": "sub_def456",
"data": {
"email": "visitor@example.com",
"message": "Hello!"
},
"submittedAt": "2026-03-26T14:20:00Z",
"submitterEmail": "visitor@example.com"
}
}
note

Webhooks fire asynchronously after the submission is saved. ClearCMS expects a 200 response. If the endpoint returns a non-200 status or times out, the submission is still stored -- webhook delivery is best-effort.


Error responses

StatusMeaning
400Invalid request body or duplicate slug
401Missing or invalid API key
403Insufficient permissions
404Form not found
422Form is not published (submissions only)
500Server error
Was this page helpful?