Forms
Create embeddable signup forms that capture contacts, apply tags, add to lists, and enroll in sequences automatically.
Overview
Forms let you collect email subscribers directly from your website without writing backend code. Each form has a unique slug and can be shared as a hosted page (/f/{slug}) or embedded via iframe. When a visitor submits a form, PushMail automatically creates or updates the contact and runs any configured auto-actions (tagging, list assignment, sequence enrollment).
The form object
{
"id": 1,
"orgId": 1,
"siteId": 1,
"name": "Newsletter Signup",
"slug": "a1b2c3d4e5f6",
"designJson": "{...}",
"status": "active",
"sequenceId": 3,
"listId": 1,
"tags": "[\"newsletter\"]",
"doubleOptIn": false,
"submissionCount": 142,
"createdAt": "2026-03-01T10:00:00.000Z",
"updatedAt": "2026-03-01T10:00:00.000Z"
}Status values
| Status | Description |
|---|---|
draft | Form is being designed, not publicly accessible |
active | Form is live and accepting submissions |
archived | Form is disabled and no longer accepting submissions |
List forms
GET /v1/forms
Returns all forms for the authenticated organization. Optionally filter by site.
| Parameter | Type | Description |
|---|---|---|
siteId | integer | Filter forms by site ID (query parameter) |
curl https://pushmail.dev/api/v1/forms?siteId=1 \
-H "Authorization: Bearer pm_live_YOUR_KEY"{
"data": {
"forms": [
{ "id": 1, "name": "Newsletter Signup", "slug": "a1b2c3d4e5f6", "status": "active", "submissionCount": 142, "..." : "..." }
]
}
}Create a form
POST /v1/forms
| Parameter | Type | Description |
|---|---|---|
siteIdrequired | integer | The site this form belongs to |
namerequired | string | Display name for the form (max 200 chars) |
designJson | string | JSON string of form design (fields, styles, settings) |
sequenceId | integer | null | Sequence to auto-enroll contacts in on submission |
listId | integer | null | List to add contacts to on submission |
tags | string[] | Tag names to apply to contacts on submission |
doubleOptIn | boolean | Require email confirmation before subscribing (default: false) |
curl -X POST https://pushmail.dev/api/v1/forms \
-H "Authorization: Bearer pm_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"siteId": 1,
"name": "Newsletter Signup",
"listId": 1,
"tags": ["newsletter"]
}'{
"data": {
"id": 1,
"slug": "a1b2c3d4e5f6",
"name": "Newsletter Signup",
"status": "draft",
"..." : "..."
}
}A random 16-character hex slug is generated automatically. Use this slug to build the public form URL: https://pushmail.dev/f/{slug}.
Get a form
GET /v1/forms/:id
curl https://pushmail.dev/api/v1/forms/1 \
-H "Authorization: Bearer pm_live_YOUR_KEY"Update a form
PUT /v1/forms/:id
| Parameter | Type | Description |
|---|---|---|
name | string | Update display name |
designJson | string | Update form design JSON |
status | string | Set status: draft, active, or archived |
sequenceId | integer | null | Update sequence auto-enrollment |
listId | integer | null | Update list auto-assignment |
tags | string[] | Update auto-applied tags |
doubleOptIn | boolean | Toggle double opt-in |
curl -X PUT https://pushmail.dev/api/v1/forms/1 \
-H "Authorization: Bearer pm_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{ "status": "active" }'Delete a form
DELETE /v1/forms/:id
Deleting a form also deletes all its submissions (cascade).
curl -X DELETE https://pushmail.dev/api/v1/forms/1 \
-H "Authorization: Bearer pm_live_YOUR_KEY"List submissions
GET /v1/forms/:id/submissions
Returns paginated submissions for a form.
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number (default: 1) |
limit | integer | Items per page (default: 50, max: 100) |
curl https://pushmail.dev/api/v1/forms/1/submissions?page=1&limit=20 \
-H "Authorization: Bearer pm_live_YOUR_KEY"{
"data": {
"submissions": [
{
"id": 1,
"formId": 1,
"contactId": 42,
"siteId": 1,
"data": "{\"email\":\"jane@example.com\",\"firstName\":\"Jane\"}",
"ipAddress": "203.0.113.1",
"userAgent": "Mozilla/5.0 ...",
"createdAt": "2026-03-05T14:30:00.000Z"
}
],
"pagination": { "page": 1, "limit": 20, "total": 1, "totalPages": 1 }
}
}Public submission endpoint
POST /v1/forms/:id/submit
This endpoint is public (no authentication required) and processes form submissions from your website visitors.
The endpoint:
- Looks up the form by ID and verifies it is
active - Parses submitted field values and maps them to contact fields using the form's
designJson - Creates or updates the contact (upsert by email within the site)
- Applies configured tags, list membership, and sequence enrollment
- Records the submission and increments the form's submission counter
- Rate limited to 10 submissions per IP per minute
- Returns CORS headers for cross-origin embedding
curl -X POST https://pushmail.dev/api/v1/forms/1/submit \
-H "Content-Type: application/json" \
-d '{ "email": "jane@example.com", "firstName": "Jane" }'{
"data": {
"success": true,
"message": "Thanks for submitting!"
}
}Hosted form page
Each form with an active status is accessible at:
https://pushmail.dev/f/{slug}This serves a standalone HTML page with the rendered form. The page is fully styled based on the form's designJson settings and submits to the public submission endpoint via JavaScript.
You can also embed the hosted page in your site with an iframe:
<iframe src="https://pushmail.dev/f/a1b2c3d4e5f6"
style="width:100%;border:none;min-height:500px;"
loading="lazy"></iframe>Campaigns
Campaigns are one-off email broadcasts sent to a list or tagged group of contacts. Schedule them for later or send immediately.
Sending
PushMail sends emails via 10 supported providers. Use our managed infrastructure or bring your own API key for full control over your sending domain and reputation.