WhatsApp Business API agency architecture — multiple client WABAs under one agency portfolio, centralized webhook routing by phone_number_id, billing separation
In this guide: Why isolation is mandatory · The correct multi-WABA architecture · Centralized webhook routing · Client onboarding workflow · Billing and revenue model options · GDPR data separation · Coexistence with Business App · SocialHook for multi-client management · FAQ

The mistake that takes all your clients offline simultaneously

The most dangerous architecture mistake an agency can make: putting multiple clients on the same WhatsApp Business Account (WABA). It looks like it saves admin overhead. It is a time bomb.

Here is what happens when one client violates Meta's messaging policies — sends unsolicited messages, gets spam-reported by enough recipients, or uses an unapproved template for the wrong purpose:

Meta restricts or suspends the WABA. Not just the offending phone number — the entire WhatsApp Business Account. Every phone number under that WABA stops receiving and sending messages simultaneously. If you have 10 clients on one WABA and client #4 runs an aggressive broadcast that gets flagged, all 10 clients go offline until the restriction lifts — which can take days or never resolve for severe violations.

This is not a theoretical risk. It is the single most common way agencies lose clients and face breach-of-service disputes. The correct architecture prevents it entirely.

The correct multi-WABA architecture

The rule is absolute: one WABA per client, one phone number per WABA (in most cases). Each client's WhatsApp infrastructure is completely isolated from every other client's. A policy violation on client A has zero effect on clients B through Z.

Agency Multi-WABA Architecture
Your Agency
Meta Business Portfolio (your MBM account)
Client 1
Acme Corp
WABA: 111...
Number: +1 555 0001
Meta billing: client card
Client 2
Beta Shop
WABA: 222...
Number: +44 7700 0002
Meta billing: client card
Client 3
Gamma SaaS
WABA: 333...
Number: +49 30 0003
Meta billing: agency card
Isolated WABA #1
ban ≠ affects others
Isolated WABA #2
ban ≠ affects others
Isolated WABA #3
ban ≠ affects others
SocialHook — one account, all client numbers
Centralized webhook delivery → your server, differentiated by phone_number_id

Wrong setup vs correct setup

❌ Wrong — agencies do this first
One WABA, multiple phone numbers
All clients share one WhatsApp Business Account
☠️One client's policy violation suspends every number simultaneously
⚖️All client data mixed in one WABA — GDPR compliance failure
💸Meta billing consolidated — impossible to separate per-client costs
🔒Agency owns everything — clients can't leave without losing their number
📊Analytics blended — can't show individual client quality scores
✓ Correct — one WABA per client
Separate WABA per client
Each client's WhatsApp account is completely isolated
Policy violation on client A has zero effect on B through Z
Clean GDPR data separation — each client owns their own data
Per-client Meta billing, transparent cost passthrough
Client retains ownership — professional relationship, clean offboarding
Per-client analytics, quality ratings, messaging tier management

Centralized webhook routing — one endpoint, all clients

With separate WABAs per client, you might assume you need separate webhook endpoints per client. You don't. Every Cloud API event — regardless of which client's WABA it comes from — contains a metadata.phone_number_id field that uniquely identifies which phone number received the message. Route all clients to one central endpoint and dispatch by this ID.

Node.js — centralized multi-client webhook router
agencyRouter.js
// Client registry — loaded from your database const clientRegistry = { '12345678901234': { clientId: 'acme-corp', name: 'Acme Corp', token: process.env.ACME_TOKEN }, '98765432109876': { clientId: 'beta-shop', name: 'Beta Shop', token: process.env.BETA_TOKEN }, '11223344556677': { clientId: 'gamma-saas', name: 'Gamma SaaS', token: process.env.GAMMA_TOKEN }, }; // Single webhook URL — registered in ALL client WABAs // Or: use SocialHook's per-number routing to your one endpoint app.post('/webhook/whatsapp', async (req, res) => { res.sendStatus(200); // acknowledge immediately // SocialHook normalized format — phone_number_id already extracted const { from, message, phone_number_id } = req.body; // Look up which client owns this number const client = clientRegistry[phone_number_id]; if (!client) { console.warn(`Unknown phone_number_id: ${phone_number_id}`); return; } // Route to client-specific handler handleClientMessage({ client, from, message, phoneNumberId: phone_number_id, }); }); async function handleClientMessage({ client, from, message, phoneNumberId }) { console.log(`[${client.name}] Message from ${from}: ${message?.body}`); // Each client gets their own logic, CRM, AI agent, etc. // Use client.token for outbound replies — each client's own access token await processWithClientConfig(client, from, message); // Log for per-client analytics and billing await logMessageEvent({ clientId: client.clientId, phoneNumberId, direction: 'inbound', from, timestamp: Date.now(), }); }
With SocialHook, this is simpler: Add all client phone numbers to your single SocialHook account. SocialHook receives events from every client's number and delivers them all to your one webhook URL — with the phone_number_id and the normalized payload already extracted. Your router code above works immediately, with zero HMAC verification or payload parsing to implement per client.

Client onboarding workflow: step by step

The end-to-end workflow to get a new client's WhatsApp number live — from their first conversation with you to their first webhook event hitting your system:

1
Client verifies their Meta Business Account1–3 days (if not done)
Your client goes to business.facebook.com and verifies their business. Verified status gives higher messaging limits from day one. This is their account — they own it, you do not. They need a valid business name, address, and domain verification. If they're already verified, skip to step 2.
2
Client authorizes your agency via Embedded Signup~10 minutes
You send the client a partner authorization link using Meta's Embedded Signup flow. They log in with their Facebook account, authorize your agency's Meta Business Portfolio to manage their WhatsApp Business Account. A new WABA is created during this flow — isolated, owned by the client, managed by you. This is the only correct way to gain management access without taking ownership.
3
Phone number registration + OTP~5 minutes
In the Meta Developer Dashboard (or via API), add the client's business phone number to their WABA. Verify via SMS or voice call OTP. The number is immediately active for sending and receiving messages. Critical: the number must not be currently registered on any WhatsApp app. If it is, the client deletes their existing account from the WhatsApp app first.
4
Add the number to SocialHook~2 minutes
Add the client's phone number to your SocialHook account. SocialHook registers the webhook on the Cloud API side automatically. From this moment, every inbound message from customers to this number arrives at your central webhook endpoint, normalized, with the client's phone_number_id for routing.
5
Generate permanent System User access token~5 minutes
In the client's Meta Business Settings → System Users, create a System User with Admin role. Assign it to their WABA. Generate a permanent access token with whatsapp_business_messaging and whatsapp_business_management permissions. Store this token in your secure key management system — it's used for all outbound messages sent on behalf of this client.
6
Create and submit message templates (if needed)1h–5 days
If the client needs to initiate outbound conversations (transactional notifications, marketing campaigns), create template messages in WhatsApp Manager under their WABA. Utility templates (order updates, reminders) typically approve within 1–24 hours. Marketing templates take 1–5 business days. The client's number can receive inbound messages and respond within the service window immediately — templates are only needed for initiating contact.
7
Test end-to-end and hand off dashboard access~30 minutes
Send a test message to the client's new number from your personal WhatsApp. Verify it arrives in your webhook handler with the correct phone_number_id. Send a reply from your system and confirm it appears on your personal WhatsApp. Once validated, give the client access to whatever dashboard or reports you've built for them. Their onboarding is complete.

Partner access vs ownership — why it matters

This is the distinction that separates a professional agency from an amateur one. There are two ways to access a client's WABA:

  • Ownership (avoid for client work): Your agency creates the WABA and the client's phone number is registered under your own Meta Business Account. You own the asset. When the client wants to leave, they have no number, no conversation history, and no continuity. This is a lock-in tactic that creates client resentment and legal exposure.
  • Partner access (correct): The client creates or already has a Meta Business Account. They authorize your agency via Meta's Embedded Signup or Partner API. You get management access to their WABA without owning it. If the client terminates the relationship, they can revoke your access and continue with another agency — their number, their data, their continuity intact.

Professional agencies always use partner access. It is also better for the agency commercially: clients trust you more when they know they're not locked in, making them more likely to refer you and stay long-term. The revenue is in the ongoing management and value-added services, not in holding the number hostage.

Client billing models: three options

Meta bills per conversation to the payment method attached to each WABA. As an agency, you have three ways to structure this:

Model 1
Direct billing
Client attaches their own credit card to their WABA. Meta charges the client directly for conversations. Your agency charges a flat monthly management fee separately.
Client pays Meta: variable
Client pays agency: $X flat
Agency risk: none
Model 2
Agency billing with markup
Your agency's payment method is attached to all client WABAs. You pay Meta, invoice clients with a markup. Higher revenue potential, more admin work, you absorb billing risk.
Agency pays Meta: actual rate
Agency invoices client: +20–50% markup
Agency risk: non-payment
Model 3
Packaged tiers
You sell conversation or message volume packages that include your margin. Client pays one predictable invoice. You absorb overage risk and volume risk. Most common for managed service agencies.
Client pays: $299/mo (500 convos)
Agency pays Meta: ~$40
Agency margin: ~$260

Most technical agencies building custom automation start with Model 1 (simplest, zero billing risk). Most managed service agencies — where you're running campaigns and customer service for clients — use Model 3 for predictable client invoicing and higher margins.

Revenue model: what WhatsApp services actually make

Understanding what's billable helps you structure your agency offering. There are three distinct revenue streams in the WhatsApp agency business:

  • Setup fee: one-time per client for WABA registration, phone number verification, template creation, webhook configuration, and system integration. Typically $500–$2,000 depending on complexity.
  • Monthly management retainer: ongoing management, monitoring quality ratings, maintaining messaging tier, template updates, support. Typically $200–$1,500/month per client.
  • Value-added services: AI agent build, CRM integration, campaign management, analytics dashboards, broadcast management. Priced per project or as add-ons to the retainer.

The WhatsApp agency model is high-margin compared to social media management because the technical barrier is high (competitors can't easily replicate) and the service is mission-critical (clients can't easily churn). An agency with 15 clients at $500/month average retainer is generating $7,500/month in recurring revenue — on top of setup fees and project work.

GDPR data separation: the compliance requirement

If any of your clients serve EU customers (or you're operating under GDPR-scope yourself), data separation between clients is not optional — it is a legal requirement. Under GDPR, each client is a separate data controller. Mixing their customer data under one WABA or one database creates both parties' liability exposure.

The practical requirements for GDPR-compliant multi-client WhatsApp management:

  • Separate WABAs — conversation data is isolated at Meta's level per WABA. This is solved architecturally by the one-WABA-per-client rule.
  • Separate database stores — your webhook handler must write each client's conversation data to separate storage namespaces, schemas, or databases. Never mix client A's contact data with client B's in the same table.
  • Data Processing Agreements (DPAs) — you need a signed DPA with each client that defines your role as data processor acting on their behalf (as data controller).
  • Data deletion — when a client offboards, you must be able to delete all their contact data from your systems within the timeframe specified in your DPA. Your data model must support this from day one.
  • Access controls — your system must prevent any one client's team from accessing another client's conversation data. Role-based access control at the client level.

Coexistence: keeping the Business App while using the API

Many of your SMB clients will ask: "Can I still use the WhatsApp Business App on my phone while the API is running?" As of 2026, Meta supports coexistence mode for this scenario.

Coexistence allows a phone number to be registered on both the WhatsApp Business App and the Cloud API simultaneously. Messages flow to both — the app receives them normally, and the API fires webhook events to your server. The client's team can continue handling conversations manually in the app while your API handles automation, routing, and AI responses in parallel.

The limitations of coexistence:

  • Messages sent from the Cloud API also appear in the Business App. Messages sent from the Business App do not fire Cloud API webhooks (they don't reach your server).
  • The Business App can only be linked on one device + up to 4 linked devices. The Cloud API has no agent limit.
  • Some interactive message types (buttons, lists) sent via the API may render differently or not render in the Business App interface.

For most agency clients, coexistence is the transitional state before they fully migrate to API-only operations. Plan for it — set up the API alongside the app first, let the client get comfortable with the new workflow, then phase out direct app usage over 30–60 days.

How SocialHook works for agencies

SocialHook is built for exactly this architecture. One account, unlimited phone numbers, all events normalized to the same JSON format and differentiated by phone_number_id. Here is what you get versus managing webhooks yourself per client:

What this means operationally:

  • One webhook URL to manage — not 15 or 50 separate webhook endpoints, HMAC secrets, and retry configurations per client. SocialHook handles all of that.
  • Add new clients in 2 minutes — add the phone number to your SocialHook account. It starts delivering events immediately. No new infrastructure.
  • Automatic retry — if your server is down during a maintenance window, SocialHook retries delivery. No events lost across any client.
  • Full delivery logs — per event, per number, per client. When a client asks "did you receive my customer's message at 3:22pm on Tuesday?" — you have a timestamp-accurate answer.
  • All three Meta channels — the same phone number entry in SocialHook handles WhatsApp, and you can add Facebook Messenger and Instagram DMs for the same client under the same normalized format.
The agency math: SocialHook costs $50/month flat for all client numbers. If you're managing 10 clients, that's $5 per client per month for the entire webhook infrastructure layer. At $500/client/month retainer, SocialHook is 1% of your revenue — and eliminates the equivalent of 4–8 hours of developer time per month managing per-client webhooks, HMAC verification, retry logic, and delivery monitoring. See the full pricing at socialhook.io/en/pricing.

Common questions

Can multiple clients share one WhatsApp Business Account?
No — and this is the most important rule in agency WhatsApp operations. Each client must have their own WABA. One client's policy violation can suspend the entire WABA, taking all clients offline simultaneously. Separate WABAs also ensure clean GDPR data separation and allow each client to maintain ownership of their number and conversation history. See the architecture diagram above for the correct setup.
How does an agency manage multiple WhatsApp numbers without separate webhook endpoints?
Use a single centralized webhook endpoint and route events by phone_number_id. Every Cloud API event includes the phone number ID in the payload — use it to look up which client the event belongs to and dispatch to client-specific handlers. With SocialHook, all client numbers deliver to one normalized endpoint automatically, already differentiated by phone_number_id. See the routing code above.
Should my agency own the client's WABA or just have management access?
Always management access (partner access), never ownership. Use Meta's Embedded Signup to get authorized access to the client's WABA. The client retains ownership of their number and data. When they leave, they continue with another provider — their number intact. Agencies that own client WABAs face client resentment, churn disputes, and legal risk. Professional agencies build long-term relationships on transparency, not lock-in.
How long does it take to onboard a new client to the WhatsApp API?
Typically 2–5 business days for the full flow: Meta Business Account verification (1–3 days if needed), WABA creation via Embedded Signup (same day), phone number registration and OTP (minutes), display name approval (1–24 hours), template creation if needed (1–24 hours for utility, up to 5 days for marketing). The number can send and receive messages immediately after OTP — display name and templates run in parallel. Adding to SocialHook and validating the webhook takes under 30 minutes.
What happens to one client if another client's number gets banned?
Nothing — if you have separate WABAs per client. A ban or restriction only affects the specific WABA and number involved. This is the primary reason separate WABAs per client are mandatory. If you had incorrectly consolidated clients into one WABA, a single violation could take all clients offline simultaneously. Proper isolation = complete blast radius containment.
Can I manage WhatsApp, Facebook Messenger, and Instagram for all clients from one system?
Yes — with SocialHook. You add each client's WhatsApp number, Facebook Page, and Instagram account to your SocialHook account. All inbound events across all three channels arrive at your central webhook in the same normalized format, differentiated by phone_number_id (WhatsApp) or page ID (Facebook/Instagram). Your routing and handler code works identically for all three channels. See the Facebook and Instagram integration pages for channel-specific setup.

One account.
All your client numbers.

Add every client's WhatsApp number to SocialHook. All events arrive at one normalized webhook — differentiated by phone_number_id, HMAC verified, retried on failure. Stop managing separate webhook infrastructure per client.

No credit card required · $50/month after trial · Unlimited client numbers