> ## Documentation Index
> Fetch the complete documentation index at: https://developer.flabslis.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Events & Responses

> What Flabs sends for each WhatsApp event, and how your webhook must reply.

Each time a report or bill is sent from your lab, Flabs sends a `POST` with a JSON body to your webhook URL. An event is sent only where Flabs would send a WhatsApp anyway (WhatsApp is on for that message and the recipient has a phone number).

Like every Flabs webhook, the request carries `Content-Type: application/json` and, when your integration has an auth token, `Authorization: Bearer <token>`; check it to make sure the request came from Flabs.

## Body

| Field | Description |
| - | - |
| `eventType` | `report.send` or `bill.send` |
| `eventTime` | When Flabs delivered the event (Unix seconds); a retry carries the retry's time |
| `labID` | The branch that sent it |
| `integratorID` | Your `integratorID`, when the bill or lead was created through the API. **Omitted otherwise.** |
| `data.billID` | Flabs bill ID. **Same on every resend of this bill** (same as `bill.completed`'s `data.billID`). |
| `data.recipient` | Which message this is and who to send it to (see [Recipient](#recipient)) |
| `data.isB2B` | `true` when the bill is a B2B bill. **Only present on B2B bills.** |
| `data.patientData` | Patient details, plus the bill's `dispatchMode` |
| `data.variables` | The values for this message (see [Message values](#message-values)) |
| `data.total`, `data.paid`, `data.due` | Bill total, amount paid and amount due, as numbers (e.g. `1200`). **Only on the report due reminder.** |

### Identifying messages

Every **Send** click creates one event. These IDs never change, so a resend carries the same values:

| To identify… | Use |
| - | - |
| The bill | `data.billID` |
| The patient | `data.patientData.patientID` |
| The message | `data.billID` + `data.recipient.template` |

### Recipient

`data.recipient` tells you which message this is and who gets it. **Always send the WhatsApp to `recipient.countryCode` + `recipient.contact`**: `patientData` is always the patient, even when the message is for the doctor, B2B centre or phlebotomist.

| Field | Description |
| - | - |
| `type` | Who it is for: `patient`, `doctor`, `b2b` or `phlebotomist` |
| `template` | The message: `report`, `report_due`, `report_b2b`, `report_doctor`, `bill`, `patient_booking`, `phlebotomist_booking` or `patient_quotation`. Use it to pick the template; several messages share an `eventType`. |
| `contact` | Their phone number, without the dial code |
| `countryCode` | Their dial code, no `+` (`91` when not recorded) |

The recipient's name is in `patientData` (patient) or `variables` (`doctorName`, `b2bName`, `phlebotomistName`).

### Patient details

Always present; strings (blank when not recorded) except `dispatchMode`. Same format as the [`bill.completed`](/webhooks/events-response) webhook's `patientData` (without height, weight and date of birth), plus `patientID`.

| Field | Description |
| - | - |
| `patientID` | Lab's patient number, same on every bill |
| `designation`, `firstName`, `lastName` | Patient's title and name |
| `age`, `ageType` | e.g. `"32"`, `"year"` (`year`/`month`/`day`) |
| `gender` | `male`, `female` or `other` |
| `contact`, `country_code` | Patient's number and dial code (`91`, no `+`) |
| `email`, `address`, `uhid` | |
| `aadhaar_number`, `insurance_number` | If recorded |
| `ownerDesignation`, `ownerName` | Pet owner (veterinary labs); blank otherwise |
| `dispatchMode` | Dispatch modes set on the bill, e.g. `["WHATSAPP", "EMAIL"]` (`SMS`, `EMAIL`, `WHATSAPP`, `HARD_COPY`, `MANUAL_WHATSAPP`); the only non-string field |

### Message values

These are in `data.variables`, always in this order. Each message carries only the ones it needs.

| Key | Value |
| - | - |
| `doctorName` | Referring doctor's name (doctor message); their number is in `recipient` |
| `b2bName` | B2B centre's name (B2B message); its number is in `recipient` |
| `labName`, `labContact` | Your lab |
| `reportDate` | `DD-MM-YYYY` |
| `reportLink` | Report PDF |
| `reportWithLetterheadLink`, `reportWithoutLetterheadLink` | Both report versions (B2B message) |
| `billLink` | Bill PDF |
| `reportStatusLink` | Report tracking page |

For a "Check Report Status" button (`https://records.flabslis.com/report-status/{{1}}`), use `data.billID`.

## The five messages

| Message | `eventType` | `recipient.type` | `recipient.template` |
| - | - | - | - |
| Report to patient | `report.send` | `patient` | `report` |
| Report due reminder | `report.send` | `patient` | `report_due` |
| Report to B2B centre | `report.send` | `b2b` | `report_b2b` |
| Report to doctor | `report.send` | `doctor` | `report_doctor` |
| Bill to patient | `bill.send` | `patient` | `bill` |

Each goes to `recipient.countryCode` + `recipient.contact`.

<Tabs>
  <Tab title="Report to patient">
    Sent when the report is ready and the bill has no due. `reportLink` is the version the lab chose (with or without letterhead).

    ```json theme={null}
    {
      "eventType": "report.send",
      "eventTime": 1791286428,
      "labID": "64a1b2c3d4e5f60718293a4b",
      "data": {
        "billID": "64b2c3d4e5f60718293a4b5c",
        "recipient": { "type": "patient", "template": "report", "contact": "9876543210", "countryCode": "91" },
        "patientData": {
          "patientID": "261006001",
          "designation": "Mr.", "firstName": "Rahul", "lastName": "Sharma",
          "age": "32", "ageType": "year", "gender": "male",
          "contact": "9876543210", "email": "rahul@example.com", "address": "14 MG Road, Bengaluru",
          "country_code": "91", "aadhaar_number": "", "insurance_number": "", "uhid": "UH-90231",
          "ownerDesignation": "", "ownerName": "",
          "dispatchMode": ["WHATSAPP", "EMAIL"]
        },
        "variables": {
          "labName": "City Diagnostics",
          "labContact": "9876500000",
          "reportLink": "https://files.example.com/report/64b2c3d4e5f60718293a4b5c.pdf"
        }
      }
    }
    ```
  </Tab>

  <Tab title="Report due">
    Sent instead of the report when the bill has a due amount. The report is not included; `total`, `paid` and `due` give the amounts, so the message can say how much is pending.

    ```json theme={null}
    {
      "eventType": "report.send",
      "eventTime": 1791286500,
      "labID": "64a1b2c3d4e5f60718293a4b",
      "data": {
        "billID": "64b2c3d4e5f60718293a4b5c",
        "recipient": { "type": "patient", "template": "report_due", "contact": "9876543210", "countryCode": "91" },
        "patientData": {
          "patientID": "261006001",
          "designation": "Mr.", "firstName": "Rahul", "lastName": "Sharma",
          "age": "32", "ageType": "year", "gender": "male",
          "contact": "9876543210", "email": "", "address": "",
          "country_code": "91", "aadhaar_number": "", "insurance_number": "", "uhid": "",
          "ownerDesignation": "", "ownerName": "",
          "dispatchMode": ["WHATSAPP", "EMAIL"]
        },
        "variables": {
          "labName": "City Diagnostics",
          "labContact": "9876500000",
          "reportStatusLink": "https://records.flabslis.com/report-status/64b2c3d4e5f60718293a4b5c"
        },
        "total": 1200,
        "paid": 500,
        "due": 700
      }
    }
    ```
  </Tab>

  <Tab title="Report to B2B">
    Sent to the B2B centre, even when the bill has a due. Both letterhead versions are included. Only this message, and a bill sent for a B2B bill, carry `isB2B`.

    ```json theme={null}
    {
      "eventType": "report.send",
      "eventTime": 1791286600,
      "labID": "64a1b2c3d4e5f60718293a4b",
      "data": {
        "billID": "64b2c3d4e5f60718293a4b5c",
        "recipient": { "type": "b2b", "template": "report_b2b", "contact": "9000000000", "countryCode": "91" },
        "isB2B": true,
        "patientData": {
          "patientID": "261006001",
          "designation": "Mr.", "firstName": "Rahul", "lastName": "Sharma",
          "age": "32", "ageType": "year", "gender": "male",
          "contact": "9876543210", "email": "", "address": "",
          "country_code": "91", "aadhaar_number": "", "insurance_number": "", "uhid": "",
          "ownerDesignation": "", "ownerName": "",
          "dispatchMode": ["WHATSAPP", "EMAIL"]
        },
        "variables": {
          "b2bName": "Sunrise Clinic",
          "labName": "City Diagnostics",
          "reportWithLetterheadLink": "https://files.example.com/report/64b2c3d4e5f60718293a4b5c.pdf",
          "reportWithoutLetterheadLink": "https://files.example.com/report/64b2c3d4e5f60718293a4b5c-without-header.pdf"
        }
      }
    }
    ```
  </Tab>

  <Tab title="Report to doctor">
    Sent when the lab shares the report with the referring doctor.

    ```json theme={null}
    {
      "eventType": "report.send",
      "eventTime": 1791286700,
      "labID": "64a1b2c3d4e5f60718293a4b",
      "data": {
        "billID": "64b2c3d4e5f60718293a4b5c",
        "recipient": { "type": "doctor", "template": "report_doctor", "contact": "9811111111", "countryCode": "91" },
        "patientData": {
          "patientID": "261006001",
          "designation": "Mr.", "firstName": "Rahul", "lastName": "Sharma",
          "age": "32", "ageType": "year", "gender": "male",
          "contact": "9876543210", "email": "", "address": "",
          "country_code": "91", "aadhaar_number": "", "insurance_number": "", "uhid": "",
          "ownerDesignation": "", "ownerName": "",
          "dispatchMode": ["WHATSAPP", "EMAIL"]
        },
        "variables": {
          "doctorName": "Dr. Rao",
          "labName": "City Diagnostics",
          "reportDate": "06-10-2026",
          "reportLink": "https://files.example.com/report/64b2c3d4e5f60718293a4b5c.pdf"
        }
      }
    }
    ```
  </Tab>

  <Tab title="Bill to patient">
    Sent when the lab sends the bill.

    ```json theme={null}
    {
      "eventType": "bill.send",
      "eventTime": 1791294286,
      "labID": "64a1b2c3d4e5f60718293a4b",
      "data": {
        "billID": "64b2c3d4e5f60718293a4b5c",
        "recipient": { "type": "patient", "template": "bill", "contact": "9876543210", "countryCode": "91" },
        "patientData": {
          "patientID": "261006001",
          "designation": "Mr.", "firstName": "Rahul", "lastName": "Sharma",
          "age": "32", "ageType": "year", "gender": "male",
          "contact": "9876543210", "email": "", "address": "",
          "country_code": "91", "aadhaar_number": "", "insurance_number": "", "uhid": "",
          "ownerDesignation": "", "ownerName": "",
          "dispatchMode": ["WHATSAPP", "EMAIL"]
        },
        "variables": {
          "labName": "City Diagnostics",
          "labContact": "9876500000",
          "billLink": "https://files.example.com/bill/64b2c3d4e5f60718293a4b5c.pdf",
          "reportStatusLink": "https://records.flabslis.com/report-status/64b2c3d4e5f60718293a4b5c"
        }
      }
    }
    ```
  </Tab>
</Tabs>

## CRM messages

`booking.send`, `phlebotomist.send` and `quotation.send` are sent when a user clicks **WhatsApp** on a booking (patient or phlebotomist, in the CRM or the Bookings page) or on a CRM lead (quotation). The CRM's default texts are on the [Templates](/whatsapp/templates#crm-messages) page.

| Field | Description |
| - | - |
| `eventType` | `booking.send`, `phlebotomist.send` or `quotation.send` |
| `eventTime`, `labID` | As above |
| `data.leadID` | CRM lead / booking ID. Same on every resend. |
| `data.recipient` | As [above](#recipient): `type` is `patient` or `phlebotomist`; `template` is `patient_booking`, `phlebotomist_booking` or `patient_quotation` |
| `data.patientData` | Same structure as [above](#patient-details), from the lead, with `crmID` (the lead's CRM number) in place of `patientID` |
| `data.variables` | The CRM's default template values, all strings, camelCased from the CRM's template tokens (`{{tests_list}}` → `testsList`): `bookingDate`, `bookingTime`, `bookingType`, `company`, `corporateClient`, `testsList`, `packagesList`, `quotationLines`, `testNames`, `totalMrp`, `discount`, `totalPrice`, `labName`, `phlebotomistName`, `phlebotomistPhone`, `patientMapLink`. Each message carries the ones it has; blank when there is no value. Custom fields are not sent. |

| Event | `recipient.type` | `recipient.template` |
| - | - | - |
| `booking.send` | `patient` | `patient_booking` |
| `phlebotomist.send` | `phlebotomist` | `phlebotomist_booking` |
| `quotation.send` | `patient` | `patient_quotation` |

Each goes to `recipient.countryCode` + `recipient.contact`.

<Tabs>
  <Tab title="Patient Booking Confirmation">
    `booking.send`: sent when the user clicks **WhatsApp → Patient** on a booking.

    ```json theme={null}
    {
      "eventType": "booking.send",
      "eventTime": 1791364500,
      "labID": "64a1b2c3d4e5f60718293a4b",
      "data": {
        "leadID": "64c3d4e5f60718293a4b5c6d",
        "recipient": { "type": "patient", "template": "patient_booking", "contact": "9876543210", "countryCode": "91" },
        "patientData": {
          "crmID": "CRM-1042",
          "designation": "Mr.", "firstName": "Rahul", "lastName": "Sharma",
          "age": "32", "ageType": "year", "gender": "male",
          "contact": "9876543210", "email": "", "address": "14 MG Road, Bengaluru",
          "country_code": "91", "aadhaar_number": "", "insurance_number": "", "uhid": "",
          "ownerDesignation": "", "ownerName": "",
          "dispatchMode": ["SMS", "EMAIL"]
        },
        "variables": {
          "bookingDate": "8 Oct 2026",
          "bookingTime": "08:00 am",
          "bookingType": "Home Collection",
          "company": "",
          "corporateClient": "",
          "testsList": "• Complete Blood Count (CBC) — ₹300",
          "packagesList": "",
          "quotationLines": "Tests:\n• Complete Blood Count (CBC) — ₹300",
          "testNames": "Complete Blood Count (CBC)",
          "totalMrp": "300",
          "discount": "",
          "totalPrice": "300",
          "labName": "City Diagnostics",
          "phlebotomistName": "Harsh Sharma",
          "phlebotomistPhone": "9811122233",
          "patientMapLink": "https://maps.google.com/?q=12.9716,77.5946"
        }
      }
    }
    ```
  </Tab>

  <Tab title="Phlebotomist Booking Details">
    `phlebotomist.send`: sent when the user clicks **WhatsApp → Phlebotomist** on a booking. `recipient` is the phlebotomist.

    ```json theme={null}
    {
      "eventType": "phlebotomist.send",
      "eventTime": 1791364580,
      "labID": "64a1b2c3d4e5f60718293a4b",
      "data": {
        "leadID": "64c3d4e5f60718293a4b5c6d",
        "recipient": { "type": "phlebotomist", "template": "phlebotomist_booking", "contact": "9811122233", "countryCode": "91" },
        "patientData": {
          "crmID": "CRM-1042",
          "designation": "Mr.", "firstName": "Rahul", "lastName": "Sharma",
          "age": "32", "ageType": "year", "gender": "male",
          "contact": "9876543210", "email": "", "address": "14 MG Road, Bengaluru",
          "country_code": "91", "aadhaar_number": "", "insurance_number": "", "uhid": "",
          "ownerDesignation": "", "ownerName": "",
          "dispatchMode": ["SMS", "EMAIL"]
        },
        "variables": {
          "bookingDate": "8 Oct 2026",
          "bookingTime": "08:00 am",
          "bookingType": "Home Collection",
          "company": "",
          "corporateClient": "",
          "testsList": "• Complete Blood Count (CBC) — ₹300",
          "packagesList": "",
          "quotationLines": "Tests:\n• Complete Blood Count (CBC) — ₹300",
          "testNames": "Complete Blood Count (CBC)",
          "totalMrp": "300",
          "discount": "",
          "totalPrice": "300",
          "labName": "City Diagnostics",
          "phlebotomistName": "Harsh Sharma",
          "phlebotomistPhone": "9811122233",
          "patientMapLink": "https://maps.google.com/?q=12.9716,77.5946"
        }
      }
    }
    ```
  </Tab>

  <Tab title="Patient Quotation">
    `quotation.send`: sent when the user clicks **Share Quotation to Patient** on a CRM lead. Booking values are not included.

    ```json theme={null}
    {
      "eventType": "quotation.send",
      "eventTime": 1791364649,
      "labID": "64a1b2c3d4e5f60718293a4b",
      "data": {
        "leadID": "64c3d4e5f60718293a4b5c6d",
        "recipient": { "type": "patient", "template": "patient_quotation", "contact": "9876543210", "countryCode": "91" },
        "patientData": {
          "crmID": "CRM-1042",
          "designation": "Mr.", "firstName": "Rahul", "lastName": "Sharma",
          "age": "32", "ageType": "year", "gender": "male",
          "contact": "9876543210", "email": "", "address": "14 MG Road, Bengaluru",
          "country_code": "91", "aadhaar_number": "", "insurance_number": "", "uhid": "",
          "ownerDesignation": "", "ownerName": "",
          "dispatchMode": ["SMS", "EMAIL"]
        },
        "variables": {
          "company": "",
          "corporateClient": "",
          "testsList": "• Complete Blood Count (CBC) — ₹300",
          "packagesList": "",
          "quotationLines": "Tests:\n• Complete Blood Count (CBC) — ₹300",
          "testNames": "Complete Blood Count (CBC)",
          "totalMrp": "300",
          "discount": "",
          "totalPrice": "300",
          "labName": "City Diagnostics"
        }
      }
    }
    ```
  </Tab>
</Tabs>

## Your response

Flabs reads **only the HTTP status code**. The body is ignored. Reply within **10 seconds**.

| Situation | Reply with | What Flabs does |
| - | - | - |
| Your provider accepted the WhatsApp | `200` (any `2xx`) | Nothing more |
| Your provider failed / template rejected | `500` (any non-`2xx`) | Retries, like every webhook (see [Retry Policy](/webhooks/introduction#retry-policy)) |
| No reply within **10 seconds** | — | Retries, like every webhook |

<CodeGroup>
  ```http Success theme={null}
  HTTP/1.1 200 OK
  Content-Type: application/json

  { "success": true }
  ```

  ```http Failure theme={null}
  HTTP/1.1 500 Internal Server Error
  Content-Type: application/json

  { "success": false, "message": "Provider rejected the template" }
  ```
</CodeGroup>

Flabs does **not** fall back to the Flabs number or AiSensy for a subscribed message: your webhook is the only sender. Reply `200` only after your provider accepted the message, and quickly. A retry carries the same `data` as the first attempt, so a late or failed reply after you already sent it means the patient gets it twice unless you skip repeats. For CRM messages, the user sees **Sent to your WhatsApp provider** once the event is queued. To stop, [delete the webhook](/whatsapp/register-webhook#remove-or-change).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.