API reference
REST API endpoints, authentication, request and response shapes.
All CLI and MCP operations go through the same REST API. You can call it directly with any HTTP client.
Base URL
https://form.motivationlabs.ai/apiAuthentication
Pass your API key as a Bearer token:
Authorization: Bearer YOUR_API_KEYGet an API key from your account settings.
OpenAPI spec
The full OpenAPI 3.1 spec is available at:
GET https://form.motivationlabs.ai/api/openapi.jsonForms
POST /api/forms
Create a new form.
Request body:
{
"title": "Contact Us",
"slug": "contact",
"branding": {
"primary_color": "#0f172a"
},
"notifications": {
"email": ["you@example.com"],
"subject": "New contact from {field:name}"
},
"humanness": true,
"fields": [
{ "id": "name", "type": "text", "label": "Your name", "required": true },
{ "id": "email", "type": "email", "label": "Email", "required": true },
{ "id": "message", "type": "textarea", "label": "Message", "required": true }
]
}Response:
{
"slug": "contact",
"public_url": "https://form.motivationlabs.ai/contact"
}GET /api/forms
List all forms for the authenticated account.
Response:
[
{
"slug": "contact",
"title": "Contact Us",
"created_at": "2026-04-01T10:00:00Z",
"stats": { "views": 310, "submissions": 42 }
}
]GET /api/forms/{slug}
Fetch a single form's config and stats.
Response:
{
"slug": "contact",
"title": "Contact Us",
"config": { ... },
"stats": {
"views": 310,
"submissions": 42,
"completion_rate": 0.135,
"sparkline_7d": [
{ "date": "2026-04-22", "count": 3 },
{ "date": "2026-04-23", "count": 5 }
]
}
}PATCH /api/forms/{slug}
Update a form's config. Only the fields you include are changed.
DELETE /api/forms/{slug}
Delete a form and all its submissions. Irreversible.
Submissions
POST /api/forms/{slug}/submit
Submit a form response. This endpoint is called by the public form page — it is not authenticated but requires a valid Turnstile token.
Request body:
{
"fields": {
"name": "Jane Smith",
"email": "jane@example.com",
"message": "Hello!"
},
"turnstile_token": "..."
}Response:
{
"submission_id": "01JE...",
"status": "received"
}GET /api/forms/{slug}/submissions
Fetch paginated submissions. Requires authentication.
Query params:
| Param | Type | Description |
|---|---|---|
limit | integer | Max results (default: 25, max: 100) |
offset | integer | Pagination offset |
since | ISO 8601 | Only return submissions after this date |
until | ISO 8601 | Only return submissions before this date |
GET /api/forms/{slug}/submissions/{id}
Fetch a single submission by ID.
GET /api/forms/{slug}/submissions/export
Export submissions. Returns CSV by default.
Query params:
| Param | Default | Description |
|---|---|---|
format | csv | csv, json, or markdown |
since | — | Filter start date |
until | — | Filter end date |
GET /api/forms/{slug}/report
Generate an agent-readable Markdown report.
Query params:
| Param | Default | Description |
|---|---|---|
period | 7d | 7d, 30d, 90d, or all |
GET /api/forms/{slug}/stats
Fetch aggregate stats: views, submissions, completion rate, 7-day sparkline, and change vs prior period.
Error responses
All errors follow this shape:
{
"error": "Human-readable message",
"code": "MACHINE_READABLE_CODE"
}| HTTP status | Meaning |
|---|---|
400 | Invalid request body or params |
401 | Missing or invalid API key |
403 | API key does not own this form |
404 | Form or submission not found |
422 | Turnstile verification failed |
429 | Rate limit exceeded |
500 | Server error |