Meta's WhatsApp App Review: where the real instructions are hidden
The permission descriptions in the dashboard tell you almost nothing. The actual per-permission instructions are buried two clicks deep in a screen most people never open, and guessing wrong costs you a day.
On this page · 8 sections
We needed three WhatsApp Business Platform permissions approved for MonGroupage: whatsapp_business_messaging, whatsapp_business_management, catalog_management. This is what actually happened getting there, not the clean version.
The submission form tells you almost nothing
The "Contrôle app" form asks, per permission, for a one-paragraph description and a video. That's it. No spec for what the video needs to show, no mention of API test calls, nothing. If you build a video based on what you think the permission does, you're guessing.
The real instructions are somewhere else entirely
There's a separate flow, "Devenir fournisseur de technologies indépendant" (Become a Tech Provider), reachable from the "Devenez partenaire" section of the sidebar — not linked from the submission form itself. That page has a step called "Record video documentation," and clicking "Afficher les instructions" per permission is where Meta actually tells you what to film:
- 01
whatsapp_business_messaging: send a message with your app via their "Try it out" tool, record your app sending it and WhatsApp (web or mobile) receiving it. - 02
whatsapp_business_management: create a message template in WhatsApp Manager, record that, and separately make a few real API calls against their published Postman collection (with a ~24h delay before Meta's review form picks them up).
Nobody tells you this page exists. We only found it by clicking through the sidebar at random after the submission form stopped giving us anything useful.
The wrong assumption that cost a day
Before finding that page, we assumed whatsapp_business_management had to be demonstrated through Embedded Signup — a carrier partner linking their own WhatsApp number to the platform in "coexistence" mode (keeping their own WhatsApp Business app working while we also get API access). That's a real, legitimate use of the permission. It is not what Meta's own checklist asks for in this submission. We built toward it anyway, for a day, before checking what was actually required.
If you're building a "connect your own WhatsApp number" flow for partners, you'll hit this for real eventually. Just don't assume it's required for app review unless Meta's own instructions for your app say so.
Embedded Signup will not work until you're already approved
Trying it anyway, with a real phone number, gets you:
1{"error":{"message":"(#200) L'application partenaire ne dispose pas des autorisations avancées de gestion et de messagerie WhatsApp Business requises pour l'intégration."}}Circular by design: the feature that proves you need Advanced Access requires Advanced Access to run. Meta's answer is a sandbox test account — App Dashboard → WhatsApp → Quickstart → "Testing Integrations" → "Claim sandbox account" — which completes the whole flow with a fake WABA and phone number, no real credentials needed.
Except that button doesn't exist if your app was set up through the newer "Cas d'utilisation" flow instead of the classic standalone WhatsApp product. Ours was. No sandbox button anywhere. We never found a workaround — just confirmation, from Meta's own documentation, that we didn't need it for this submission after all.
`business_management` and `catalog_management` are not the same kind of permission at all
Easy to conflate them as "two flavors of admin access." They're not:
- 01
whatsapp_business_managementcovers the WhatsApp side — templates, phone numbers, the business account itself. - 02
catalog_managementcovers Meta's separate Commerce/Catalog API — creating, reading, and updating product catalog entries.
A customer placing an order from your WhatsApp catalog uses neither of these — that's plain whatsapp_business_messaging (you send a catalog_message, the order comes back as a normal inbound message). We'd been sending that catalog message for weeks already. It proves nothing about catalog_management.
We had nothing real to show for `catalog_management`, so we built it
The catalog was synced the manual way: export a CSV, upload it by hand in Commerce Manager. Zero API calls. Not something you can film honestly.
So: a Django management command pushing products straight to Meta's Catalog Batch API (POST /{catalog_id}/items_batch). First attempt, every item came back rejected:
1{"validation_status":[{"errors":[{"message":"Can not find required field id"}]}]}The fix: the data object needs its own id field, identical in value to the retailer_id already set at the request's top level. Two fields, same value, both required. Not obvious from the batch endpoint's own docs.
Second attempt, no errors, but a warning on every item:
1{"message":"Champ non reconnu: Une requête pour l'article DC-03 contient un champ non reconnu : name"}The field is called title, not name. Same for image_link, not image_url. These are the exact column names Meta's own CSV feed spec uses — we just assumed the Batch API would take anything reasonable. It silently accepts the request, drops the field it doesn't recognize, and ships the item with no title and a price of 0,00. No error. You find out by looking at the product in Commerce Manager afterward.
Bulk delete through the UI: looked done, wasn't
Separate from the review, while cleaning up test data mixed into the real catalog: selecting ~100 products and hitting delete in Commerce Manager showed a "Suppression des produits" spinner that sat there for hours, then vanished on reload — with every product still there. Checked against the API directly (GET /{catalog_id}/products?summary=true), the count hadn't moved.
A single item deleted through the Batch API (method: "DELETE", same id-in-data requirement as above) worked in under ten seconds. A batch of 5 through the same endpoint came back "An unknown error has occurred" — no detail, no validation_status, nothing. One at a time kept working, until enough rapid calls in a row made even single deletes start failing the same way. Looked like a write-side rate limit specific to items_batch, separate from read calls, which kept succeeding the whole time.
Net result: the UI's bulk action is not something we'd trust again without checking the API count afterward, and a determined retry loop against a failing endpoint is worth stopping, not pushing through.
What actually mattered, in order
- 01Find Meta's own per-app instructions before assuming what a permission requires — they're not where the submission form would lead you to look.
- 02Don't build toward a feature (Embedded Signup coexistence, in our case) as App Review prep unless Meta's instructions for that permission actually ask for it.
- 03A permission with zero current usage in your app needs a real feature built for it, not a staged recording — and that feature will have its own undocumented API quirks to find the hard way.
- 04Every response from a Batch-style endpoint deserves actually being read, success included. A 200 with a
warningsarray is not the same as a clean write, and we only noticed because we went back and checked Commerce Manager by hand.