Forms
Build and embed signup forms that automatically subscribe contacts to your mailing lists
Forms capture leads directly from your website or landing page. When someone submits a form, they are added to your contacts as subscribed and linked to the configured segment.
Authentication
Management endpoints require an API key or active session. The public submit endpoint requires no authentication.
Authorization: Bearer msk_...
Endpoints
| Method | Path | Auth | Description |
|---|---|---|---|
GET | /v1/forms | API key / session | List forms |
POST | /v1/forms | API key / session | Create form |
GET | /v1/forms/:id | API key / session | Get form + embed code |
PATCH | /v1/forms/:id | API key / session | Update form |
DELETE | /v1/forms/:id | API key / session | Delete form |
GET | /v1/forms/:id/submissions | API key / session | List submissions |
POST | /api/public/forms/:id/submit | None | Submit a form (public) |
List forms
GET /v1/forms
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number |
limit | integer | 20 | Results per page (max 100) |
status | active | inactive | — | Filter by status |
curl "https://api.misar.io/mail/v1/forms?status=active" \
-H "Authorization: Bearer msk_..."const res = await fetch("https://api.misar.io/mail/v1/forms?status=active", {
headers: { Authorization: "Bearer msk_..." },
});
const { data } = await res.json();Create a form
POST /v1/forms
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Internal name |
fields | array | Yes | Form field definitions |
segment_id | string | No | Segment to add subscribers to |
redirect_url | string | No | URL to redirect after successful submission |
settings | object | No | Visual and behaviour settings |
curl -X POST https://api.misar.io/mail/v1/forms \
-H "Authorization: Bearer msk_..." \
-H "Content-Type: application/json" \
-d '{
"name": "Newsletter signup — homepage",
"segment_id": "seg_01hvxyz",
"redirect_url": "https://yoursite.com/thank-you",
"fields": [
{ "name": "email", "type": "email", "label": "Email address", "required": true },
{ "name": "firstName", "type": "text", "label": "First name", "required": false }
],
"settings": {
"submit_label": "Subscribe",
"success_message": "Thank you for subscribing!"
}
}'const res = await fetch("https://api.misar.io/mail/v1/forms", {
method: "POST",
headers: {
Authorization: "Bearer msk_...",
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "Newsletter signup — homepage",
segment_id: "seg_01hvxyz",
redirect_url: "https://yoursite.com/thank-you",
fields: [
{ name: "email", type: "email", label: "Email address", required: true },
{ name: "firstName", type: "text", label: "First name", required: false },
],
settings: {
submit_label: "Subscribe",
success_message: "Thank you for subscribing!",
},
}),
});
const { data } = await res.json();Response
{
"success": true,
"data": {
"id": "frm_01hvabc",
"name": "Newsletter signup — homepage",
"status": "active",
"segment_id": "seg_01hvxyz",
"redirect_url": "https://yoursite.com/thank-you",
"fields": [...],
"settings": {...},
"submission_count": 0,
"created_at": "2026-05-27T10:00:00Z",
"updated_at": "2026-05-27T10:00:00Z"
}
}Get a form
GET /v1/forms/:id
Returns the full form object including the embed_code field ready to paste into your site.
Embed code (script tag)
<div id="misar-form-frm_01hvabc"></div>
<script src="https://mail.misar.io/embed/form.js"
data-form-id="frm_01hvabc"
data-container="misar-form-frm_01hvabc"
integrity="sha384-{FORM_EMBED_SRI_HASH}"
crossorigin="anonymous"
async></script>
Replace {FORM_EMBED_SRI_HASH} with the current hash from your form's embed code in the MisarMail dashboard. The hash is regenerated whenever the embed script is updated. Using Subresource Integrity ensures your page is protected against CDN-level script tampering.
Embed code (iframe)
<iframe
src="https://mail.misar.io/embed/forms/frm_01hvabc"
width="100%"
height="400"
frameborder="0"
></iframe>
Update a form
PATCH /v1/forms/:id
Send only the fields you want to change. Updating fields replaces the full fields array.
Delete a form
DELETE /v1/forms/:id
Returns { "success": true }. Existing submissions are preserved.
List submissions
GET /v1/forms/:id/submissions
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number |
limit | integer | 20 | Results per page (max 100) |
curl "https://api.misar.io/mail/v1/forms/frm_01hvabc/submissions?limit=50" \
-H "Authorization: Bearer msk_..."const res = await fetch(
"https://api.misar.io/mail/v1/forms/frm_01hvabc/submissions?limit=50",
{ headers: { Authorization: "Bearer msk_..." } }
);
const { data } = await res.json();Response
{
"success": true,
"data": {
"submissions": [
{
"id": "sub_01hvdef",
"contact_id": "con_01hvghi",
"email": "[email protected]",
"fields": { "firstName": "Alex" },
"submitted_at": "2026-05-26T14:22:00Z",
"ip_address": "203.0.113.5"
}
],
"pagination": {
"page": 1,
"limit": 50,
"total": 312,
"total_pages": 7
}
}
}Public form submit
POST /api/public/forms/:id/submit
No authentication required. This endpoint is called by the embed script or your own frontend. It creates or updates a contact and links them to the segment configured on the form.
| Field | Type | Description |
|---|---|---|
email | string | Required. Contact email address |
firstName | string | Optional |
lastName | string | Optional |
customFields | object | Optional. Key-value pairs for custom contact fields |
curl -X POST https://api.misar.io/mail/api/public/forms/frm_01hvabc/submit \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"firstName": "Alex",
"customFields": { "company": "Acme Inc" }
}'await fetch("https://api.misar.io/mail/api/public/forms/frm_01hvabc/submit", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
email: "[email protected]",
firstName: "Alex",
customFields: { company: "Acme Inc" },
}),
});Response
{
"success": true,
"data": {
"contact_id": "con_01hvghi",
"status": "subscribed"
}
}If the email already exists, the contact record is updated with any new field values. The contact's status is set to subscribed unless they are currently unsubscribed, in which case the submission is recorded but the status is not changed.
Your plan includes a limit on the number of active forms. Attempting to activate a form beyond your plan limit returns a 402 error. Check your plan on the billing page.