Forms API
Create, read, update, and delete forms programmatically using the Trigglio REST API.
The Forms API requires a Business plan or higher, or the API Access add-on ($19/mo on Pro+). All endpoints require a forms:write scope for mutations and forms:read for reads.
Base URL
https://trigglio.com/api/v1/formsAuthentication
All requests require a Bearer token:
Authorization: Bearer tr_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxEndpoints
List Forms
GET /api/v1/formsQuery Parameters:
| Parameter | Default | Description |
|---|---|---|
page | 1 | Page number (min: 1) |
limit | 20 | Items per page (1-100) |
status | — | Filter by draft or published |
search | — | Search by form name (case-insensitive) |
sort | updated_at | Sort by created_at, updated_at, or name |
order | desc | Sort direction: asc or desc |
cURL
curl -X GET "https://trigglio.com/api/v1/forms?status=published&limit=10" \
-H "Authorization: Bearer $API_KEY"Response:
{
"data": [
{
"id": "clx...",
"name": "Contact Form",
"description": "Collect leads",
"status": "published",
"mode": "conversational",
"slug": "contact-form-abc123",
"fieldCount": 5,
"responseCount": 142,
"createdAt": "2026-02-01T00:00:00.000Z",
"updatedAt": "2026-02-20T00:00:00.000Z",
"publishedAt": "2026-02-15T00:00:00.000Z"
}
],
"meta": { "page": 1, "limit": 10, "total": 42, "totalPages": 5 }
}Get Form
GET /api/v1/forms/{formId}Returns the full form including schema, theme, and settings.
Create Form
POST /api/v1/formsRequest Body:
{
"name": "Customer Feedback",
"description": "Collect product feedback",
"mode": "conversational",
"status": "draft",
"schema": {
"fields": [
{
"id": "field-name",
"type": "short_text",
"label": "Your name",
"required": true,
"placeholder": "Jane Doe"
},
{
"id": "field-email",
"type": "email",
"label": "Email address",
"required": true
},
{
"id": "field-rating",
"type": "rating",
"label": "How would you rate our product?",
"required": true,
"ratingConfig": {
"style": "stars",
"maxRating": 5,
"startLabel": "Poor",
"endLabel": "Excellent"
}
},
{
"id": "field-feedback",
"type": "long_text",
"label": "Any additional feedback?",
"required": false
}
],
"settings": {
"submitButtonText": "Send Feedback",
"successMessage": "Thank you for your feedback!"
}
}
}Only name is required. If schema is omitted, an empty form is created.
Idempotency: Include an Idempotency-Key header to safely retry requests:
Idempotency-Key: unique-request-id-12345Update Form
PATCH /api/v1/forms/{formId}Only include the fields you want to update:
{
"name": "Updated Name",
"status": "published"
}Setting status to "published" will set publishedAt automatically.
Delete Form
DELETE /api/v1/forms/{formId}Permanently deletes the form and all its responses.
Field Types
| Type | Description | Requires |
|---|---|---|
short_text | Single-line text input | — |
long_text | Multi-line textarea | — |
email | Email with validation | — |
phone | Phone number | — |
number | Numeric input | — |
url | URL/website input | — |
date | Date picker | — |
dropdown | Single select dropdown | options[] |
multiple_choice | Radio buttons | options[] |
checkboxes | Multi-select checkboxes | options[] |
rating | Star/number/emoji scale | ratingConfig |
file_upload | File upload | — |
heading | Section heading (display only) | — |
paragraph | Text block (display only) | — |
page_break | Multi-page separator | — |
payment | Stripe payment collection | paymentConfig (Pro+) |
Options Format
For dropdown, multiple_choice, and checkboxes:
{
"options": [
{ "id": "opt-1", "label": "Option A", "value": "option_a" },
{ "id": "opt-2", "label": "Option B", "value": "option_b" }
]
}Rating Config
{
"ratingConfig": {
"style": "stars",
"maxRating": 5,
"startLabel": "Poor",
"endLabel": "Excellent"
}
}Styles: stars, numbers, smileys, emojis, hearts, thumbs
Conditional Logic
Show, hide, or require fields based on other field values:
{
"conditionalLogic": {
"action": "show",
"logicType": "all",
"rules": [
{
"id": "rule-1",
"sourceFieldId": "field-rating",
"operator": "less_than",
"value": 3
}
]
}
}Operators: equals, not_equals, contains, not_contains, is_empty, is_not_empty, greater_than, less_than
Error Responses
All errors use a consistent format:
{
"error": {
"code": "validation_error",
"message": "Validation failed: 2 errors",
"details": [
{ "field": "schema.fields[0].type", "message": "Invalid field type \"textarea\"" },
{ "field": "schema.fields[1].options", "message": "dropdown fields must have at least one option" }
]
}
}| Code | Status | Description |
|---|---|---|
validation_error | 400 | Invalid request data |
unauthorized | 401 | Missing or invalid API key |
insufficient_scope | 403 | API key lacks required scope |
feature_not_available | 403 | Plan upgrade required |
limit_exceeded | 403 | Form count limit reached |
not_found | 404 | Form does not exist |
slug_conflict | 409 | Slug already in use |
rate_limited | 429 | Too many requests |
Rate Limits
Every response includes rate limit headers:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 2026-02-21T12:31:00.000ZLimits: 100 requests/minute and 1,000 requests/hour per API key.