--- name: growth-meta-whatsapp description: Use when a WhatsApp dispatch needs building, sending, or rescuing, on Meta Cloud API or a BSP. Triggers — template rejected or paused; messages not delivering; errors 131026, 131049, 132015, 131031, 130497; quality rating dropped; number restricted or WABA suspended; messaging tier, throughput, or 24-hour-window limits; per-message pricing; opt-in/LGPD; webhooks, Flows, media; chip warming, BSP migration, outsourced dispatch. --- # WhatsApp Business Platform — Production Reference (2025-2026) > Naming: Meta's umbrella is **WhatsApp Business Platform**; the current API is the **Cloud API**. "WhatsApp Business API" is legacy phrasing (the On-Premises API sunset Oct 23, 2025). "WABA" (WhatsApp Business Account) is an account entity, **not** an API. API current version: v23.0+. All conversation-based pricing replaced by per-message pricing July 1, 2025. > **Depends on:** the `growth-meta` skill (BM health, verification, account quality/classifier, proxy/isolation, disposable-BM strategy, ban mechanics). ALWAYS load `growth-meta` first. Do NOT load `growth-meta-ads` unless doing CTWA. > **Also depends on:** the `database-mapping` skill, for anything that measures a dispatch. Measurement has to know which table holds a person, which column holds a phone, and what counts as money arriving or leaving; that binding is the project's and lives in its database map. Load `database-mapping` before measuring — a dispatch whose project is unmapped, or mapped against a schema that has since moved, cannot be measured, and the engine stops rather than guessing. It is named here rather than left to a hook: the reach has to work in any project and any harness, with nothing auto-loading it on your behalf. > **Related:** `growth-meta-ads` (CTWA campaign setup + CAPI attribution); `growth-ycloud` (the YCloud BSP platform) + `growth-ycloud-api` (YCloud v2 REST API). --- ``` MANDATORY — read context AND report the full BM roster BEFORE any action (including before clarifying questions): 1. READ `.maccing/growth/README.md` (the platform/account index), if it exists. 2. ENUMERATE every BM — never assume one. The path is `meta///`, so list `.maccing/growth/meta/*/` (profiles) and `.maccing/growth/meta/*/*/` (BMs), then READ the root README, EVERY profile README, and EVERY BM README found. 3. Also READ EVERY WABA README: `.maccing/growth/meta/*/*/whatsapp/*/README.md`. 4. TELL the operator a roster of ALL BMs up front — one line each (profile · BM · verification/tier · WhatsApp number · quality · wallet/ramp) — INCLUDING BMs unrelated to the current task. Never silently narrow to one BM. Skipping this = operating on stale data and hiding live assets from the operator. ``` --- ## Send Doctrine — read this before the routing table > ⚠️ **DOCTRINE — the campaign/broadcast SEND is ALWAYS operator-executed, NEVER automated by the agent.** > The agent builds and validates the recipient list, runs the pre-send health gate, picks the template, and > reconciles results afterward — but the **human operator** is the one who uploads the list and clicks Send > in the BSP UI (e.g. YCloud → Campaigns → New campaign). The agent MUST NOT submit a marketing broadcast > programmatically: no `POST /v2/whatsapp/messages` loop over a list, no broadcast endpoint, no > `sendDirectly` fan-out. **Why:** a broadcast is irreversible, costs real money, reaches hundreds of real > people, and one mistake (wrong template, wrong list, wrong variable mapping) can crater a hard-won quality > rating or permanently ban the number — a human at the trigger is the last safety gate. Scope: this covers > **bulk campaign/broadcast sends**; single transactional/inbox replies inside the 24h service window are not > the target. Duplicated verbatim from [references/sending-and-scale.md](references/sending-and-scale.md) on purpose: the router below hands out files that contain a working send, so the prohibition has to load first. Do not "de-duplicate" it away. --- ## Routing Table | Intent | Reference | Use for | |---|---|---| | Message types, payloads, interactive messages, typing indicator, read receipt | [references/message-types.md](references/message-types.md) | All send-message JSON shapes; text, image, video, document, audio, sticker, location, contacts, reaction, buttons, lists, flows, typing | | Template creation, approval, pacing, limits, dispatch strategy | [references/templates.md](references/templates.md) | Creating templates via API, template JSON, approval process, quality states, pacing vs pausing, Template Strategy for marketing broadcasts (copy, image headers, forbidden words, opt-out) | | Quality KPIs, throughput tiers, daily limits, quality rating, recovery protocol, queue management | [references/sending-and-scale.md](references/sending-and-scale.md) | 80 MPS throughput, messaging limit tiers, quality system, quality KPIs, recovery protocol, bulk send queue code | | WhatsApp Flows (native in-chat forms, appointments, surveys) | [references/flows.md](references/flows.md) | Flow JSON schema, API endpoints, dynamic flows backend, payment flows (Brazil/India) | | Webhook events, payloads, signature verification, BSUID, best practices | [references/webhooks.md](references/webhooks.md) | Incoming message webhooks, status updates, BSUID June 2026 change, Express handler code, queue-first architecture | | Media upload, retrieve, download, caching | [references/media.md](references/media.md) | Supported formats, size limits, upload/retrieve/download API, media ID reuse strategy | | Node.js/TypeScript SDK, raw fetch, integration patterns | [references/integration-sdk.md](references/integration-sdk.md) | `@great-detail/whatsapp` SDK setup, webhook handler, raw fetch, order lifecycle/CTWA/CRM patterns | | Error codes, retry logic, delivery failures, 131026/131049/132015 | [references/error-codes.md](references/error-codes.md) | Full error code table by category, retry strategy TypeScript snippet, real-world broadcast baselines | | Opt-in/opt-out, LGPD (Brazil), GDPR, anti-spam, content restrictions, Business Profile compliance, display-name approval, verification, OBA, financial-niche | [references/compliance.md](references/compliance.md) | Consent requirements, opt-out recognition, LGPD 5-year retention, 2026 AI restriction, Business Profile API + field definitions, display-name approval, verification, OBA requirements, financial-niche restrictions | | Per-message pricing, free windows (CSW/CTWA), Meta rate card, cost optimization, BSP comparison table, WhatsApp Payments | [references/pricing-and-billing.md](references/pricing-and-billing.md) | PMP rates by market, free window rules, volume tier discounts, Meta base rate card, cost calc, full BSP comparison table, WhatsApp Payments (Brazil/India) | | Direct Cloud API setup, BSP migration, number quality/longevity, cold lists | [references/waba-provisioning.md](references/waba-provisioning.md) | Direct Cloud API setup sequence, switching BSP / migrating WABA (PIN reset, device-trust gotchas), cold list strategy | | Outsourced dispatch (a third party sends on their numbers), and the campaign measurement contract | [references/outsourced-dispatch.md](references/outsourced-dispatch.md) | Outsource-vs-own-WABA call, unit price vs own CPDM, phone×segment attribution, split-test design, statistical power / MDE, copy-vs-product verification, vendor checklist, entity correlation; declaring cells and controls and calling `measure` from `@maccing/growth` | | Disposable BM pipeline, proxy/isolation stack, BM sources, profile acquisition, phone number strategy, display name strategy | `growth-meta` skill | Full disposable-BM strategy, proxy comparison table, BM setup sequence, Number Warming Protocol (official WABA), phone number acquisition | | YCloud BSP platform (campaigns, inbox, contacts, webhooks) | `growth-ycloud` skill | BSP platform operations, campaign management, YCloud features | | YCloud v2 REST API (send message, list messages, webhook endpoints, pagination) | `growth-ycloud-api` skill | YCloud API reference, pagination gotchas (`page` not `offset`), HMAC signature, campaign-send lag caveat, broadcast monitoring | --- ## 1. Platform Overview ### WhatsApp Business App vs. Cloud API | Dimension | WhatsApp Business App | WhatsApp Cloud API | |---|---|---| | Target | Small business, 1-2 agents | Enterprise, automation, scale | | Access | Free mobile app | REST API (Meta-hosted) | | Volume | Manual, limited | Programmatic, unlimited | | Automation | None | Full (chatbots, CRM, flows) | | Templates | Basic | Full template library | | Multi-agent | No | Yes (via inbox platform) | | Analytics | None | Full metrics API | | Cost | Free | Per-message charges apply | **On-Premises API:** Permanently shut down October 23, 2025. Cloud API is the only path. Error code 1005 = number still on on-prem. ### Coexistence — one number on both the Business App and Cloud API Meta's own name for this is **"API Solutions for Business App Users"**; support and partner channels call it **Coexistence**. It is entered through **Embedded Signup**: the business connects its existing WhatsApp Business app account and number to Cloud API, then keeps answering 1:1 from the phone while the API sends at volume, with both directions mirrored ([Meta primary doc](https://developers.facebook.com/documentation/business-messaging/whatsapp/embedded-signup/onboarding-business-app-users/)). - **Who can offer it:** the integrator must already be a Solution Partner or Tech Provider; the business must run WhatsApp Business app **2.24.17+**. - **Sync:** contacts, and 1:1 history for the most recent 6 months, are synchronizable — but only if you subscribe to the `history`, `smb_app_state_sync` and `smb_message_echoes` webhook fields AND fire both `smb_app_data` sync calls within **24h** of onboarding. Miss that window and the customer must offboard and redo Embedded Signup. - **Confirm the state:** `GET /{PHONE_NUMBER_ID}?fields=is_on_biz_app,platform_type` — both modes live is `is_on_biz_app: true` plus `platform_type: CLOUD_API`. - **What it costs you:** throughput is **fixed at 20 mps** (against the 80 default), **Broadcast lists are disabled** (existing ones go read-only), and group chats, disappearing messages, view-once, live location and voice/video calls are unsupported on the Cloud API side. - **Window and billing:** a customer service window opens only when a user messages a number that is *already* onboarded. Messages sent from the app sit outside the CSW entirely — they neither create nor extend a Cloud API window, and are not billed as Cloud API. - **Offboarding is client-side:** the Deregister API will NOT deregister a coexisting number. The business disconnects in-app (Settings → Account → Business Platform → Disconnect Account), which fires `account_update` with `PARTNER_REMOVED`. - **Expect error 131060** (an `unsupported` messages webhook) on a user's first inbound and from unsupported companion devices — normal, usually clears within seconds. **Dispatch verdict:** the 20 mps ceiling and the loss of Broadcast lists make coexistence an inbox/service posture, not a broadcast posture. Do not onboard a number you intend to broadcast from. **Integration paths:** 1. **Direct Cloud API** — REST against Meta directly. Full control, requires engineering effort. 2. **BSP (Business Solution Provider)** — managed infrastructure with inbox, automation, analytics UI. Recommended BSP: YCloud (see `growth-ycloud` skill). --- ## 2. Cloud API Setup **Prerequisites:** Meta Developer account, verified Meta Business Manager, verified business entity, phone number not previously on any WhatsApp account. **Step-by-step:** 1. Create Meta Business Account at `business.facebook.com` 2. Register as Meta Developer at `developers.facebook.com` 3. Create a **Business** type app → Set Up WhatsApp product 4. Add phone number → verify via SMS or voice call 5. Generate **System User permanent token** (Admin role, permissions: `whatsapp_business_messaging`, `whatsapp_business_management`, `catalog_management`) — never use the 24h temporary token in production 6. Configure HTTPS webhook endpoint → subscribe to the `messages` field 7. (Optional) Apply for OBA blue badge (WABA 30+ days old, verified, 2FA, notable coverage) **API version:** v23.0. Base URL: `https://graph.facebook.com/v23.0/{phone_number_id}/messages`. Pin to a specific version in production. **Webhook verification handler:** ```typescript app.get('/webhook', (req, res) => { const mode = req.query['hub.mode']; const token = req.query['hub.verify_token']; const challenge = req.query['hub.challenge']; if (mode === 'subscribe' && token === process.env.WEBHOOK_VERIFY_TOKEN) { res.status(200).send(challenge); } else { res.sendStatus(403); } }); ``` --- ## 13. WhatsApp Business Calling API (July 2025) GA July 15, 2025. Voice calls directly within WhatsApp conversations. **CSW interaction:** A user-initiated call opens and resets the 24-hour Customer Service Window, identical to an inbound message. After a call, businesses can send free-form service messages and free utility templates for 24 hours. **Two call types:** user-initiated (inbound) and brand-initiated (outbound, to opted-in users). **Requirements:** System User token with `whatsapp_business_messaging`, HTTPS webhook subscribed to `calls` field, WebRTC implementation (or BSP), IVR via DTMF. **Key features:** full conversation thread visible during call, click-to-call buttons in interactive/template messages, IVR via DTMF. --- ## 14. Marketing Messages Lite API (MM Lite) Launched April 2025. A dedicated API for marketing broadcasts using Meta's ads AI to optimize delivery timing and recipient selection. | Aspect | MM Lite API | Cloud API | |---|---|---| | Purpose | Marketing broadcasts | All message types | | AI optimization | Yes (Meta ads AI) | No | | Delivery rate | Up to 9% higher | Standard | | US users | Not delivered | Not delivered (since April 2025) | | Interaction | One-way (templates only) | Two-way | **When to use:** large marketing broadcasts → MM Lite; customer support, utility, two-way → Cloud API. **Note for 360dialog / Gupshup users:** prefer MM API route to avoid their ~6-7% marketing surcharge that applies only on the standard Cloud API endpoint. --- ## 15. WhatsApp Business Management API **Phone Number Management:** `GET /{WABA_ID}/phone_numbers`, add/register numbers programmatically, set display names, manage 2FA PINs. **Template Management:** ``` POST /{WABA_ID}/message_templates # Create GET /{WABA_ID}/message_templates # List (filter: ?status=APPROVED) POST /{TEMPLATE_ID} # Update DELETE /{TEMPLATE_ID} # Delete ``` **QR Code Management:** `POST /{PHONE_NUMBER_ID}/message_qrdls` — create pre-filled chat QR codes. **Analytics:** `GET /{WABA_ID}/analytics?start=...&end=...&granularity=DAY&metric_types=SENT,DELIVERED,READ` --- ## 16. Business Profile Fields See [references/compliance.md](references/compliance.md) for all Business Profile field definitions, the `POST /{PHONE_NUMBER_ID}/whatsapp_business_profile` API reference, display-name approval mechanics, verification, OBA requirements, and financial-niche profile compliance. --- ## 18. 2025-2026 Key Changes Summary | Change | Date | Impact | |---|---|---| | On-Premises API sunset | October 23, 2025 | All must use Cloud API | | Per-message pricing (PMP replaces CBP) | July 1, 2025 | Each template message billed individually | | Utility free in CSW | July 1, 2025 | Utility templates inside 24h window are free | | Auth rates -65% to -78% (LATAM) | July 1, 2025 | Major OTP cost reduction | | Marketing blocked to US numbers | April 1, 2025 | No marketing to US users (error 131049) | | MM Lite API launched | April 2025 | AI-optimized marketing delivery | | Messaging limits: portfolio-level | October 7, 2025 | All numbers in portfolio share tier | | Tier evaluation: every 6 hours | 2025 | Faster scaling | | WhatsApp Business Calling GA | July 15, 2025 | Voice calls in WhatsApp | | Blue badge replaces green badge | 2024 (rolled out 2024-2025) | UI change only; existing badges converted | | Service conversations unlimited-free | November 1, 2024 | No monthly cap; all service conversations free | | Utility/Auth body cap: 512 chars | October 1, 2025 | Error 2388040 if exceeded at creation | | Flagged phone-number status eliminated | October 7, 2025 | Red quality only blocks advancement, no auto-downgrade | | Verified tier floor raised to 2,000/day | October 7, 2025 | Was 1,000 | | HTTPS URL requirement for templates | January 1, 2026 | Shorteners rejected; must be live HTTPS | | Brazil BRL local billing | July 1, 2026 | Eligible accounts billed in BRL | | Meta CA cert change (mTLS) | March 31, 2026 | Update trust store: meta-outbound-api-ca-2025-12.pem | | BSUID added to webhooks | March 31, 2026 | New `identity.user_id` field | | BSUID may replace phone in `from` | June 2026+ | CRM must handle both identifiers | | AI chatbot restriction | 2026 | Only task-specific AI allowed | | Auto-categorization enforcement | April 9/16, 2025 | Meta auto-corrects category; repeat offenders lose UTILITY access 7 days | | Carousel messages (interactive) | unverified | 2-10 cards, CSW only (non-template) — [references/message-types.md](references/message-types.md#interactive-media-carousel) | | Business App + Cloud API coexistence | unverified | Same number in both; 20 mps ceiling, Broadcast lists disabled — [§1 → Coexistence](#coexistence--one-number-on-both-the-business-app-and-cloud-api) | > **Two dates above read `unverified` on purpose.** Neither feature page carries a publication or updated date, and Meta's public changelog — the one place a landing date is published — returned HTTP 500 on every attempt. So the "February 2026" and "January 2026" dates previously asserted here could not be confirmed against a primary source, and are no longer asserted. Both *features* are confirmed from Meta docs — [interactive media carousel](https://developers.facebook.com/documentation/business-messaging/whatsapp/messages/interactive-media-carousel-messages) and [coexistence](https://developers.facebook.com/documentation/business-messaging/whatsapp/embedded-signup/onboarding-business-app-users/) — only their ship dates are unknown. To close the gap, retry the changelog; do not restore a remembered date. --- ## 19. Quick Reference ### Essential Endpoints ``` POST https://graph.facebook.com/v23.0/{PHONE_NUMBER_ID}/messages # Send message POST https://graph.facebook.com/v23.0/{PHONE_NUMBER_ID}/media # Upload media GET https://graph.facebook.com/v23.0/{MEDIA_ID} # Get media URL POST https://graph.facebook.com/v23.0/{WABA_ID}/message_templates # Create template GET https://graph.facebook.com/v23.0/{WABA_ID}/message_templates # List templates GET https://graph.facebook.com/v23.0/{WABA_ID}/phone_numbers # Get phone numbers POST https://graph.facebook.com/v23.0/{WABA_ID}/flows # Create flow POST https://graph.facebook.com/v23.0/{FLOW_ID}/publish # Publish flow GET https://graph.facebook.com/v23.0/{WABA_ID}/analytics # Analytics ``` ### Required Permissions ``` whatsapp_business_messaging # Send/receive messages whatsapp_business_management # Manage templates, phone numbers, settings catalog_management # Product catalog integration (optional) ``` ### New Integration Checklist - [ ] Meta Business account created and verified - [ ] App created in Meta Developer dashboard - [ ] Phone number added and verified (6-digit code) - [ ] System User created with Admin role - [ ] Permanent access token generated and stored securely - [ ] Webhook endpoint deployed with HTTPS - [ ] Webhook verification challenge handler implemented - [ ] Webhook signature verification implemented (`x-hub-signature-256`) - [ ] `messages` field subscribed in webhook settings - [ ] At least one template created and approved - [ ] Opt-in collection mechanism in place before any proactive messaging - [ ] Env vars: `WA_PHONE_NUMBER_ID`, `WA_BUSINESS_ACCOUNT_ID`, `WA_ACCESS_TOKEN`, `APP_SECRET`, `WEBHOOK_VERIFY_TOKEN` - [ ] CRM stores both phone number AND BSUID fields - [ ] Error handling with retry logic implemented - [ ] Idempotent webhook processing with message ID deduplication ### Cost Calculation Formula ``` Monthly Cost = Σ (messages_delivered × country_rate × category_multiplier) - volume_discounts (utility/auth only) - free_CSW_utility_messages - free_72h_CTWA_messages Effective Rate: Marketing >> Utility > Authentication >> Service (free) ```