Inbox

Contacts

Keep one record per person across your messaging channels, with tags, notes and subscription state, and use it to target broadcasts and sequences.

A contact is a person you talk to. One contact can have several channels: their Instagram DMs, their WhatsApp number and their Telegram chat can all point at the same record. Contacts carry tags, notes, a subscription flag and custom fields, and they are what broadcasts and sequences target.

Contacts belong to a profile. Pozy creates them as people message your accounts; you can also create and import them yourself.

#Create a contact

Create the record and, optionally, its first channel in the same call by passing accountId, platform and platformIdentifier (the person's id on that platform; a phone number for WhatsApp and SMS).

curl -X POST https://api.pozy.ai/v1/contacts \
  -H "Authorization: Bearer $POZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "profileId": "6650c1e2a3b4c5d6e7f80911",
    "name": "Marta Pons",
    "email": "marta@example.com",
    "tags": ["vip", "newsletter"],
    "accountId": "6650c1e2a3b4c5d6e7f80a44",
    "platform": "whatsapp",
    "platformIdentifier": "+34600111222"
  }'

isSubscribed defaults to true. If something about the request was off but the contact was still created (for example a channel that could not be attached), the response carries a warning.

#Import in bulk

POST /v1/contacts/bulk imports up to 1,000 contacts per call into one profile. Duplicates are skipped and any new tags are merged onto the existing contact.

Request body
{
  "profileId": "6650c1e2a3b4c5d6e7f80911",
  "accountId": "6650c1e2a3b4c5d6e7f80a44",
  "contacts": [
    { "name": "Marta Pons", "platformIdentifier": "+34600111222", "tags": ["spring-2026"] },
    { "name": "Leo Martin", "platformIdentifier": "+34600333444", "email": "leo@example.com" }
  ]
}
Response
{ "success": true, "created": 2, "skipped": 0, "errors": [], "total": 2 }
  • accountId is required whenever contacts carry a platformIdentifier, and then every row needs one.
  • On WhatsApp and SMS, identifiers are normalised to digits. A value that is not a phone number is rejected for that row only.
  • Bad rows are reported in errors with HTTP 200; the rest of the import still goes through. Check errors on every call.

#Find contacts

GET /v1/contacts lists a profile's contacts. Filter with search (name, email and company), tag or tags, platform, accountId and isSubscribed, and page with limit (up to 200) and skip.

Each contact includes its tags, custom field values, notes, message counters (messagesSentCount, messagesReceivedCount) and the last time a message went each way. GET /v1/contacts/{id}/channels lists every channel of one contact, with the conversation id for each.

#Update and tag

PATCH /v1/contacts/{contactId} changes only the fields you send: name, email, company, avatarUrl, tags, isSubscribed, isBlocked and notes.

tags replaces the whole list. To add one tag, read the contact, append, and send the full list back. Workflows can tag contacts for you with their add_tag and remove_tag nodes; see Workflow nodes.

#Opt-in and blocking

Field Effect
isSubscribed: false Broadcast segments that filter on isSubscribed: true leave the contact out, and sequences with exitOnUnsubscribe (on by default) end for them
isBlocked: true Marks the person as blocked in your records

Respect opt-outs on every channel. For WhatsApp, SMS and RCS, the platforms and carriers require prior consent before you send promotional messages. See WhatsApp and SMS.

#Delete

DELETE /v1/contacts/{contactId} permanently deletes the contact and all its channels. It cannot be undone.

#Contact webhooks

Event Fires when
contact.updated A contact's details changed
contact.deleted A contact was deleted
contact.tag_added, contact.tag_removed A tag was added or removed, by the API, a workflow node or a tracked link click in a comment automation
contact.field_changed A custom field changed value

Tag and field events fire once per real change. Re-adding a tag the contact already has, or writing a field's current value, fires nothing. Creating a contact with tags fires nothing either; only changes to existing contacts do. The payload's source says who made the change: api (the API or the dashboard), workflow or automation.

#Endpoints

Endpoint What it does
GET /v1/contacts List contacts
POST /v1/contacts Create contact
GET /v1/contacts/{contactId} Get contact
PATCH /v1/contacts/{contactId} Update contact
DELETE /v1/contacts/{contactId} Delete contact
GET /v1/contacts/{contactId}/channels List channels for a contact
POST /v1/contacts/bulk Bulk create contacts

#Webhook events

Event When it fires
contact.updated Contact updated.
contact.deleted Contact deleted.
contact.tag_added Contact tag added.
contact.tag_removed Contact tag removed.
contact.field_changed Contact field changed.