Sync WhatsApp Account Names With account.profile.updated
To synchronize the connected WhatsApp account’s own name in your application, handle UnifyPort’s account.profile.updated event. Read data.profile.display_name, which prefers the business name and falls back to the push name. Update the account’s profile display—not a customer’s contact record, your internal account label, or its connection status. The documented trigger is WhatsApp name events; this is not a universal profile-change feed for every channel.
Key takeaways
- Route the event by workspace, provider, and
account_id, never by the displayed name. - Keep account configuration
nameseparate from the provider’s public name. full_syncdescribes a profile sync source, not completion of message-history recovery.- A profile notification does not prove authorization or a running connection.
Decide which name the screen should show
A support account selector can legitimately show two different names: the team’s operational label and the name observed from the messaging platform. A rename should not silently change ownership, routing, or permissions.
| Value or event | What it represents | Recommended destination |
|---|---|---|
Account configuration name | Label maintained through account configuration | Internal account selector label |
data.profile.display_name | Public name derived from the provider profile | Separate provider-name line |
data.profile.business_name / push_name | Name components shown in the event reference | Optional profile detail view |
contact.updated | A contact’s address-book names | Customer contact projection |
account.status.updated | Authentication or runtime state | Connection-health view |
The contact-name synchronization guide handles the customer’s side. Reusing that handler for an account profile risks changing the wrong entity. Similarly, do not infer an account rename from a customer’s message sender name.
The Get account reference returns account configuration and provider_profile separately. It provides a starting read for the screen; a missing public name should appear as unavailable rather than being invented from the internal label.
Read account.profile.updated without widening its meaning
The event reference defines this illustrative payload. These are documentation example values, not a customer observation:
{
"id": "evt_profile_7e91d2c4",
"type": "account.profile.updated",
"provider": "whatsapp",
"account_id": "acc_8c21d0",
"occurred_at": "2026-08-28T09:51:51Z",
"data": {
"account": { "provider_account_ref": "provider_account_example" },
"profile": {
"display_name": "Example Business",
"business_name": "Example Business",
"push_name": "Example Account"
},
"event": {
"kind": "account_profile_updated",
"source": "self_rename"
}
}
}
Use the provided display_name rather than implementing a competing precedence rule. A changed push_name need not make the visible name change while a business name takes precedence.
The documented data.event.source values distinguish:
self_rename: the connected account changed its own name.full_sync: the profile came from a full sync snapshot.
Neither value identifies the human who made a change. Do not manufacture an operator audit entry from it. full_sync also does not establish that all messages, contacts, avatars, or other account data were synchronized.
Build the account card as a separate projection
Recommended implementation sequence:
- Subscribe before relying on updates. Include
account.profile.updatedin the endpoint’s required event set, preserving existing subscriptions and signing configuration. The event-filter guide explains explicit lists versus a wildcard. - Verify and persist. Follow the delivery contract: verify hex HMAC-SHA256 over
X-Device-Timestamp, a dot, and the raw body usingsigning_secret; check timestamp freshness. Store authenticated events durably before acknowledging with 2xx. - Resolve the existing account. Use the receiver’s workspace context and the envelope’s provider and
account_id. A new name must not create a second account or move conversations to another account. - Update only the profile display. Keep internal labels, customer names, authorization, and runtime state untouched. Render names as text, not HTML.
- Record provenance locally. Keep event ID, occurrence time, and source alongside the projection. These are local bookkeeping choices, not additional API fields.
This JavaScript helper only extracts a display candidate from an already authenticated event. It does not implement storage, ordering, or a complete receiver:
function profileNameCandidate(event) {
if (event.type !== 'account.profile.updated' ||
event.provider !== 'whatsapp') return null;
if (typeof event.account_id !== 'string' || !event.account_id) {
throw new Error('Missing account identity');
}
const name = event.data?.profile?.display_name;
if (typeof name !== 'string') {
throw new Error('Profile display name needs review');
}
return { accountId: event.account_id, displayName: name };
}
The returned keys are application variables. If the name is absent or invalid, retain the authenticated event for review instead of replacing the entire profile with defaults. For an empty string, define an explicit local “name unavailable” display policy; do not import the contact event’s clearing rules into this different contract.
Handle older deliveries and initial reads deliberately
Deduplicate ordinary event retries by event ID. Delivery order is not guaranteed: use occurred_at and the event ID as a deterministic tiebreaker when applying profile events, with the deduplication and projection change committed together.
A REST read and a webhook do not come with a documented shared profile revision here. Do not let a slow initial account read overwrite an event applied while the read was in flight. Serialize initialization and event processing, or keep the read as a baseline and apply buffered events afterward. If observations conflict, flag them for reconciliation rather than claiming perfect upstream ordering.
UnifyPort is an unofficial interface. This event is not a command to change the native profile, a complete profile archive, or guaranteed replay. Do not assume LINE, Zalo, Telegram, or whatsapp-protocol emits it because those integrations share an envelope.
FAQ
Why did push_name change but display_name stay the same?
The documented display name prefers BusinessName and falls back to PushName. Inspect the supplied components before treating an unchanged display as a failed update.
Does full_sync mean message history is complete?
No. It identifies this profile event’s source, not message-history completeness or recovery.
Should I update the account’s name through PATCH after receiving the event?
Not as an automatic synchronization step. That would change account configuration rather than merely displaying the observed provider name. Keep internal-label edits deliberate and separate.
Next step and sources
Implement the account card against the account profile event reference. Proposed acceptance checks: both source values, different business and push names, duplicate and older deliveries, missing or empty names, and a late initial read. Confirm that customer contacts, internal labels, and connection status remain unchanged. These are tests to run, not reported results.
References checked on 2026-11-05:
Turn messaging integration into a stable product pipeline.
Start by sending through one API, then bring every inbound message back into your business system with standard events.