REST API Reference
All API endpoints use the base path /api/v1 and require Bearer token authentication.
Authentication
Include your API key in every request as a Bearer token:
Authorization: Bearer af_live_your_api_key_here
API keys follow the format af_live_<48 hex chars>. The key is shown once at server startup. It is stored as a SHA-256 hash — the plaintext is never persisted.
Keep your key secret. Do not commit it to source control or expose it in client-side code.
Create Form
Create a new form with one or more fields. Returns the form metadata including a public URL for sharing.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
title | string | Yes | Form title (max 255 chars) |
description | string | No | Optional description shown on the form |
fields | array | Yes | Array of field objects |
callback_url | string | No | Webhook URL (max 2048 chars) |
callback_metadata | object | No | Arbitrary JSON passed through to webhook payload |
settings | object | No | Additional settings (reserved for future use) |
expires_in | string | No | Duration until expiry. Default: "48h" |
expires_in Format
A number followed by a unit: m (minutes), h (hours), or d (days).
| Example | Meaning |
|---|---|
"30m" | 30 minutes |
"2h" | 2 hours |
"7d" | 7 days |
null | No expiry |
Field Object
| Field | Type | Required | Description |
|---|---|---|---|
key | string | Yes | Identifier used in response data (e.g. "full_name") |
type | string | Yes | One of the 8 field types |
label | string | Yes | Display label (max 255 chars) |
description | string | No | Helper text shown below label |
required | boolean | No | Default: false |
config | object | No | Type-specific options (see Field Types) |
Example Request
curl -X POST https://your-server.com/api/v1/forms \ -H "Authorization: Bearer af_live_..." \ -H "Content-Type: application/json" \ -d '{ "title": "Feedback", "fields": [ {"key": "rating", "type": "number", "label": "Rating (1-5)", "required": true, "config": {"min": 1, "max": 5}}, {"key": "comment", "type": "textarea", "label": "Comment"} ], "callback_url": "https://your-app.com/webhook", "expires_in": "7d" }'
Response 201 Created
{
"id": "01JNXXXXXXXXXXXXXXXXXX",
"title": "Feedback",
"description": null,
"url": "https://your-server.com/f/01JNXXXXXXXXXXXXXXXXXX",
"status": "active",
"fields_count": 2,
"expires_at": "2026-03-12T10:00:00",
"created_at": "2026-03-05T10:00:00"
}List Forms
List forms for the authenticated account. Results are paginated using cursor-based pagination.
Query Parameters
| Param | Type | Default | Description |
|---|---|---|---|
status | string | — | Filter by status: active, completed, cancelled, expired |
cursor | string | — | Pagination cursor (last seen form ID) |
limit | integer | 20 | Max results per page |
Response 200 OK
[
{
"id": "01JNXXXXXXXXXXXXXXXXXX",
"title": "Feedback",
"description": null,
"url": "https://your-server.com/f/01JN...",
"status": "active",
"fields_count": 2,
"expires_at": "2026-03-12T10:00:00",
"created_at": "2026-03-05T10:00:00"
}
]Get Form
Get detailed information about a form, including its field definitions and callback URL.
Response 200 OK
{
"id": "01JNXXXXXXXXXXXXXXXXXX",
"title": "Feedback",
"description": null,
"url": "https://your-server.com/f/01JN...",
"status": "active",
"fields_count": 2,
"expires_at": "2026-03-12T10:00:00",
"created_at": "2026-03-05T10:00:00",
"fields": [
{"key": "rating", "type": "number", "label": "Rating (1-5)",
"required": true, "config": {"min": 1, "max": 5}},
{"key": "comment", "type": "textarea", "label": "Comment",
"required": false, "config": {}}
],
"callback_url": "https://your-app.com/webhook",
"settings": {}
}Update Form
Update a form's status or expiry. All fields are optional.
Request Body
| Field | Type | Description |
|---|---|---|
status | string | Set to "cancelled" to cancel the form |
expires_at | string | ISO 8601 datetime, or null to remove expiry |
Example: Cancel a Form
curl -X PATCH https://your-server.com/api/v1/forms/FORM_ID \ -H "Authorization: Bearer af_live_..." \ -H "Content-Type: application/json" \ -d '{"status": "cancelled"}'
Response 200 OK
Returns the updated form object (same schema as Create Form response).
Delete Form
Permanently delete a form and all associated responses.
Response 204 No Content
Empty response body on success.
List Responses
Get all responses for a form, ordered by submission time (newest first).
Response 200 OK
[
{
"id": "01JNYYYYYYYYYYYYYYY",
"form_id": "01JNXXXXXXXXXXXXXXXXXX",
"data": {
"rating": 5,
"comment": "Great product!"
},
"submitted_at": "2026-03-05T12:00:00",
"metadata": {
"ip": "203.0.113.42",
"user_agent": "Mozilla/5.0..."
}
}
]Get Response
Get a single response by ID.
Response 200 OK
Returns a single response object (same schema as items in List Responses).
Error Responses
All errors return a JSON body with a detail field.
{"detail": "Form not found"}| Status | Meaning | Detail |
|---|---|---|
401 | Unauthorized | Invalid or missing API key |
403 | Forbidden | No credentials provided |
404 | Not Found | Form or response not found |
410 | Gone | Form has expired |
422 | Validation Error | Invalid request body (Pydantic validation detail) |
Form Status Values
| Status | Description |
|---|---|
active | Form is accepting submissions |
completed | Form has been submitted (one response per form) |
cancelled | Form was cancelled via API |
expired | Form's expires_at time has passed |