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
| Method | Path | Description |
|---|---|---|
GET | /api/v1/contacts | List contacts (paginated) |
POST | /api/v1/contacts | Create a contact |
PATCH | /api/v1/contacts/:id | Update a contact |
DELETE | /api/v1/contacts/:id | Delete a contact |
POST | /api/v1/contacts/import | Bulk import from CSV or JSON |
List contacts
/mail/v1/contactsList contacts with optional filtering and pagination.
Query parameters
pageintegerquerydefault: 1Page number.
limitintegerquerydefault: 50Results per page (max 100).
statusstringqueryFilter: subscribed, unsubscribed, bounced, complained.
segment_idUUIDqueryFilter by segment membership.
searchstringquerySearch by email or name.
Response fields
successbooleantrue when the request succeeded.
contactsArray<Contact>The page of contacts. Each contact includes id, email, firstName, lastName, status, tags, customFields, and created_at.
paginationobjectPagination 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
/mail/v1/contactsCreate a single contact. Plan limits apply.
Request body
emailstringbodyrequiredMust be a valid email.
firstNamestringbodyContact's first name.
lastNamestringbodyContact's last name.
phonestringbodyContact's phone number.
tagsstring[]bodyUp to 50 tags.
customFieldsobjectbodyCustom key-value data.
statusstringbodysubscribed (default), unsubscribed, bounced, complained.
Response fields
successbooleantrue when the contact was created.
contactobjectThe 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 plan409— Email already exists in your contacts
Update a contact
/mail/v1/contacts/:idUpdate a contact. Only provided fields are updated.
Path parameters
idUUIDpathrequiredID of the contact to update.
Request body
firstNamestringbodyContact's first name.
lastNamestringbodyContact's last name.
phonestringbodyContact's phone number.
tagsstring[]bodyUp to 50 tags.
customFieldsobjectbodyCustom key-value data.
statusstringbodysubscribed, unsubscribed, bounced, complained.
{
"firstName": "Jane",
"tags": ["customer", "vip"],
"status": "unsubscribed"
}Delete a contact
/mail/v1/contacts/:idPermanently delete a contact. This also removes them from all segments.
Path parameters
idUUIDpathrequiredID of the contact to delete.
Response fields
successbooleantrue when the contact was deleted.
{ "success": true }Bulk import contacts
/mail/v1/contacts/importBulk 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>bodyrequiredContacts to import. Each entry accepts the same fields as a single create (email, firstName, tags, etc.).
update_existingbooleanbodyWhen true, existing contacts matched by email are updated instead of skipped.
Response fields
successbooleantrue when the import completed.
importedintegerNumber of new contacts created.
updatedintegerNumber of existing contacts updated.
skippedintegerNumber 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 plan403— Contact limit would be exceeded by this import400— Invalid CSV format or missingemailcolumn