Skip to main content
Contacts (also called profiles) are the people in your audience. The Contacts API lets you create them, update them, and read them back. All requests require authentication.

Create or update a contact

POST /api/v1/customer/create Upserts a contact and returns 201 Created. If a contact with the same email or phone already exists, it’s updated; otherwise it’s created. This endpoint does not add anyone to a list — for that, see the Lists API.

Request

You must send email or phone — at least one. Everything else is optional.
email
string
The contact’s email address. Required unless you send phone.
phone
string
Phone number, 7–20 characters. Required unless you send email. Needed for WhatsApp messaging.
external_id
string
Your own identifier for this person (your database ID), for reconciling across systems.
first_name
string
Max 100 characters.
last_name
string
Max 100 characters.
email_opt_in
string
Email marketing consent: SUBSCRIBED, NON_SUBSCRIBED, or UNSUBSCRIBED. Defaults to NON_SUBSCRIBED when omitted. Only send SUBSCRIBED when the person actually opted in.
phone_opt_in
string
SMS/WhatsApp consent, same values. Defaults to NON_SUBSCRIBED.
is_suppressed
boolean
Whether the contact is suppressed. Defaults to false.
double_opt_in
boolean
Whether to require email confirmation before the contact counts as subscribed. Defaults to false.
source
string
Where this contact came from, e.g. booking-platform. Defaults to api.
dob
string
Date of birth as an ISO 8601 date, e.g. 1990-01-15.
gender
string
MALE, FEMALE, or OTHER. Case-sensitive.
country
string
Max 100 characters. Normalized to a country code on write.
state
string
Max 100 characters.
city
string
Max 100 characters.
address1
string
Max 255 characters.
address2
string
Max 255 characters.
postal_code
string
3–20 characters.
custom_properties
object
Key–value pairs stored as custom fields — usable in segments and personalization. Maximum 30 keys per request, string values.
Omitting email_opt_in creates the contact as NON_SUBSCRIBED, and they will receive no marketing email. Set it explicitly whenever you have consent — this is the single most common reason API-created contacts appear to be ignored by campaigns.
Unrecognized fields are rejected with 400. Send first_name, not firstName.
Example request

Response

201 Created
Keep the id — it’s the stable identifier for fetching this contact later, and for sending events with contactUUID.

Custom properties

  • Maximum 30 keys per request; more returns 400.
  • Values are stored as strings. Numbers and booleans are converted; nested objects are not — they store as unusable text, so flatten them before sending.
  • Empty and whitespace-only values are dropped rather than stored.

Get a contact

GET /api/v1/customer/{id}
Returns the same profile envelope as above, or 404 if no contact has that ID.

List contacts

GET /api/v1/customer Returns contacts in pages.
For a one-time bulk load of an existing audience, the dashboard’s CSV import is faster and friendlier to rate limits than looping over this API.