Misar Docs
MisarMailMisar.BlogMisarReachMisarPostMisar.DevMisar PlatformMisar IdentityMisar Posts API
Api Reference

Contacts

Manage contacts, segments, and bulk import via CSV/JSON

Contacts are the recipients in your email lists. Each contact belongs to the authenticated user and is isolated from other users' contacts.

Authentication

All contact endpoints require an API key with the contacts scope. Base URL: https://api.misar.io/mail.

Endpoints

MethodPathDescription
GET/api/v1/contactsList contacts (paginated)
POST/api/v1/contactsCreate a contact
PATCH/api/v1/contacts/:idUpdate a contact
DELETE/api/v1/contacts/:idDelete a contact
POST/api/v1/contacts/importBulk import from CSV or JSON

List contacts

GET/mail/v1/contacts

List contacts with optional filtering and pagination.

Query parameters

pageintegerquerydefault: 1

Page number.

limitintegerquerydefault: 50

Results per page (max 100).

statusstringquery

Filter: subscribed, unsubscribed, bounced, complained.

segment_idUUIDquery

Filter by segment membership.

searchstringquery

Search by email or name.

Response fields

successboolean

true when the request succeeded.

contactsArray<Contact>

The page of contacts. Each contact includes id, email, firstName, lastName, status, tags, customFields, and created_at.

paginationobject

Pagination metadata: page, limit, total, and total_pages.

{
  "success": true,
  "contacts": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "email": "[email protected]",
      "firstName": "Jane",
      "lastName": "Doe",
      "status": "subscribed",
      "tags": ["customer", "vip"],
      "customFields": { "plan": "pro" },
      "created_at": "2026-01-15T10:00:00Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 50,
    "total": 1234,
    "total_pages": 25
  }
}

Create a contact

POST/mail/v1/contacts

Create a single contact. Plan limits apply.

Request body

emailstringbodyrequired

Must be a valid email.

firstNamestringbody

Contact's first name.

lastNamestringbody

Contact's last name.

phonestringbody

Contact's phone number.

tagsstring[]body

Up to 50 tags.

customFieldsobjectbody

Custom key-value data.

statusstringbody

subscribed (default), unsubscribed, bounced, complained.

Response fields

successboolean

true when the contact was created.

contactobject

The created contact, including id and email.

{
  "email":        "[email protected]",
  "firstName":    "Jane",
  "lastName":     "Doe",
  "phone":        "+1234567890",
  "tags":         ["customer"],
  "customFields": { "plan": "pro", "signup_source": "website" },
  "status":       "subscribed"
}
{
  "success": true,
  "contact": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "email": "[email protected]"
  }
}

Errors

  • 403 — Contact limit reached for your plan
  • 409 — Email already exists in your contacts

Update a contact

PATCH/mail/v1/contacts/:id

Update a contact. Only provided fields are updated.

Path parameters

idUUIDpathrequired

ID of the contact to update.

Request body

firstNamestringbody

Contact's first name.

lastNamestringbody

Contact's last name.

phonestringbody

Contact's phone number.

tagsstring[]body

Up to 50 tags.

customFieldsobjectbody

Custom key-value data.

statusstringbody

subscribed, unsubscribed, bounced, complained.

{
  "firstName": "Jane",
  "tags": ["customer", "vip"],
  "status": "unsubscribed"
}

Delete a contact

DELETE/mail/v1/contacts/:id

Permanently delete a contact. This also removes them from all segments.

Path parameters

idUUIDpathrequired

ID of the contact to delete.

Response fields

successboolean

true when the contact was deleted.

{ "success": true }

Bulk import contacts

POST/mail/v1/contacts/import

Bulk import contacts from CSV or JSON. Available on Pro plan and above. Send a JSON body, or send Content-Type: text/csv with a CSV body.

Request body (JSON)

contactsArray<Contact>bodyrequired

Contacts to import. Each entry accepts the same fields as a single create (email, firstName, tags, etc.).

update_existingbooleanbody

When true, existing contacts matched by email are updated instead of skipped.

Response fields

successboolean

true when the import completed.

importedinteger

Number of new contacts created.

updatedinteger

Number of existing contacts updated.

skippedinteger

Number of rows skipped.

errorsArray<{row, email, error}>

Per-row errors encountered during import.

{
  "contacts": [
    { "email": "[email protected]", "firstName": "Alice", "tags": ["newsletter"] },
    { "email": "[email protected]",   "firstName": "Bob"   }
  ],
  "update_existing": true
}
email,firstName,lastName,tags
[email protected],Alice,Smith,newsletter
[email protected],Bob,Jones,
{
  "success": true,
  "imported": 1842,
  "updated":  143,
  "skipped":  15,
  "errors": [
    { "row": 3, "email": "invalid-email", "error": "Invalid email format" }
  ]
}

Errors

  • 403 — Bulk import not available on Free plan
  • 403 — Contact limit would be exceeded by this import
  • 400 — Invalid CSV format or missing email column