Skip to main content
A submission is a UUID-keyed record describing one form response from a visitor on a public Page.

Identifiers

object
string
required
Always "submission".
id
string
required
UUID. Use as your foreign key in external systems.
page_id
string | null
UUID of the Page the submission came from. null if the parent page was deleted.
submission_number
integer
required
Sequential, per-organization counter. The dashboard formats it as SUB-0001; the wire value is the raw integer.

Status, priority, flag

status
string
required
One of new, read, in_progress, resolved, spam. Default is new.
priority
string
required
One of none, low, medium, high. Default is none.
flagged
boolean
required
Free-floating “needs attention” toggle. Independent of status and priority.

Assignment

assignee_id
string | null
UUID of the user who owns this submission. null means unassigned.
resolved_by
string | null
UUID of the user who resolved the submission. Stamped automatically when status moves to resolved and the actor is an OAuth user; it stays null when an API key performs the resolve (there’s no user to attribute). Clear via PATCH with null to undo.
resolved_at
string | null
ISO 8601 timestamp when the submission was resolved. Auto-stamped by the server the moment status moves to resolved. You may also set it explicitly via PATCH; a malformed value (not a parseable ISO 8601 timestamp) is rejected with 400.
notes
string | null
Free-text internal annotation. Not visible to the visitor.

Data

data
object
required
The form response itself, keyed by block ID (not field label). Each entry has the shape:
{
  "type":  "form_email",
  "label": "Email",
  "value": "[email protected]",
  "order": 1
}
  • type — the form block type (form_text, form_email, form_textarea, form_select, form_checkbox, …).
  • label — the author-set label at submission time. Survives subsequent edits to the page.
  • value — the submitted value. string for most fields, string[] for multi-select / checkboxes, null for empty optional fields, number for numeric inputs.
  • order — the block’s sort order on the page when the submission was captured. Use this to render fields in form order, since JSON object keys aren’t ordered.
Block IDs are stable across page edits but field labels are not. If you’re mapping submission data to external system fields, key on block ID. Use label only for display.
metadata
object
required
Free-form key/value pairs captured at submit time. Common keys: utm_source, utm_medium, utm_campaign, referrer, user_agent. May be {} but never null.

Attribution

qr_code_id
string | null
QR code the visitor scanned to reach the page. Server-resolved from a session cookie — visitors can’t forge this.
product_id
string | null
Product whose scan URL drove this visit. Server-resolved.
object_id
string | null
Custom object whose /o/<slug> URL drove this visit.
conversation_id
string | null
Conversation that presented the form, if the submission originated from a chatbot’s present_page tool call rather than a direct page visit.

Destination

destination
object | null
The redirect destination resolved at submit time. The page’s block configuration determines what the visitor sees after submitting; this field records what was applied. null means the visitor saw the default thank-you screen.Shape is a tagged union on type:
{ "type": "url",           "value": { "url": "https://yoursite.com/thanks" } }
{ "type": "page",          "value": { "pageId": "…" } }
{ "type": "article",       "value": { "articleId": "…" } }
{ "type": "chatbot",       "value": { "chatbotId": "…" } }
{ "type": "knowledge_base","value": { "knowledgeBaseId": "…" } }
{ "type": "file",          "value": { "fileUrl": "…", "filename": "…" } }
{ "type": "email",         "value": { "email": "…", "subject": "…", "body": "…" } }
{ "type": "phone",         "value": { "phone": "+15555550123" } }
{ "type": "google_review", "value": { "placeId": "ChIJ…", "businessName": "…" } }

Activity

viewed_at
string | null
ISO 8601. When the visitor first loaded the page. null if not captured (legacy submissions).
duration_seconds
number | null
Seconds between viewed_at and created_at — time-to-complete. null when viewed_at is null.

Timestamps

created_at
string
required
ISO 8601. When the visitor submitted.

Complete example

{
  "object": "submission",
  "id": "d4c5e6f7-1a2b-4c3d-9e8f-0a1b2c3d4e5f",
  "page_id": "7a8b9c0d-1e2f-4a3b-9c8d-0e1f2a3b4c5d",
  "submission_number": 421,
  "status": "new",
  "priority": "medium",
  "flagged": false,
  "assignee_id": null,
  "resolved_by": null,
  "resolved_at": null,
  "notes": null,
  "data": {
    "blk_h3yt2": {
      "type": "form_text",
      "label": "Name",
      "value": "Jamie Lee",
      "order": 0
    },
    "blk_qm8wp": {
      "type": "form_email",
      "label": "Email",
      "value": "[email protected]",
      "order": 1
    },
    "blk_n21vr": {
      "type": "form_textarea",
      "label": "Message",
      "value": "Loved the launch — any chance of a demo this week?",
      "order": 2
    }
  },
  "metadata": {
    "utm_source": "linkedin",
    "utm_campaign": "spring-launch",
    "referrer": "https://www.linkedin.com/feed/"
  },
  "destination": {
    "type": "url",
    "value": { "url": "https://yoursite.com/thanks" }
  },
  "viewed_at": "2026-05-22T10:14:01+00:00",
  "duration_seconds": 38,
  "qr_code_id": null,
  "product_id": null,
  "object_id": null,
  "conversation_id": null,
  "created_at": "2026-05-22T10:14:39+00:00"
}