Audience

Managing contacts

Add contacts to an audience with an email and optional name, track their subscribe state, and address them by id or email.

A contact is a single person on an audience. Contacts are nested under the audience that owns them — every contact operation runs against /audiences/:audience_id/contacts.

The only required field is email. You can optionally store a first_name and last_name, an unsubscribed flag that controls whether campaigns reach them, and a properties map of custom fields you can use to personalize campaigns.

The contact object

{
  "object": "contact",
  "id": "479e3145-dd0e-4f64-bf48-1d4b6d4cd8f6",
  "email": "steve@example.com",
  "first_name": "Steve",
  "last_name": "Wozniak",
  "unsubscribed": false,
  "properties": {
    "company_name": "Acme Corp"
  },
  "created_at": "2026-06-23T17:30:11.000Z"
}

Emails are stored lowercased. first_name and last_name are null when not provided. properties is always present and includes every registered custom property, merged with fallback values.

Adding a contact

Send the email (required) plus any optional fields to the audience’s contacts collection. Alongside first_name, last_name, and unsubscribed, you can include a properties object of custom field values — each key must already be registered as a contact property on your account and the value must match its type.

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 });

Upsert by email

Contacts are unique by email within an audience. If you create a contact whose email already exists in that audience, MailBlastr merges into the existing contact instead of creating a duplicate. This makes the create call safe to call repeatedly (for example, on every signup) without producing duplicates.

The merge never destroys data: an omitted first_name/last_name keeps the value already stored, properties are merged key by key (incoming keys win), and unsubscribed is monotonic — a create can suppress a contact but can never re-subscribe one, so sending unsubscribed: false for an opted-out contact leaves the opt-out in place. Use PATCH to re-subscribe a contact or to clear a name.

Addressing a contact by id or email

Anywhere a contact identifier appears in the path — get, update, delete — you can pass either the contact id or its email. MailBlastr detects which you provided. Both of these refer to the same contact:

GET https://www.mailblastr.com/api/audiences/AUDIENCE_ID/contacts/479e3145-dd0e-4f64-bf48-1d4b6d4cd8f6
GET https://www.mailblastr.com/api/audiences/AUDIENCE_ID/contacts/steve@example.com

Contact properties

Every contact has four default propertiesemail, first_name, last_name, and unsubscribed. You can also register custom properties to store additional information (for example company_name or plan) and use those values to personalize campaigns. Properties are registered once per account with POST /contact-properties — there is no per-audience registry, so a registered key is valid for every contact in every audience.

Set custom values by passing a properties map when you create or update a contact:

{
  "email": "steve@example.com",
  "first_name": "Steve",
  "properties": {
    "company_name": "Acme Corp",
    "plan": "pro"
  }
}
A property key must already be registered on your account and the value must match its declared type. On POST /contacts (and the audience-scoped POST /audiences/:audience_id/contacts) unknown keys or mismatched types are rejected and the contact is not changed. Property keys are case-sensitive — company_name and companyName are different keys.

Bulk import by CSV

To add many contacts at once, upload a CSV in the dashboard (up to 256 MB). The original file is stored privately with a collision-safe timestamped key before the rows are processed. If the CSV is larger than your remaining plan capacity, only the first eligible net-new contacts that fit are added; the result shows the capacity available before and after the import and how many valid rows were omitted. Existing contacts can still be updated because they do not increase the account-wide contact count. Map each CSV column to a contact field — email, first_name, last_name, unsubscribed — or to a custom property.

on_conflictBehavior
upsertUpdate the existing contact with the values from the CSV row.
skipLeave the existing contact untouched and skip the row.

Automatic creation

Contacts are also created automatically when an automation runs for an email address that does not yet exist on the audience, so you do not have to pre-add every recipient.

Next steps