Motivation Form Docs

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/api

Authentication

Pass your API key as a Bearer token:

Authorization: Bearer YOUR_API_KEY

Get 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.json

Forms

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:

ParamTypeDescription
limitintegerMax results (default: 25, max: 100)
offsetintegerPagination offset
sinceISO 8601Only return submissions after this date
untilISO 8601Only 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:

ParamDefaultDescription
formatcsvcsv, json, or markdown
sinceFilter start date
untilFilter end date

GET /api/forms/{slug}/report

Generate an agent-readable Markdown report.

Query params:

ParamDefaultDescription
period7d7d, 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 statusMeaning
400Invalid request body or params
401Missing or invalid API key
403API key does not own this form
404Form or submission not found
422Turnstile verification failed
429Rate limit exceeded
500Server error

On this page