Use Tab, then Enter to open a result.
WhatsApp Flows allow businesses to create structured, app-like experiences within the chat interface. These flows often require dynamic data that exists outside the WhatsApp ecosystem. Synchronous endpoint callbacks provide the mechanism to fetch this data. When a user interacts with a flow, the flow sends a request to your server. Your server processes the logic and returns a response. The flow then updates its UI based on that data. This interaction happens in real time.
Building these integrations requires a solid understanding of the data_exchange action. You must handle encryption, process JSON payloads, and manage latency. This article provides the technical blueprint for establishing these connections.
Understanding the Synchronous Callback Architecture
A synchronous callback is a blocking operation within a WhatsApp Flow. When a flow hits an endpoint, the user sees a loading indicator. The flow waits for your server to respond before moving to the next screen or updating the current one. This differs from asynchronous webhooks which do not block the user interface.
The core of this system is the data_exchange action. You define this action in the Flow JSON. It tells WhatsApp to send a POST request to your configured URL. This request contains a payload with user input and flow state information. Your server must decrypt this payload, perform necessary database or API lookups, and send back an encrypted JSON response.
Prerequisites for API Integration
Before implementing the logic, ensure you have the following components ready.
- Meta Business Account: You need access to the WhatsApp Business Platform.
- Verified Webhook URL: An HTTPS endpoint that is publicly accessible. Meta requires valid SSL certificates.
- Encryption Keys: A public and private RSA key pair. You upload the public key to the Meta developer portal. You keep the private key on your server to decrypt requests.
- Flow Template: A defined Flow JSON structure with screens and components.
- Backend Environment: A server capable of handling POST requests and performing RSA decryption. Node.js, Python, and Go are common choices.
Implementing the Data Exchange Action
The implementation starts in the Flow JSON definition. You attach the data_exchange action to a component, such as a button or a screen's on-enter event.
Defining the Action in JSON
In your Flow JSON, use the following structure to trigger a callback. The flow_token acts as a unique identifier for the session.
{
"name": "data_exchange",
"payload": {
"flow_token": "session_id_12345",
"action": "ping",
"data": {
"user_selection": "${form.choice_field}"
}
}
}
When the user triggers this action, WhatsApp sends a request to your endpoint. The action field helps your server identify which logic to execute. Use the data object to pass specific form inputs to your API.
Handling the Server-Side Request
Your server receives a POST request with a specific header and a body containing an encrypted payload. The header X-Hub-Signature-256 ensures the request comes from Meta. However, for WhatsApp Flows, the primary security layer is the asymmetric encryption of the payload itself.
Decrypting the Request
Meta encrypts the payload using a unique session key. They then encrypt that session key with your public RSA key. Your server must perform these steps:
- Extract the encrypted session key and the encrypted payload.
- Decrypt the session key using your private RSA key.
- Use the decrypted session key to decrypt the payload via AES-GCM.
Here is a conceptual implementation using Node.js and the standard crypto library.
const crypto = require('crypto');
function decryptPayload(encryptedData, privateKey) {
const { encrypted_aes_key, initial_vector, ciphertext, tag } = encryptedData;
// Decrypt the AES key with your RSA private key
const aesKey = crypto.privateDecrypt(
{ key: privateKey, padding: crypto.constants.RSA_PKCS1_OAEP_PADDING },
Buffer.from(encrypted_aes_key, 'base64')
);
// Decrypt the payload with the AES key
const decipher = crypto.createDecipheriv(
'aes-128-gcm',
aesKey,
Buffer.from(initial_vector, 'base64')
);
decipher.setAuthTag(Buffer.from(tag, 'base64'));
let decrypted = decipher.update(ciphertext, 'base64', 'utf8');
decrypted += decipher.final('utf8');
return JSON.parse(decrypted);
}
Structuring the API Response
After processing the data, your server must return a response. The response must follow a specific JSON structure. This response tells the flow what to do next. You can update the data on the current screen or tell the flow to navigate to a new screen.
Standard Response Format
{
"version": "3.0",
"screen": "SUCCESS_SCREEN",
"data": {
"order_status": "In Transit",
"delivery_date": "2023-11-25",
"items": [
{ "name": "Wireless Mouse", "price": "25.00" },
{ "name": "USB-C Cable", "price": "12.00" }
]
}
}
If the server logic fails, return an error object. The flow will handle this error based on your configuration.
Practical Example: Real-Time Inventory Check
A retail business uses a WhatsApp Flow for customers to check product availability. The customer enters a product ID. The flow sends a synchronous callback to the business database.
- User Input: The user types
PROD-99in a text input field. - Callback Trigger: On button click, the flow sends
PROD-99to the API. - API Logic: The server queries the SQL database. It finds that 5 units are available in the local warehouse.
- Flow Update: The server returns the availability count. The flow transitions to a screen showing "5 units available" and an "Add to Cart" button.
This integration prevents users from trying to buy out-of-stock items. It reduces friction and improves the customer experience.
Managing Latency and Timeouts
WhatsApp Flows have a strict timeout of 10 seconds for synchronous callbacks. If your server takes longer, the flow displays a generic error. This kills the user session.
Follow these rules to maintain performance:
- Optimize Database Queries: Use indexing on fields frequently queried by flows.
- External API Caching: If your server calls another third-party API, cache the results if the data does not change every second.
- Minimize Payload Size: Do not send unnecessary data back to the flow. Large payloads increase decryption time and network latency.
- Use Regional Servers: Host your endpoint in a data center close to Meta's infrastructure to reduce round-trip time.
Error Handling and Debugging
Debugging encrypted payloads is difficult. During the development phase, log the decrypted payloads to a secure logging service. This allows you to verify the data structure coming from Meta.
Common issues include:
- Mismatched Screen Names: If your response references a screen name that does not exist in the JSON, the flow crashes.
- JSON Type Errors: Sending a string where the flow expects an array of objects causes UI rendering failures.
- Encryption Failures: Ensure the RSA padding matches the Meta specification exactly. Small deviations lead to decryption errors.
The Role of WASenderApi in Development
While official WhatsApp Flows require the Meta Business API, developers often use tools like WASenderApi to manage the broader messaging lifecycle. WASenderApi allows for session management and message sending via a standard WhatsApp account.
In a complex architecture, you might use WASenderApi to trigger the initial flow message. For example, a script monitors a database. When a new lead appears, WASenderApi sends a message containing the flow button. The user then interacts with the official Meta Flow. This hybrid approach allows for flexible automation while leveraging the native UI capabilities of Meta's official platform. Keep in mind that official flows still require an official WABA (WhatsApp Business Account) for the flow execution itself.
Advanced Security: Signature Verification
Beyond payload encryption, verify the request signature. Meta sends a signature in the headers. Use your App Secret to generate a local HMAC SHA256 hash of the raw request body. Compare your hash with the one in the header. If they do not match, discard the request. This prevents unauthorized entities from sending fake data to your server.
Integration Testing Workflow
Testing a synchronous callback requires a live environment. You cannot test this on a local host without a tunnel. Use tools like Ngrok or Cloudflare Tunnels to expose your local development server to the internet.
- Start the tunnel and copy the HTTPS URL.
- Update the Flow configuration in the Meta Developer Portal with the tunnel URL.
- Use a test phone number to trigger the flow.
- Observe the terminal logs for the incoming POST request.
- Verify the decryption logic and the returned response.
Frequently Asked Questions
Can I use synchronous callbacks for long-running processes?
No. Synchronous callbacks are for immediate data retrieval. For processes taking longer than 10 seconds, use an asynchronous pattern. Let the user finish the flow, then send a message later using the API once the process completes.
Is it possible to bypass encryption for testing?
No. Meta mandates encryption for all WhatsApp Flow data exchanges. You must implement the RSA and AES logic even during the initial development phase.
How many data exchange actions can a single flow have?
There is no strict limit on the number of actions. However, every action adds potential latency. Minimize callbacks to keep the user experience smooth.
What happens if my server is down?
If the server does not respond or returns a 500 error, the flow displays a message to the user saying the service is unavailable. Always design your flow to handle these states gracefully by providing a fallback contact method.
Can I send media files through a synchronous callback?
Synchronous callbacks primarily handle JSON data. To show images or documents in a flow, send the URL of the media in the JSON response. The flow UI components then render the media from those URLs.
Next Steps for Developers
After successfully implementing a synchronous callback, focus on state management. Use the flow_token to track user progress across multiple callbacks. Ensure your database updates happen atomically to prevent data corruption during concurrent flow sessions. Once the logic is stable, monitor your API performance metrics to ensure the 10-second window is always respected. Moving from static flows to dynamic, API-driven flows significantly increases the utility of WhatsApp as a business tool.