Overview
Forms belong to a project; each definition has a human-chosen form id (slug) used by the public submit endpoint, and a MongoDB _id used by dashboard APIs.
The dashboard UI at /forms?projectId=… lists forms, opens the builder at /forms/<mongoId>?projectId=…, and shows submissions at /forms/<mongoId>/data. This page documents the HTTP API those screens call and the public endpoint third-party sites use to post leads.
Identifiers
| Name | Where | Notes |
|---|---|---|
projectId |
Query string, JSON body | MongoDB ObjectId string for the project (same as snippet data-project-id). |
formId |
URL-safe slug; stored lowercase | Unique across all projects. Used by POST /api/forms/submit and embed HTML. Not the same as _id. |
_id |
Path param /api/forms/[id] |
MongoDB ObjectId of the Form document — used when fetching/updating/deleting a form or listing its submissions. |
Authentication
Dashboard APIs require a valid JWT; the public submit route does not.
- Dashboard routes (
GET/POST /api/forms,GET/PUT/DELETE /api/forms/[id],GET/DELETE …/submissions): sendAuthorization: Bearer <JWT>with the user session token, or rely on theprzio_tokencookie after login. - Project access: the user must be the project owner or a member; tool access
formis enforced on list/create. - Public submit:
POST /api/forms/submitaccepts JSON from any origin; CORS echoes the requestOriginwhen present. No API key in the browser is required for submit.
Base URL: Use your deployment host (e.g. https://app.przio.com). Paths below are rooted at /api.
REST · manage forms
Authenticated. [id] is always the Form document’s MongoDB _id.
List forms for a project
GET /api/forms?projectId=PROJECT_ID Authorization: Bearer YOUR_SESSION_JWT
200 — { "forms": Form[] } (newest first).
Create form
POST /api/forms
Authorization: Bearer YOUR_SESSION_JWT
Content-Type: application/json
{
"formId": "newsletter-footer",
"name": "Newsletter signup",
"formType": "subscription",
"projectId": "PROJECT_ID",
"fields": [],
"steps": [],
"status": "draft",
"successClientEventEnabled": false,
"successClientEventName": ""
}
Required: formId, name, formType, projectId. Optional: fields, steps, status, success-event flags. Custom event name must match ^[a-zA-Z0-9:_-]+$ when non-empty.
201 — { "form": Form }. Errors: duplicate formId → 400.
Get one form
GET /api/forms/FORM_MONGO_ID Authorization: Bearer YOUR_SESSION_JWT
Update form
PUT /api/forms/FORM_MONGO_ID
Authorization: Bearer YOUR_SESSION_JWT
Content-Type: application/json
{
"name": "Updated name",
"fields": [ /* ... */ ],
"status": "active",
"successClientEventEnabled": true,
"successClientEventName": "mystore:lead-captured"
}
Omit keys you do not want to change. To rename the slug, send "formId": "new-slug" (must stay unique).
Delete form
DELETE /api/forms/FORM_MONGO_ID Authorization: Bearer YOUR_SESSION_JWT
200 — { "message": "Form deleted successfully" }.
REST · submit (public)
No login required. Form must exist and status must be active.
POST /api/forms/submit
Content-Type: application/json
{
"formId": "pre-seeds",
"data": { "email": "user@example.com" },
"visitorId": "optional-przio-visitor-uuid",
"isQA": false,
"trackingType": "production"
}
- formId — slug (case-insensitive match in DB).
- data — object keyed by field
namevalues from the form definition. - visitorId — optional; typically from PRZIO visitor cookie for correlation.
- isQA — optional boolean for preview/test submissions.
- trackingType — optional
"QA"or"production"(default production).
201 — { "message": "Form submitted successfully", "submissionId": "…" }. Server stores IP (from x-forwarded-for / x-real-ip) and user-agent.
400 — missing formId/data, or form not active. 404 — unknown formId.
Side effects: After save, enabled auto-send email rules for the form may send templated mail via configured SMTP (see below).
REST · submissions
Authenticated; path uses Form _id.
GET /api/forms/FORM_MONGO_ID/submissions Authorization: Bearer YOUR_SESSION_JWT
200 — { "submissions": Submission[] } sorted by submittedAt descending (matches dashboard table).
Delete submissions
DELETE /api/forms/FORM_MONGO_ID/submissions
Authorization: Bearer YOUR_SESSION_JWT
Content-Type: application/json
{ "submissionIds": ["id1", "id2"] }
Or wipe all rows:
{ "deleteAll": true }
200 — { "deletedCount": number }.
Form resource shape
Fields mirror the TypeScript model in the repo (lib/models/Form.ts).
| Property | Type | Notes |
|---|---|---|
_id | string | Mongo id — use in REST paths. |
formId | string | Lowercase unique slug. |
name | string | Display name in dashboard. |
formType | string | subscription | survey | contact | custom | quiz |
projectId | ObjectId | Owning project. |
fields | FormField[] | See field types. |
steps | FormStep[] | Optional multi-step (survey) metadata. |
status | string | draft | active | inactive — only active accepts public submit. |
successClientEventEnabled | boolean | Whether embed JSON enables CustomEvent dispatch after successful submit. |
successClientEventName | string | Optional extra event name (alphanumeric + :_-). |
createdAt / updatedAt | ISO date | Timestamps. |
successClientEvent* on the Form document.Submission resource shape
| Property | Notes |
|---|---|
_id | Submission id (returned as submissionId from submit). |
formId | Slug copy for querying. |
formObjectId | Reference to Form _id. |
projectId | Project reference. |
data | Arbitrary key/value payload from the submit body. |
submittedAt | Server time. |
ipAddress | From proxy headers when available. |
userAgent | Request UA string. |
visitorId | Optional PRZIO visitor id. |
isQA | QA flag from submit payload. |
trackingType | QA or production. |
SDK & browser events
Load sdk.min.js (or dev sdk.js) with your project id on every page that hosts an embedded form.
The minified SDK includes a small bridge that intercepts successful responses to /api/forms/submit (via fetch or XMLHttpRequest). When the embed JSON (script[type="application/json"][data-przio-form-config]) has successClientEvent.enabled === true, it dispatches:
- Always —
przio:form-submit-success(detailincludesformIdand APIresponse). - Additionally — your custom event name when set and different from the default.
window.addEventListener('przio:form-submit-success', function (e) {
console.log(e.detail); // { formId, response }
});
Embed forms through Popup or Personalization activities so exported HTML includes the JSON config block next to the form — see Forms overview and the in-app Integration → Form tutorial.
Embed JSON config
The bridge reads script[type="application/json"][data-przio-form-config="<formId>"]. When successClientEvent.enabled is true, events fire after a successful submit response.
Shape (conceptual):
{
"successClientEvent": {
"enabled": true,
"eventName": "mystore:lead-captured"
}
}
Implementation reference: frontend/lib/przioFormSuccessBridgeScript.ts (bundled into public SDK).
Auto-send email
Optional rules tied to a form can send email after submit when SMTP is configured.
On each successful submission, the server loads enabled AutoSendEmail rules for that form, resolves recipients (including merge tags from data and optional recipient folders), and sends via admin or user SMTP. Failures are logged to email history — configure rules in the dashboard rather than via public API here.
Field types
Each field has id, name (key in submit data), label, type, required, optional placeholder, options for choice controls, validation, and optional stepId.
type | Notes |
|---|---|
text | Single-line input. |
email | Email validation in UI. |
number | Optional min/max in validation. |
textarea | Multi-line. |
select | Requires options[]. |
checkbox | Boolean-style or multi-option depending on builder. |
radio | Requires options[]. |
date | Date picker. |
tel | Telephone. |
url | URL input. |
Common errors
| Status | Meaning |
|---|---|
| 400 | Validation — duplicate slug, invalid event name, missing required JSON keys, inactive form on submit. |
| 401 | Missing or invalid JWT on protected routes. |
| 403 | User cannot access project or form tool. |
| 404 | Unknown form slug (submit) or mongo id. |
| 500 | Server error — retry or contact support. |
Integration checklist
- Activate the form before production traffic (
status: active). - SDK on host pages that render popup/personalization embeds.
- Re-embed after field changes so HTML + JSON config stay aligned.
- Listen for
przio:form-submit-success(and custom name if configured). - Submit payload keys must match field
namevalues. - Privacy — avoid logging PII in client listeners in production without policy.