WhatsApp Flow Endpoint Implementation Guide

Getting Started

WhatsApp Flow Endpoint is an HTTPS endpoint that receives requests from our service when users interact with Flows. Our service will make requests to Flows with Endpoints to achieve dynamic Flow loading or to obtain user operation data.

Basic Requirements

  • HTTPS Endpoint: Must be a publicly accessible HTTPS URL
  • POST Method: Endpoint must support POST requests
  • Response Time: Must respond within 15 seconds
  • JSON Processing: Handle plain JSON request and response payloads
  • Security: HTTPS ensures secure communication

Request Flow Overview

  1. User interacts with WhatsApp Flow
  2. Our service makes request to your endpoint
  3. Your endpoint processes the business logic
  4. Your endpoint returns JSON response
  5. Flow continues based on your response

Implement Endpoint Logic

Your endpoint needs to handle three main types of requests, distinguished by the action field:

Health Check Request

Health check requests are used to verify that your endpoint is working properly.

Request Payload Structure

{
  "action": "ping"
}

Processing Logic

  • When receiving action: "ping", simply return status confirmation
  • No complex business logic processing required
  • Mainly used by Meta platform to verify endpoint availability

Response

{
  "data": {
    "status": "active"
  }
}

Response Description:

  • status: Always return "active" to indicate the endpoint is working properly

Error Notification Request

When errors occur during Flow execution, our service sends error notification requests.

Request Payload Structure

{
  "version": "<VERSION>",
  "flow_token": "<FLOW-TOKEN>",
  "action": "data_exchange | INIT",
  "data": {
    "error": "<ERROR-KEY>",
    "error_message": "<ERROR-MESSAGE>"
  }
}

Processing Logic

  • Log error information for debugging and monitoring
  • Perform appropriate cleanup operations based on error type
  • Acknowledge receipt of error notification

Response

{
  "data": {
    "acknowledged": true
  }
}

Response Description:

  • acknowledged: Always return true to indicate error notification has been acknowledged
  • This is a confirmation response that you have processed the error notification

Data Exchange Request

Data exchange requests are the most important request type, containing user interaction data within the Flow.

Request Payload Structure

{
  "version": "3.0",
  "screen": "SCREEN_ID",
  "action": "INIT|data_exchange|BACK",
  "data": {
    // Screen data, structure depends on specific Flow design
    "field1": "value1",
    "field2": "value2",
    // ... other fields
  },
  "flow_token": "FLOW_TOKEN_STRING"
}

Field Description:

FieldRequiredTypeDescription
versionYesstringMust be set to "3.0"
screenYesstringCurrent screen ID. If action is set to INIT or BACK, this field may not be populated. Note: "SUCCESS" is a reserved name and cannot be used by any screens.
actionYesstringOperation type:
INIT: If the request is triggered when opening the Flow
data_exchange: If the request is triggered when submitting the screen
BACK: If the request is triggered when pressing "back"
dataYesobjectScreen form data or user input as JSON object. If action is set to INIT or BACK, this field may not be populated.
flow_tokenYesstringFlow session token generated by you as part of the Flow message

Processing Logic

Handle different action types accordingly:

INIT Operation:

if ("INIT".equals(action)) {
    // Initialize Flow, return initial screen data
    return initializeFlow(screen, data, flowToken);
}

data_exchange Operation:

if ("data_exchange".equals(action)) {
    // Process user submitted data, return next step operation
    return processDataExchange(screen, data, flowToken);
}

BACK Operation:

if ("BACK".equals(action)) {
    // Handle user going back to previous screen
    return handleBackNavigation(screen, data, flowToken);
}

Response

The response structure for data exchange requests should follow this format:

Standard Response Structure:

{
  "screen": "SCREEN_NAME",
  "data": {
    "key1": "value1",
    "key2": "value2"
  }
}

Example Response for Navigation:

{
  "screen": "NEXT_SCREEN",
  "data": {
    "user_name": "John Doe",
    "selected_option": "premium_plan",
    "total_amount": 99.99
  }
}

Response for Validation Errors:

{
  "screen": "CURRENT_SCREEN",
  "data": {
    "error_message": "Please check your input and try again"
  }
}

Flow Completion Response:

To trigger flow completion, send the following response:

{
  "screen": "SUCCESS",
  "data": {
    "extension_message_response": {
      "params": {
        "flow_token": "<FLOW_TOKEN>",
        "optional_param1": "<value1>",
        "optional_param2": "<value2>"
      }
    }
  }
}

Flow Completion Parameters:

ParameterRequiredTypeDescription
screenYesstringMust be set to "SUCCESS" to trigger flow completion
data.extension_message_response.paramsYesobjectA JSON object with data included in the flow completion message
data.extension_message_response.params.flow_tokenYesstringFlow token generated by business signifying a session or user flow
Additional optional parametersNoanyCan be included and will be forwarded to the response message webhook

As a result, the flow will be closed and a flow response message will be sent to the chat.

Implementation Example

Here's a general example of how to handle different request types in your endpoint:

@PostMapping("/flow-endpoint")
public ResponseEntity<Map<String, Object>> handleFlowRequest(
    @RequestBody Map<String, Object> request) {
    
    String action = (String) request.get("action");
    String screen = (String) request.get("screen");
    Map<String, Object> data = (Map<String, Object>) request.get("data");
    String flowToken = (String) request.get("flow_token");
    
    Map<String, Object> response = new HashMap<>();
    
    switch (action) {
        case "ping":
            response.put("data", Map.of("status", "active"));
            break;
            
        case "INIT":
            response = handleFlowInitialization(screen, data, flowToken);
            break;
            
        case "data_exchange":
            response = handleDataExchange(screen, data, flowToken);
            break;
            
        case "BACK":
            response = handleBackNavigation(screen, data, flowToken);
            break;
            
        default:
            response.put("screen", screen);
            response.put("data", Map.of("error_message", "Unknown action: " + action));
    }
    
    return ResponseEntity.ok(response);
}

private Map<String, Object> handleFlowInitialization(String screen, Map<String, Object> data, String flowToken) {
    // Initialize flow with default data
    Map<String, Object> response = new HashMap<>();
    response.put("screen", "WELCOME_SCREEN");
    response.put("data", Map.of("welcome_message", "Welcome to our service!"));
    return response;
}

private Map<String, Object> handleDataExchange(String screen, Map<String, Object> data, String flowToken) {
    // Process user input and determine next screen
    Map<String, Object> response = new HashMap<>();
    
    // Example: validate user input
    if (data.containsKey("email") && isValidEmail((String) data.get("email"))) {
        response.put("screen", "CONFIRMATION_SCREEN");
        response.put("data", Map.of("user_email", data.get("email")));
    } else {
        response.put("screen", screen); // Stay on current screen
        response.put("data", Map.of("error_message", "Please enter a valid email address"));
    }
    
    return response;
}

private Map<String, Object> handleBackNavigation(String screen, Map<String, Object> data, String flowToken) {
    // Handle back navigation
    Map<String, Object> response = new HashMap<>();
    response.put("screen", "PREVIOUS_SCREEN");
    response.put("data", new HashMap<>());
    return response;
}

Important Notes

  1. HTTPS Security: Ensure your endpoint uses HTTPS for secure communication
  2. Error Handling: Properly handle various exception scenarios
  3. Response Time: Ensure response within 15 seconds
  4. Logging: Log key operations for debugging and monitoring
  5. Data Validation: Validate received data format and content
  6. JSON Processing: Handle JSON parsing and serialization correctly

By correctly implementing these logics, your endpoint will be able to successfully handle various WhatsApp Flow requests and provide users with a smooth interactive experience.