Sending

Form submissions

When a template carries a WhatsApp Flow, the person filling it in sends their answers back to you. Every submission is kept, announced by the flow.completed webhook, and readable here with any files they uploaded.

How a submission reaches you

  • You send a template with a flow button, with an optional template.flow.token of your own. See Send a message.
  • They open the form in WhatsApp, fill it in and submit.
  • We record it, match it to the message that carried the form, and POST flow.completed to your endpoint.
  • The same record is here, for reading back, catching up after downtime, or fetching an uploaded file.

Every endpoint on this page needs the flow_responses:read scope. It is separate from messages:read on purpose: the answers are whatever your customers typed, and a key that only sends or checks delivery should not be able to read them.

List them

shell
curl "https://sendrixbackend.exebee.com/v1/flow_responses?flow_token=lead-8812" \
  -H "Authorization: Bearer sk_live_..."
json
{
  "object": "list",
  "data": [
    {
      "id": "frs_7c2d4e1a-0b3f-4c5d-9e6f-1a2b3c4d5e6f",
      "object": "flow_response",
      "message_id": "msg_2a9c1f7e-4d3b-4a8e-b1c2-3d4e5f6a7b8c",
      "source_message_id": "msg_c16cead6-8385-481f-9e2e-e146d51f2738",
      "template_id": "tpl_cb9182c4-6e22-4095-bd26-a61c9f8d7fba",
      "flow_id": "1019982851061063",
      "flow_token": "lead-8812",
      "from": "919833663235",
      "response": {
        "screen_0_Full_name_0": "Asha Verma",
        "screen_0_City_1": "Pune",
        "photo_picker": [
          { "id": "3631120727156756", "file_name": "IMG_5237.jpg", "mime_type": "image/jpeg", "sha256": "..." }
        ]
      },
      "files": [
        { "index": 0, "field": "photo_picker", "file_name": "IMG_5237.jpg", "mime_type": "image/jpeg" }
      ],
      "created_at": "2026-09-15T12:50:44.000Z"
    }
  ],
  "limit": 50, "offset": 0, "total": 1, "has_more": false
}

Newest first.

ParameterEffect
flow_tokenOnly submissions carrying this token. The usual way to find the one for your own record.
source_message_idOnly submissions from forms that message carried.
template_idOnly submissions from forms sent with that template.
flow_idOnly submissions to that flow, by Meta's flow id.
created_after, created_beforeISO 8601 times. Handy for catching up on everything since your endpoint was last up.
limit, offsetPaging. Up to 100 per page.

The fields

FieldMeans
message_idThe inbound message the submission arrived as, in the person's conversation.
source_message_idThe message that carried the form. Null when it cannot be traced, for example a form sent outside Sendrix.
flow_tokenYours if you set template.flow.token. Otherwise one we made, starting sxf_.
responseThe answers, keyed exactly as the flow names its fields. The token is taken out.
filesFiles uploaded in the form. index is what you pass to fetch one.

Read one

shell
curl https://sendrixbackend.exebee.com/v1/flow_responses/frs_7c2d4e1a-0b3f-4c5d-9e6f-1a2b3c4d5e6f \
  -H "Authorization: Bearer sk_live_..."

The same shape as one entry in the list. The id is the one in the flow.completed webhook, so a receiver can read the full record straight from the event.

Fetch an uploaded file

shell
curl https://sendrixbackend.exebee.com/v1/flow_responses/frs_7c2d4e1a-0b3f-4c5d-9e6f-1a2b3c4d5e6f/files/0 \
  -H "Authorization: Bearer sk_live_..."
json
{
  "object": "file_link",
  "file_name": "IMG_5237.jpg",
  "mime_type": "image/jpeg",
  "url": "https://...",
  "expires_at": "2026-09-15T13:05:44.000Z"
}

url downloads the file and works for fifteen minutes. Ask again for a fresh one. It is not the file itself, so the response is small whatever the upload was.

Errors

CodeStatusMeans
insufficient_scope403The key does not hold flow_responses:read.
not_found404No submission with that id in this workspace, or no file at that index.
upstream_unavailable502WhatsApp would not hand over the file, most often because it is past 30 days.

Every code is listed on Errors.