A contact is one person you can message, with their profile, custom attributes, consent on each channel and topic choices. identify creates or updates a contact by your externalId, then email, then phone, so use it for every sync rather than looking contacts up by id first. Being on a list or in a segment is not consent: marketing reaches a contact only with consent on its channel. A contact's own records sit under it too: its lists, segments, topic choices, events, journeys, messages and push installations, each a device or browser registered by your own stable externalInstallationId. See IDs and identity.
Endpoints
| Endpoint | Request |
|---|---|
| List contacts | GET /v1/contacts |
| Create or update a contact | POST /v1/contacts/identify |
| Identify contacts in a batch | POST /v1/contacts/batch |
| Retrieve a contact | GET /v1/contacts/{id} |
| Update a contact | PATCH /v1/contacts/{id} |
| Delete a contact | DELETE /v1/contacts/{id} |
| Delete contacts | POST /v1/contacts/delete |
| Merge a contact into another | POST /v1/contacts/{id}/merge |
| List a contact's consent changes | GET /v1/contacts/{id}/consent-changes |
| Export a contact's data | GET /v1/contacts/{id}/export |
| List a contact's lists | GET /v1/contacts/{id}/lists |
| List a contact's segments | GET /v1/contacts/{id}/segments |
| List a contact's topics | GET /v1/contacts/{id}/topics |
| Set a contact's topic choice | PUT /v1/contacts/{id}/topics/{topicId} |
| List a contact's events | GET /v1/contacts/{id}/events |
| List a contact's journey enrollments | GET /v1/contacts/{id}/journeys |
| List a contact's messages | GET /v1/contacts/{id}/messages |
| List a contact's push installations | GET /v1/contacts/{id}/installations |
| Register a push installation | POST /v1/contacts/{id}/installations |
| Delete a push installation | DELETE /v1/contacts/{id}/installations/{externalInstallationId} |
The ContactDetail object
{
"id": "0192f3a1-7c2e-7d4b-9a10-3e5f6a7b8c9d",
"externalId": "customer-4821",
"email": "[email protected]",
"firstName": "Amaka",
"lastName": "Obi",
"phone": "+447700900123",
"timezone": "Europe/London",
"country": "GB",
"locale": "en-NG",
"rfm": {
"group": "loyal",
"recency": 3,
"frequency": 4,
"monetary": 5,
"purchaseCount": 6,
"totalSpent": {
"currency": "USD",
"value": 412.5
},
"lastPurchasedAt": "2026-03-02T18:20:00.000Z"
},
"dates": {
"birthday": "1992-03-14"
},
"attributes": {
"plan": "pro",
"favourite_spice": "smoked paprika",
"orders": 3
},
"consent": {
"email": true,
"push": false
},
"createdAt": "2026-09-12T08:15:00.000Z",
"updatedAt": "2026-10-01T09:30:00.000Z",
"emailSuppression": {
"suppressed": false,
"reason": null
},
"listIds": [
"0192f3a2-1b3c-7e5d-8a21-4f6a7b8c9d0e"
]
}idstringrequireduuid
externalIdstring | nullrequiredYour own id for the contact, if set.
emailstring | nullrequiredemail
firstNamestring | nullrequiredlastNamestring | nullrequiredphonestring | nullrequiredPhone number in E.164 format.
timezonestring | nullrequiredIANA timezone, e.g.
Europe/London.countrystring | nullrequiredISO 3166-1 alpha-2 code: as written, or inferred from the phone, else the timezone.
localestring | nullrequiredBCP 47 tag (
fr,fr-CA): the language the contact reads (its first subtag), and how merge tags format numbers, dates and money for them.rfmobject | nullrequiredThe contact's RFM (recency, frequency and monetary value) group among the workspace's customers, from its purchase events (the workspace's
purchaseEvent: an order, a paid invoice, a booking, a donation), each score from 1 to 5 (a fifth of the customers each; 5 is the most recent, most frequent or highest spend), and their purchase totals. Spend counts only purchases in the workspace's main currency; when the purchase carries no amount,monetaryfollows frequency. Recomputed daily, so a purchase today shows tomorrow;nullfor someone who has never purchased.7 child attributes
groupstringrequiredone of
champions,loyal,cant_lose_them,potential_loyalists,new_customers,need_attention,about_to_sleep,at_risk,hibernating,lostrecencyintegerrequiredmin 1 · max 5
frequencyintegerrequiredmin 1 · max 5
monetaryintegerrequiredmin 1 · max 5
purchaseCountintegerrequiredTheir purchase events (the workspace's
purchaseEvent), in any currency.min > 0
totalSpentobject | nullrequiredWhat their purchases' amounts (
purchaseValueProperty) add up to, in the workspace's main currency (currencyonGET /v1/reports/rfm); purchases in other currencies and refunds are left out.nullwhen the purchase carries no amount.2 child attributes
currencystring | nullrequiredThe currency, an ISO 4217 code; null when none was named.
valuenumberrequiredThe amount in that currency.
lastPurchasedAtstringrequiredWhen their latest purchase happened.
date-time
datesmap<string, string>requiredNamed calendar dates, e.g.
birthday, asYYYY-MM-DDor--MM-DD.attributesmap<string, object>requiredCustom attributes, keyed by attribute name.
consentContactConsentrequiredConsent on each channel.
2 child attributes
emailbooleanrequiredWhether the contact has consented to email.
pushbooleanrequiredWhether the contact has consented to push.
createdAtstringrequireddate-time
updatedAtstringrequireddate-time
emailSuppressionobjectrequired2 child attributes
suppressedbooleanrequiredWhether email to this contact is blocked.
reasonstring | nullrequiredWhy email to this contact is suppressed:
bounced,complained,complained_transactional,unsubscribed,manual,imported, orother_workspace(a bounce or complaint in another workspace with the same owner or partner).
listIdsstring[]requiredIds of the lists the contact is in.