Skip to main content

As interactive message

Send a flow in a user-initiated conversation (within the 24-hour window).
import { WhatsAppClient } from '@kapso/whatsapp-cloud-api';

const client = new WhatsAppClient({
  baseUrl: 'https://api.kapso.ai/meta/whatsapp',
  kapsoApiKey: process.env.KAPSO_API_KEY!
});

await client.messages.sendInteractiveFlow({
  phoneNumberId: '647015955153740',
  to: '15551234567',
  bodyText: 'Book your appointment',
  parameters: {
    flowId: '1197715005513101',
    flowCta: 'Book now',
    flowAction: 'navigate',
    flowActionPayload: {
      screen: 'BOOKING',
      data: { available_dates: ['2024-01-15', '2024-01-16'] }
    }
  }
});

As template message

Send a flow outside the 24-hour window using a message template with a FLOW button.

Create template

await client.templates.create({
  businessAccountId: '123456789',
  name: 'booking_flow',
  category: 'UTILITY',
  language: 'en_US',
  components: [
    {
      type: 'BODY',
      text: 'Ready to book your appointment?'
    },
    {
      type: 'BUTTONS',
      buttons: [
        {
          type: 'FLOW',
          text: 'Book now',
          flowId: '1197715005513101',
          flowAction: 'navigate',
          navigateScreen: 'BOOKING'
        }
      ]
    }
  ]
});

Send template

await client.messages.sendTemplate({
  phoneNumberId: '647015955153740',
  to: '15551234567',
  template: {
    name: 'booking_flow',
    language: { code: 'en_US' },
    components: [
      {
        type: 'button',
        subType: 'flow',
        index: '0',
        parameters: [
          {
            type: 'action',
            action: {
              flowToken: 'user_123_booking',
              flowActionData: {
                available_dates: ['2024-01-15', '2024-01-16']
              }
            }
          }
        ]
      }
    ]
  }
});

Parameters

ParameterDescription
flowIdThe unique ID of your published flow
flowCtaButton text (1-20 characters)
flowActionnavigate (default) or data_exchange
flowActionPayloadInitial screen and data to pass to the flow
flowTokenIdentifier for this flow session - see below

Flow token

The flowToken is a correlation ID. Meta sends it back with every data endpoint request and when the user completes the flow. Default behavior: If not provided, Kapso uses the flowId as the token. This is required for Kapso to automatically collect and store flow responses.
If you use a custom flowToken (different from the flowId), Kapso won’t be able to link responses to the flow. Only use a custom token if you’re handling responses yourself via the data endpoint.
When to customize:
  • You’re using a data endpoint and need to pass context (e.g., user ID, order ID)
  • You’re handling response tracking yourself
  • The token is available in every data endpoint request via data_exchange.flow_token

Receiving responses

When a user completes a flow, you receive a whatsapp.message.received webhook. The message has type: interactive with interactive.type: nfm_reply.
{
  "message": {
    "id": "wamid.ABC123...",
    "from": "15551234567",
    "timestamp": "1704067200",
    "type": "interactive",
    "interactive": {
      "type": "nfm_reply",
      "nfm_reply": {
        "name": "flow",
        "body": "Sent",
        "response_json": "{\"flow_token\":\"1197715005513101\",\"appointment_date\":\"2024-01-15\",\"appointment_time\":\"10:00\"}"
      }
    },
    "kapso": {
      "flow_response": {
        "flow_token": "1197715005513101",
        "appointment_date": "2024-01-15",
        "appointment_time": "10:00"
      },
      "flow_token": "1197715005513101",
      "flow_name": "flow"
    }
  }
}
The interactive.nfm_reply.response_json contains the raw JSON string from the flow’s final screen. Kapso parses this and adds:
FieldDescription
kapso.flow_responseParsed response data from the flow
kapso.flow_tokenThe flow token (matches flowId by default)
kapso.flow_nameAlways "flow" for WhatsApp Flows
To receive flow responses, subscribe to the whatsapp.message.received webhook event and filter for interactive.type === "nfm_reply".