Flow Endpoints, RSA Encryption & Dynamic Routing
Dynamic WhatsApp Flows require an encrypted HTTPS endpoint to exchange data between WhatsApp user screens and your business backend in real time.
This guide details the cryptographic requirements (Data API v3.0), the action lifecycle protocol (INIT, data_exchange, BACK, and ping), and SMSPort's automated key management.
1. Cryptography Architecture (Data API v3.0)
Every request from WhatsApp to your endpoint is encrypted using a hybrid cryptosystem:
- Asymmetric Layer (RSA-OAEP-2048):
- Your business creates an RSA-2048 keypair.
- The public key is uploaded and registered with Meta for your sender phone number.
- WhatsApp encrypts a newly generated 128-bit AES symmetric key using your RSA public key with SHA-256 and MGF1 padding.
- Symmetric Layer (AES-GCM-128):
- The user's screen submission data is encrypted using AES-128-GCM with a 12-byte initialization vector (IV) and a 16-byte authentication tag.
- Response Encryption:
- To send data back to WhatsApp, your endpoint encrypts the JSON response using the same AES key and an inverted bitwise IV (
IV ^ 0xFF).
- To send data back to WhatsApp, your endpoint encrypts the JSON response using the same AES key and an inverted bitwise IV (
2. Dynamic Action Lifecycle Protocol
Your HTTPS endpoint must handle 4 primary action types dispatched in the decrypted JSON payload:
{
"version": "3.0",
"action": "data_exchange",
"screen": "APPOINTMENT",
"data": {
"department": "cardiology"
},
"flow_token": "usr_94208a7b_token"
}1. `INIT` Action
Triggered when a user opens a Flow that has endpoint mode enabled:
- Server Responsibility: Return default options, dynamic user greeting, and first screen layout data.
- Response: Next screen name (
screen: "DETAILS") and initialdatadictionary.
2. `data_exchange` Action
Triggered when a user clicks a button or footer with "on-click-action": { "name": "data_exchange" }:
- Server Responsibility: Validate submitted inputs (e.g., credit score, appointment date availability), run database lookups, and return the next screen.
- Response: Return the target screen and updated dynamic options.
3. `BACK` Action
Triggered when a user taps the client header back arrow on a screen configured with "refresh_on_back": true:
- Server Responsibility: Re-fetch dynamic availability without storing form mutations.
4. `ping` Health Check Action
WhatsApp automatically pings your endpoint to monitor uptime and health:
- Server Request:
{"action": "ping"} - Mandatory Response:
{"data": {"status": "active"}}(Must return HTTP 200 within 10 seconds).
3. SMSPort Automated Key Management
SMSPort eliminates manual OpenSSL CLI operations through its built-in encryption service:
- One-Click Key Generation:
- In
/whatsapp-flows, open Flow Details > Encryption & Endpoints. - Click Generate Keypair to automatically generate a compliant RSA-2048 key in the database.
- In
- Automatic Meta Registration:
- Click Register Public Key to transmit your PEM certificate to Meta's Graph API (
/{phone_number_id}/whatsapp_business_encryption).
- Click Register Public Key to transmit your PEM certificate to Meta's Graph API (
- Built-in Decryption & Routing Engine:
- Incoming webhook payloads to
/webhooks/meta/whatsapp/flows/:flowId/exchangeare decrypted, processed, and re-encrypted seamlessly.
- Incoming webhook payloads to
4. Media Upload CDN Handling & Decryption (Flow 4.0+)
When a user submits files via PhotoPicker or DocumentPicker, WhatsApp encrypts each file before uploading to WhatsApp's MMG CDN. Your business endpoint or Cloud API response receives a payload containing CDN download URLs alongside AES-256 decryption keys and HMAC authentication parameters:
Media Payload Schema
{
"signed_contract": [
{
"cdn_url": "https://mmg.whatsapp.net/v/t62.7119-24/31415926_...",
"encryption_metadata": {
"encryption_key": "dGVzdF9hZXNfMjU2X2tleV9leGFtcGxlMTIzNDU2Nzg5MDE=",
"iv": "ZXhhbXBsZV9pdl8xNmJ5dGU=",
"hmac_key": "dGVzdF9obWFjXzMyYnl0ZV9rZXlfZXhhbXBsZTEyMzQ1Njc4",
"plaintext_hash": "c2hhMjU2X3BsYWludGV4dF9oYXNoX2V4YW1wbGVfMTIzNDU2",
"encrypted_hash": "c2hhMjU2X2VuY3J5cHRlZF9oYXNoX2V4YW1wbGVfMTIzNA=="
}
}
]
}Decryption Algorithm (AES-256-CBC + HMAC-SHA256)
To decrypt uploaded user files, execute the following cryptographic pipeline:
- Download Ciphertext: Issue an HTTP GET request to
cdn_urland download the raw bytes into a buffer. - Verify Encrypted Hash: Calculate the SHA-256 hash of the downloaded buffer and confirm it matches Base64-decoded
encrypted_hash. - Split Ciphertext and HMAC Signature:
- In WhatsApp MMG files, the last 10 bytes of the downloaded buffer represent the truncated HMAC-SHA256 signature (
mac_tag). - The preceding bytes (
buffer.subarray(0, buffer.length - 10)) represent the actual encrypted payload (file_ciphertext).
- In WhatsApp MMG files, the last 10 bytes of the downloaded buffer represent the truncated HMAC-SHA256 signature (
- Authenticate HMAC:
- Compute HMAC-SHA256 over
(iv + file_ciphertext)using Base64-decodedhmac_key. - Take the first 10 bytes of this computed HMAC and compare against
mac_tag. Reject if mismatch.
- Compute HMAC-SHA256 over
- Decrypt AES-256-CBC:
- Decrypt
file_ciphertextusing AES-256-CBC with Base64-decodedencryption_keyandiv. - Remove PKCS#7 padding to recover the raw file bytes.
- Decrypt
- Verify Plaintext Integrity:
- Compute SHA-256 of the decrypted bytes and verify it matches Base64-decoded
plaintext_hash.
- Compute SHA-256 of the decrypted bytes and verify it matches Base64-decoded
- Storage:
- Save or stream the plaintext buffer directly to your S3 bucket or local document archive.