Contacts
Look people up and keep their records current
Every tool takes an optional orgId - tech providers only, naming the managed client to act on. An id outside the target org behaves exactly like a missing one.
Contacts - 5
| Tool | Scope | Does |
|---|---|---|
list_contacts | CONTACTS_READ | Filter by externalId, phone, channel, custom fields, created range. Expensive with search, channel or fields. |
get_contact | CONTACTS_READ | By Wexio id or your externalId. |
list_field_definitions | CONTACTS_READ | The org's field schema - the writable keys. |
upsert_contact | CONTACTS_MANAGE | Idempotent on your externalId; can bind a channel identity. |
set_contact_fields | CONTACTS_MANAGE | Sets field values by key. |
Contact Tools
Four tools let an agent look a person up and keep their record current - without you storing Wexio's IDs.
upsert_contact
Creates or updates a contact, idempotently keyed on your own externalId. Two calls with the same externalId touch one contact.
| Argument | Type | Required | Description |
|---|---|---|---|
externalId | string | No | Your id for this person. The idempotency key. |
displayName | string | No | Name shown in the inbox. |
firstName / lastName | string | No | Given and family name. |
phone | string | No | Phone number, E.164. |
language | string | No | Preferred language code. |
fields | { key, value }[] | No | Custom field values by key. |
channel | object | No | Bind a messaging identity - see below. |
channel binds an identity before the person ever writes, so a later real inbound resolves to the same contact instead of creating a duplicate:
| Field | Type | Description |
|---|---|---|
kind | "WHATSAPP" | "TELEGRAM" | "VIBER" | Which channel. |
phone | string | For WhatsApp. |
telegramId | string | For Telegram. |
viberUserId | string | For Viber. |
integrationId | string | Defaults to the org's integration for that channel - usually omit it. |
Skip the channel binding and an imported contact plus the person who later messages you are two contacts until someone merges them. Bind at import time.
get_contact
Reads a contact by Wexio's id or your own externalId - pass whichever you have.
| Argument | Type | Required | Description |
|---|---|---|---|
id | string | One of the two | Wexio's contact id. |
externalId | string | One of the two | Your own id. |
Output - the contact DTO, mirroring the GraphQL ContactApi allow-list:
{
id: string | null;
externalId: string | null; // your own id, echoed back
channels: string[];
erased: boolean;
displayName?: string | null; // PII_READ
avatarUrl?: string | null; // PII_READ
phone?: string | null; // PII_READ
email?: string | null; // PII_READ
}Identity fields are withheld without PII_READ, but externalId, channels and erased are not PII-gated. So even a masked agent can confirm which of your users a contact is, and which channels it can be reached on - it just cannot read their name or number.
The same DTO comes back from upsert_contact and set_contact_fields.
set_contact_fields
Sets field values on a contact, targeted by id or externalId.
| Argument | Type | Required | Description |
|---|---|---|---|
id / externalId | string | One of the two | Which contact. |
fields | { key, value }[] | Yes | The values to set. |
Writable keys are your custom fields and non-read-only system fields. Channel and identity keys are rejected - an agent cannot rewrite who a person is on a channel. Call list_field_definitions to discover what it may actually write.
list_field_definitions
Returns the org's field schema, so an agent can discover the writable keys instead of guessing them. No arguments beyond the optional orgId.
Have the agent call this once before its first set_contact_fields, and key off the result. A guessed field key is a failed write, and the agent has no other way to learn your schema.