Use Tab, then Enter to open a result.
Architecture of Real Time Interactions
WhatsApp Flows introduce a specific architectural requirement. You must choose between synchronous callbacks and asynchronous webhooks. Most developers treat these as interchangeable. They are not. A synchronous callback requires your server to process data and return a response within a strict window while the user waits on a loading screen. An asynchronous webhook follows the traditional fire and forget pattern where the server acknowledges receipt and processes the logic later.
Choosing the wrong pattern leads to session timeouts and a degraded user experience. In high volume environments, the overhead of RSA decryption for synchronous flows often becomes a bottleneck that standard webhook listeners do not face.
The Latency Problem
Meta enforces a 10 second timeout for synchronous callbacks. This sounds generous. In practice, it is a trap. That 10 second window includes the round trip time from the user device to Meta, from Meta to your server, your internal processing, and the return trip. If your server takes 4 seconds to query a database and 2 seconds to perform RSA decryption, you are approaching the danger zone.
Network jitter and cold starts for serverless functions consume the remaining buffer. If the response does not reach the device in time, the Flow displays a generic error. You lose the lead. You lose the transaction.
Asynchronous webhooks do not have this constraint. Meta expects a 200 OK response within a few seconds, but the user does not sit behind a blocked UI. You process the data in the background and send a follow up message when the work finishes.
Prerequisites for Implementation
Before implementing either pattern, ensure your stack meets these technical requirements:
- A validated WhatsApp Business Account (WABA).
- An endpoint protected by HTTPS with a valid TLS certificate.
- Libraries for RSA-2048 decryption and AES-128-GCM encryption.
- A high performance key-value store like Redis for state management.
- Logic to handle the
x-hub-signature-256header for webhook verification.
Synchronous Callback Implementation
Synchronous callbacks use the ENDPOINT action in the Flow JSON. Your server receives an encrypted payload. You must decrypt it, determine the next screen, and return a response containing the new screen data and an encrypted payload.
Decryption and Response Logic
This example demonstrates the structure of a synchronous handler using Node.js logic. Note the requirement to handle the specific payload structure defined by Meta.
const crypto = require('crypto');
function handleFlowCallback(requestBody, privateKey) {
const { encrypted_flow_data, encrypted_aes_key, initial_vector } = requestBody;
// Decrypt the AES key using your RSA private key
const decryptedAesKey = crypto.privateDecrypt(
{ key: privateKey, padding: crypto.constants.RSA_PKCS1_OAEP_PADDING },
Buffer.from(encrypted_aes_key, 'base64')
);
// Decrypt the payload using AES-GCM
const decipher = crypto.createDecipheriv(
'aes-128-gcm',
decryptedAesKey,
Buffer.from(initial_vector, 'base64')
);
// Processing logic goes here
const responseData = {
screen: 'SUCCESS_SCREEN',
data: {
appointment_id: '12345',
status: 'confirmed'
}
};
// Encrypt response before returning to Meta
return encryptResponse(responseData, decryptedAesKey, initial_vector);
}
Asynchronous Webhook Implementation
Asynchronous webhooks trigger after a Flow completes or at specific nodes if configured. The server receives the data and immediately returns a 200 OK. Use this for heavy lifting like generating PDFs, complex CRM syncs, or external API calls with high latency.
Webhook Data Structure
When a Flow completes, the submission arrives at your webhook as a standard message object. The button_reply or interactive object contains the Flow JSON data.
{
"object": "whatsapp_business_account",
"entry": [
{
"id": "WABA_ID",
"changes": [
{
"value": {
"messaging_product": "whatsapp",
"metadata": { "display_phone_number": "123456789", "phone_number_id": "987654321" },
"messages": [
{
"from": "USER_PHONE_NUMBER",
"id": "MESSAGE_ID",
"timestamp": "1670000000",
"type": "interactive",
"interactive": {
"type": "nfm_reply",
"nfm_reply": {
"name": "flow",
"response_json": "{\"selected_option\":\"plan_a\",\"user_email\":\"test@example.com\"}"
}
}
}
]
},
"field": "messages"
}
]
}
]
}
Performance Comparison and Trade Offs
Computation Overhead
Synchronous callbacks are computationally expensive. Every single transition that requires data from your server involves RSA decryption. If you have 1,000 users interacting with a Flow simultaneously, your CPU load will spike. Asynchronous webhooks often receive plain JSON or use simpler HMAC signatures. This reduces the compute cost per request.
Reliability and Retries
Meta does not retry synchronous callbacks. If your server is down or slow, the user sees an error and the interaction stops. Webhooks provide a safety net. Meta retries failed webhook deliveries with exponential backoff. This ensures that even if your database is temporarily locked, the user data eventually reaches your system.
Complexity and State
Synchronous callbacks allow you to maintain state within the Flow without an external database. You pass data from Screen A to Screen B through the callback response. Asynchronous webhooks require you to correlate the incoming data with a user record in your own database. This adds architectural complexity but improves long term data integrity.
Dealing with Third Party Providers
The uncomfortable truth about many WhatsApp API providers is their middleware latency. Many providers act as a proxy between Meta and your server. This adds two extra network hops. In a synchronous Flow, this overhead is often the difference between a successful transition and a timeout.
If you use a provider like WASenderApi, you gain the advantage of session management and easier onboarding. However, you must measure the latency of their webhook forwarding. If the provider takes 2 seconds to process the message before sending it to your endpoint, your effective budget for internal logic drops to 8 seconds. For high performance requirements, direct integration or low latency proxies are mandatory.
Edge Cases and Failure Modes
RSA Key Rotation
If you rotate your RSA keys in the Meta App Dashboard but do not update your server code immediately, all synchronous Flows will break. The decryption will fail. Use a configuration management system to sync keys across your infrastructure.
Payload Size Limits
Flow responses have size limits. Attempting to send a massive JSON object with hundreds of catalog items in a synchronous response will trigger a 413 error or a timeout. Use pagination or filter the data on the server side before responding.
Certificate Chain Issues
Meta requires a full certificate chain for webhook and callback endpoints. If your server only provides the leaf certificate and omits the intermediate CA, the connection will fail. Use tools like SSL Labs to verify your chain configuration.
Troubleshooting Guide
- Flow Error: "Something went wrong": This is the generic UI message for a timeout or decryption failure. Check your server logs for RSA padding errors. If no logs appear, Meta could not reach your endpoint. Verify your firewall allows Meta IP ranges.
- Slow Transitions: Profile your database queries. If a query takes more than 500ms, it is too slow for a Flow callback. Use Redis to cache frequently accessed data.
- Signature Mismatch: Ensure you are using the raw request body for HMAC verification. Express.js and other frameworks often parse the body into JSON, which changes the string and breaks the signature.
- Decryption Errors: Check the padding. Meta uses
RSA_PKCS1_OAEP_PADDING. If your library defaults toPKCS1_v1_5, the decryption will fail every time.
FAQ
Can I use both callbacks and webhooks in the same Flow? Yes. You use a synchronous callback to validate data between screens and an asynchronous webhook at the end of the Flow to trigger long running processes like invoice generation.
Does the 10 second timeout apply to the final submission? No. The final submission is usually handled by a webhook. The timeout applies to transitions where the user waits for the next screen to load based on your server response.
Is RSA decryption faster in specific languages? Languages with native C bindings like Node.js or Go handle RSA operations more efficiently than interpreted logic. For high scale, avoid performing these operations in heavy frameworks with significant overhead.
How do I test callbacks without a live WABA? Use the WhatsApp Business Cloud API sandbox or the Flow Builder preview tool. The preview tool allows you to point to a local tunnel like Ngrok to test your callback logic in real time.
Conclusion
Synchronous callbacks offer a seamless user experience but demand tight performance engineering. Asynchronous webhooks provide reliability and scalability at the cost of immediate UI feedback. For most lead generation tasks, use synchronous callbacks for validation and asynchronous webhooks for data storage. Monitor your decryption latency and keep your database queries lean to stay well within the 10 second limit. If your infrastructure cannot guarantee sub-second processing, move your logic to an asynchronous pattern to avoid losing users to timeout errors.