The user_preferences field reports when a WhatsApp user stops or resumes marketing messages from a business. It is the webhook that tells you who opted out before a marketing send fails with error 131050.
What user_preferences Reports
Each event carries a user_preferences[] entry with:
| Field | Values |
|---|---|
category | Always marketing_messages. |
value | stop (the user stopped marketing messages) or resume (the user resumed them). |
detail | User requested to stop marketing messages or User requested to resume marketing messages. |
timestamp | Unix timestamp of the preference change. |
When It Fires
Meta sends it when a WhatsApp user stops or resumes marketing messages from the business. It does not fire when a user gives Interested or Not interested feedback through the Offers and announcements setting.
Payload Shape
{
"object": "whatsapp_business_account",
"entry": [
{
"id": "<WABA_ID>",
"changes": [
{
"field": "user_preferences",
"value": {
"messaging_product": "whatsapp",
"metadata": {
"display_phone_number": "15550783881",
"phone_number_id": "106540352242922"
},
"contacts": [
{
"profile": { "name": "Sheena Nelson" },
"wa_id": "16505551234",
"user_id": "US.13491208655302741918",
"parent_user_id": "US.ENT.506847293015824"
}
],
"user_preferences": [
{
"wa_id": "16505551234",
"user_id": "US.13491208655302741918",
"parent_user_id": "US.ENT.506847293015824",
"detail": "User requested to stop marketing messages",
"category": "marketing_messages",
"value": "stop",
"timestamp": 1731705721
}
]
}
}
]
}
]
}
User Identifiers
The same identifiers appear in contacts[] and in each user_preferences[] entry, and each one can be missing:
| Field | Omitted when |
|---|---|
wa_id | The user enabled a username and their phone number cannot be shared with you. |
user_id | Business-scoped user IDs (BSUIDs) are not enabled for your business. |
parent_user_id | You have not enabled parent BSUIDs. |
parent_user_id is for identification only. Meta never applies a preference at the parent BSUID level, so store the opt-out against the user, not the parent. See BSUID webhook changes for the wider identifier rollout.
Dualhook Handling
Dualhook subscription: not subscribed. Dualhook's Meta app does not subscribe to user_preferences, so a Dualhook connection never delivers it to you, and Meta does not allow Webhook Override for this field. To receive it, subscribe your own Meta app to the field and to the WABA.
Without it, the reliable signal on a Dualhook connection is the failed status with error 131050 on the messages webhook, which Meta delivers to your endpoint directly. Dualhook does not keep an opt-out list or block marketing sends to users who stopped them.
Implementation Notes
- Key the preference on
user_idwhen present, and fall back towa_id. - Treat
stopas a suppression for marketing messages only; it does not cover utility or service messages. - Apply
resumeonly if it is newer than the laststopyou stored for that user. - Suppress on
131050failures as well, because you may miss preference events or join them to the wrong user.