---
title: "WhatsApp BSUID: Why Your CRM Gets No Phone Numbers"
canonical_url: "https://www.calypso.so/blog/whatsapp-stopped-sending-phone-numbers-your-crm-is-quietly-creating-duplicates"
last_updated: "2026-09-13T17:41:48.701Z"
meta:
  description: "Cloud API webhooks now omit phone numbers. Learn what BSUIDs mean for your CRM, how to spot silent duplicate records, and the fix that keeps matching intact."
  keywords: "WhatsApp BSUID, WhatsApp Cloud API phone number missing, user_id_update webhook, WhatsApp CRM duplicate contacts, REQUEST_CONTACT_INFO, WhatsApp LID username"
  "og:description": "Cloud API webhooks now omit phone numbers. Learn what BSUIDs mean for your CRM, how to spot silent duplicate records, and the fix that keeps matching intact."
  "og:title": "WhatsApp BSUID: Why Your CRM Gets No Phone Numbers"
  "twitter:description": "Cloud API webhooks now omit phone numbers. Learn what BSUIDs mean for your CRM, how to spot silent duplicate records, and the fix that keeps matching intact."
  "twitter:title": "WhatsApp BSUID: Why Your CRM Gets No Phone Numbers"
---

Calypso home

Blog / Guides

# **WhatsApp stopped sending phone numbers. Your CRM is quietly creating duplicates.**

WhatsApp Cloud API payloads can now arrive with no phone number at all. Here is why, how to diagnose it in your own data, and what to change before duplicates pile up.

**whatsapp-crm**

![Calypso Research](https://www.calypso.so/logo-calypso-icon.png)

**Calypso Research**

9 min read·September 13, 2026·4 sources

**Essay ** If your WhatsApp conversations land in the CRM keyed by phone number, some of them are now arriving with no number at all. Nothing errors. The message still arrives, the conversation still opens, and the integration does exactly what it was told to do: it looks up the phone number, finds nothing, and creates a new contact. Three weeks later the same customer shows up three times in a report and nobody can explain it. This is not a bug in your CRM or your integration vendor. It is a deliberate change in how WhatsApp identifies users, it has a deadline attached, and most tooling has not caught up. This piece walks through what changed, how to confirm it is happening in your data this morning, and what a fix actually looks like. ## What changed, and when WhatsApp's Cloud API webhooks historically carried a phone number in the from field on every inbound message. That number was the de facto primary key for an entire ecosystem: CRMs, helpdesks, marketing platforms, all of them matched inbound messages to contacts by string comparison against a phone field. Meta is retiring that assumption. Webhook payloads now carry a per-business user identifier, the BSUID, in fields like user_id, from_user_id, and recipient_user_id. The phone number appears only under two conditions: there was contact between that person and your business within the last 30 days, or the person exists in your business Contact Book. Integrators were given a deadline of June 2026 to support these identifiers. That deadline has effectively already passed in terms of planning: if your vendor has not shipped BSUID support, you are now in the window where payloads start arriving number-less and your system has no key to match on. The change is rolling out across business-initiated and user-initiated conversations, so you may see partial behavior for a while, which is the worst case because it makes the problem look intermittent. The practical consequence is that a phone-keyed CRM stops matching for any contact outside the 30-day window or the Contact Book. A customer who last wrote to you five weeks ago messages again, and the payload contains a user_id and no phone number. Your integration does not fail. It invents a new record. ## Why the failure is silent Every serious integration failure you have dealt with probably announced itself: a webhook returned 500s, a queue backed up, an alert fired. This one does none of that. The message delivery succeeds. The conversation renders. The agent replies. Every pipeline metric looks green because from WhatsApp's perspective, nothing went wrong. The only thing that failed is a database join, and a failed join that falls back to insert is indistinguishable from a new customer. The damage surfaces downstream, on someone else's timeline. Duplicates accumulate in the contact table. Attribution breaks, because the second and third records of the same person have no link to the original conversation history, so revenue gets attributed to a fresh contact with no prior touchpoints. Support context disappears: the customer references a thread your agent cannot see, because the agent is looking at record number three while the thread lives on record number one. If you are measured on throughput, this shows up as agents re-qualifying people who were already qualified, and as a contact database that gets worse every week instead of better. There is also a data hygiene trap: the duplicates are not identical. One record has a phone number and a purchase history. The others have a user_id, a first name, and nothing else. Any deduplication pass you run will look at the sparse records and reasonably conclude they are different people. The problem compounds quietly. ## A check you can run this morning You do not need vendor cooperation to confirm this. Open your CRM and filter for contacts created in the last 30 days where the phone field is empty. If your integration was built before the identifier change, every one of those records is a WhatsApp conversation that arrived without a number and got inserted instead of matched. Then look for the same person twice. Sort by first name and last name, or by any secondary signal you have, and count how many of the empty-phone records have a twin with a populated phone field and an earlier creation date. That twin pair is the smoking gun: one customer, two records, split by a missing phone number. Note the timestamps. If the empty-phone record was created more than 30 days after the last inbound message on the original record, you are looking at the 30-day window rule doing exactly what Meta said it would do. Run one more count while you are in there: what fraction of new contacts in the last 30 days have empty phone fields versus populated ones. That ratio is your exposure. If it is five percent, you have a maintenance task. If it is climbing week over week, you have a deadline, and the deadline is the next payload that arrives number-less. ## The second failure mode: rotation nobody instruments Matching on BSUID instead of phone number solves the missing-number problem, but it introduces a second one that almost nobody has instrumented for. BSUIDs rotate. When a business changes its WhatsApp number, the per-business user identifier changes with it. WhatsApp announces this through a user_id_update webhook, which tells you that user X is now user Y. If you ignore that webhook, one customer becomes two records, this time with two different user_ids and no shared phone number to rescue the match. This is the failure mode that will hurt the most, because it hits your most valuable contacts: businesses, repeat customers, anyone whose number changes while keeping their relationship with you. And unlike the missing-number case, there is no obvious symptom at all. Both records look complete. They just never talk to each other. The uncomfortable truth is that most teams will not handle this. It requires storing the old identifier as an alias, listening for the update event, and merging or relinking on receipt. That is real engineering work with no visible feature to show for it. But it is the difference between an identity model that survives contact with reality and one that quietly degrades. Ask your integration vendor today whether they consume user_id_update events. If the answer is a blank look, you know where you stand. ## Usernames, LIDs, and why you cannot look anyone up WhatsApp usernames complicate the picture in a specific way. A username maps onto WhatsApp's LID, an internal identifier that is distinct from the phone number and from your BSUID. There is no directory. There is no partial search. If you have a username or an identifier and want to find the corresponding record, you need an exact match against something you already stored. This kills the most natural repair strategy: when a duplicate pair shows up, someone goes looking for the missing half to merge them. With phone numbers you could normalize, search, and reconcile. With LIDs and BSUIDs and no lookup API, the only way to link records is to have captured the linkage yourself, at the time it happened, in your own data. Anything you did not store at ingestion time is unrecoverable. The operational takeaway is that your ingestion path becomes the only chance to get identity right. Every webhook payload is a one-time opportunity to record every identifier it carries, because there is no second source and no retroactive lookup. Teams that treat identity as a join performed at read time will lose data. Teams that treat it as a write-time capture problem will be fine. ## REQUEST_CONTACT_INFO: asking is now a product decision Meta is shipping REQUEST_CONTACT_INFO in July 2026 as the sanctioned way to ask a user for their phone number inside the conversation. That is the only compliant mechanism. Screen-scraping, third-party enrichment, or guessing from context are all off the table, and honestly they were never reliable anyway. This changes the nature of the phone number. It used to be a database default: every contact had one because the channel handed it to you. Now it is something you may have to request, in-conversation, and the user may decline. That makes asking a product decision with a real cost: an extra step in the flow, a friction point at exactly the moment you want the conversation moving. You should decide deliberately which conversations are worth that friction and which are not. A useful framing: do you actually need the phone number, or do you need stable identity? If your answer is stable identity, the BSUID gives you that for free and you never need to ask. If you genuinely need the number, for outbound SMS fallback or for matching against a phone-keyed legacy system, then design the ask as part of the flow, at a natural moment, with a reason attached. Do not bolt it onto onboarding as a form field and hope. The teams that will do well here are the ones that stop treating the phone number as the identity and start treating it as one attribute among several: useful when present, requested when needed, never load-bearing. ## What the fix actually looks like Nobody needs to replace their CRM over this. The fix is architectural, not a migration. Your contact model needs a stable internal identifier that is yours, generated by you, and never derived from a channel field. The BSUID, the phone number, the LID, and any username become attributes attached to that identifier, stored as a set of aliases rather than as the key itself. Matching at ingestion then becomes: does any known alias match an identifier in this payload? If yes, attach the conversation to that contact and update the alias set with anything new. If no, create a contact with whatever identifiers arrived, phone or not, and record the creation reason. When a user_id_update webhook arrives, find the old alias, relink it to the same contact, and log the rotation. None of this requires new infrastructure. It requires changing what your integration treats as the primary key and adding one webhook handler. Most WhatsApp tooling has not done this yet, and it is worth saying plainly. The ecosystem spent a decade treating the phone number as the identity because it always had been. Vendors are now retrofitting BSUID support, and quality varies widely. When you evaluate yours, ask three specific questions: do you store the BSUID as a first-class alias, do you handle user_id_update events, and what happens to matching when a payload arrives with no phone number. If the third answer is we create a new contact, you have found your duplicate source. - Stable internal contact id, generated by you, never derived from a channel field - Phone number, BSUID, and LID stored as attributes or aliases on that id - A handler for user_id_update that relinks the old alias on rotation - Ingestion-time capture of every identifier in the payload, since there is no retroactive lookup - A deliberate decision on when REQUEST_CONTACT_INFO is worth the friction ## Where this leaves you operationally If you own the process and are measured on throughput, this problem is a tax on every conversation that comes through the channel: agents re-qualifying known customers, attribution reports you cannot defend, a contact base that inflates. The cost of ignoring it grows linearly with volume, and the fix is a bounded engineering task measured in days, not quarters. Start with the diagnostic this morning. Quantify the empty-phone records and the duplicate pairs. Then have the identity conversation with your integration vendor or your internal team, using the three questions above. Handle the rotation webhook even if it feels like an edge case, because the customers it affects are the ones you can least afford to split in half. And once identity is stable at the record level, the conversation layer gets easier too. When every message reliably lands on the right contact, you can put the conversation on a board, give it an objective, and let the work move through columns with context intact. That is the model we built Calypso around: every WhatsApp conversation on a board with an objective, its own knowledge, and an agent that works the columns as steps. It only works if the conversation lands on the right customer every time, which is exactly what the identifier change is testing. Get the identity layer right first. Everything downstream of it gets simpler.**Sources ** References and source material used in this essay. - [**1****WhatsApp CRM with Calypso**calypso.so](https://www.calypso.so/use-cases/whatsapp-crm) - [**2****Meta WhatsApp Cloud API changelog**developers.facebook.com](https://developers.facebook.com/docs/whatsapp/changelog) - [**3****Meta webhook reference for WhatsApp Business Platform**developers.facebook.com](https://developers.facebook.com/docs/whatsapp/cloud-api/webhooks/components) - [**4****WhatsApp Business Platform user identity documentation**developers.facebook.com](https://developers.facebook.com/docs/whatsapp/cloud-api/reference)**Keep reading **## Related essays. More writing from the same engineering and product topic cluster. [NewGuides**Jun 16, 2026 · 5 min read**<h3>**Multimodal Retrieval-Augmented Generation and Multimodal RAG Agents: The Complete 2026 Guide**</h3>Learn how multimodal retrieval-augmented generation extends classic RAG across text, images, layouts, tables, audio, video, and agentic workflows.**Multimodal RAG****RAG Agents**Guides**Read article **](https://www.calypso.so/blog/multimodal-rag-agents-guide) [GuideGuides**Jun 15, 2026 · 13 min read**<h3>**The Complete Guide to Gemini File Search: Multimodal RAG with the Gemini API File Search Tool**</h3>An in-depth, practical guide to the Gemini API File Search tool — how managed Gemini File Search RAG works end to end, and how multimodal retrieval handles PDFs, docs, images, screenshots, charts, diagrams, metadata, and citations in production.**Gemini File Search****Multimodal RAG**Guides**Read article **](https://www.calypso.so/blog/gemini-file-search-complete-2026-guide)**From essay to product**## **Turn engineering ideas into source-backed answers.** Use Calypso to organize sources, attach them to hosted agents, and launch grounded answers across your website, workflows, and product UI. [**See live demo **](https://www.calypso.so/demos) [**Get Started for Free **](https://whatsapp.calypso.so/join)