API Reference

Create contact

POST /contacts — add a contact to a sending domain (upsert by email).

POST/contacts

Add a contact to one of your sending domains. Contacts are domain-scoped: pass the domain the contact belongs to along with the required email. If a contact with that email already exists in the domain, it is updated instead of duplicated (upsert by email). Passing audience_id on this endpoint is rejected with a 422 — use the audience-scoped variant below when you want to target an audience explicitly.

Body
domainstringrequired

The sending domain the contact belongs to (one of your domains, e.g. yourdomain.com).

emailstringrequired

The contact’s email address. Stored lowercased. Must be a valid email.

first_namestringoptional

Optional first name. Stored as null when omitted.

last_namestringoptional

Optional last name. Stored as null when omitted.

unsubscribedbooleanoptional

Optional opt-out flag. Defaults to false. When true, campaigns skip this contact.

propertiesobjectoptional

Optional map of custom property keys and values to attach to the contact (e.g. { "company_name": "Acme Corp", "score": 10 }). Each key must be a registered contact property and the value must match its declared type (string or number).

Request
import { MailBlastr } from 'mailblastr';

const mb = new MailBlastr('mb_xxxxxxxxx');

const { data, error } = await mb.contacts.create({
  "domain": "yourdomain.com",
  "email": "steve@example.com",
  "first_name": "Steve",
  "last_name": "Wozniak",
  "unsubscribed": false
});
console.log({ data, error });
Response (201)
{
  "object": "contact",
  "id": "479e3145-dd0e-4f64-bf48-1d4b6d4cd8f6"
}
Upsert: re-posting an existing email merges the incoming first_name, last_name, and properties into the existing contact (preserving existing name values when omitted) and applies unsubscribed monotonically (once unsubscribed, a re-post cannot resubscribe). Use PATCH to change only some fields.

Audience-scoped variant

The nested route POST /audiences/:audience_id/contacts still works and adds the contact to a specific audience instead of a domain — no domain field in the body:

Request (audience-scoped)
import { MailBlastr } from 'mailblastr';

const mb = new MailBlastr('mb_xxxxxxxxx');

const { data, error } = await mb.contacts.create({
  audienceId: 'AUDIENCE_ID',
  "email": "steve@example.com",
  "first_name": "Steve",
  "last_name": "Wozniak",
  "unsubscribed": false
});
console.log({ data, error });

A missing email or domain returns 422 missing_required_field; an invalid email returns 422 validation_error. A domain (or audience) that is not yours returns 404 not_found. See Errors.