Skip to content

Contacts

Contacts are the foundation of the entire bulk system. Each contact has an email as its unique identifier within your API key, plus optional fields: name and metadata (a free-form JSON object for any segmentation data you need). A contact can belong to multiple lists and can have one of four statuses: active, unsubscribed, bounced, or complained.

FieldTypeDescription
idintegerInternal identifier.
emailstringContact’s email. Unique per key.
namestringOptional name.
metadataobjectFree-form JSON object for custom attributes.
statusstringactive | unsubscribed | bounced | complained
key_idstringAPI key the contact belongs to.
created_atstringCreation date (ISO 8601).
updated_atstringLast updated date (ISO 8601).
GET /v1/bulk/contacts

Query parameters:

ParameterDescription
limitMaximum number of results (default: 100).
offsetOffset for pagination.
statusFilter by status: active, unsubscribed, bounced, complained.
q / searchSearch by email or name.
key_idFilter by API key (admin only).
formatcsv to export in CSV format.

POST /v1/bulk/contacts

Body:

{
"email": "ana@empresa.com",
"name": "Ana García",
"metadata": { "plan": "pro" }
}

If a contact with that email already exists, their data is updated. Returns 201 with the full contact.


GET /v1/bulk/contacts/{email}

Returns the contact with that email, including all their fields.


PATCH /v1/bulk/contacts/{email}

Body (all fields are optional):

{
"name": "Ana García López",
"status": "unsubscribed",
"metadata": { "plan": "enterprise" }
}

DELETE /v1/bulk/contacts/{email}

Permanently deletes the contact. Returns 204 No Content.


GET /v1/bulk/contacts/{email}/engagement

Returns the history of campaigns received by that contact and their engagement score.

Response:

{
"email": "ana@empresa.com",
"sends": [
{
"campaign_id": "camp_abc123",
"campaign_name": "Newsletter Q2",
"sent_at": "2026-04-15T10:00:00Z",
"opened": true,
"clicked": false
}
],
"totals": {
"sends": 5,
"opens": 3,
"clicks": 1
},
"score": "active",
"last_engagement_at": "2026-04-15T14:22:00Z"
}

The score field can be active, passive, or dormant based on the contact’s recent activity.


POST /v1/bulk/contacts/import

Body: array of objects with email (required), name and metadata optional.

[
{ "email": "ana@empresa.com", "name": "Ana García", "metadata": { "plan": "pro" } },
{ "email": "pedro@cliente.io", "name": "Pedro Sánchez" },
{ "email": "maria@otro.com" }
]

Returns 207 Multi-Status with the result for each entry:

{
"created": 2,
"updated": 1,
"failed": 0,
"errors": []
}

POST /v1/bulk/contacts/import-preview

Checks how many emails already exist in your account before importing. Does not modify any data.

Body:

{ "emails": ["ana@empresa.com", "nuevo@dominio.com"] }

Response:

{
"existing": ["ana@empresa.com"],
"total_unique": 2,
"total_received": 2
}

POST /v1/bulk/contacts/delete

Atomic deletion of multiple contacts. Body:

{ "emails": ["ana@empresa.com", "pedro@cliente.io"] }

Response:

{
"requested": 2,
"deleted": 2,
"not_found": [],
"forbidden": []
}
Ventana de terminal
curl -X POST https://api.mailerdash.com/v1/bulk/contacts \
-H "Authorization: Bearer $MAILERDASH_API_KEY" \
-H "Content-Type: application/json" \
-d '{"email": "ana@empresa.com", "name": "Ana García", "metadata": {"plan": "pro", "signup_source": "landing"}}'
Ventana de terminal
curl -X POST https://api.mailerdash.com/v1/bulk/contacts/import \
-H "Authorization: Bearer $MAILERDASH_API_KEY" \
-H "Content-Type: application/json" \
-d '[
{"email": "ana@empresa.com", "name": "Ana García", "metadata": {"plan": "pro"}},
{"email": "pedro@cliente.io", "name": "Pedro Sánchez", "metadata": {"region": "CDMX"}},
{"email": "maria@otro.com"}
]'

For the full request/response schema and error codes, see the bulk API reference.