Cloud API Architecture
Since October 2025, WhatsApp Business Platform runs on Cloud API. At a high level:
- Businesses send messages through Meta Graph API
- Businesses receive events through webhooks
- Meta Cloud API acts as the managed messaging intermediary between business systems and WhatsApp transport
Encryption Model
WhatsApp messaging uses the Signal protocol for encryption. Cloud API also applies standard platform security controls:
- Data in transit —
HTTPS+TLS - Data at rest — encrypted storage on Meta infrastructure
Security boundary:
- WhatsApp transport does not expose message content to WhatsApp operators.
- Cloud API processes message content to provide platform functionality on behalf of the business.
Message Flow
User to Business
- User sends a message.
- Message is encrypted in transit to Cloud API.
- Cloud API processes and decrypts for delivery to the business webhook.
- Data is temporarily retained for core platform functionality (e.g. retries and retransmissions).
Business to User
- Business sends message request to Cloud API.
- Cloud API temporarily stores and processes for delivery and reliability.
- Cloud API encrypts for destination delivery.
- WhatsApp transport delivers to the user client.
In Dualhook setups, inbound messages arrive at your endpoint directly from Meta via Webhook Override. For outbound operations, your backend calls Dualhook's exact allowlisted Graph-compatible runtime routes with a per-connection dh_live_... key. The surface covers messages, media, selected templates, health/status, profiles, safe phone/calling settings, and QR codes without becoming an arbitrary Graph gateway.
All native authenticated Graph calls made by Dualhook pass through a server-only transport that derives Meta's app-secret proof from the exact authorizing token. Neither the token nor the proof is exposed to customers. The runtime resolves the existing authoritative routing projection before decrypting authorization, compares every route to the connection's stored phone/WABA assets, verifies template and media object ownership, rejects customer-controlled fields/hosts/callbacks, and uses manual redirect handling so credentials cannot be forwarded to another origin. OAuth code exchange (before a token exists), inbound webhook signatures, and validated Facebook/CDN media downloads are separate documented flows rather than Graph proof exceptions inferred by callers.
Local Storage (Data Residency)
Cloud API Local Storage lets a business choose the region where Meta keeps message content at rest. By default Meta stores it in its US data centers. With Local Storage enabled, Meta processes a message for up to 60 minutes (90 minutes on the Marketing Messages API) and then deletes the content from data centers outside the chosen region, keeping it only inside that region. This is useful for GDPR and other residency requirements.
Local Storage is a per phone number setting on Meta's side (storage_configuration on the phone number's settings), not a WABA or Dualhook setting. It covers:
- Incoming and outgoing message text
- Media payloads (audio, document, image, video)
- Template messages, including runtime parameters
- Limited, tokenized metadata Meta keeps to link and audit the localized payloads
It does not cover phone numbers extracted from shared contact cards (Meta keeps those in its contact book on Meta data centers regardless of the Local Storage setting), and it does not change where Dualhook runs: Dualhook never stores message content in any region (see Stored and Collected Data).
Supported Regions (as of September 2026)
| Region | Countries (code) |
|---|---|
| Europe | Germany / EU (DE), Switzerland (CH), United Kingdom (GB) |
| APAC | Australia (AU), Indonesia (ID), India (IN), Japan (JP), Singapore (SG), South Korea (KR) |
| LATAM | Brazil (BR) |
| MEA | Bahrain (BH), South Africa (ZA), United Arab Emirates (AE) |
| North America | Canada (CA) |
Region availability can change. Always validate against Meta's current data_localization_region documentation before rollout.
Checking the current setting
Read it through the Runtime API with your dh_live_ key:
curl "https://api.dualhook.com/v25.0/<PHONE_NUMBER_ID>/settings" \
-H "Authorization: Bearer <DH_LIVE_KEY>"
"storage_configuration": {"status": "DEFAULT"} means Local Storage has never been enabled and Meta uses its default US storage. Once enabled, the response shows "status": "IN_COUNTRY_STORAGE_ENABLED" together with "data_localization_region": "<CODE>". This response is the evidence to keep for data protection records.
Enabling or changing Local Storage
Meta only accepts a Local Storage change while the phone number is deregistered from the Cloud API, so enabling it on a live number is a short maintenance step:
- Agree a time window with Dualhook support and pause outbound sends. The number cannot send or receive during the change; Meta states downtime is typically under five minutes.
- Dualhook deregisters the number from the Cloud API and applies the region on Meta's phone settings. Your connection, WABA, phone number ID, templates, webhook override, and
dh_live_key are unchanged. - You register the number again from the connection's Health Report ("Register phone number") with the number's six-digit two-step verification PIN. The PIN is forwarded to Meta by that action and is not stored; never send it to support. If nobody has it, reset two-step verification for the number in WhatsApp Manager first.
- Confirm the setting with the Runtime API read above and check that messaging and webhooks work.
Meta rate-limits registration and deregistration calls separately, each at 10 per number in a rolling 72 hours (error 133016 and a 72-hour lock beyond that), so plan a single pass. Disabling or changing the region later needs the same deregister, apply, register cycle.
Limitations once enabled
- Media uploaded by a localized number is only accessible to that number and cannot be reused by other phone numbers.
- Local Storage is not available on Coexistence numbers (the Deregister API is blocked there).
- Meta excludes localized numbers from its Cloud API availability and latency metrics because they run on separate storage infrastructure.
Stored and Collected Data
Cloud API stores and processes operational data needed for platform behavior. Published guidance describes temporary message retention up to 30 days for core functionality (such as retries and retransmissions).
Business identity and config data is managed in Meta business systems. Consumer identifiers used for delivery are processed for message routing.
GDPR and Shared Responsibility
Meta provides platform controls and documentation to support compliance. Each business remains responsible for its own legal compliance obligations (GDPR and other applicable laws).
Platform security controls do not replace your internal privacy, access-control, and retention policies.
Dualhook Security Model
Dualhook follows a stricter privacy boundary than what Cloud API requires:
- Message content is routed directly from Meta to your webhook endpoint via Webhook Override.
- Inbound message-path webhooks go directly from Meta to your endpoint and are not proxied by Dualhook.
- Outbound message and media payloads transit Dualhook's runtime without body persistence, caching, or content logging. Successful allowlisted phone/WABA metadata reads use a connection-isolated 60-second cache; message, media, template, profile, error, and mutation responses are never cached.
- Meta tokens, app secrets, generated proofs, Authorization headers, and credential-bearing Meta URLs are excluded from logs, persisted errors, analytics, and customer responses.
- Structured, quoted-JSON, and JSON-encoded error fields pass through the same credential sanitizer. The runtime preserves safe public Meta error fields while sanitizing non-success JSON before relay.
- Management responses use explicit projections; SIP credentials, encryption material, storage settings, callback configuration, and raw pagination URLs are removed even if Meta returns them unexpectedly.
- Customer-controlled webhook subscriptions or phone-level webhook overrides are not exposed. WABA routing and offboarding remain owned by Dualhook's existing lifecycle services.
- Dualhook stores only operational metadata needed for setup, monitoring, and compliance features.
See Compliance & Data Retention for retention windows and export options.
Operational Security Checklist
- Protect each connection's
dh_live_...key and rotate it from the connection Overview page. Dualhook does not expose its customer-scoped Meta authorization tokens. - Validate inbound webhook POSTs (envelope, WABA ID,
phone_number_id), keep the override URL high-entropy and private, and enforce HTTPS. See Messaging Webhook → Inbound Webhook POST Validation. - Use least-privilege roles for Meta portfolio and system users.
- Enable and manage two-step verification on business numbers.
- Monitor quality, account alerts, and security-related webhook events.
- Keep clear audit trails for template changes, number ownership, and webhook endpoint changes.