> ## 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.

# Introduction

# Webhooks

Webhooks allow you to receive real-time notifications when specific events occur in the Flabs system. Instead of repeatedly polling our API to check for updates, webhooks will automatically send HTTP POST requests to your specified endpoint whenever subscribed events happen.

## Overview

Webhooks are HTTP callbacks that Flabs sends to your application when certain events occur. This enables you to:

* Get instant notifications when bills or reports are completed
* Automate workflows based on bill lifecycle events
* Reduce API polling and improve system efficiency
* Build real-time integrations with the Flabs platform

## Supported Events

Flabs supports the following webhook events:

### Bill Events

* **`bill.created`** - Triggered when a new bill is created in the system
* **`bill.completed`** - Triggered when all reports in a bill are completed and the entire bill is finalized
* **`bill.deleted`** - Triggered when a bill is deleted from the system

### Report Events

* **`report.completed`** - Triggered when an individual report within a bill is completed

### CRM Events

* **`lead.created`** - Triggered when a lead is created in the CRM
* **`booking.created`** - Triggered when a booking is created (directly, or when a lead is converted to a booking)
* **`booking.phlebotomist_assigned`** - Triggered when a phlebotomist is assigned to the booking
* **`booking.phlebotomist_arrived`** - Triggered when the phlebotomist reaches the patient's location
* **`booking.phlebotomist_sample_collected`** - Triggered when the phlebotomist collects the sample from the patient
* **`booking.phlebotomist_sample_submitted`** - Triggered when the phlebotomist submits the collected sample back to the lab (this also **auto-creates the bill**, which triggers your `bill.created` event)
* **`booking.rescheduled`** - Triggered when the booking's scheduled date or time is changed
* **`booking.cancelled`** - Triggered when the booking is cancelled

<Note>
  Each bill consists of multiple reports. The `bill.completed` event is only
  triggered when all reports within that bill are finished, while
  `report.completed` is triggered for each individual report as it gets
  completed.
</Note>

CRM events carry a small `data` object instead of bill data:

```json theme={null}
{
  "labID": "lab_67890",
  "eventType": "lead.created",
  "eventTime": 1705747800,
  "integratorID": "EXT-LEAD-10231",
  "data": {
    "leadID": "6530a4a6f1d2c8b7e9a54321",
    "phase": "lead",
    "first_name": "Rahul"
  }
}
```

| Field             | Type   | Description                                       |
| ----------------- | ------ | ------------------------------------------------- |
| `data.leadID`     | string | Identifier of the lead/booking                    |
| `data.phase`      | string | `lead` or `booking`                               |
| `data.first_name` | string | Patient first name                                |
| `integratorID`    | string | The `integratorID` you sent on create (top level) |

<Note>
  The six `booking.*` lifecycle events (assigned through cancelled) fire **only for bookings created through the integration** — bookings that carry the `integratorID` you sent to [Create Lead or Booking](/crm/endpoint/create_lead). A booking created inside the Flabs CRM (with no `integratorID`) does **not** emit them.
</Note>

## Catch-all vs party-scoped

How webhooks are registered depends on your account mode (see [CRM integration modes](/crm/introduction)):

* **Catch-all (default):** register one webhook with **no party**. It receives every event for the lab.
* **Party-scoped (B2B):** for a doctor's CRM, a hospital portal, a wellness app, or a corporate health dashboard — register **one webhook per party** by attaching a `corporateUser` or `organization` when subscribing. Each webhook receives only that party's events. A party can have one active webhook per event. See [Party-scoped flow](/crm/party-scoped).

When reading or deleting webhooks on a party-scoped account, pass the same party so the call only touches that party's webhooks.

## Security Requirements

* **HTTPS Only**: All webhook endpoints must use HTTPS protocol for security
* **Authentication**: Bearer token authentication is required to register webhooks
* **Endpoint Validation**: Your webhook endpoint must be publicly accessible and return appropriate HTTP status codes

## Webhook Payload Structure

When an event occurs, Flabs will send a POST request to your registered endpoint with the following structure:

```json theme={null}
{
  "labID": "lab_67890",
  "eventType": "bill.completed",
  "eventTime": 1705747800,
  "data": {
    "billID": "bill_12345",
    "integratorID": "your_unique_integrator_id",
    "billData": {
      "status": "completed",
      "testData": [
        {
          "_id": "test_001",
          "status": "completed"
        },
        {
          "_id": "test_002",
          "status": "completed"
        }
      ]
    },
    "reportURL": "https://reports.flabs.in/bill/bill_12345",
    "sampleImages": [
      {
        "url": "https://flabs-lab.s3.ap-south-1.amazonaws.com/sample/sample-image-1.jpg",
        "lat": 19.076,
        "lng": 72.8777,
        "capturedAt": "2024-01-20T07:52:14.318Z"
      },
      {
        "url": "https://flabs-lab.s3.ap-south-1.amazonaws.com/sample/sample-image-2.jpg",
        "lat": null,
        "lng": null,
        "capturedAt": "2024-01-20T07:53:02.771Z"
      }
    ]
  }
}
```

### Payload Fields

| Field                             | Type           | Description                                                                                                                                                                           |
| --------------------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `labID`                           | string         | Unique identifier for the laboratory                                                                                                                                                  |
| `eventType`                       | string         | Type of event (bill.created, bill.completed, bill.deleted, report.completed)                                                                                                          |
| `eventTime`                       | integer        | Unix timestamp when the event occurred                                                                                                                                                |
| `data.billID`                     | string         | Unique identifier for the bill                                                                                                                                                        |
| `data.integratorID`               | string         | Your unique integrator ID (set when creating bill via API)                                                                                                                            |
| `data.billData.status`            | string         | Current status of the bill                                                                                                                                                            |
| `data.billData.testData`          | array          | Array of test/report data within the bill                                                                                                                                             |
| `data.billData.testData[]._id`    | string         | Unique identifier for each test/report                                                                                                                                                |
| `data.billData.testData[].status` | string         | Status of individual test/report                                                                                                                                                      |
| `data.reportURL`                  | string         | URL to access the complete bill report                                                                                                                                                |
| `data.sampleImages`               | array          | `bill.completed` only. Geo-tagged sample-collection photos captured by the phlebotomist on bills created from a home-collection booking. Always present; `[]` when the bill has none. |
| `data.sampleImages[].url`         | string         | Public URL of the captured photo. Always present.                                                                                                                                     |
| `data.sampleImages[].lat`         | number \| null | Phlebotomist's latitude at capture time. `null` when GPS was unavailable.                                                                                                             |
| `data.sampleImages[].lng`         | number \| null | Phlebotomist's longitude at capture time. `null` when GPS was unavailable.                                                                                                            |
| `data.sampleImages[].capturedAt`  | string         | ISO 8601 timestamp recorded when the photo was saved to the booking.                                                                                                                  |

<Note>
  The `integratorID` field contains your unique identifier that you provide when
  creating a bill through the Create Bill API. This helps you correlate webhook
  events with your internal records.
</Note>

## Getting Started

1. **Get an Auth Token**: Use the [authentication endpoints](/auth/introduction) to obtain a Bearer token
2. **Register Your Webhook**: Use the [webhook registration endpoint](/webhooks/endpoint/register_webhook) to subscribe to events
3. **Handle Webhook Requests**: Implement an endpoint on your server to receive and process webhook notifications
4. **Verify Webhooks**: Validate incoming webhook requests using the optional auth token

## Best Practices

* Always respond with a `2xx` status code to acknowledge receipt
* Implement proper error handling and retry logic
* Use HTTPS endpoints for security
* Validate webhook authenticity using the auth token
* Process webhooks asynchronously to avoid timeouts
* Implement idempotency to handle duplicate deliveries

## Retry Policy

Webhook deliveries are subject to the following retry mechanism:

* Maximum of 3 retry attempts for failed deliveries
* 2-minute interval between each retry attempt
* After 3 failed retries, you must contact Flabs support to get that webhook event

<Warning>
  Ensure your webhook endpoint responds quickly (within 10 seconds) to avoid
  timeouts.
</Warning>
