# Leads

Carebit Pro is required.

Patient enquiries and referrals received by the Organization.

**Required API scopes:** `leads.create`, `leads.read`, `leads.update`

## List a Lead's form responses

`GET /v1/lead_form_responses`

Returns the forms a Lead submitted, newest first. `lead_id` is required. The same submissions are summarized in the `form_responses` array of the Lead itself. Enquiries a staff member recorded by hand are not returned, because they have no form. Lost Leads are included. Carebit Pro is required.

**Required API scopes:** `leads.read`

## Parameters

- `lead_id` (query, `string`) (required) - The Lead whose form submissions should be returned.
- `limit` (query, `integer`) - The maximum number of items to return. Defaults to `25`; the maximum is `100`.
- `starting_after` (query, `string`) - Return items after this resource ID. You cannot use this with `cursor`.
- `cursor` (query, `string`) - The `next_cursor` value from the previous page. You cannot use this with `starting_after`.

## Response `200`

Paginated list of `LeadFormResponse` objects.

- `any`

### Example

```json
{
  "object": "list",
  "data": [
    {
      "id": "b5f5c363-d0b7-4e92-86ef-1d87afe8e8f8",
      "object": "lead_form_response",
      "answers": [
        {
          "field_name": "presenting_problem",
          "field_type": "text_area",
          "label": "What can we help with?",
          "value": "Persistent knee pain",
          "values": []
        }
      ],
      "created_at": "2026-01-01T09:00:00Z",
      "form_name": "New patient inquiry",
      "form_type": "inquiry_form",
      "lead_id": "00000000-0000-4000-8000-00000000000c",
      "links": {
        "lead": "https://api.carebit.co/v1/leads/00000000-0000-4000-8000-00000000000c",
        "self": "https://api.carebit.co/v1/lead_form_responses/b5f5c363-d0b7-4e92-86ef-1d87afe8e8f8"
      },
      "referral_notes": null,
      "referral_source": "consultant",
      "referred_by_clinician_id": "b5ac896f-f746-4df1-899a-c12d33b84b2d",
      "referred_by_organization_id": "8cda84a9-bf46-4f81-8f3c-66dd352e95db",
      "submitted_at": "2026-01-01T09:00:00Z",
      "tracking": {
        "ad_id": null,
        "fbclid": null,
        "gad_campaign_id": null,
        "gad_source": null,
        "gbraid": null,
        "gclid": null,
        "landing_page_origin": null,
        "utm_campaign": null,
        "utm_content": null,
        "utm_medium": null,
        "utm_source": null,
        "utm_term": null
      },
      "updated_at": "2026-01-01T09:00:00Z"
    }
  ],
  "has_more": false,
  "next_cursor": "eyJzdGFydF90aW1lIjoiMjAyNi0wMS0wMVQwOTowMDowMFoifQ",
  "url": "/v1/lead_form_responses"
}
```

## Response `400`

The `lead_id` parameter is missing, or a pagination parameter is invalid.

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Response `401`

The access token is missing, invalid, expired, or revoked.

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Response `403`

The access token lacks the required scope, the project is disabled, or the Organization does not have Carebit Pro.

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Response `404`

The Lead does not exist in this Organization.

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Response `429`

Too many requests. Retry after the delay indicated by `Retry-After`.

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Code samples

```bash
curl -X GET "https://api.carebit.co/v1/lead_form_responses?lead_id=00000000-0000-4000-8000-00000000000c" \
  -H "Authorization: Bearer $CAREBIT_ACCESS_TOKEN"
```

```javascript
const response = await fetch("https://api.carebit.co/v1/lead_form_responses?lead_id=00000000-0000-4000-8000-00000000000c", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.CAREBIT_ACCESS_TOKEN}`,
  },
});

if (!response.ok) {
  throw new Error(`Carebit API error: ${response.status}`);
}

const data = await response.json();
```

```python
import os
import requests

response = requests.get(
    "https://api.carebit.co/v1/lead_form_responses?lead_id=00000000-0000-4000-8000-00000000000c",
    headers={
        "Authorization": f"Bearer {os.environ['CAREBIT_ACCESS_TOKEN']}",
    }
)
response.raise_for_status()
data = response.json()
```

```ruby
require "httparty"

response = HTTParty.get(
  "https://api.carebit.co/v1/lead_form_responses?lead_id=00000000-0000-4000-8000-00000000000c",
  headers: {
    "Authorization" => "Bearer #{ENV.fetch("CAREBIT_ACCESS_TOKEN")}"
  }
)
raise "Carebit API error: #{response.code}" unless response.success?
data = response.parsed_response
```

```php
<?php

$client = new GuzzleHttp\Client();

$response = $client->get("https://api.carebit.co/v1/lead_form_responses?lead_id=00000000-0000-4000-8000-00000000000c", [
    "headers" => [
      "Authorization" => "Bearer " . getenv("CAREBIT_ACCESS_TOKEN"),
    ]
]);
$data = json_decode((string) $response->getBody(), true, flags: JSON_THROW_ON_ERROR);
```


## Get a Lead's form response

`GET /v1/lead_form_responses/:id`

Returns one form submission with its questions and answers, the referral data captured with it, and its marketing attribution. Carebit Pro is required.

**Required API scopes:** `leads.read`

## Parameters

- `id` (path, `string`) (required)

## Response `200`

The requested `LeadFormResponse`.

- `object`
  - `answers` (`array`) - The questions and answers, in the order the respondent saw them. Layout blocks, hidden fields and the form's bot trap are omitted. A file upload question is omitted too; the uploaded files appear in the Lead's `attachments`.
    - `items` (`object`) - One question and its submitted answer, embedded in a FormResponse.
      - `field_name` (`string | null`) - The machine name of the question, for example `presenting_problem`. Match on this rather than on `label`, which an Organization can reword at any time.
      - `field_type` (`string | null`) - The kind of question asked, for example `text_area` or `date_field`. Use it to parse `value`.
      - `label` (`string`) - The question as it was shown to the respondent, with HTML sanitized. A question saved with no label returns an empty string.
      - `value` (`string | null`) - The submitted answer, always a string. A `date_field` returns an ISO 8601 date such as `1990-06-15`. A `consent_field` returns a UTC ISO 8601 timestamp. A `number_field` returns a decimal such as `12.5`. A `checkbox` returns `true` or `false`. A `dropdown` or `radio` returns the selected option's value, such as `both_knees`, not its display label. A `multiselect` returns null and uses `values` instead.
      - `values` (`array`) - The selected option values for a `multiselect` question, such as `["both_knees"]`. Empty for every other question type. Like `value`, these are option values rather than display labels, because a label is free text the Organization can reword at any time.
        - `items` (`string`)
  - `created_at` (`string`) - format: `date-time`; An ISO 8601 timestamp in UTC, with a `Z` suffix. For example, `2026-07-01T09:00:00Z`.
  - `form_name` (`string`) - The name of the form the respondent submitted.
  - `form_type` (`string`) - enum: `inquiry_form`, `referral_form`; Whether the submission came from an enquiry form or a referral form. This describes the form, not the Lead. A Lead whose `lead_type` is `referral` can still hold an `inquiry_form` submission.
  - `id` (`string`) - format: `uuid`; The resource's unique identifier, formatted as an RFC 4122 version 4 UUID.
  - `lead_id` (`string`) - format: `uuid`; The Lead the submission created or updated.
  - `links` (`object`) - URLs to related resources.
    - `lead` (`string`) - format: `uri`; The full URL of a related resource.
    - `self` (`string`) - format: `uri`; The full URL of a related resource.
  - `object` (`any`) - Discriminator value emitted at `object`.
  - `referral_notes` (`string | null`) - The referral notes captured with this submission. The Lead's own `referral_notes` is taken from its first submission that supplied one, so this can differ.
  - `referral_source` (`string | null`) - enum: `consultant`, `embassy`, `family_or_friend`, `gp_practice`, `hospital`, `insurance_company`, `physiotherapist`, `presentation_talk`, `previous_patient`, `private_practice`, `search_engine`, `self_referral`, `social_media`, `website`, `other`, `null`; How this submission reached the Organization. A form submitted on the Organization's website records `website`.
  - `referred_by_clinician_id` (`string | null`) - format: `uuid`; The Clinician who referred this submission, when one was identified.
  - `referred_by_organization_id` (`string | null`) - format: `uuid`; The Organization that referred this submission, when one was identified.
  - `submitted_at` (`string`) - format: `date-time`; An ISO 8601 timestamp in UTC, with a `Z` suffix. For example, `2026-07-01T09:00:00Z`.
  - `tracking` (`any`) - The marketing attribution captured with this submission.
  - `updated_at` (`string`) - format: `date-time`; An ISO 8601 timestamp in UTC, with a `Z` suffix. For example, `2026-07-01T09:00:00Z`.

### Example

```json
{
  "id": "b5f5c363-d0b7-4e92-86ef-1d87afe8e8f8",
  "object": "lead_form_response",
  "answers": [
    {
      "field_name": "presenting_problem",
      "field_type": "text_area",
      "label": "What can we help with?",
      "value": "Persistent knee pain",
      "values": []
    }
  ],
  "created_at": "2026-01-01T09:00:00Z",
  "form_name": "New patient inquiry",
  "form_type": "inquiry_form",
  "lead_id": "00000000-0000-4000-8000-00000000000c",
  "links": {
    "lead": "https://api.carebit.co/v1/leads/00000000-0000-4000-8000-00000000000c",
    "self": "https://api.carebit.co/v1/lead_form_responses/b5f5c363-d0b7-4e92-86ef-1d87afe8e8f8"
  },
  "referral_notes": null,
  "referral_source": "consultant",
  "referred_by_clinician_id": "b5ac896f-f746-4df1-899a-c12d33b84b2d",
  "referred_by_organization_id": "8cda84a9-bf46-4f81-8f3c-66dd352e95db",
  "submitted_at": "2026-01-01T09:00:00Z",
  "tracking": {
    "ad_id": null,
    "fbclid": null,
    "gad_campaign_id": null,
    "gad_source": null,
    "gbraid": null,
    "gclid": null,
    "landing_page_origin": null,
    "utm_campaign": null,
    "utm_content": null,
    "utm_medium": null,
    "utm_source": null,
    "utm_term": null
  },
  "updated_at": "2026-01-01T09:00:00Z"
}
```

## Response `401`

The access token is missing, invalid, expired, or revoked.

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Response `403`

The access token lacks the required scope, the project is disabled, or the Organization does not have Carebit Pro.

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Response `404`

Error response.

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Response `429`

Too many requests. Retry after the delay indicated by `Retry-After`.

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Code samples

```bash
curl -X GET "https://api.carebit.co/v1/lead_form_responses/b5f5c363-d0b7-4e92-86ef-1d87afe8e8f8" \
  -H "Authorization: Bearer $CAREBIT_ACCESS_TOKEN"
```

```javascript
const response = await fetch("https://api.carebit.co/v1/lead_form_responses/b5f5c363-d0b7-4e92-86ef-1d87afe8e8f8", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.CAREBIT_ACCESS_TOKEN}`,
  },
});

if (!response.ok) {
  throw new Error(`Carebit API error: ${response.status}`);
}

const data = await response.json();
```

```python
import os
import requests

response = requests.get(
    "https://api.carebit.co/v1/lead_form_responses/b5f5c363-d0b7-4e92-86ef-1d87afe8e8f8",
    headers={
        "Authorization": f"Bearer {os.environ['CAREBIT_ACCESS_TOKEN']}",
    }
)
response.raise_for_status()
data = response.json()
```

```ruby
require "httparty"

response = HTTParty.get(
  "https://api.carebit.co/v1/lead_form_responses/b5f5c363-d0b7-4e92-86ef-1d87afe8e8f8",
  headers: {
    "Authorization" => "Bearer #{ENV.fetch("CAREBIT_ACCESS_TOKEN")}"
  }
)
raise "Carebit API error: #{response.code}" unless response.success?
data = response.parsed_response
```

```php
<?php

$client = new GuzzleHttp\Client();

$response = $client->get("https://api.carebit.co/v1/lead_form_responses/b5f5c363-d0b7-4e92-86ef-1d87afe8e8f8", [
    "headers" => [
      "Authorization" => "Bearer " . getenv("CAREBIT_ACCESS_TOKEN"),
    ]
]);
$data = json_decode((string) $response->getBody(), true, flags: JSON_THROW_ON_ERROR);
```


## List Lead pipelines and stages

`GET /v1/lead_pipelines`

Returns the Organization's Lead and referral pipelines. When updating a Lead, use a stage from the pipeline for its `lead_type`. Carebit Pro is required.

**Required API scopes:** `leads.read`

## Response `200`

Paginated list of `LeadPipeline` objects.

- `any`

### Example

```json
{
  "object": "list",
  "data": [
    {
      "id": "5412a51a-d3f9-44d8-8291-939bc55c434e",
      "object": "lead_pipeline",
      "created_at": "2026-01-01T09:00:00Z",
      "lead_type": "inquiry",
      "name": "Initial consultation",
      "stages": [
        {
          "id": "00000000-0000-4000-8000-00000000000d",
          "object": "lead_stage",
          "created_at": "2026-01-01T09:00:00Z",
          "is_conversion_stage": true,
          "is_lost_stage": true,
          "name": "Initial consultation",
          "position": 1,
          "updated_at": "2026-01-01T09:00:00Z"
        }
      ],
      "updated_at": "2026-01-01T09:00:00Z"
    }
  ],
  "has_more": false,
  "next_cursor": "eyJzdGFydF90aW1lIjoiMjAyNi0wMS0wMVQwOTowMDowMFoifQ",
  "url": "/v1/lead_pipelines"
}
```

## Response `401`

The access token is missing, invalid, expired, or revoked.

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Response `403`

The access token lacks the required scope, the project is disabled, or the Organization does not have Carebit Pro.

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Response `429`

Too many requests. Retry after the delay indicated by `Retry-After`.

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Code samples

```bash
curl -X GET "https://api.carebit.co/v1/lead_pipelines" \
  -H "Authorization: Bearer $CAREBIT_ACCESS_TOKEN"
```

```javascript
const response = await fetch("https://api.carebit.co/v1/lead_pipelines", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.CAREBIT_ACCESS_TOKEN}`,
  },
});

if (!response.ok) {
  throw new Error(`Carebit API error: ${response.status}`);
}

const data = await response.json();
```

```python
import os
import requests

response = requests.get(
    "https://api.carebit.co/v1/lead_pipelines",
    headers={
        "Authorization": f"Bearer {os.environ['CAREBIT_ACCESS_TOKEN']}",
    }
)
response.raise_for_status()
data = response.json()
```

```ruby
require "httparty"

response = HTTParty.get(
  "https://api.carebit.co/v1/lead_pipelines",
  headers: {
    "Authorization" => "Bearer #{ENV.fetch("CAREBIT_ACCESS_TOKEN")}"
  }
)
raise "Carebit API error: #{response.code}" unless response.success?
data = response.parsed_response
```

```php
<?php

$client = new GuzzleHttp\Client();

$response = $client->get("https://api.carebit.co/v1/lead_pipelines", [
    "headers" => [
      "Authorization" => "Bearer " . getenv("CAREBIT_ACCESS_TOKEN"),
    ]
]);
$data = json_decode((string) $response->getBody(), true, flags: JSON_THROW_ON_ERROR);
```


## List Leads

`GET /v1/leads`

Returns the Organization's patient enquiries and referrals. Results include leads in a lost stage, including a lead discarded when it was marked lost. A discarded lead that is not in a lost stage is omitted. Use `is_lost` to return only one group, and `stage_id` to return leads in one stage. Carebit Pro is required.

**Required API scopes:** `leads.read`

## Parameters

- `clinician_id` (query, `string`) - Filter by the identifier of the assigned clinician.
- `email` (query, `string`) - Filter by exact email address.
- `is_lost` (query, `boolean`) - When `true`, only leads whose current stage is a lost stage are returned. When `false`, only leads in any other stage are returned. Omit to return both. A lost stage has the `mark_lead_lost` action, or the title Lost or Rejected.
- `service_id` (query, `string`) - Filter by the Service the Lead is enquiring about.
- `stage_id` (query, `string`) - Filter by the identifier of the lead's current pipeline stage. The stage must belong to one of the Organization's lead pipelines.
- `updated_since` (query, `string`) - Return Leads updated at or after this ISO 8601 timestamp.
- `limit` (query, `integer`) - The maximum number of items to return. Defaults to `25`; the maximum is `100`.
- `starting_after` (query, `string`) - Return items after this resource ID. You cannot use this with `cursor`.
- `cursor` (query, `string`) - The `next_cursor` value from the previous page. You cannot use this with `starting_after`.

## Response `200`

Paginated list of `Lead` objects.

- `any`

### Example

```json
{
  "object": "list",
  "data": [
    {
      "id": "00000000-0000-4000-8000-00000000000c",
      "object": "lead",
      "address_line_1": "10 Harley Street",
      "address_line_2": "Marylebone",
      "attachments": [
        {
          "id": "f631636b-32e2-41be-8e4f-0a34ee0d5d59",
          "download_url": "https://files.example.invalid/document.pdf?signature=test",
          "filename": "referral-letter.pdf"
        }
      ],
      "city": "London",
      "clinician": {
        "id": "00000000-0000-4000-8000-000000000002",
        "object": "clinician",
        "created_at": "2026-01-01T09:00:00Z",
        "display_name": "Dr Alex Morgan",
        "email": "alex.morgan@example.com",
        "first_name": "Alex",
        "last_name": "Morgan",
        "links": {
          "bookings": "https://api.carebit.co/v1/bookings?clinician_id=00000000-0000-4000-8000-000000000002"
        },
        "medical_specialty": "Cardiology",
        "title": "Dr",
        "updated_at": "2026-01-01T09:00:00Z"
      },
      "country_code": "GB",
      "county": "Greater London",
      "created_at": "2026-01-01T09:00:00Z",
      "creation_source": "api",
      "date_of_birth": "1990-01-01",
      "display_name": "Dr Alex Morgan",
      "email": "alex.morgan@example.com",
      "first_name": "Alex",
      "form_responses": [
        {
          "id": "adf881b8-4eed-42c0-8903-515f6cc8a134",
          "form_name": "New patient inquiry",
          "form_type": "inquiry_form",
          "submitted_at": "2026-01-01T09:00:00Z",
          "url": "https://files.example.invalid/document.pdf?signature=test"
        }
      ],
      "gdpr_consent_granted_at": "2026-01-01T09:00:00Z",
      "gdpr_consent_withdrawn_at": "2026-01-01T09:00:00Z",
      "internal_notes": "Asked about evening appointments with Dr Smith.",
      "is_converted_to_patient": true,
      "is_lost": false,
      "is_opted_out_of_sms": false,
      "is_signed_up_to_newsletters": true,
      "last_name": "Morgan",
      "lead_type": "inquiry",
      "links": {
        "clinician": "https://api.carebit.co/v1/clinicians/00000000-0000-4000-8000-000000000002",
        "remote_file_import_batch": "https://api.carebit.co/v1/remote_file_import_batches/00000000-0000-4000-8000-00000000000a",
        "self": "https://api.carebit.co/v1/leads/00000000-0000-4000-8000-00000000000c",
        "service": "https://api.carebit.co/v1/services/00000000-0000-4000-8000-000000000005"
      },
      "mobile": "7700900123",
      "mobile_country_dial_code": "GB",
      "organization_privacy_policy_consent_granted_at": "2026-01-01T09:00:00Z",
      "patient_id": "00000000-0000-4000-8000-000000000004",
      "phone": "2071234567",
      "phone_country_dial_code": "GB",
      "postcode": "W1G 9PF",
      "presenting_problem": "Persistent right knee pain",
      "referral_notes": "Referred by Dr Patel at Riverside Medical.",
      "referral_source": "consultant",
      "referred_by_clinician_id": "b5ac896f-f746-4df1-899a-c12d33b84b2d",
      "referred_by_organization_id": "8cda84a9-bf46-4f81-8f3c-66dd352e95db",
      "remote_file_import_batch_id": "00000000-0000-4000-8000-00000000000a",
      "service": {
        "id": "00000000-0000-4000-8000-000000000005",
        "object": "service",
        "created_at": "2026-01-01T09:00:00Z",
        "description": "An initial consultation at the Harley Street Clinic.",
        "duration_minutes": 30,
        "is_bookable_online": true,
        "name": "Initial consultation",
        "service_variants": [
          {
            "id": "00000000-0000-4000-8000-000000000006",
            "clinician_id": "00000000-0000-4000-8000-000000000002",
            "currency": "GBP",
            "description": "An initial consultation at the Harley Street Clinic.",
            "links": {
              "clinician": "https://api.carebit.co/v1/clinicians/00000000-0000-4000-8000-000000000002",
              "location": "https://api.carebit.co/v1/locations/00000000-0000-4000-8000-000000000003"
            },
            "location_id": "00000000-0000-4000-8000-000000000003",
            "net_price": 1,
            "permits_remote_bookings": true
          }
        ],
        "tax_rate": {
          "id": "00000000-0000-4000-8000-000000000029",
          "description": "An initial consultation at the Harley Street Clinic.",
          "percentage": 20,
          "title": "VAT"
        },
        "updated_at": "2026-01-01T09:00:00Z"
      },
      "sex": "female",
      "stage": {
        "id": "00000000-0000-4000-8000-00000000000d",
        "object": "lead_stage",
        "created_at": "2026-01-01T09:00:00Z",
        "is_conversion_stage": true,
        "is_lost_stage": true,
        "name": "Initial consultation",
        "position": 1,
        "updated_at": "2026-01-01T09:00:00Z"
      },
      "title": "Dr",
      "updated_at": "2026-01-01T09:00:00Z"
    }
  ],
  "has_more": false,
  "next_cursor": "eyJzdGFydF90aW1lIjoiMjAyNi0wMS0wMVQwOTowMDowMFoifQ",
  "url": "/v1/leads"
}
```

## Response `400`

A filter or pagination parameter is invalid.

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Response `401`

The access token is missing, invalid, expired, or revoked.

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Response `403`

The access token lacks the required scope, the project is disabled, or the Organization does not have Carebit Pro.

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Response `404`

The `stage_id` was not found on a lead pipeline in the Organization.

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Response `429`

Too many requests. Retry after the delay indicated by `Retry-After`.

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Code samples

```bash
curl -X GET "https://api.carebit.co/v1/leads" \
  -H "Authorization: Bearer $CAREBIT_ACCESS_TOKEN"
```

```javascript
const response = await fetch("https://api.carebit.co/v1/leads", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.CAREBIT_ACCESS_TOKEN}`,
  },
});

if (!response.ok) {
  throw new Error(`Carebit API error: ${response.status}`);
}

const data = await response.json();
```

```python
import os
import requests

response = requests.get(
    "https://api.carebit.co/v1/leads",
    headers={
        "Authorization": f"Bearer {os.environ['CAREBIT_ACCESS_TOKEN']}",
    }
)
response.raise_for_status()
data = response.json()
```

```ruby
require "httparty"

response = HTTParty.get(
  "https://api.carebit.co/v1/leads",
  headers: {
    "Authorization" => "Bearer #{ENV.fetch("CAREBIT_ACCESS_TOKEN")}"
  }
)
raise "Carebit API error: #{response.code}" unless response.success?
data = response.parsed_response
```

```php
<?php

$client = new GuzzleHttp\Client();

$response = $client->get("https://api.carebit.co/v1/leads", [
    "headers" => [
      "Authorization" => "Bearer " . getenv("CAREBIT_ACCESS_TOKEN"),
    ]
]);
$data = json_decode((string) $response->getBody(), true, flags: JSON_THROW_ON_ERROR);
```


## Create a Lead

`POST /v1/leads`

Creates a patient enquiry or referral in the Organization. Attachments can use a public HTTPS URL or Base64-encoded data. Carebit validates and scans them for malware in the background; poll the returned remote file import batch for their status. Each successful request creates a new Lead unless the response is an Idempotency-Key replay. Carebit Pro is required.

**Required API scopes:** `leads.create`

## Parameters

- `Idempotency-Key` (header, `string`) (required) - Client-generated idempotency key. Required for every POST/PATCH write. Replay of the same key with the same body returns the stored response with an `Idempotency-Replayed: true` header. Same key + different body returns `422 idempotency_key_reused`. A duplicate that arrives while the first request is still in flight returns `409 idempotency_conflict` with `Retry-After: 1`.

## Request body (`application/json`)

- `object`
  - `address_line_1` (`string | null`) - The primary address line of the lead.
  - `address_line_2` (`string | null`) - The secondary address line of the lead.
  - `attachments` (`array`) - The files to attach to the Lead in the background. Provide either `url` or `file_base64` for each file. Carebit validates and scans every file for malware.
    - `items` (`object`)
      - `file_base64` (`string`) - format: `byte`; The file bytes encoded as Base64. Provide this with `filename` instead of `url`. The decoded file can be at most 7 MB.
      - `filename` (`string | null`) - The filename to use for the attachment. Required with `file_base64`; defaults to the remote file's filename for URL sources.
      - `url` (`string`) - format: `uri`; The public HTTPS URL that Carebit can fetch.
  - `city` (`string | null`) - The city in the lead's postal address.
  - `clinician_id` (`string | null`) - format: `uuid`; The identifier of the clinician the lead is assigned to. Must be a clinician enabled in your Organization. Pass `null` to unassign.
  - `country_code` (`string | null`) - The uppercase ISO 3166-1 alpha-2 country code for the lead's postal address.
  - `county` (`string | null`) - The county or region in the lead's postal address.
  - `date_of_birth` (`string | null`) - format: `date`; The date of birth of the lead, in ISO 8601 format (YYYY-MM-DD).
  - `email` (`string | null`) - format: `email`; The contact email address of the lead.
  - `first_name` (`string`) - The first name of the lead. Required on create.
  - `gdpr_consent_granted_at` (`string | null`) - format: `date-time`; The ISO 8601 UTC timestamp at which the lead granted GDPR consent.
  - `gdpr_consent_withdrawn_at` (`string | null`) - format: `date-time`; The ISO 8601 UTC timestamp at which the lead withdrew GDPR consent.
  - `internal_notes` (`string | null`) - Internal notes shown in the Notes box next to presenting problem on the Carebit lead enquiry screen. Distinct from `referral_notes`.
  - `is_opted_out_of_sms` (`boolean`) - Whether the lead has opted out of SMS communication.
  - `is_signed_up_to_newsletters` (`boolean`) - Whether the lead has signed up to receive newsletters.
  - `last_name` (`string`) - The last name of the lead. Required on create.
  - `lead_type` (`string`) - enum: `inquiry`, `referral`; Whether to treat the record as a patient enquiry or a referral. Defaults to `inquiry` on create.
  - `mobile` (`string | null`) - The mobile phone number of the lead, without the country dial code.
  - `mobile_country_dial_code` (`string | null`) - The ISO 3166-1 alpha-2 country code that selects the international dial code for `mobile`, for example `GB` selects `+44`.
  - `organization_privacy_policy_consent_granted_at` (`string | null`) - format: `date-time`; The ISO 8601 UTC timestamp at which the lead granted consent to the Organization's privacy policy.
  - `phone` (`string | null`) - The landline phone number of the lead, without the country dial code.
  - `phone_country_dial_code` (`string | null`) - The ISO 3166-1 alpha-2 country code that selects the international dial code for `phone`, for example `GB` selects `+44`.
  - `postcode` (`string | null`) - The postal code in the lead's postal address.
  - `presenting_problem` (`string | null`) - The presenting problem the lead described. Shown next to Notes on the Carebit lead enquiry screen.
  - `referral_notes` (`string | null`) - The referral notes shown on the Carebit lead enquiry screen.
  - `referral_source` (`string | null`) - enum: `consultant`, `embassy`, `family_or_friend`, `gp_practice`, `hospital`, `insurance_company`, `physiotherapist`, `presentation_talk`, `previous_patient`, `private_practice`, `search_engine`, `self_referral`, `social_media`, `website`, `other`, `null`; The referral source shown on the Carebit lead enquiry screen.
  - `service_id` (`string | null`) - format: `uuid`; The Service the Lead is enquiring about. It must belong to your Organization. Pass `null` to clear.
  - `sex` (`string | null`) - The sex of the Lead as supplied on the enquiry.
  - `title` (`string | null`) - The personal title of the lead, when recorded.

### Example

```json
{
  "attachments": [
    {
      "filename": "referral-letter.pdf",
      "url": "https://files.example.com/referral-letter.pdf"
    }
  ],
  "clinician_id": "00000000-0000-4000-8000-000000000002",
  "country_code": "GB",
  "email": "riley.cooper@example.invalid",
  "first_name": "Riley",
  "internal_notes": "Asked about evening appointments with Dr Smith.",
  "last_name": "Cooper",
  "lead_type": "inquiry",
  "mobile": "7700900123",
  "mobile_country_dial_code": "GB",
  "presenting_problem": "Right knee pain",
  "referral_notes": "Referred by Dr Patel at Riverside Medical.",
  "referral_source": "gp_practice",
  "service_id": "00000000-0000-4000-8000-000000000005"
}
```

## Response `201`

Lead created.

- `object`
  - `address_line_1` (`string | null`) - The primary address line of the lead.
  - `address_line_2` (`string | null`) - The secondary address line of the lead.
  - `attachments` (`array`) - The files attached to the lead.
    - `items` (`object`)
      - `download_url` (`string | null`) - format: `uri`; The short-lived signed download URL for the attachment. Null while the malware scan is not complete.
      - `filename` (`string | null`) - The original filename of the attachment.
      - `id` (`string`) - format: `uuid`; The resource's unique identifier, formatted as an RFC 4122 version 4 UUID.
  - `city` (`string | null`) - The city in the lead's postal address.
  - `clinician` (`any`) - The clinician the lead is assigned to, when recorded.
  - `country_code` (`string | null`) - The ISO 3166-1 alpha-2 country code for the postal address, such as `GB` for the United Kingdom.
  - `county` (`string | null`) - The county or region in the lead's postal address.
  - `created_at` (`string`) - format: `date-time`; An ISO 8601 timestamp in UTC, with a `Z` suffix. For example, `2026-07-01T09:00:00Z`.
  - `creation_source` (`string | null`) - How the Lead was created. `api` means the record was created through the Developer Platform API. Read-only.
  - `date_of_birth` (`string | null`) - format: `date`; The date of birth of the lead, in ISO 8601 format (YYYY-MM-DD).
  - `display_name` (`string | null`) - The formatted display name of the lead, including their title when recorded.
  - `email` (`string | null`) - format: `email`; The contact email address of the lead.
  - `first_name` (`string`) - The first name of the lead.
  - `form_responses` (`array`) - The forms this lead submitted, oldest first. Follow each `url` for the answers. Enquiries a staff member recorded by hand are not listed, because they have no form.
    - `items` (`object`)
      - `form_name` (`string`) - The name of the form the respondent submitted.
      - `form_type` (`string`) - enum: `inquiry_form`, `referral_form`; Whether the submission came from an enquiry form or a referral form.
      - `id` (`string`) - format: `uuid`; The resource's unique identifier, formatted as an RFC 4122 version 4 UUID.
      - `submitted_at` (`string`) - format: `date-time`; An ISO 8601 timestamp in UTC, with a `Z` suffix. For example, `2026-07-01T09:00:00Z`.
      - `url` (`string`) - format: `uri`; The full URL of a related resource.
  - `gdpr_consent_granted_at` (`string | null`) - format: `date-time`; An ISO 8601 timestamp in UTC, with a `Z` suffix. For example, `2026-07-01T09:00:00Z`.
  - `gdpr_consent_withdrawn_at` (`string | null`) - format: `date-time`; An ISO 8601 timestamp in UTC, with a `Z` suffix. For example, `2026-07-01T09:00:00Z`.
  - `id` (`string`) - format: `uuid`; The resource's unique identifier, formatted as an RFC 4122 version 4 UUID.
  - `internal_notes` (`string | null`) - Internal notes shown in the Notes box next to presenting problem on the Carebit lead enquiry screen. Distinct from `referral_notes`.
  - `is_converted_to_patient` (`boolean`) - Whether the lead has been converted to a patient. Read-only.
  - `is_lost` (`boolean`) - Whether the lead's current pipeline stage is a lost stage. A lost stage has the `mark_lead_lost` action, or the title Lost or Rejected. Read-only.
  - `is_opted_out_of_sms` (`boolean`) - Whether the lead has opted out of SMS communication.
  - `is_signed_up_to_newsletters` (`boolean`) - Whether the lead has signed up to receive newsletters.
  - `last_name` (`string`) - The last name of the lead.
  - `lead_type` (`string`) - enum: `inquiry`, `referral`; Whether the record is a patient enquiry or a referral.
  - `links` (`object`) - URLs to related resources. `remote_file_import_batch` is present on create responses when at least one attachment was submitted.
    - `clinician` (`string | null`) - format: `uri`; The full URL of a related resource.
    - `remote_file_import_batch` (`string`) - format: `uri`; The full URL of a related resource.
    - `self` (`string`) - format: `uri`; The full URL of a related resource.
    - `service` (`string | null`) - format: `uri`; The full URL of a related resource.
  - `mobile` (`string | null`) - The mobile phone number of the lead, without the country dial code.
  - `mobile_country_dial_code` (`string | null`) - The ISO 3166-1 alpha-2 country code that selects the international dial code for `mobile`, for example `GB` selects `+44`.
  - `object` (`any`) - Discriminator value emitted at `object`.
  - `organization_privacy_policy_consent_granted_at` (`string | null`) - format: `date-time`; An ISO 8601 timestamp in UTC, with a `Z` suffix. For example, `2026-07-01T09:00:00Z`.
  - `patient_id` (`string | null`) - format: `uuid`; The identifier of the Patient this Lead was converted to. Null until conversion. Read-only.
  - `phone` (`string | null`) - The landline phone number of the lead, without the country dial code.
  - `phone_country_dial_code` (`string | null`) - The ISO 3166-1 alpha-2 country code that selects the international dial code for `phone`, for example `GB` selects `+44`.
  - `postcode` (`string | null`) - The postal code in the lead's postal address.
  - `presenting_problem` (`string | null`) - The presenting problem the lead described. Shown next to Notes on the Carebit lead enquiry screen.
  - `referral_notes` (`string | null`) - The referral notes shown on the Carebit lead enquiry screen.
  - `referral_source` (`string | null`) - enum: `consultant`, `embassy`, `family_or_friend`, `gp_practice`, `hospital`, `insurance_company`, `physiotherapist`, `presentation_talk`, `previous_patient`, `private_practice`, `search_engine`, `self_referral`, `social_media`, `website`, `other`, `null`; The referral source shown on the Carebit lead enquiry screen.
  - `referred_by_clinician_id` (`string | null`) - format: `uuid`; The Clinician who referred this Lead, when one was identified. Taken from the Lead's first submission that identified one; a per-submission value is on the LeadFormResponse.
  - `referred_by_organization_id` (`string | null`) - format: `uuid`; The Organization that referred this Lead, when one was identified. Taken from the Lead's first submission that identified one; a per-submission value is on the LeadFormResponse.
  - `remote_file_import_batch_id` (`string`) - format: `uuid`; The identifier of the remote file import batch created for the submitted attachments. Present on create responses when at least one attachment was submitted.
  - `service` (`any`) - The Service the Lead is enquiring about, when recorded.
  - `sex` (`string | null`) - The sex of the Lead as supplied on the enquiry.
  - `stage` (`any`) - The current pipeline stage of the lead. Read-only; use `stage_id` when updating the lead.
  - `title` (`string | null`) - The personal title of the lead, when recorded.
  - `updated_at` (`string`) - format: `date-time`; An ISO 8601 timestamp in UTC, with a `Z` suffix. For example, `2026-07-01T09:00:00Z`.

### Example

```json
{
  "id": "00000000-0000-4000-8000-00000000000c",
  "object": "lead",
  "address_line_1": "10 Harley Street",
  "address_line_2": "Marylebone",
  "attachments": [
    {
      "id": "f631636b-32e2-41be-8e4f-0a34ee0d5d59",
      "download_url": "https://files.example.invalid/document.pdf?signature=test",
      "filename": "referral-letter.pdf"
    }
  ],
  "city": "London",
  "clinician": {
    "id": "00000000-0000-4000-8000-000000000002",
    "object": "clinician",
    "created_at": "2026-01-01T09:00:00Z",
    "display_name": "Dr Alex Morgan",
    "email": "alex.morgan@example.com",
    "first_name": "Alex",
    "last_name": "Morgan",
    "links": {
      "bookings": "https://api.carebit.co/v1/bookings?clinician_id=00000000-0000-4000-8000-000000000002"
    },
    "medical_specialty": "Cardiology",
    "title": "Dr",
    "updated_at": "2026-01-01T09:00:00Z"
  },
  "country_code": "GB",
  "county": "Greater London",
  "created_at": "2026-01-01T09:00:00Z",
  "creation_source": "api",
  "date_of_birth": "1990-01-01",
  "display_name": "Dr Alex Morgan",
  "email": "alex.morgan@example.com",
  "first_name": "Alex",
  "form_responses": [
    {
      "id": "adf881b8-4eed-42c0-8903-515f6cc8a134",
      "form_name": "New patient inquiry",
      "form_type": "inquiry_form",
      "submitted_at": "2026-01-01T09:00:00Z",
      "url": "https://files.example.invalid/document.pdf?signature=test"
    }
  ],
  "gdpr_consent_granted_at": "2026-01-01T09:00:00Z",
  "gdpr_consent_withdrawn_at": "2026-01-01T09:00:00Z",
  "internal_notes": "Asked about evening appointments with Dr Smith.",
  "is_converted_to_patient": true,
  "is_lost": false,
  "is_opted_out_of_sms": false,
  "is_signed_up_to_newsletters": true,
  "last_name": "Morgan",
  "lead_type": "inquiry",
  "links": {
    "clinician": "https://api.carebit.co/v1/clinicians/00000000-0000-4000-8000-000000000002",
    "remote_file_import_batch": "https://api.carebit.co/v1/remote_file_import_batches/00000000-0000-4000-8000-00000000000a",
    "self": "https://api.carebit.co/v1/leads/00000000-0000-4000-8000-00000000000c",
    "service": "https://api.carebit.co/v1/services/00000000-0000-4000-8000-000000000005"
  },
  "mobile": "7700900123",
  "mobile_country_dial_code": "GB",
  "organization_privacy_policy_consent_granted_at": "2026-01-01T09:00:00Z",
  "patient_id": "00000000-0000-4000-8000-000000000004",
  "phone": "2071234567",
  "phone_country_dial_code": "GB",
  "postcode": "W1G 9PF",
  "presenting_problem": "Persistent right knee pain",
  "referral_notes": "Referred by Dr Patel at Riverside Medical.",
  "referral_source": "consultant",
  "referred_by_clinician_id": "b5ac896f-f746-4df1-899a-c12d33b84b2d",
  "referred_by_organization_id": "8cda84a9-bf46-4f81-8f3c-66dd352e95db",
  "remote_file_import_batch_id": "00000000-0000-4000-8000-00000000000a",
  "service": {
    "id": "00000000-0000-4000-8000-000000000005",
    "object": "service",
    "created_at": "2026-01-01T09:00:00Z",
    "description": "An initial consultation at the Harley Street Clinic.",
    "duration_minutes": 30,
    "is_bookable_online": true,
    "name": "Initial consultation",
    "service_variants": [
      {
        "id": "00000000-0000-4000-8000-000000000006",
        "clinician_id": "00000000-0000-4000-8000-000000000002",
        "currency": "GBP",
        "description": "An initial consultation at the Harley Street Clinic.",
        "links": {
          "clinician": "https://api.carebit.co/v1/clinicians/00000000-0000-4000-8000-000000000002",
          "location": "https://api.carebit.co/v1/locations/00000000-0000-4000-8000-000000000003"
        },
        "location_id": "00000000-0000-4000-8000-000000000003",
        "net_price": 1,
        "permits_remote_bookings": true
      }
    ],
    "tax_rate": {
      "id": "00000000-0000-4000-8000-000000000029",
      "description": "An initial consultation at the Harley Street Clinic.",
      "percentage": 20,
      "title": "VAT"
    },
    "updated_at": "2026-01-01T09:00:00Z"
  },
  "sex": "female",
  "stage": {
    "id": "00000000-0000-4000-8000-00000000000d",
    "object": "lead_stage",
    "created_at": "2026-01-01T09:00:00Z",
    "is_conversion_stage": true,
    "is_lost_stage": true,
    "name": "Initial consultation",
    "position": 1,
    "updated_at": "2026-01-01T09:00:00Z"
  },
  "title": "Dr",
  "updated_at": "2026-01-01T09:00:00Z"
}
```

## Response `400`

The `Idempotency-Key` header is missing (`idempotency_key_required`) or exceeds 255 characters (`idempotency_key_too_long`).

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Response `401`

The access token is missing, invalid, expired, or revoked.

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Response `403`

The access token lacks the required scope, the project is disabled, or the Organization does not have Carebit Pro.

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Response `404`

A referenced resource was not found in your Organization.

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Response `409`

A concurrent request holds the idempotency lease (`idempotency_conflict`). Retry after the delay indicated by `Retry-After`.

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Response `422`

The `Idempotency-Key` was previously used with a different request body (`idempotency_key_reused`), or the request body failed validation.

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Response `429`

Too many requests. Retry after the delay indicated by `Retry-After`.

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Code samples

```bash
curl -X POST "https://api.carebit.co/v1/leads" \
  -H "Authorization: Bearer $CAREBIT_ACCESS_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "attachments": [
    {
      "filename": "referral-letter.pdf",
      "url": "https://files.example.com/referral-letter.pdf"
    }
  ],
  "clinician_id": "00000000-0000-4000-8000-000000000002",
  "country_code": "GB",
  "email": "riley.cooper@example.invalid",
  "first_name": "Riley",
  "internal_notes": "Asked about evening appointments with Dr Smith.",
  "last_name": "Cooper",
  "lead_type": "inquiry",
  "mobile": "7700900123",
  "mobile_country_dial_code": "GB",
  "presenting_problem": "Right knee pain",
  "referral_notes": "Referred by Dr Patel at Riverside Medical.",
  "referral_source": "gp_practice",
  "service_id": "00000000-0000-4000-8000-000000000005"
}'
```

```javascript
const response = await fetch("https://api.carebit.co/v1/leads", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CAREBIT_ACCESS_TOKEN}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
  "attachments": [
    {
      "filename": "referral-letter.pdf",
      "url": "https://files.example.com/referral-letter.pdf"
    }
  ],
  "clinician_id": "00000000-0000-4000-8000-000000000002",
  "country_code": "GB",
  "email": "riley.cooper@example.invalid",
  "first_name": "Riley",
  "internal_notes": "Asked about evening appointments with Dr Smith.",
  "last_name": "Cooper",
  "lead_type": "inquiry",
  "mobile": "7700900123",
  "mobile_country_dial_code": "GB",
  "presenting_problem": "Right knee pain",
  "referral_notes": "Referred by Dr Patel at Riverside Medical.",
  "referral_source": "gp_practice",
  "service_id": "00000000-0000-4000-8000-000000000005"
}),
});

if (!response.ok) {
  throw new Error(`Carebit API error: ${response.status}`);
}

const data = await response.json();
```

```python
import os
import requests
import uuid

response = requests.post(
    "https://api.carebit.co/v1/leads",
    headers={
        "Authorization": f"Bearer {os.environ['CAREBIT_ACCESS_TOKEN']}",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "attachments": [
            {
                "filename": "referral-letter.pdf",
                "url": "https://files.example.com/referral-letter.pdf"
            }
        ],
        "clinician_id": "00000000-0000-4000-8000-000000000002",
        "country_code": "GB",
        "email": "riley.cooper@example.invalid",
        "first_name": "Riley",
        "internal_notes": "Asked about evening appointments with Dr Smith.",
        "last_name": "Cooper",
        "lead_type": "inquiry",
        "mobile": "7700900123",
        "mobile_country_dial_code": "GB",
        "presenting_problem": "Right knee pain",
        "referral_notes": "Referred by Dr Patel at Riverside Medical.",
        "referral_source": "gp_practice",
        "service_id": "00000000-0000-4000-8000-000000000005"
    }
)
response.raise_for_status()
data = response.json()
```

```ruby
require "httparty"
require "json"
require "securerandom"

response = HTTParty.post(
  "https://api.carebit.co/v1/leads",
  headers: {
    "Authorization" => "Bearer #{ENV.fetch("CAREBIT_ACCESS_TOKEN")}",
    "Idempotency-Key" => SecureRandom.uuid,
    "Content-Type" => "application/json"
  },
  body: {
    "attachments" => [
      {
        "filename" => "referral-letter.pdf",
        "url" => "https://files.example.com/referral-letter.pdf"
      }
    ],
    "clinician_id" => "00000000-0000-4000-8000-000000000002",
    "country_code" => "GB",
    "email" => "riley.cooper@example.invalid",
    "first_name" => "Riley",
    "internal_notes" => "Asked about evening appointments with Dr Smith.",
    "last_name" => "Cooper",
    "lead_type" => "inquiry",
    "mobile" => "7700900123",
    "mobile_country_dial_code" => "GB",
    "presenting_problem" => "Right knee pain",
    "referral_notes" => "Referred by Dr Patel at Riverside Medical.",
    "referral_source" => "gp_practice",
    "service_id" => "00000000-0000-4000-8000-000000000005"
  }.to_json
)
raise "Carebit API error: #{response.code}" unless response.success?
data = response.parsed_response
```

```php
<?php

$client = new GuzzleHttp\Client();

$response = $client->post("https://api.carebit.co/v1/leads", [
    "headers" => [
      "Authorization" => "Bearer " . getenv("CAREBIT_ACCESS_TOKEN"),
      "Idempotency-Key" => bin2hex(random_bytes(16)),
    ],
    "json" => [
      "attachments" => [
        [
          "filename" => "referral-letter.pdf",
          "url" => "https://files.example.com/referral-letter.pdf"
        ]
      ],
      "clinician_id" => "00000000-0000-4000-8000-000000000002",
      "country_code" => "GB",
      "email" => "riley.cooper@example.invalid",
      "first_name" => "Riley",
      "internal_notes" => "Asked about evening appointments with Dr Smith.",
      "last_name" => "Cooper",
      "lead_type" => "inquiry",
      "mobile" => "7700900123",
      "mobile_country_dial_code" => "GB",
      "presenting_problem" => "Right knee pain",
      "referral_notes" => "Referred by Dr Patel at Riverside Medical.",
      "referral_source" => "gp_practice",
      "service_id" => "00000000-0000-4000-8000-000000000005"
    ]
]);
$data = json_decode((string) $response->getBody(), true, flags: JSON_THROW_ON_ERROR);
```


## Get a Lead

`GET /v1/leads/:id`

Returns a patient enquiry or referral from the Organization. A discarded lead that is not in a lost stage is not found. Carebit Pro is required.

**Required API scopes:** `leads.read`

## Parameters

- `id` (path, `string`) (required)

## Response `200`

The requested `Lead`.

- `object`
  - `address_line_1` (`string | null`) - The primary address line of the lead.
  - `address_line_2` (`string | null`) - The secondary address line of the lead.
  - `attachments` (`array`) - The files attached to the lead.
    - `items` (`object`)
      - `download_url` (`string | null`) - format: `uri`; The short-lived signed download URL for the attachment. Null while the malware scan is not complete.
      - `filename` (`string | null`) - The original filename of the attachment.
      - `id` (`string`) - format: `uuid`; The resource's unique identifier, formatted as an RFC 4122 version 4 UUID.
  - `city` (`string | null`) - The city in the lead's postal address.
  - `clinician` (`any`) - The clinician the lead is assigned to, when recorded.
  - `country_code` (`string | null`) - The ISO 3166-1 alpha-2 country code for the postal address, such as `GB` for the United Kingdom.
  - `county` (`string | null`) - The county or region in the lead's postal address.
  - `created_at` (`string`) - format: `date-time`; An ISO 8601 timestamp in UTC, with a `Z` suffix. For example, `2026-07-01T09:00:00Z`.
  - `creation_source` (`string | null`) - How the Lead was created. `api` means the record was created through the Developer Platform API. Read-only.
  - `date_of_birth` (`string | null`) - format: `date`; The date of birth of the lead, in ISO 8601 format (YYYY-MM-DD).
  - `display_name` (`string | null`) - The formatted display name of the lead, including their title when recorded.
  - `email` (`string | null`) - format: `email`; The contact email address of the lead.
  - `first_name` (`string`) - The first name of the lead.
  - `form_responses` (`array`) - The forms this lead submitted, oldest first. Follow each `url` for the answers. Enquiries a staff member recorded by hand are not listed, because they have no form.
    - `items` (`object`)
      - `form_name` (`string`) - The name of the form the respondent submitted.
      - `form_type` (`string`) - enum: `inquiry_form`, `referral_form`; Whether the submission came from an enquiry form or a referral form.
      - `id` (`string`) - format: `uuid`; The resource's unique identifier, formatted as an RFC 4122 version 4 UUID.
      - `submitted_at` (`string`) - format: `date-time`; An ISO 8601 timestamp in UTC, with a `Z` suffix. For example, `2026-07-01T09:00:00Z`.
      - `url` (`string`) - format: `uri`; The full URL of a related resource.
  - `gdpr_consent_granted_at` (`string | null`) - format: `date-time`; An ISO 8601 timestamp in UTC, with a `Z` suffix. For example, `2026-07-01T09:00:00Z`.
  - `gdpr_consent_withdrawn_at` (`string | null`) - format: `date-time`; An ISO 8601 timestamp in UTC, with a `Z` suffix. For example, `2026-07-01T09:00:00Z`.
  - `id` (`string`) - format: `uuid`; The resource's unique identifier, formatted as an RFC 4122 version 4 UUID.
  - `internal_notes` (`string | null`) - Internal notes shown in the Notes box next to presenting problem on the Carebit lead enquiry screen. Distinct from `referral_notes`.
  - `is_converted_to_patient` (`boolean`) - Whether the lead has been converted to a patient. Read-only.
  - `is_lost` (`boolean`) - Whether the lead's current pipeline stage is a lost stage. A lost stage has the `mark_lead_lost` action, or the title Lost or Rejected. Read-only.
  - `is_opted_out_of_sms` (`boolean`) - Whether the lead has opted out of SMS communication.
  - `is_signed_up_to_newsletters` (`boolean`) - Whether the lead has signed up to receive newsletters.
  - `last_name` (`string`) - The last name of the lead.
  - `lead_type` (`string`) - enum: `inquiry`, `referral`; Whether the record is a patient enquiry or a referral.
  - `links` (`object`) - URLs to related resources. `remote_file_import_batch` is present on create responses when at least one attachment was submitted.
    - `clinician` (`string | null`) - format: `uri`; The full URL of a related resource.
    - `remote_file_import_batch` (`string`) - format: `uri`; The full URL of a related resource.
    - `self` (`string`) - format: `uri`; The full URL of a related resource.
    - `service` (`string | null`) - format: `uri`; The full URL of a related resource.
  - `mobile` (`string | null`) - The mobile phone number of the lead, without the country dial code.
  - `mobile_country_dial_code` (`string | null`) - The ISO 3166-1 alpha-2 country code that selects the international dial code for `mobile`, for example `GB` selects `+44`.
  - `object` (`any`) - Discriminator value emitted at `object`.
  - `organization_privacy_policy_consent_granted_at` (`string | null`) - format: `date-time`; An ISO 8601 timestamp in UTC, with a `Z` suffix. For example, `2026-07-01T09:00:00Z`.
  - `patient_id` (`string | null`) - format: `uuid`; The identifier of the Patient this Lead was converted to. Null until conversion. Read-only.
  - `phone` (`string | null`) - The landline phone number of the lead, without the country dial code.
  - `phone_country_dial_code` (`string | null`) - The ISO 3166-1 alpha-2 country code that selects the international dial code for `phone`, for example `GB` selects `+44`.
  - `postcode` (`string | null`) - The postal code in the lead's postal address.
  - `presenting_problem` (`string | null`) - The presenting problem the lead described. Shown next to Notes on the Carebit lead enquiry screen.
  - `referral_notes` (`string | null`) - The referral notes shown on the Carebit lead enquiry screen.
  - `referral_source` (`string | null`) - enum: `consultant`, `embassy`, `family_or_friend`, `gp_practice`, `hospital`, `insurance_company`, `physiotherapist`, `presentation_talk`, `previous_patient`, `private_practice`, `search_engine`, `self_referral`, `social_media`, `website`, `other`, `null`; The referral source shown on the Carebit lead enquiry screen.
  - `referred_by_clinician_id` (`string | null`) - format: `uuid`; The Clinician who referred this Lead, when one was identified. Taken from the Lead's first submission that identified one; a per-submission value is on the LeadFormResponse.
  - `referred_by_organization_id` (`string | null`) - format: `uuid`; The Organization that referred this Lead, when one was identified. Taken from the Lead's first submission that identified one; a per-submission value is on the LeadFormResponse.
  - `remote_file_import_batch_id` (`string`) - format: `uuid`; The identifier of the remote file import batch created for the submitted attachments. Present on create responses when at least one attachment was submitted.
  - `service` (`any`) - The Service the Lead is enquiring about, when recorded.
  - `sex` (`string | null`) - The sex of the Lead as supplied on the enquiry.
  - `stage` (`any`) - The current pipeline stage of the lead. Read-only; use `stage_id` when updating the lead.
  - `title` (`string | null`) - The personal title of the lead, when recorded.
  - `updated_at` (`string`) - format: `date-time`; An ISO 8601 timestamp in UTC, with a `Z` suffix. For example, `2026-07-01T09:00:00Z`.

### Example

```json
{
  "id": "00000000-0000-4000-8000-00000000000c",
  "object": "lead",
  "address_line_1": "10 Harley Street",
  "address_line_2": "Marylebone",
  "attachments": [
    {
      "id": "f631636b-32e2-41be-8e4f-0a34ee0d5d59",
      "download_url": "https://files.example.invalid/document.pdf?signature=test",
      "filename": "referral-letter.pdf"
    }
  ],
  "city": "London",
  "clinician": {
    "id": "00000000-0000-4000-8000-000000000002",
    "object": "clinician",
    "created_at": "2026-01-01T09:00:00Z",
    "display_name": "Dr Alex Morgan",
    "email": "alex.morgan@example.com",
    "first_name": "Alex",
    "last_name": "Morgan",
    "links": {
      "bookings": "https://api.carebit.co/v1/bookings?clinician_id=00000000-0000-4000-8000-000000000002"
    },
    "medical_specialty": "Cardiology",
    "title": "Dr",
    "updated_at": "2026-01-01T09:00:00Z"
  },
  "country_code": "GB",
  "county": "Greater London",
  "created_at": "2026-01-01T09:00:00Z",
  "creation_source": "api",
  "date_of_birth": "1990-01-01",
  "display_name": "Dr Alex Morgan",
  "email": "alex.morgan@example.com",
  "first_name": "Alex",
  "form_responses": [
    {
      "id": "adf881b8-4eed-42c0-8903-515f6cc8a134",
      "form_name": "New patient inquiry",
      "form_type": "inquiry_form",
      "submitted_at": "2026-01-01T09:00:00Z",
      "url": "https://files.example.invalid/document.pdf?signature=test"
    }
  ],
  "gdpr_consent_granted_at": "2026-01-01T09:00:00Z",
  "gdpr_consent_withdrawn_at": "2026-01-01T09:00:00Z",
  "internal_notes": "Asked about evening appointments with Dr Smith.",
  "is_converted_to_patient": true,
  "is_lost": false,
  "is_opted_out_of_sms": false,
  "is_signed_up_to_newsletters": true,
  "last_name": "Morgan",
  "lead_type": "inquiry",
  "links": {
    "clinician": "https://api.carebit.co/v1/clinicians/00000000-0000-4000-8000-000000000002",
    "remote_file_import_batch": "https://api.carebit.co/v1/remote_file_import_batches/00000000-0000-4000-8000-00000000000a",
    "self": "https://api.carebit.co/v1/leads/00000000-0000-4000-8000-00000000000c",
    "service": "https://api.carebit.co/v1/services/00000000-0000-4000-8000-000000000005"
  },
  "mobile": "7700900123",
  "mobile_country_dial_code": "GB",
  "organization_privacy_policy_consent_granted_at": "2026-01-01T09:00:00Z",
  "patient_id": "00000000-0000-4000-8000-000000000004",
  "phone": "2071234567",
  "phone_country_dial_code": "GB",
  "postcode": "W1G 9PF",
  "presenting_problem": "Persistent right knee pain",
  "referral_notes": "Referred by Dr Patel at Riverside Medical.",
  "referral_source": "consultant",
  "referred_by_clinician_id": "b5ac896f-f746-4df1-899a-c12d33b84b2d",
  "referred_by_organization_id": "8cda84a9-bf46-4f81-8f3c-66dd352e95db",
  "remote_file_import_batch_id": "00000000-0000-4000-8000-00000000000a",
  "service": {
    "id": "00000000-0000-4000-8000-000000000005",
    "object": "service",
    "created_at": "2026-01-01T09:00:00Z",
    "description": "An initial consultation at the Harley Street Clinic.",
    "duration_minutes": 30,
    "is_bookable_online": true,
    "name": "Initial consultation",
    "service_variants": [
      {
        "id": "00000000-0000-4000-8000-000000000006",
        "clinician_id": "00000000-0000-4000-8000-000000000002",
        "currency": "GBP",
        "description": "An initial consultation at the Harley Street Clinic.",
        "links": {
          "clinician": "https://api.carebit.co/v1/clinicians/00000000-0000-4000-8000-000000000002",
          "location": "https://api.carebit.co/v1/locations/00000000-0000-4000-8000-000000000003"
        },
        "location_id": "00000000-0000-4000-8000-000000000003",
        "net_price": 1,
        "permits_remote_bookings": true
      }
    ],
    "tax_rate": {
      "id": "00000000-0000-4000-8000-000000000029",
      "description": "An initial consultation at the Harley Street Clinic.",
      "percentage": 20,
      "title": "VAT"
    },
    "updated_at": "2026-01-01T09:00:00Z"
  },
  "sex": "female",
  "stage": {
    "id": "00000000-0000-4000-8000-00000000000d",
    "object": "lead_stage",
    "created_at": "2026-01-01T09:00:00Z",
    "is_conversion_stage": true,
    "is_lost_stage": true,
    "name": "Initial consultation",
    "position": 1,
    "updated_at": "2026-01-01T09:00:00Z"
  },
  "title": "Dr",
  "updated_at": "2026-01-01T09:00:00Z"
}
```

## Response `401`

The access token is missing, invalid, expired, or revoked.

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Response `403`

The access token lacks the required scope, the project is disabled, or the Organization does not have Carebit Pro.

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Response `404`

Error response.

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Response `429`

Too many requests. Retry after the delay indicated by `Retry-After`.

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Code samples

```bash
curl -X GET "https://api.carebit.co/v1/leads/00000000-0000-4000-8000-00000000000c" \
  -H "Authorization: Bearer $CAREBIT_ACCESS_TOKEN"
```

```javascript
const response = await fetch("https://api.carebit.co/v1/leads/00000000-0000-4000-8000-00000000000c", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.CAREBIT_ACCESS_TOKEN}`,
  },
});

if (!response.ok) {
  throw new Error(`Carebit API error: ${response.status}`);
}

const data = await response.json();
```

```python
import os
import requests

response = requests.get(
    "https://api.carebit.co/v1/leads/00000000-0000-4000-8000-00000000000c",
    headers={
        "Authorization": f"Bearer {os.environ['CAREBIT_ACCESS_TOKEN']}",
    }
)
response.raise_for_status()
data = response.json()
```

```ruby
require "httparty"

response = HTTParty.get(
  "https://api.carebit.co/v1/leads/00000000-0000-4000-8000-00000000000c",
  headers: {
    "Authorization" => "Bearer #{ENV.fetch("CAREBIT_ACCESS_TOKEN")}"
  }
)
raise "Carebit API error: #{response.code}" unless response.success?
data = response.parsed_response
```

```php
<?php

$client = new GuzzleHttp\Client();

$response = $client->get("https://api.carebit.co/v1/leads/00000000-0000-4000-8000-00000000000c", [
    "headers" => [
      "Authorization" => "Bearer " . getenv("CAREBIT_ACCESS_TOKEN"),
    ]
]);
$data = json_decode((string) $response->getBody(), true, flags: JSON_THROW_ON_ERROR);
```


## Update a Lead

`PATCH /v1/leads/:id`

Updates any patient enquiry or referral in the Organization, regardless of how it was created. Use `stage_id` to move the Lead within the pipeline for its resulting `lead_type`. Conversion and lost stages can start the Organization's configured workflows. Attribution and lifecycle fields are read-only. Carebit Pro is required.

**Required API scopes:** `leads.update`

## Parameters

- `id` (path, `string`) (required)
- `Idempotency-Key` (header, `string`) (required) - Client-generated idempotency key. Required for every POST/PATCH write. Replay of the same key with the same body returns the stored response with an `Idempotency-Replayed: true` header. Same key + different body returns `422 idempotency_key_reused`. A duplicate that arrives while the first request is still in flight returns `409 idempotency_conflict` with `Retry-After: 1`.

## Request body (`application/json`)

- `object`
  - `address_line_1` (`string | null`) - The primary address line of the lead.
  - `address_line_2` (`string | null`) - The secondary address line of the lead.
  - `city` (`string | null`) - The city in the lead's postal address.
  - `clinician_id` (`string | null`) - format: `uuid`; The identifier of the clinician the lead is assigned to. Must be a clinician enabled in your Organization. Pass `null` to unassign.
  - `country_code` (`string | null`) - The uppercase ISO 3166-1 alpha-2 country code for the lead's postal address.
  - `county` (`string | null`) - The county or region in the lead's postal address.
  - `date_of_birth` (`string | null`) - format: `date`; The date of birth of the lead, in ISO 8601 format (YYYY-MM-DD).
  - `email` (`string | null`) - format: `email`; The contact email address of the lead.
  - `first_name` (`string`) - The first name of the lead. Required on create.
  - `gdpr_consent_granted_at` (`string | null`) - format: `date-time`; The ISO 8601 UTC timestamp at which the lead granted GDPR consent.
  - `gdpr_consent_withdrawn_at` (`string | null`) - format: `date-time`; The ISO 8601 UTC timestamp at which the lead withdrew GDPR consent.
  - `internal_notes` (`string | null`) - Internal notes shown in the Notes box next to presenting problem on the Carebit lead enquiry screen. Distinct from `referral_notes`.
  - `is_opted_out_of_sms` (`boolean`) - Whether the lead has opted out of SMS communication.
  - `is_signed_up_to_newsletters` (`boolean`) - Whether the lead has signed up to receive newsletters.
  - `last_name` (`string`) - The last name of the lead. Required on create.
  - `lead_type` (`string`) - enum: `inquiry`, `referral`; Whether to treat the record as a patient enquiry or a referral. Defaults to `inquiry` on create.
  - `mobile` (`string | null`) - The mobile phone number of the lead, without the country dial code.
  - `mobile_country_dial_code` (`string | null`) - The ISO 3166-1 alpha-2 country code that selects the international dial code for `mobile`, for example `GB` selects `+44`.
  - `organization_privacy_policy_consent_granted_at` (`string | null`) - format: `date-time`; The ISO 8601 UTC timestamp at which the lead granted consent to the Organization's privacy policy.
  - `phone` (`string | null`) - The landline phone number of the lead, without the country dial code.
  - `phone_country_dial_code` (`string | null`) - The ISO 3166-1 alpha-2 country code that selects the international dial code for `phone`, for example `GB` selects `+44`.
  - `postcode` (`string | null`) - The postal code in the lead's postal address.
  - `presenting_problem` (`string | null`) - The presenting problem the lead described. Shown next to Notes on the Carebit lead enquiry screen.
  - `referral_notes` (`string | null`) - The referral notes shown on the Carebit lead enquiry screen.
  - `referral_source` (`string | null`) - enum: `consultant`, `embassy`, `family_or_friend`, `gp_practice`, `hospital`, `insurance_company`, `physiotherapist`, `presentation_talk`, `previous_patient`, `private_practice`, `search_engine`, `self_referral`, `social_media`, `website`, `other`, `null`; The referral source shown on the Carebit lead enquiry screen.
  - `service_id` (`string | null`) - format: `uuid`; The Service the Lead is enquiring about. It must belong to your Organization. Pass `null` to clear.
  - `sex` (`string | null`) - The sex of the Lead as supplied on the enquiry.
  - `stage_id` (`string`) - format: `uuid`; The identifier of a stage in the pipeline that matches the Lead's resulting `lead_type`.
  - `title` (`string | null`) - The personal title of the lead, when recorded.

### Example

```json
{
  "presenting_problem": "Left knee pain (updated)",
  "stage_id": "00000000-0000-4000-8000-00000000000d"
}
```

## Response `200`

The requested `Lead`.

- `object`
  - `address_line_1` (`string | null`) - The primary address line of the lead.
  - `address_line_2` (`string | null`) - The secondary address line of the lead.
  - `attachments` (`array`) - The files attached to the lead.
    - `items` (`object`)
      - `download_url` (`string | null`) - format: `uri`; The short-lived signed download URL for the attachment. Null while the malware scan is not complete.
      - `filename` (`string | null`) - The original filename of the attachment.
      - `id` (`string`) - format: `uuid`; The resource's unique identifier, formatted as an RFC 4122 version 4 UUID.
  - `city` (`string | null`) - The city in the lead's postal address.
  - `clinician` (`any`) - The clinician the lead is assigned to, when recorded.
  - `country_code` (`string | null`) - The ISO 3166-1 alpha-2 country code for the postal address, such as `GB` for the United Kingdom.
  - `county` (`string | null`) - The county or region in the lead's postal address.
  - `created_at` (`string`) - format: `date-time`; An ISO 8601 timestamp in UTC, with a `Z` suffix. For example, `2026-07-01T09:00:00Z`.
  - `creation_source` (`string | null`) - How the Lead was created. `api` means the record was created through the Developer Platform API. Read-only.
  - `date_of_birth` (`string | null`) - format: `date`; The date of birth of the lead, in ISO 8601 format (YYYY-MM-DD).
  - `display_name` (`string | null`) - The formatted display name of the lead, including their title when recorded.
  - `email` (`string | null`) - format: `email`; The contact email address of the lead.
  - `first_name` (`string`) - The first name of the lead.
  - `form_responses` (`array`) - The forms this lead submitted, oldest first. Follow each `url` for the answers. Enquiries a staff member recorded by hand are not listed, because they have no form.
    - `items` (`object`)
      - `form_name` (`string`) - The name of the form the respondent submitted.
      - `form_type` (`string`) - enum: `inquiry_form`, `referral_form`; Whether the submission came from an enquiry form or a referral form.
      - `id` (`string`) - format: `uuid`; The resource's unique identifier, formatted as an RFC 4122 version 4 UUID.
      - `submitted_at` (`string`) - format: `date-time`; An ISO 8601 timestamp in UTC, with a `Z` suffix. For example, `2026-07-01T09:00:00Z`.
      - `url` (`string`) - format: `uri`; The full URL of a related resource.
  - `gdpr_consent_granted_at` (`string | null`) - format: `date-time`; An ISO 8601 timestamp in UTC, with a `Z` suffix. For example, `2026-07-01T09:00:00Z`.
  - `gdpr_consent_withdrawn_at` (`string | null`) - format: `date-time`; An ISO 8601 timestamp in UTC, with a `Z` suffix. For example, `2026-07-01T09:00:00Z`.
  - `id` (`string`) - format: `uuid`; The resource's unique identifier, formatted as an RFC 4122 version 4 UUID.
  - `internal_notes` (`string | null`) - Internal notes shown in the Notes box next to presenting problem on the Carebit lead enquiry screen. Distinct from `referral_notes`.
  - `is_converted_to_patient` (`boolean`) - Whether the lead has been converted to a patient. Read-only.
  - `is_lost` (`boolean`) - Whether the lead's current pipeline stage is a lost stage. A lost stage has the `mark_lead_lost` action, or the title Lost or Rejected. Read-only.
  - `is_opted_out_of_sms` (`boolean`) - Whether the lead has opted out of SMS communication.
  - `is_signed_up_to_newsletters` (`boolean`) - Whether the lead has signed up to receive newsletters.
  - `last_name` (`string`) - The last name of the lead.
  - `lead_type` (`string`) - enum: `inquiry`, `referral`; Whether the record is a patient enquiry or a referral.
  - `links` (`object`) - URLs to related resources. `remote_file_import_batch` is present on create responses when at least one attachment was submitted.
    - `clinician` (`string | null`) - format: `uri`; The full URL of a related resource.
    - `remote_file_import_batch` (`string`) - format: `uri`; The full URL of a related resource.
    - `self` (`string`) - format: `uri`; The full URL of a related resource.
    - `service` (`string | null`) - format: `uri`; The full URL of a related resource.
  - `mobile` (`string | null`) - The mobile phone number of the lead, without the country dial code.
  - `mobile_country_dial_code` (`string | null`) - The ISO 3166-1 alpha-2 country code that selects the international dial code for `mobile`, for example `GB` selects `+44`.
  - `object` (`any`) - Discriminator value emitted at `object`.
  - `organization_privacy_policy_consent_granted_at` (`string | null`) - format: `date-time`; An ISO 8601 timestamp in UTC, with a `Z` suffix. For example, `2026-07-01T09:00:00Z`.
  - `patient_id` (`string | null`) - format: `uuid`; The identifier of the Patient this Lead was converted to. Null until conversion. Read-only.
  - `phone` (`string | null`) - The landline phone number of the lead, without the country dial code.
  - `phone_country_dial_code` (`string | null`) - The ISO 3166-1 alpha-2 country code that selects the international dial code for `phone`, for example `GB` selects `+44`.
  - `postcode` (`string | null`) - The postal code in the lead's postal address.
  - `presenting_problem` (`string | null`) - The presenting problem the lead described. Shown next to Notes on the Carebit lead enquiry screen.
  - `referral_notes` (`string | null`) - The referral notes shown on the Carebit lead enquiry screen.
  - `referral_source` (`string | null`) - enum: `consultant`, `embassy`, `family_or_friend`, `gp_practice`, `hospital`, `insurance_company`, `physiotherapist`, `presentation_talk`, `previous_patient`, `private_practice`, `search_engine`, `self_referral`, `social_media`, `website`, `other`, `null`; The referral source shown on the Carebit lead enquiry screen.
  - `referred_by_clinician_id` (`string | null`) - format: `uuid`; The Clinician who referred this Lead, when one was identified. Taken from the Lead's first submission that identified one; a per-submission value is on the LeadFormResponse.
  - `referred_by_organization_id` (`string | null`) - format: `uuid`; The Organization that referred this Lead, when one was identified. Taken from the Lead's first submission that identified one; a per-submission value is on the LeadFormResponse.
  - `remote_file_import_batch_id` (`string`) - format: `uuid`; The identifier of the remote file import batch created for the submitted attachments. Present on create responses when at least one attachment was submitted.
  - `service` (`any`) - The Service the Lead is enquiring about, when recorded.
  - `sex` (`string | null`) - The sex of the Lead as supplied on the enquiry.
  - `stage` (`any`) - The current pipeline stage of the lead. Read-only; use `stage_id` when updating the lead.
  - `title` (`string | null`) - The personal title of the lead, when recorded.
  - `updated_at` (`string`) - format: `date-time`; An ISO 8601 timestamp in UTC, with a `Z` suffix. For example, `2026-07-01T09:00:00Z`.

### Example

```json
{
  "id": "00000000-0000-4000-8000-00000000000c",
  "object": "lead",
  "address_line_1": "10 Harley Street",
  "address_line_2": "Marylebone",
  "attachments": [
    {
      "id": "f631636b-32e2-41be-8e4f-0a34ee0d5d59",
      "download_url": "https://files.example.invalid/document.pdf?signature=test",
      "filename": "referral-letter.pdf"
    }
  ],
  "city": "London",
  "clinician": {
    "id": "00000000-0000-4000-8000-000000000002",
    "object": "clinician",
    "created_at": "2026-01-01T09:00:00Z",
    "display_name": "Dr Alex Morgan",
    "email": "alex.morgan@example.com",
    "first_name": "Alex",
    "last_name": "Morgan",
    "links": {
      "bookings": "https://api.carebit.co/v1/bookings?clinician_id=00000000-0000-4000-8000-000000000002"
    },
    "medical_specialty": "Cardiology",
    "title": "Dr",
    "updated_at": "2026-01-01T09:00:00Z"
  },
  "country_code": "GB",
  "county": "Greater London",
  "created_at": "2026-01-01T09:00:00Z",
  "creation_source": "api",
  "date_of_birth": "1990-01-01",
  "display_name": "Dr Alex Morgan",
  "email": "alex.morgan@example.com",
  "first_name": "Alex",
  "form_responses": [
    {
      "id": "adf881b8-4eed-42c0-8903-515f6cc8a134",
      "form_name": "New patient inquiry",
      "form_type": "inquiry_form",
      "submitted_at": "2026-01-01T09:00:00Z",
      "url": "https://files.example.invalid/document.pdf?signature=test"
    }
  ],
  "gdpr_consent_granted_at": "2026-01-01T09:00:00Z",
  "gdpr_consent_withdrawn_at": "2026-01-01T09:00:00Z",
  "internal_notes": "Asked about evening appointments with Dr Smith.",
  "is_converted_to_patient": true,
  "is_lost": false,
  "is_opted_out_of_sms": false,
  "is_signed_up_to_newsletters": true,
  "last_name": "Morgan",
  "lead_type": "inquiry",
  "links": {
    "clinician": "https://api.carebit.co/v1/clinicians/00000000-0000-4000-8000-000000000002",
    "remote_file_import_batch": "https://api.carebit.co/v1/remote_file_import_batches/00000000-0000-4000-8000-00000000000a",
    "self": "https://api.carebit.co/v1/leads/00000000-0000-4000-8000-00000000000c",
    "service": "https://api.carebit.co/v1/services/00000000-0000-4000-8000-000000000005"
  },
  "mobile": "7700900123",
  "mobile_country_dial_code": "GB",
  "organization_privacy_policy_consent_granted_at": "2026-01-01T09:00:00Z",
  "patient_id": "00000000-0000-4000-8000-000000000004",
  "phone": "2071234567",
  "phone_country_dial_code": "GB",
  "postcode": "W1G 9PF",
  "presenting_problem": "Persistent right knee pain",
  "referral_notes": "Referred by Dr Patel at Riverside Medical.",
  "referral_source": "consultant",
  "referred_by_clinician_id": "b5ac896f-f746-4df1-899a-c12d33b84b2d",
  "referred_by_organization_id": "8cda84a9-bf46-4f81-8f3c-66dd352e95db",
  "remote_file_import_batch_id": "00000000-0000-4000-8000-00000000000a",
  "service": {
    "id": "00000000-0000-4000-8000-000000000005",
    "object": "service",
    "created_at": "2026-01-01T09:00:00Z",
    "description": "An initial consultation at the Harley Street Clinic.",
    "duration_minutes": 30,
    "is_bookable_online": true,
    "name": "Initial consultation",
    "service_variants": [
      {
        "id": "00000000-0000-4000-8000-000000000006",
        "clinician_id": "00000000-0000-4000-8000-000000000002",
        "currency": "GBP",
        "description": "An initial consultation at the Harley Street Clinic.",
        "links": {
          "clinician": "https://api.carebit.co/v1/clinicians/00000000-0000-4000-8000-000000000002",
          "location": "https://api.carebit.co/v1/locations/00000000-0000-4000-8000-000000000003"
        },
        "location_id": "00000000-0000-4000-8000-000000000003",
        "net_price": 1,
        "permits_remote_bookings": true
      }
    ],
    "tax_rate": {
      "id": "00000000-0000-4000-8000-000000000029",
      "description": "An initial consultation at the Harley Street Clinic.",
      "percentage": 20,
      "title": "VAT"
    },
    "updated_at": "2026-01-01T09:00:00Z"
  },
  "sex": "female",
  "stage": {
    "id": "00000000-0000-4000-8000-00000000000d",
    "object": "lead_stage",
    "created_at": "2026-01-01T09:00:00Z",
    "is_conversion_stage": true,
    "is_lost_stage": true,
    "name": "Initial consultation",
    "position": 1,
    "updated_at": "2026-01-01T09:00:00Z"
  },
  "title": "Dr",
  "updated_at": "2026-01-01T09:00:00Z"
}
```

## Response `400`

The `Idempotency-Key` header is missing (`idempotency_key_required`) or exceeds 255 characters (`idempotency_key_too_long`).

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Response `401`

The access token is missing, invalid, expired, or revoked.

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Response `403`

The access token lacks the required scope, the project is disabled, or the Organization does not have Carebit Pro.

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Response `404`

Error response.

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Response `409`

A concurrent request holds the idempotency lease (`idempotency_conflict`). Retry after the delay indicated by `Retry-After`.

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Response `422`

The `Idempotency-Key` was previously used with a different request body (`idempotency_key_reused`), or the request body failed validation.

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Response `429`

Too many requests. Retry after the delay indicated by `Retry-After`.

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Code samples

```bash
curl -X PATCH "https://api.carebit.co/v1/leads/00000000-0000-4000-8000-00000000000c" \
  -H "Authorization: Bearer $CAREBIT_ACCESS_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "presenting_problem": "Left knee pain (updated)",
  "stage_id": "00000000-0000-4000-8000-00000000000d"
}'
```

```javascript
const response = await fetch("https://api.carebit.co/v1/leads/00000000-0000-4000-8000-00000000000c", {
  method: "PATCH",
  headers: {
    Authorization: `Bearer ${process.env.CAREBIT_ACCESS_TOKEN}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
  "presenting_problem": "Left knee pain (updated)",
  "stage_id": "00000000-0000-4000-8000-00000000000d"
}),
});

if (!response.ok) {
  throw new Error(`Carebit API error: ${response.status}`);
}

const data = await response.json();
```

```python
import os
import requests
import uuid

response = requests.patch(
    "https://api.carebit.co/v1/leads/00000000-0000-4000-8000-00000000000c",
    headers={
        "Authorization": f"Bearer {os.environ['CAREBIT_ACCESS_TOKEN']}",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "presenting_problem": "Left knee pain (updated)",
        "stage_id": "00000000-0000-4000-8000-00000000000d"
    }
)
response.raise_for_status()
data = response.json()
```

```ruby
require "httparty"
require "json"
require "securerandom"

response = HTTParty.patch(
  "https://api.carebit.co/v1/leads/00000000-0000-4000-8000-00000000000c",
  headers: {
    "Authorization" => "Bearer #{ENV.fetch("CAREBIT_ACCESS_TOKEN")}",
    "Idempotency-Key" => SecureRandom.uuid,
    "Content-Type" => "application/json"
  },
  body: {
    "presenting_problem" => "Left knee pain (updated)",
    "stage_id" => "00000000-0000-4000-8000-00000000000d"
  }.to_json
)
raise "Carebit API error: #{response.code}" unless response.success?
data = response.parsed_response
```

```php
<?php

$client = new GuzzleHttp\Client();

$response = $client->patch("https://api.carebit.co/v1/leads/00000000-0000-4000-8000-00000000000c", [
    "headers" => [
      "Authorization" => "Bearer " . getenv("CAREBIT_ACCESS_TOKEN"),
      "Idempotency-Key" => bin2hex(random_bytes(16)),
    ],
    "json" => [
      "presenting_problem" => "Left knee pain (updated)",
      "stage_id" => "00000000-0000-4000-8000-00000000000d"
    ]
]);
$data = json_decode((string) $response->getBody(), true, flags: JSON_THROW_ON_ERROR);
```

