# Integrate with AI Source: https://developer.flabslis.com/ai/integrate-with-ai Connect the Flabs docs MCP to your AI code editor and let it build the integration for you. Every page of this documentation is also available to AI coding assistants through our **Model Context Protocol (MCP) server**. Point your editor at it once, then ask your assistant to "integrate with Flabs" — it reads the live API reference, auth flow, schemas and webhook specs on demand and writes the integration code for you. MCP server URL:  `https://developer.flabslis.com/mcp` ## How it works ```mermaid theme={null} flowchart LR A[You ask your AI
“integrate with Flabs”] --> B[AI queries the
Flabs docs MCP] B --> C[Reads auth, CRM,
billing & webhook specs] C --> D[Writes the integration
code in your project] ``` The MCP exposes the same content you're reading now — the auth token flow, CRM lead/booking endpoints, the billing pre-booking API, webhook events and the OpenAPI specs — as structured, searchable context. Your assistant pulls only the pages it needs, so it generates code against the **current** API instead of guessing. ## 1. Add the MCP server to your editor Pick your tool. The server is a remote HTTP MCP — no install, no API key needed to read the docs. Add to `.cursor/mcp.json` in your project (or the global config): ```json theme={null} { "mcpServers": { "flabs-developer": { "url": "https://developer.flabslis.com/mcp" } } } ``` Run in your project directory: ```bash theme={null} claude mcp add --transport http flabs-developer https://developer.flabslis.com/mcp ``` Add to `.vscode/mcp.json`: ```json theme={null} { "servers": { "flabs-developer": { "type": "http", "url": "https://developer.flabslis.com/mcp" } } } ``` Add to `~/.codeium/windsurf/mcp_config.json`: ```json theme={null} { "mcpServers": { "flabs-developer": { "serverUrl": "https://developer.flabslis.com/mcp" } } } ``` Reload your editor so it picks up the new server. You should see a **flabs-developer** MCP with two tools: a docs **search** and a read-only docs **filesystem**. ## 2. Ask the AI to integrate Once the server is connected, describe what you want in plain language. The assistant will search the docs, read the relevant endpoints, and scaffold the code. A few prompts that work well: ```text theme={null} Using the flabs-developer MCP, add a Flabs integration to this project: authenticate with my client credentials, fetch my branches, and create a CRM lead. ``` ```text theme={null} Set up a webhook handler for Flabs bill.completed and report.completed events, following the payload structure in the flabs-developer docs. ``` ```text theme={null} I'm a corporate (party-scoped) account. Wire up test-pricing lookups and lead creation scoped to my corporateUser, per the Flabs party-scoped guide. ``` The assistant pulls the exact request/response shapes, required fields, rate limits and error codes from the docs — so the generated client matches the real API. The MCP only exposes **public documentation**. Never put your `clientID`, `clientSecret`, or tokens into prompts or commit them to source control — load them from environment variables or a secrets manager. See the [Authentication guide](/auth/introduction). ## What the assistant can build Token generation and refresh handling with your client credentials. Branch lookup, test/package pricing, and lead/booking creation. Create pre-bookings that kick off the lab workflow. Endpoints that react to bill, report and CRM events. ## Tips for better results * **Tell it your account mode.** Mention whether you're catch-all (default) or [party-scoped](/crm/party-scoped) so it scopes calls correctly. * **Name your stack.** "in Node/Express", "in Python/FastAPI", etc. produces idiomatic code. * **Ask it to verify against the docs.** "Double-check the required fields against the flabs-developer MCP" catches missed parameters before you run anything. ## Support Stuck or need credentials? Reach our team at **[hello@flabs.in](mailto:hello@flabs.in)** or **+91 7253928905**, Monday to Friday, 9 AM to 6 PM IST. # Auth Token Source: https://developer.flabslis.com/auth/endpoint/get_auth_token POST /client/auth/token Generates a new auth token and refresh token using client ID and client secret. # Refresh Auth Token Source: https://developer.flabslis.com/auth/endpoint/get_auth_token_refresh POST /client/auth/token/refresh Get new Authorization token using the refresh token and client credentials. # Authentication APIs Source: https://developer.flabslis.com/auth/introduction APIs for client authentication and token management Flabs Logo Light Flabs Logo Dark ## Overview Flabs authentication APIs allow you to securely authenticate clients and manage tokens for API access. Get auth tokens using client credentials Refresh your auth token when it expires ## Authentication Flow Our authentication system uses a two-token approach with a streamlined flow designed for security and efficiency: Authentication Flow Diagram ### Flow Breakdown 1. **Initial Authentication**: Use your Client ID and Client Secret to generate both an access token and refresh token 2. **Token Storage**: Store the refresh token securely in cache for future use 3. **API Access**: Use the access token (valid for 10 minutes) for all API requests 4. **Token Refresh**: When the access token expires, use the refresh token to generate a new access token without re-authentication 5. **Refresh Token Longevity**: The refresh token remains valid for 30 days of inactivity, eliminating the need for frequent re-authentication ### Key Benefits * **Access Token**: Valid for 10 minutes, used for API requests * **Refresh Token**: Expires after 30 days of inactivity; used to obtain new authentication tokens * **Seamless Experience**: No need to repeatedly provide credentials once authenticated All authentication tokens should be included in the Authorization header using the Bearer scheme. ## Getting Started To integrate with our authentication system: 1. Obtain client credentials (Client ID and Client Secret) 2. Generate an initial auth token using the [token endpoint](/auth/endpoint/get_auth_token) 3. Store both tokens securely 4. When the auth token expires, use the [refresh endpoint](/auth/endpoint/get_auth_token_refresh) to get the auth token again with logging again. # Create Pre-booking Source: https://developer.flabslis.com/billing/endpoint/create_bill POST /client/billing/create Create a pre-booking in the Flabs system with patient details and test/package information. This initiates the billing workflow. ## Overview Create a pre-booking in the Flabs system to initiate the laboratory workflow. This endpoint accepts patient details and test/package information to start the billing process. ## Authentication Requires a valid Bearer token from the [authentication API](/auth/endpoint/get_auth_token). ## Request Parameters ### Required Fields | Field | Type | Description | | ---------------------------- | ------- | ----------------------------------------------------------- | | `patient_details` | object | Patient information (required) | | `patient_details.first_name` | string | Patient's first name | | `patient_details.gender` | string | Patient's gender (`male`, `female`, `other`) | | `patient_details.age` | integer | Patient's age | | `patient_details.age_type` | string | Age unit (`year`, `month`, `day`) | | `integrator_id` | string | Your unique identifier for this booking | | `lead_source` | string | Source of the booking (contact Flabs for available sources) | ### Test/Package Requirements At least one of the following is required: | Field | Type | Description | | ------------------------------ | ----- | ---------------------------------------------------- | | `mapped_tests` | array | Tests mapped with Flabs (use `flabs_id` or `id`) | | `unmapped_tests` | array | Tests not mapped with Flabs | | `mapped_packages` | array | Packages mapped with Flabs (use `id` only) | | `unmapped_packages` | array | Packages not mapped with Flabs | | `unmapped_packages_with_tests` | array | Packages with associated tests not mapped with Flabs | ### Optional Fields | Field | Type | Description | | --------------------------- | ------ | --------------------------------------------------------------- | | `barCode` | string | Unique barcode identifier | | `patient_details.last_name` | string | Patient's last name | | `doctor` | string | Referring doctor ID (contact Flabs for the ID) | | `hospital` | string | Referring hospital ID (contact Flabs for the ID) | | `rate_list_type` | string | Rate list to apply for pricing (contact Flabs for valid values) | ## Important Notes * Patient details are mandatory with all required fields - At least one test or package array must be provided - Barcodes must be unique across the system * Contact Flabs team for available lead sources - Contact Flabs team for `doctor` / `hospital` IDs and valid `rate_list_type` values * Use `flabs_id` or `id` for mapped tests - Only `id` is available for mapped packages (no `flabs_id`) - The `preBookingID` in the response is used to track the booking through the workflow # Introduction Source: https://developer.flabslis.com/billing/introduction # Billing API The Billing API enables you to create pre-bookings in the Flabs system, initiating the complete laboratory workflow from booking to report delivery. ## Billing Workflow The billing process follows a structured workflow as shown below: Billing Flow ### Workflow Steps 1. **Your Platform** → **Pre Booking**: Call `/client/billing/create` API to create a pre-booking 2. **Pre Booking** → **Bill Creation**: Flabs creates a bill internally 3. **Bill Creation** → **Report Entry**: Laboratory processes samples and enters report data 4. **Report Entry** → **Report Approval**: Reports are reviewed and approved 5. **Webhook Notifications**: Receive real-time updates at each stage (if subscribed) ## Key Concepts ### Required Data * **Patient Details**: Basic patient information (name, age, gender) * **Integrator ID**: Your unique identifier for tracking * **Lead Source**: Source of the booking request * **Tests/Packages**: Either mapped (with Flabs IDs) or unmapped tests and packages ### Test and Package Mapping * **Mapped Tests**: Tests already synchronized between your system and Flabs * **Unmapped Tests**: Tests that need manual mapping by Flabs team * **Mapped Packages**: Package bundles with established Flabs IDs * **Unmapped Packages**: Package bundles requiring manual mapping ### Webhook Integration Subscribe to webhook events to receive notifications about: * `bill.created` - When bill is generated * `bill.completed` - When entire bill is processed * `report.completed` - When individual reports are ready ## Getting Started 1. **Authentication**: Obtain a Bearer token from [authentication endpoints](/auth/introduction) 2. **Create Pre-booking**: Use the [billing create endpoint](/billing/endpoint/create_bill) 3. **Subscribe to Webhooks**: Set up [webhook notifications](/webhooks/introduction) for status updates, and check the [event payloads](/webhooks/events-response) your endpoint will receive 4. **Track Progress**: Monitor bill status through webhook events ## Important Notes * At least one of the following is required: `mapped_tests`, `unmapped_tests`, `mapped_packages`, or `unmapped_packages` - Contact the Flabs team to add new lead sources or get additional field information - Barcodes must be unique across the system Ensure all required patient details are provided. Missing information may cause booking creation to fail. # Create Lead or Booking Source: https://developer.flabslis.com/crm/endpoint/create_lead POST /client/crm/lead/create Creates a CRM entry for the patient. Set `phase: "lead"` (default) to drop the entry into the lead funnel — it will be auto-assigned to a telecaller and trigger a `NEW_LEAD` notification. Set `phase: "booking"` to skip the lead stage and create a confirmed booking directly — it will trigger a `BOOKING_CONFIRMED` notification. # List Branches Source: https://developer.flabslis.com/crm/endpoint/list_branches GET /client/labs Returns every active branch under your account. Use the returned `branchID` for all other CRM calls. # List Packages Source: https://developer.flabslis.com/crm/endpoint/list_packages GET /client/crm/packages Returns every package offered by the given branch. Use the `_id` of a package as the `package` field when creating a lead or booking. The `total` returned reflects the pricing for the party you pass (`corporateUser` or `organization`); without a party it is the branch's standard price. Party-scoped accounts must pass a party. # List Tests Source: https://developer.flabslis.com/crm/endpoint/list_tests GET /client/crm/tests Returns every test offered by the given branch. Use the `_id` of a test as the `test` field when creating a lead or booking. The `cost` returned reflects the pricing for the party you pass (`corporateUser` or `organization`); without a party it is the branch's standard cost. Party-scoped accounts must pass a party. # CRM Source: https://developer.flabslis.com/crm/introduction Push leads and bookings into the Flabs CRM from your own funnels. The CRM API has four endpoints. Use them in this order: ```mermaid theme={null} flowchart TB A[POST /client/auth/token] B[GET /client/labs
pick a branchID] C[GET /client/crm/tests
?branchID=...] D[GET /client/crm/packages
?branchID=...] E[POST /client/crm/lead/create] F{phase} G[Telecaller picks it up
and converts it into a booking] H[Booking is scheduled
and shows up in the phlebo app] A --> B B --> C B --> D C --> E D --> E E --> F F -->|lead| G F -->|booking| H ``` ## Integration modes Your account runs in one of two modes. Most accounts use **catch-all** — this page covers it. If your business routes work per referring corporate, doctor, or hospital, use **party-scoped**. No party needed. Tests/packages return standard branch pricing, and one webhook receives every event for the lab. **This page.** For a doctor's CRM, a hospital portal, a wellness app, or a corporate health dashboard. Every lead, booking, and price is tied to a corporate / doctor / hospital, and each gets its own webhook. Enabled by Flabs — contact support. ## Endpoints Fetch the branches under your account. Fetch every test offered by a branch. Fetch every package offered by a branch. Create a CRM entry. Phase decides whether it's a lead or a booking. ## Lead vs Booking | | Lead (default) | Booking | | ----------------------- | -------------- | ------------------------------------------------------------------------ | | `phase` | `"lead"` | `"booking"` | | Auto-assign | ✅ telecaller | ❌ | | Notification | `NEW_LEAD` | `BOOKING_CONFIRMED` | | Required booking fields | – | `bookingType`, `scheduledAt` | | Defaults set by server | – | `bookingStatus: Scheduled`, `paymentStatus: Pending`, `convertedAt: now` | ## Rules to know * **`integratorID` is required** — every `create` call must include your own unique `integratorID` for the entry. It is stored on the lead/booking, carried onto the bill when it converts, and echoed back in webhooks so you can match events to your records. * **Branch scope** — every CRM call needs a `branchID`. Get it from `GET /client/labs`. * **Duplicates** — if a lead or booking with the same `contact` (or `email`) was already ingested **today** for your account, the API returns `409 Conflict`. * **Auto-assign** — runs only when `phase = "lead"` and `assignedTo` is not set in the body. Honours the strategy you've configured in CRM settings. * **Rate limit** — 60 requests/minute per account on every CRM endpoint. Fields not listed in the request schema are silently ignored. Send only what you need. # Party-scoped (B2B) Source: https://developer.flabslis.com/crm/party-scoped Build a doctor's CRM, a hospital portal, a wellness app, or a corporate health dashboard — every lead, booking, price, and webhook tied to a specific corporate, doctor, or hospital. Use this mode when you operate on behalf of **referring parties** — a corporate, a doctor, or a hospital — and each one needs its own pricing and its own event feed. Typical builders are **a doctor's CRM, a hospital portal, a wellness app, or a corporate health dashboard**, where every lead, booking, price, and webhook must stay scoped to one party. Party-scoped mode is enabled by Flabs for your account. [Contact support](mailto:hello@flabs.in) to turn it on. Until then your account behaves as [catch-all](/crm/introduction). ## What changes vs. catch-all In catch-all mode a party is optional. In party-scoped mode it is **mandatory** on every call that touches a price or creates an entry, and webhooks are split per party. | Step | Catch-all | Party-scoped | | --------------------- | ----------------------- | -------------------------------------------------------------- | | List tests / packages | Standard branch price | **Pass a party** → that party's negotiated price | | Create lead / booking | Party optional | **Must attach a party** | | Webhooks | One webhook for the lab | **One webhook per party**, events routed to the matching party | ## A party is one of | Field | Meaning | | ------------------------------ | ------------------------------------------------------------------ | | `corporateUser` | A corporate / company / TPA identifier | | `organization` | A doctor or hospital identifier (used on **tests/packages** calls) | | `referredOrganization` | Referring **doctor** (used on **lead/booking** create) | | `referredHospitalOrganization` | Referring **hospital** (used on **lead/booking** create) | Pass **one** party per call. On tests/packages use `corporateUser` **or** `organization`. On create you may attach a doctor, a hospital, and a corporate together. ## Flow ```mermaid theme={null} flowchart TB A[POST /client/auth/token] B[GET /client/labs
pick a branchID] C[GET /client/crm/tests
?branchID=...&corporateUser=... or &organization=...] D[GET /client/crm/packages
?branchID=...&corporateUser=... or &organization=...] E[POST /client/crm/lead/create
+ integratorID + a party] F[Register one webhook per party
POST /client/events/subscribe] G[Event fires → routed only to
that party's webhook] A --> B B --> C B --> D C --> E D --> E E --> G F --> G ``` ## 1. Get party-specific pricing Pass the party on the tests / packages calls. The returned `cost` / `total` is that party's negotiated rate; tests with no special rate fall back to the branch price. ```bash theme={null} GET /client/crm/tests?branchID=&corporateUser= GET /client/crm/packages?branchID=&organization= ``` ## 2. Create the lead or booking with a party Send your `integratorID` (always required) **and** at least one party. ```json theme={null} POST /client/crm/lead/create { "branchID": "6530a4a6f1d2c8b7e9a12345", "integratorID": "EXT-LEAD-10231", "phase": "lead", "first_name": "Rahul", "contact": "9876543210", "age": 32, "age_type": "year", "corporateUser": "6530a4a6f1d2c8b7e9acorp1", "tests": [{ "test": "6530a4a6f1d2c8b7e9aabcde", "cost": 350 }] } ``` Every party you pass is validated — it must exist and belong to the branch, otherwise you get `404`. ## 3. Register one webhook per party When subscribing, attach the party the webhook is for. Events for that party's bills/leads are delivered **only** to its webhook. ```json theme={null} POST /client/events/subscribe { "labID": "6530a4a6f1d2c8b7e9a12345", "events": ["bill.completed", "lead.created"], "endpoint": "https://corp-a.example.com/flabs/webhook", "protocol": "https", "corporateUser": "6530a4a6f1d2c8b7e9acorp1" } ``` See [Webhooks](/webhooks/introduction) for the event list, and [Events Response](/webhooks/events-response) for the exact payload each event delivers. ## Rules to know * **Party required** — tests/packages and create calls without a party return `400`. * **One per party** — a party can have only one active webhook per event; a duplicate returns `409`. * **Reading webhooks** — `GET /client/events/getAllEvents` and delete also take the party, and only act on that party's webhooks. * Everything else — `branchID` scope, same-day duplicate `409`, 60 req/min — works exactly like [catch-all](/crm/introduction). # Code Blocks Source: https://developer.flabslis.com/essentials/code Display inline code and code blocks ## Basic ### Inline Code To denote a `word` or `phrase` as code, enclose it in backticks (\`). ``` To denote a `word` or `phrase` as code, enclose it in backticks (`). ``` ### Code Block Use [fenced code blocks](https://www.markdownguide.org/extended-syntax/#fenced-code-blocks) by enclosing code in three backticks and follow the leading ticks with the programming language of your snippet to get syntax highlighting. Optionally, you can also write the name of your code after the programming language. ```java HelloWorld.java theme={null} class HelloWorld { public static void main(String[] args) { System.out.println("Hello, World!"); } } ``` ````md theme={null} ```java HelloWorld.java class HelloWorld { public static void main(String[] args) { System.out.println("Hello, World!"); } } ``` ```` # Images and Embeds Source: https://developer.flabslis.com/essentials/images Add image, video, and other HTML elements ## Image ### Using Markdown The [markdown syntax](https://www.markdownguide.org/basic-syntax/#images) lets you add images using the following code ```md theme={null} ![title](/path/image.jpg) ``` Note that the image file size must be less than 5MB. Otherwise, we recommend hosting on a service like [Cloudinary](https://cloudinary.com/) or [S3](https://aws.amazon.com/s3/). You can then use that URL and embed. ### Using Embeds To get more customizability with images, you can also use [embeds](/writing-content/embed) to add images ```html theme={null} ``` ## Embeds and HTML elements ``` # Markdown Syntax Source: https://developer.flabslis.com/essentials/markdown Text, title, and styling in standard markdown ## Titles Best used for section headers. ```md theme={null} ## Titles ``` ### Subtitles Best use to subsection headers. ```md theme={null} ### Subtitles ``` Each **title** and **subtitle** creates an anchor and also shows up on the table of contents on the right. ## Text Formatting We support most markdown formatting. Simply add `**`, `_`, or `~` around text to format it. | Style | How to write it | Result | | ------------- | ----------------- | ----------------- | | Bold | `**bold**` | **bold** | | Italic | `_italic_` | *italic* | | Strikethrough | `~strikethrough~` | ~~strikethrough~~ | You can combine these. For example, write `**_bold and italic_**` to get ***bold and italic*** text. You need to use HTML to write superscript and subscript text. That is, add `` or `` around your text. | Text Size | How to write it | Result | | ----------- | ------------------------ | ---------------------- | | Superscript | `superscript` | superscript | | Subscript | `subscript` | subscript | ## Linking to Pages You can add a link by wrapping text in `[]()`. You would write `[link to google](https://google.com)` to [link to google](https://google.com). Links to pages in your docs need to be root-relative. Basically, you should include the entire folder path. For example, `[link to text](/writing-content/text)` links to the page "Text" in our components section. Relative links like `[link to text](../text)` will open slower because we cannot optimize them as easily. ## Blockquotes ### Singleline To create a blockquote, add a `>` in front of a paragraph. > Dorothy followed her through many of the beautiful rooms in her castle. ```md theme={null} > Dorothy followed her through many of the beautiful rooms in her castle. ``` ### Multiline > Dorothy followed her through many of the beautiful rooms in her castle. > > The Witch bade her clean the pots and kettles and sweep the floor and keep the fire fed with wood. ```md theme={null} > Dorothy followed her through many of the beautiful rooms in her castle. > > The Witch bade her clean the pots and kettles and sweep the floor and keep the fire fed with wood. ``` ### LaTeX Mintlify supports [LaTeX](https://www.latex-project.org) through the Latex component. 8 x (vk x H1 - H2) = (0,1) ```md theme={null} 8 x (vk x H1 - H2) = (0,1) ``` # Navigation Source: https://developer.flabslis.com/essentials/navigation The navigation field in docs.json defines the pages that go in the navigation menu The navigation menu is the list of links on every website. You will likely update `docs.json` every time you add a new page. Pages do not show up automatically. ## Navigation syntax Our navigation syntax is recursive which means you can make nested navigation groups. You don't need to include `.mdx` in page names. ```json Regular Navigation theme={null} "navigation": { "tabs": [ { "tab": "Docs", "groups": [ { "group": "Getting Started", "pages": ["quickstart"] } ] } ] } ``` ```json Nested Navigation theme={null} "navigation": { "tabs": [ { "tab": "Docs", "groups": [ { "group": "Getting Started", "pages": [ "quickstart", { "group": "Nested Reference Pages", "pages": ["nested-reference-page"] } ] } ] } ] } ``` ## Folders Simply put your MDX files in folders and update the paths in `docs.json`. For example, to have a page at `https://yoursite.com/your-folder/your-page` you would make a folder called `your-folder` containing an MDX file called `your-page.mdx`. You cannot use `api` for the name of a folder unless you nest it inside another folder. Mintlify uses Next.js which reserves the top-level `api` folder for internal server calls. A folder name such as `api-reference` would be accepted. ```json Navigation With Folder theme={null} "navigation": { "tabs": [ { "tab": "Docs", "groups": [ { "group": "Group Name", "pages": ["your-folder/your-page"] } ] } ] } ``` ## Hidden Pages MDX files not included in `docs.json` will not show up in the sidebar but are accessible through the search bar and by linking directly to them. # Reusable Snippets Source: https://developer.flabslis.com/essentials/reusable-snippets Reusable, custom snippets to keep content in sync One of the core principles of software development is DRY (Don't Repeat Yourself). This is a principle that apply to documentation as well. If you find yourself repeating the same content in multiple places, you should consider creating a custom snippet to keep your content in sync. ## Creating a custom snippet **Pre-condition**: You must create your snippet file in the `snippets` directory. Any page in the `snippets` directory will be treated as a snippet and will not be rendered into a standalone page. If you want to create a standalone page from the snippet, import the snippet into another file and call it as a component. ### Default export 1. Add content to your snippet file that you want to re-use across multiple locations. Optionally, you can add variables that can be filled in via props when you import the snippet. ```mdx snippets/my-snippet.mdx theme={null} Hello world! This is my content I want to reuse across pages. My keyword of the day is {word}. ``` The content that you want to reuse must be inside the `snippets` directory in order for the import to work. 2. Import the snippet into your destination file. ```mdx destination-file.mdx theme={null} --- title: My title description: My Description --- import MySnippet from '/snippets/path/to/my-snippet.mdx'; ## Header Lorem impsum dolor sit amet. ``` ### Reusable variables 1. Export a variable from your snippet file: ```mdx snippets/path/to/custom-variables.mdx theme={null} export const myName = 'my name'; export const myObject = { fruit: 'strawberries' }; ``` 2. Import the snippet from your destination file and use the variable: ```mdx destination-file.mdx theme={null} --- title: My title description: My Description --- import { myName, myObject } from '/snippets/path/to/custom-variables.mdx'; Hello, my name is {myName} and I like {myObject.fruit}. ``` ### Reusable components 1. Inside your snippet file, create a component that takes in props by exporting your component in the form of an arrow function. ```mdx snippets/custom-component.mdx theme={null} export const MyComponent = ({ title }) => (

{title}

... snippet content ...

); ``` MDX does not compile inside the body of an arrow function. Stick to HTML syntax when you can or use a default export if you need to use MDX. 2. Import the snippet into your destination file and pass in the props ```mdx destination-file.mdx theme={null} --- title: My title description: My Description --- import { MyComponent } from '/snippets/custom-component.mdx'; Lorem ipsum dolor sit amet. ``` # Global Settings Source: https://developer.flabslis.com/essentials/settings Mintlify gives you complete control over the look and feel of your documentation using the docs.json file Every Mintlify site needs a `docs.json` file with the core configuration settings. Learn more about the [properties](#properties) below. ## Properties Name of your project. Used for the global title. Example: `mintlify` An array of groups with all the pages within that group The name of the group. Example: `Settings` The relative paths to the markdown files that will serve as pages. Example: `["customization", "page"]` Path to logo image or object with path to "light" and "dark" mode logo images Path to the logo in light mode Path to the logo in dark mode Where clicking on the logo links you to Path to the favicon image Hex color codes for your global theme The primary color. Used for most often for highlighted content, section headers, accents, in light mode The primary color for dark mode. Used for most often for highlighted content, section headers, accents, in dark mode The primary color for important buttons The color of the background in both light and dark mode The hex color code of the background in light mode The hex color code of the background in dark mode Array of `name`s and `url`s of links you want to include in the topbar The name of the button. Example: `Contact us` The url once you click on the button. Example: `https://mintlify.com/docs` Link shows a button. GitHub shows the repo information at the url provided including the number of GitHub stars. If `link`: What the button links to. If `github`: Link to the repository to load GitHub information from. Text inside the button. Only required if `type` is a `link`. Array of version names. Only use this if you want to show different versions of docs with a dropdown in the navigation bar. An array of the anchors, includes the `icon`, `color`, and `url`. The [Font Awesome](https://fontawesome.com/search?q=heart) icon used to feature the anchor. Example: `comments` The name of the anchor label. Example: `Community` The start of the URL that marks what pages go in the anchor. Generally, this is the name of the folder you put your pages in. The hex color of the anchor icon background. Can also be a gradient if you pass an object with the properties `from` and `to` that are each a hex color. Used if you want to hide an anchor until the correct docs version is selected. Pass `true` if you want to hide the anchor until you directly link someone to docs inside it. One of: "brands", "duotone", "light", "sharp-solid", "solid", or "thin" Override the default configurations for the top-most anchor. The name of the top-most anchor Font Awesome icon. One of: "brands", "duotone", "light", "sharp-solid", "solid", or "thin" An array of navigational tabs. The name of the tab label. The start of the URL that marks what pages go in the tab. Generally, this is the name of the folder you put your pages in. Configuration for API settings. Learn more about API pages at [API Components](/api-playground/demo). The base url for all API endpoints. If `baseUrl` is an array, it will enable for multiple base url options that the user can toggle. The authentication strategy used for all API endpoints. The name of the authentication parameter used in the API playground. If method is `basic`, the format should be `[usernameName]:[passwordName]` The default value that's designed to be a prefix for the authentication input field. E.g. If an `inputPrefix` of `AuthKey` would inherit the default input result of the authentication field as `AuthKey`. Configurations for the API playground Whether the playground is showing, hidden, or only displaying the endpoint with no added user interactivity `simple` Learn more at the [playground guides](/api-playground/demo) Enabling this flag ensures that key ordering in OpenAPI pages matches the key ordering defined in the OpenAPI file. This behavior will soon be enabled by default, at which point this field will be deprecated. A string or an array of strings of URL(s) or relative path(s) pointing to your OpenAPI file. Examples: ```json Absolute theme={null} "openapi": "https://example.com/openapi.json" ``` ```json Relative theme={null} "openapi": "/openapi.json" ``` ```json Multiple theme={null} "openapi": ["https://example.com/openapi1.json", "/openapi2.json", "/openapi3.json"] ``` An object of social media accounts where the key:property pair represents the social media platform and the account url. Example: ```json theme={null} { "x": "https://x.com/mintlify", "website": "https://mintlify.com" } ``` One of the following values `website`, `facebook`, `x`, `discord`, `slack`, `github`, `linkedin`, `instagram`, `hacker-news` Example: `x` The URL to the social platform. Example: `https://x.com/mintlify` Configurations to enable feedback buttons Enables a button to allow users to suggest edits via pull requests Enables a button to allow users to raise an issue about the documentation Customize the dark mode toggle. Set if you always want to show light or dark mode for new users. When not set, we default to the same mode as the user's operating system. Set to true to hide the dark/light mode toggle. You can combine `isHidden` with `default` to force your docs to only use light or dark mode. For example: ```json Only Dark Mode theme={null} "modeToggle": { "default": "dark", "isHidden": true } ``` ```json Only Light Mode theme={null} "modeToggle": { "default": "light", "isHidden": true } ``` A background image to be displayed behind every page. See example with [Infisical](https://infisical.com/docs) and [FRPC](https://frpc.io). # Introduction Source: https://developer.flabslis.com/introduction Welcome to the documentation of Flabs developer platform APIs Hero Light Hero Dark ## Overview Welcome to Flabs API documentation. Our APIs allow labs to integrate with the Flabs platform to create a seamless experience for managing patient data, reports, and lab workflows. ## Authentication All Flabs APIs use token-based authentication. To access our APIs, you'll need: 1. **Client ID**: A unique identifier for your lab 2. **Client Secret**: A secret key provided to authenticate your lab These credentials must be kept secure and should never be exposed in client-side code or public repositories. To obtain your Client ID and Client Secret, please contact our support team at [hello@flabs.in](mailto:hello@flabs.in) ## API Overview Authenticate your lab to access Flabs APIs Set up real-time event notifications Manage billing and payment processing Manage patient authentication and report access ## Getting Started Follow these steps to integrate with the Flabs platform: ### 1. Obtain Credentials Contact our support team to get your Client ID and Client Secret. ### 2. Generate Authentication Token Use your credentials to obtain an authentication token through our authentication endpoint. ### 3. Use the Token in API Requests Include the token in the Authorization header of your API requests. ## Error Handling All Flabs APIs follow a consistent error format that includes success status, error code, message, and detailed information when available. ## Rate Limiting To ensure system stability, our APIs implement rate limiting. If you exceed the limits, you'll receive a `429 Too Many Requests` response. ## Support For any questions or issues regarding the API integration, please contact: * Email: [hello@flabs.in](mailto:hello@flabs.in) * Phone: +91 7253928905 Our tech team is available Monday to Friday, 9 AM to 6 PM IST. # Get OTP Source: https://developer.flabslis.com/patient/endpoint/get_otp POST /client/patient/getLoginOTP Sends an OTP to the provided contact number for patient verification. # Get Patient Reports Source: https://developer.flabslis.com/patient/endpoint/get_records GET /client/patient/getReports Retrieves all reports for a patient registered through the client lab. # Verify OTP Source: https://developer.flabslis.com/patient/endpoint/verify_otp POST /client/patient/verifyLoginOTP Verifies the OTP sent to the patient's contact number. # Patient APIs Introduction Source: https://developer.flabslis.com/patient/introduction APIs for patient authentication and report retrieval Flabs Logo Light Flabs Logo Dark ## Overview Flabs Patient APIs allow you to authenticate patients via OTP and retrieve their medical reports securely. Send OTP to patient's contact number Verify OTP and get patient token Retrieve all patient reports ## Patient Authentication Flow Our patient authentication system uses a two-step verification process: 1. **Request OTP**: Send an OTP to the patient's contact number 2. **Verify OTP**: Validate the OTP to receive a patient token 3. **Access Reports**: Use the patient token to access patient-specific reports All API requests require both the lab authentication token (in the Authorization header) and for the reports endpoint, the patient token (in the patient-authorization header). ## Getting Started To integrate with our patient authentication system: 1. Authenticate your lab client using the Auth API 2. Request an OTP for the patient using the [getLoginOTP](/patient/endpoint/get_otp) endpoint 3. Have the patient verify the OTP using the [verifyLoginOTP](/patient/endpoint/verify_otp) endpoint 4. Retrieve the patient's reports using the [getReports](/patient/endpoint/get_records) endpoint ## Security Patient data is secure and can only be accessed with: * A valid lab authentication token * A valid patient-specific token obtained through OTP verification This dual authentication ensures that only authorized labs can access patient data, and only for patients who have verified their identity. # Delete Webhook Source: https://developer.flabslis.com/webhooks/endpoint/delete_webhook DELETE /client/events/deleteEvent/{id} Delete a specific webhook by its unique identifier. This permanently removes it and stops all deliveries. **Party-scoped accounts:** you MUST pass the same party (`corporateUser` or `organization`) the webhook is bound to; you can only delete your own party's webhooks. # Get All Webhooks Source: https://developer.flabslis.com/webhooks/endpoint/get_all_webhooks GET /client/events/getAllEvents Retrieve active webhooks for your account, including event types, protocols, and metadata. **Catch-all accounts:** returns the lab's webhooks. **Party-scoped accounts:** you MUST pass a party (`corporateUser` or `organization`) and only that party's webhooks are returned. # Register Webhook Source: https://developer.flabslis.com/webhooks/endpoint/register_webhook POST /client/events/subscribe Subscribe to webhook events to receive real-time notifications when bills, reports, leads, or bookings change. **Catch-all accounts (default):** do not send a party — one webhook receives every event for the lab. **Party-scoped accounts:** you MUST attach a party (`corporateUser` or `organization`); the webhook then receives only that party's events. A party may have only one active webhook per event (a duplicate returns `409`). Sending a party on a catch-all account (or omitting it on a party-scoped account) returns `400`. ## Overview Register your application to receive webhook notifications for specific events in the Flabs system. This endpoint allows you to subscribe to real-time notifications across the bill, report, and CRM booking lifecycle — from a bill being created or completed to a phlebotomist collecting and submitting a sample. ## Authentication This endpoint requires a valid Bearer token obtained from the [authentication API](/auth/endpoint/get_auth_token). ## Request Parameters All parameters are sent in the request body as JSON: | Parameter | Type | Required | Description | | --------------- | ------ | -------- | --------------------------------------------------------------------- | | `labID` | string | Yes | Flabs lab (branch) identifier. Fetch via `GET /client/labs` | | `events` | array | Yes | List of event types to subscribe to | | `endpoint` | string | Yes | Your webhook endpoint URL (must use HTTPS) | | `protocol` | string | Yes | Protocol for webhook delivery (only "https" is supported) | | `corporateUser` | string | Cond. | Party-scoped accounts only — bind the webhook to this corporate | | `organization` | string | Cond. | Party-scoped accounts only — bind the webhook to this doctor/hospital | **Catch-all accounts (default):** do not send a party. **Party-scoped accounts:** you must send `corporateUser` **or** `organization` (not both); the webhook then receives only that party's events. See [integration modes](/crm/introduction). ### Supported Events **Bill & report events** * `bill.created` - New bill created * `bill.completed` - Entire bill completed (all reports finished) * `bill.deleted` - Bill deleted from system * `report.completed` - Individual report completed **CRM events** * `lead.created` - New CRM lead created * `booking.created` - New CRM booking created (or a lead converted to a booking) * `booking.phlebotomist_assigned` - A phlebotomist was assigned to the booking * `booking.phlebotomist_arrived` - The phlebotomist reached the patient's location * `booking.phlebotomist_sample_collected` - The phlebotomist collected the sample * `booking.phlebotomist_sample_submitted` - The sample was submitted back to the lab (auto-creates the bill) * `booking.rescheduled` - The booking's scheduled date or time was changed * `booking.cancelled` - The booking was cancelled See [Events Response](/webhooks/events-response) for the exact JSON payload each of these events delivers to your endpoint. # Events Response Source: https://developer.flabslis.com/webhooks/events-response The exact JSON body Flabs POSTs to your endpoint for every webhook event. This page shows the exact payload your endpoint receives for each of the 12 webhook events. Every field is described once in the [field reference](#field-reference) at the bottom. For what each event means and how to subscribe, see [Webhooks](/webhooks/introduction) and [Register Webhook](/webhooks/endpoint/register_webhook). ## Bill events ### `bill.created` Sent when a new bill is created. ```json theme={null} { "labID": "665f2a1c9b4e7d1a2c3f4b01", "eventType": "bill.created", "eventTime": 1738751400, "data": { "billID": "6710b8e4d2a91f3c5e77aa12", "integratorID": "EXT-ORDER-90231", "billData": { "status": "ongoing", "testData": [ { "_id": "6530a4a6f1d2c8b7e9a11111", "status": "PENDING" }, { "_id": "6530a4a6f1d2c8b7e9a22222", "status": "PENDING" } ] } } } ``` ### `bill.completed` Sent when every report on the bill is finished and the bill moves to `completed` (or `delivered`). ```json theme={null} { "labID": "665f2a1c9b4e7d1a2c3f4b01", "eventType": "bill.completed", "eventTime": 1738755102, "data": { "billID": "6710b8e4d2a91f3c5e77aa12", "integratorID": "EXT-ORDER-90231", "billData": { "status": "completed", "testData": [ { "_id": "6530a4a6f1d2c8b7e9a11111", "status": "COMPLETE", "testName": "Complete Blood Count (CBC)", "parameter": [ { "parameterName": "Haemoglobin", "id": "6530a4a6f1d2c8b7e9a33333", "value": "13.4" }, { "parameterName": "Total WBC Count", "id": "6530a4a6f1d2c8b7e9a44444?0", "value": "7200" } ] }, { "_id": "6530a4a6f1d2c8b7e9a22222", "status": "COMPLETE", "testName": "Allergy Panel (Food)", "parameter": [] } ] }, "reportURL": "https://flabs-lab.s3.ap-south-1.amazonaws.com/report/6710b8e4d2a91f3c5e77aa12.pdf", "sampleImages": [ { "url": "https://flabs-lab.s3.ap-south-1.amazonaws.com/sample/sample-image-1.jpg", "lat": 19.076, "lng": 72.8777, "capturedAt": "2025-02-05T07:52:14.318Z" }, { "url": "https://flabs-lab.s3.ap-south-1.amazonaws.com/sample/sample-image-2.jpg", "lat": null, "lng": null, "capturedAt": "2025-02-05T07:53:02.771Z" } ], "patientData": { "designation": "Mr.", "firstName": "Rahul", "lastName": "Sharma", "age": "32", "ageType": "year", "gender": "male", "contact": "9876543210", "email": "rahul.sharma@example.com", "address": "14 MG Road, Bengaluru", "country_code": "91", "aadhaar_number": "", "insurance_number": "", "uhid": "UH-90231", "height": "176", "weight": "72", "date_of_birth": "1993-08-14T00:00:00+05:30" } } } ``` ### `bill.deleted` Sent when a bill is deleted. The payload carries identifiers only — no `billData`, no `reportURL`, no test list. ```json theme={null} { "labID": "665f2a1c9b4e7d1a2c3f4b01", "eventType": "bill.deleted", "eventTime": 1738756800, "data": { "billID": "6710b8e4d2a91f3c5e77aa12", "integratorID": "EXT-ORDER-90231" } } ``` ## Report events ### `report.completed` Sent each time an individual test on the bill is marked complete, while the bill as a whole is still unfinished. ```json theme={null} { "labID": "665f2a1c9b4e7d1a2c3f4b01", "eventType": "report.completed", "eventTime": 1738753200, "data": { "reportID": "6710b8e4d2a91f3c5e77aa12", "integratorID": "EXT-ORDER-90231", "reportData": { "status": "partial", "testData": [ { "_id": "6530a4a6f1d2c8b7e9a11111", "status": "COMPLETE" }, { "_id": "6530a4a6f1d2c8b7e9a22222", "status": "PENDING" } ] }, "reportURL": "https://flabs-lab.s3.ap-south-1.amazonaws.com/report/6710b8e4d2a91f3c5e77aa12.pdf" } } ``` ## CRM events All eight CRM events share the same shape. ### `lead.created` Sent when a lead is created in the CRM. This is the only CRM event where `phase` is `lead`. ```json theme={null} { "labID": "665f2a1c9b4e7d1a2c3f4b01", "eventType": "lead.created", "eventTime": 1738747800, "integratorID": "EXT-LEAD-10231", "data": { "leadID": "6712c4f7a8b3e91d4f22cc09", "phase": "lead", "first_name": "Rahul" } } ``` ### `booking.created` Sent when a booking is created directly, or when an existing lead is converted into a booking. In the conversion case `leadID` is unchanged and `phase` flips to `booking`. ```json theme={null} { "labID": "665f2a1c9b4e7d1a2c3f4b01", "eventType": "booking.created", "eventTime": 1738748400, "integratorID": "EXT-LEAD-10231", "data": { "leadID": "6712c4f7a8b3e91d4f22cc09", "phase": "booking", "first_name": "Rahul" } } ``` ### Booking lifecycle events The six events below track a home-collection booking from assignment through completion or cancellation. The body is identical in every case — only `eventType` differs. ```json booking.phlebotomist_assigned theme={null} { "labID": "665f2a1c9b4e7d1a2c3f4b01", "eventType": "booking.phlebotomist_assigned", "eventTime": 1738749000, "integratorID": "EXT-LEAD-10231", "data": { "leadID": "6712c4f7a8b3e91d4f22cc09", "phase": "booking", "first_name": "Rahul" } } ``` ```json booking.phlebotomist_arrived theme={null} { "labID": "665f2a1c9b4e7d1a2c3f4b01", "eventType": "booking.phlebotomist_arrived", "eventTime": 1738750200, "integratorID": "EXT-LEAD-10231", "data": { "leadID": "6712c4f7a8b3e91d4f22cc09", "phase": "booking", "first_name": "Rahul" } } ``` ```json booking.phlebotomist_sample_collected theme={null} { "labID": "665f2a1c9b4e7d1a2c3f4b01", "eventType": "booking.phlebotomist_sample_collected", "eventTime": 1738750800, "integratorID": "EXT-LEAD-10231", "data": { "leadID": "6712c4f7a8b3e91d4f22cc09", "phase": "booking", "first_name": "Rahul" } } ``` ```json booking.phlebotomist_sample_submitted theme={null} { "labID": "665f2a1c9b4e7d1a2c3f4b01", "eventType": "booking.phlebotomist_sample_submitted", "eventTime": 1738751400, "integratorID": "EXT-LEAD-10231", "data": { "leadID": "6712c4f7a8b3e91d4f22cc09", "phase": "booking", "first_name": "Rahul" } } ``` ```json booking.rescheduled theme={null} { "labID": "665f2a1c9b4e7d1a2c3f4b01", "eventType": "booking.rescheduled", "eventTime": 1738748700, "integratorID": "EXT-LEAD-10231", "data": { "leadID": "6712c4f7a8b3e91d4f22cc09", "phase": "booking", "first_name": "Rahul" } } ``` ```json booking.cancelled theme={null} { "labID": "665f2a1c9b4e7d1a2c3f4b01", "eventType": "booking.cancelled", "eventTime": 1738748900, "integratorID": "EXT-LEAD-10231", "data": { "leadID": "6712c4f7a8b3e91d4f22cc09", "phase": "booking", "first_name": "Rahul" } } ``` `booking.phlebotomist_sample_submitted` also auto-creates the bill for that booking, so a `bill.created` delivery follows it, then `report.completed` and `bill.completed` for the same patient. *** ## Field reference ### Envelope Present on every event. | Field | Type | Description | | ----------- | ------- | ------------------------------------------------------------------- | | `labID` | string | The Flabs lab (branch) the event belongs to. | | `eventType` | string | The event name, one of the 12 above. | | `eventTime` | integer | Unix timestamp in seconds, stamped when the delivery is dispatched. | | `data` | object | Event-specific body. | ### Bill and report events | Field | Type | Description | | ----------------------------------- | -------------- | -------------------------------------------------------------------------------------------------------- | | `data.billID` | string | The bill identifier. Sent on `bill.created`, `bill.completed` and `bill.deleted`. | | `data.reportID` | string | `report.completed` only. Carries the bill identifier. | | `data.integratorID` | string | Your identifier for the bill, sent at create time. | | `data.billData` / `data.reportData` | object | Bill state. `billData` on bill events, `reportData` on `report.completed`. | | `…testData` | array | Every test on the bill. Always present. | | `…testData[]._id` | string | The catalogue test identifier, as returned by [List Tests](/crm/endpoint/list_tests). | | `…testData[].testName` | string | `bill.completed` only. Name of the test. Always present. | | `…testData[].parameter` | array | `bill.completed` only. Entered result values. Always present; `[]` when the test has none, never `null`. | | `…parameter[].parameterName` | string | Name of the parameter, e.g. `Haemoglobin`. | | `…parameter[].id` | string | Parameter identifier. | | `…parameter[].value` | string | The entered value. Always a string, including numeric results. | | `data.reportURL` | string | Link to the bill's report PDF. | | `data.sampleImages` | array | `bill.completed` only. Geo-tagged sample-collection photos. Always present; `[]` when there are none. | | `data.sampleImages[].url` | string | Link to the captured photo. | | `data.sampleImages[].lat` | number \| null | Latitude at capture time. `null` when GPS was unavailable; the key is always present. | | `data.sampleImages[].lng` | number \| null | Longitude at capture time. `null` when GPS was unavailable; the key is always present. | | `data.sampleImages[].capturedAt` | string | ISO 8601 capture timestamp. Omitted when it was never recorded. | | `data.patientData` | object | `bill.completed` only. The patient the bill belongs to. See below. | ### Patient data `bill.completed` only. Every key below is always present; a detail the lab never recorded is sent as an empty string, never `null` or omitted. Values are sent exactly as the lab stored them, so treat them as free text unless noted. | Field | Type | Description | | ----------------------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------- | | `data.patientData.designation` | string | Salutation, e.g. `Mr.`, `Mrs.`, `Dr.`. | | `data.patientData.firstName` | string | Given name. | | `data.patientData.lastName` | string | Family name. | | `data.patientData.age` | string | Age in `ageType` units. Sent as a string, e.g. `"32"`. | | `data.patientData.ageType` | string | Unit for `age`: `year`, `month` or `day`. Lowercase and singular. | | `data.patientData.gender` | string | `male`, `female` or `other`. Always lowercase. | | `data.patientData.contact` | string | Mobile number, without the country code. | | `data.patientData.country_code` | string | Dial code for `contact`, with no `+` — e.g. `91` for India. | | `data.patientData.email` | string | Email address. | | `data.patientData.address` | string | Postal address as a single line. | | `data.patientData.aadhaar_number` | string | Aadhaar number, when recorded. | | `data.patientData.insurance_number` | string | Insurance/policy number, when recorded. | | `data.patientData.uhid` | string | The lab's unique health ID for the patient. | | `data.patientData.height` | string | Height as recorded, e.g. `176`. No unit is attached. | | `data.patientData.weight` | string | Weight as recorded, e.g. `72`. No unit is attached. | | `data.patientData.date_of_birth` | string | ISO 8601 with the `+05:30` IST offset, e.g. `1993-08-14T00:00:00+05:30`. Empty string when no date of birth is on file. | `age` and `date_of_birth` are recorded independently. A patient can have an age with no date of birth, and the two are not recalculated against each other — use whichever your system needs, and prefer `date_of_birth` when both are present. `patientData` carries personal and health information, including government identity numbers when the lab has recorded them. Store only the fields you need, and keep them encrypted in transit and at rest. ### CRM events | Field | Type | Description | | ----------------- | ------ | ------------------------------------------------------------------------------------------ | | `integratorID` | string | Your identifier for the record, sent at create time. Should be unique. Omitted when empty. | | `data.leadID` | string | Identifier of the lead or booking. Unchanged when a lead converts to a booking. | | `data.phase` | string | `lead` or `booking`. Always `booking` on every `booking.*` event. | | `data.first_name` | string | Patient's first name. Always present. | # Introduction Source: https://developer.flabslis.com/webhooks/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 Looking for the exact JSON body each event delivers? See [Events Response](/webhooks/events-response) for a copy-paste sample and field reference for all 12 events. ## 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 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. CRM events carry a small `data` object instead of bill data — see [Events Response](/webhooks/events-response#crm-events) for a sample of each one: ```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) | 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. ## 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. A `bill.completed` delivery looks like this — for the other eleven events, see [Events Response](/webhooks/events-response): ```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": "COMPLETE", "testName": "Complete Blood Count (CBC)", "parameter": [ { "parameterName": "Haemoglobin", "id": "6530a4a6f1d2c8b7e9a11111", "value": "13.4" }, { "parameterName": "Total WBC Count", "id": "6530a4a6f1d2c8b7e9a22222?0", "value": "7200" } ] }, { "_id": "test_002", "status": "COMPLETE", "testName": "Allergy Panel (Food)", "parameter": [] } ] }, "reportURL": "https://flabs-lab.s3.ap-south-1.amazonaws.com/report/bill_12345.pdf", "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" } ], "patientData": { "designation": "Mr.", "firstName": "Rahul", "lastName": "Sharma", "age": "32", "ageType": "year", "gender": "male", "contact": "9876543210", "email": "rahul.sharma@example.com", "address": "14 MG Road, Bengaluru", "country_code": "91", "aadhaar_number": "", "insurance_number": "", "uhid": "UH-90231", "height": "176", "weight": "72", "date_of_birth": "1993-08-14T00:00:00+05:30" } } } ``` ### 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.billData.testData[].testName` | string | `bill.completed` only. Name of the test. Always present. | | `data.billData.testData[].parameter` | array | `bill.completed` only. Result values entered for the test. Always present; `[]` when the test has no parameter-style results (see note below), never `null`. | | `data.billData.testData[].parameter[].parameterName` | string | Display name of the parameter, e.g. `Haemoglobin`. | | `data.billData.testData[].parameter[].id` | string | Stable identifier for this parameter within the test. Use it to correlate the same parameter across deliveries. | | `data.billData.testData[].parameter[].value` | string | The entered value. Always sent as a string, including numeric results. | | `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. | | `data.patientData` | object | `bill.completed` only. Details of the patient the bill belongs to. Always present, with all 16 keys — see [Patient data](/webhooks/events-response#patient-data) for each one. | `testName` and `parameter` are sent on **`bill.completed` only**. The `bill.created` and `report.completed` payloads carry the bare `_id` and `status` for each test. `parameter` is filled in only for tests with named, individually-valued results. Other tests — allergy and microbiology panels, or results written as free text, images or a PDF — send `testName` with an empty `parameter` array. For those, read the result from `reportURL`. 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. ## 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 — see [Events Response](/webhooks/events-response) for the exact body of every event 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 Ensure your webhook endpoint responds quickly (within 10 seconds) to avoid timeouts. # Welcome to Flabs Source: https://developer.flabslis.com/welcome

Welcome to Flabs Developer Documentation

Get started with our docs and guides

Guide

Learn everything about Flabs platform. Build your first integration.

API References

Automate actions with REST APIs and OpenAPI specs.

GitHub

Explore our repositories and contributions.

Billing

Manage invoices and billing workflows.

Webhooks

React to events with secure webhook notifications.

Patient

Authenticate and fetch patient records securely.