Automette docs

List submissions

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

Authorization

ApiKeyAuth
AuthorizationBearer <token>

API key from Settings → API Keys.

In: header

Path Parameters

id*string

Query Parameters

since?string

Only submissions at or after this ISO 8601 timestamp.

Formatdate-time
until?string

Only submissions at or before this ISO 8601 timestamp.

Formatdate-time
status?string

Defaults to complete.

Value in

  • "complete"
  • "spam"
  • "all"
limit?integer

1–100. Defaults to 50.

cursor?string

Response Body

application/json

application/json

application/json

application/json

curl -X GET "https://example.com/api/v1/forms/string/submissions?since=2026-08-01T00%3A00%3A00Z"
{  "submissions": [    {      "id": "cm4sub9tz0001kp04h3m8x2qa",      "form_id": "cm4frm2xy0001kp04a7c9v1de",      "status": "complete",      "submitted_at": "2026-08-14T18:22:10.000Z",      "answers": {        "parent_name": "Anita",        "child_age": "8_9"      }    }  ],  "next_cursor": null}

Connect a form to a template PUT

Every submission generates a document from this template. This is the join between the two products. `field_map` is keyed by the **template's** variable (`headline.text` for canvas, `data.customer` for Typst). Each value is either a form field key written as a plain string, or an object for sources that are not a form answer: ```json { "template_id": "cm4tpl…", "field_map": { "headline.text": "video_title", "backdrop.src": "cover_image", "footer.text": { "kind": "fixed", "value": "© Acme" }, "issued.text": { "kind": "system", "value": "submitted_at" } }, "output_formats": ["png"], "public_links": true } ``` Nothing is matched by label or position — both sides are keys you chose. An `image` question maps onto an image variable: the uploaded file is what reaches the renderer. Generation runs in the background after a submission is accepted. Poll `GET /api/v1/forms/{id}/submissions`, whose `document` field carries the status and URL, or subscribe to `render.completed`.

Submit to a form POST

Submit to your own form from a server, with your API key instead of a captcha. The answers go through the same lifecycle as a response typed into the form: they are validated against the current published version, the close state and submission cap are enforced, and — when the form is connected to a template — the document is generated in the background. Keys are the form's field keys; `GET /api/v1/forms/{id}` lists them. For `image` and `file` fields, send the key returned by `POST /api/forms/{id}/upload`, which needs no authentication. Spam protection does not apply on this path. Your API key already establishes who is calling, which is the thing a captcha is a rough substitute for — so a form can keep its captcha on for the public page while your integration posts to it directly. The response returns as soon as the submission is stored, before the document exists. Read it back with `GET`, whose `document` field carries the status and URL, or subscribe to `render.completed`. **This is not the way to generate a document from code.** `POST /api/v1/renders` is: it takes your data and returns the file. Use this endpoint when you want what the form adds on top — the response lands in the inbox and the CSV export, webhooks fire, notification and confirmation emails send, and the answers validate against the published version, so its field keys and template field map are not restated on every call. That makes it the right path for a custom front-end you host yourself, for backfilling responses from another form product, and for exercising your own pipeline without turning spam protection off.