Endpoints
| Method | Path | Description |
|---|---|---|
POST | /v1/contacts | Create or upsert a contact |
GET | /v1/contacts/{id} | Get a single contact with consent records |
PATCH | /v1/contacts/{id} | Update contact fields |
DELETE | /v1/contacts/{id} | Delete a contact (manager role) |
POST | /v1/contacts/import | Bulk import up to 10,000 contacts |
GET | /v1/contacts/{id}/consent | List consent records |
POST | /v1/contacts/{id}/consent | Grant or update consent |
DELETE | /v1/contacts/{id}/consent/{record_id} | Revoke a consent record |
The contact object
Contacts are returned with their full consent history embedded inconsent_records.
Fields
Platform-assigned contact identifier.
Your own identifier for this contact. Unique within the workspace. Useful for syncing with a CRM.
Email address. Used for email channel sends and deduplication.
Phone number in international format (e.g.
+4917612345678). Used for SMS and RCS sends.First name. Available as a merge tag in templates.
Last name. Available as a merge tag in templates.
Lifecycle status of the contact.
| Value | Meaning |
|---|---|
ACTIVE | Can receive messages |
UNSUBSCRIBED | Opted out — blocked from NEWSLETTER sends |
BOUNCED | Hard bounce — blocked from email sends |
BLOCKED | Manually or policy blocked — no sends |
How the contact entered the system:
API, IMPORT, LANDING_PAGE, or MANUAL.Free-form string labels. Used for segmentation and filtering in campaigns.
Arbitrary key-value pairs for extra contact attributes. Values are merged on update.
All consent records for this contact. Each record covers one
channel_type + message_type combination. See Consent API for full field reference.Deduplication
A contact is deduplicated by email hash within a workspace. If youPOST /v1/contacts with an email that already exists, the platform upserts the record and returns the existing contact with updated fields rather than creating a duplicate.
Suppression
Contacts with statusUNSUBSCRIBED, BOUNCED, or BLOCKED are automatically suppressed from message sends. Attempting to send to a suppressed contact returns a 422 with reason: "contact_suppressed".