Profiles
The marketing contact as a whole person - consent per channel, location, properties and an activity log. Not the call center phone book (Contacts).
/profilesList or look up profiles
A profile is the marketing contact as a whole person: consent per channel, location, how they found you, custom properties and an activity log. It is the person an audience holds - **not** `/v1/contacts`, which is the call center phone book. With no filter this returns a cursor-paginated list of the organization's profiles. With `email` or `phone` it is a lookup: the one person, or an empty list, in the same list envelope (the two filters are not combined with `from` / `to`). A phone must be a US number in any written form (400 `invalid_phone` otherwise). Requires scope: audiences:read.
Parameters
Query
limitstarting_afterfromtoemailphoneResponse 200
idrequiredobjectrequiredemailphonefirstNamerequiredlastNamerequiredcompanytitlestatusrequiredconsentrequiredemailsmslocationattributionfirstlastpropertiesrequiredaudienceIdsrequiredcreatedAtupdatedAtErrors
/profilesCreate or update a profile
Pushes one person: found by email, else phone, and created when new or updated when they exist, so the same person pushed twice is one profile. The response is **201** with `created: true` for a new person and **200** with `created: false` for an existing one. Send an `email`, a `phone` or both (400 otherwise). Fields you omit are left as they are, `properties` merge key by key, and a person who first arrived by phone is carried over when their email turns up. `consent` records an opt-in or opt-out per channel; an opt-out also lands on the suppression lists campaigns read. **An unsubscribed person stays unsubscribed.** A write through this API never re-subscribes anyone: sending `consent.email: "subscribed"` for someone who has unsubscribed, bounced or marked a message as spam is ignored, and the person stays out of every send. Supports idempotent retries via the Idempotency-Key header. Requires scope: audiences:write.
Parameters
Headers
Idempotency-KeyRequest body
emailphonefirstNamelastNamecompanytitleconsentemailsmslocationattributionfirstlastpropertiesResponse 200
Errors
/profiles/bulkCreate or update many profiles
Up to 100 people in one call, each row the same body as POST /profiles. Send `audienceId` to also put them on that list. One bad row never stops the rest: `results` answers row by row. Each row counts as one request and one write. A bulk add starts no flow; a person pushed on their own does. Someone who unsubscribed stays unsubscribed and is not added to the list. Supports idempotent retries via the Idempotency-Key header. Requires scope: audiences:write.
Parameters
Headers
Idempotency-KeyRequest body
profilesrequiredemailphonefirstNamelastNamecompanytitleconsentlocationattributionpropertiesaudienceIdResponse 200
objectcreatedupdatedfailedaddedToAudienceresultsindexidcreatedaddedToAudienceerrorErrors
/profiles/{profileId}Retrieve a profile
Returns one profile. Returns 404 if it is missing, deleted or belongs to another organization. Requires scope: audiences:read.
Parameters
Path
profileIdrequiredResponse 200
idrequiredobjectrequiredemailphonefirstNamerequiredlastNamerequiredcompanytitlestatusrequiredconsentrequiredemailsmslocationattributionfirstlastpropertiesrequiredaudienceIdsrequiredcreatedAtupdatedAtErrors
/profiles/{profileId}Update a profile
Send only what changes. An empty string clears a name, company or title, and `properties: { "key": null }` removes a property. A profile's email cannot change (400 `email_locked`): delete it and create a new one. Setting `consent` to unsubscribed also writes the suppression lists, whichever address the request names. **An unsubscribed person stays unsubscribed.** A write through this API never re-subscribes anyone: sending `consent.email: "subscribed"` for someone who has unsubscribed, bounced or marked a message as spam is ignored, and the person stays out of every send. Requires scope: audiences:write.
Parameters
Path
profileIdrequiredRequest body
emailphonefirstNamelastNamecompanytitleconsentemailsmslocationattributionfirstlastpropertiesResponse 200
idrequiredobjectrequiredemailphonefirstNamerequiredlastNamerequiredcompanytitlestatusrequiredconsentrequiredemailsmslocationattributionfirstlastpropertiesrequiredaudienceIdsrequiredcreatedAtupdatedAtErrors
/profiles/{profileId}Delete a profile
Takes the person out of the contact list. Saved audiences keep their own recipients and an unsubscribe stays on record, so deleting someone never restarts mail they stopped. Requires scope: audiences:write.
Parameters
Path
profileIdrequiredResponse 200
objectrequiredidrequireddeletedrequiredErrors
/profiles/{profileId}/eventsList a profile's activity
The profile's activity log, newest first: sends, opens, clicks, consent changes, list changes, and the named events you recorded. Unlike the other lists, `limit` defaults to 50 and goes up to 100. Filter with `type`, a comma list of event types (profile_created, profile_updated, added_to_audience, removed_from_audience, email_sent, email_delivered, email_opened, email_clicked, email_bounced, email_complained, sms_sent, sms_replied, flow_entered, flow_finished, unsubscribed, consent_changed, event). Requires scope: audiences:read.
Parameters
Path
profileIdrequiredQuery
limitstarting_aftertypeResponse 200
idrequiredobjectrequiredtyperequirednameatrequiredchannelsubjectcampaignIdcampaignNameflowIdflowNameaudienceIdaudienceNamesourcedetailurlpropertiesErrors
/profiles/{profileId}/eventsRecord an event
Records a named event on the profile - something that happened in your own product, such as "Placed Order". It lands on the activity log and starts any live flow that listens for that name; `enrolledInFlows` says how many. `properties` keep plain text, numbers and booleans; nested objects are dropped. Supports idempotent retries via the Idempotency-Key header. Requires scope: audiences:write.
Parameters
Path
profileIdrequiredHeaders
Idempotency-KeyRequest body
namerequiredpropertiestimeResponse 201
objectrequiredprofileIdrequirednamerequiredenrolledInFlowsrequired