Misar IO Docs
MisarMailApi Reference

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

MethodPathAuthDescription
GET/v1/formsAPI key / sessionList forms
POST/v1/formsAPI key / sessionCreate form
GET/v1/forms/:idAPI key / sessionGet form + embed code
PATCH/v1/forms/:idAPI key / sessionUpdate form
DELETE/v1/forms/:idAPI key / sessionDelete form
GET/v1/forms/:id/submissionsAPI key / sessionList submissions
POST/api/public/forms/:id/submitNoneSubmit a form (public)

List forms

GET /v1/forms

ParameterTypeDefaultDescription
pageinteger1Page number
limitinteger20Results per page (max 100)
statusactive | inactiveFilter 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

FieldTypeRequiredDescription
namestringYesInternal name
fieldsarrayYesForm field definitions
segment_idstringNoSegment to add subscribers to
redirect_urlstringNoURL to redirect after successful submission
settingsobjectNoVisual 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

ParameterTypeDefaultDescription
pageinteger1Page number
limitinteger20Results 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.

FieldTypeDescription
emailstringRequired. Contact email address
firstNamestringOptional
lastNamestringOptional
customFieldsobjectOptional. 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.