# List patients

Returns a paginated list of patients for a practice.

Optional query parameters allow filtering results by site, as well as create
and update date ranges.

Endpoint: GET /patients
Version: 2026-01-01
Security: oauth2

## Security:

  - `oauth2` (unknown)
    oauth2 scopes: patient:read

## Query parameters:

  - `limit` (integer)
    Maximum number of records to return per page.

  - `cursor` (string)
    Cursor reference to the next page of records.

  - `site_id` (string)
    Filter records to those occurring at the specified site. The value should be a UUID corresponding to a site within the practice.

  - `created_date_from` (string)
    Inclusive start of a created date range filter. Calendar date only (`YYYY-MM-DD`).
Use together with `created_date_to` for explicit date range control.
- When used together with `created_date_to`, the range between the two values must not exceed 90 days.
- When used without `created_date_to`, returns records from `created_date_from` up to 90 days later
(or up to the current date-time if it is earlier).

  - `created_date_to` (string)
    Inclusive end of a created date range filter. Calendar date only (`YYYY-MM-DD`).
Use together with `created_date_from` for explicit date range control.
- When used together with `created_date_from`, the range between the two values must not exceed 90 days.
- When used without `created_date_from`, returns records from 90 days before `created_date_to` (or from the
earliest available date if less than 90 days of data exists) up to `created_date_to`.

  - `updated_date_from` (string)
    Inclusive start of an updated date range filter. Calendar date only (`YYYY-MM-DD`).
Use together with `updated_date_to` for explicit date range control.
- When used together with `updated_date_to`, the range between the two values must not exceed 90 days.
- When used without `updated_date_to`, returns records from `updated_date_from` up to 90 days later
(or up to the current date-time if it is earlier).

  - `updated_date_to` (string)
    Inclusive end of an updated date range filter. Calendar date only (`YYYY-MM-DD`).
Use together with `updated_date_from` for explicit date range control.
- When used together with `updated_date_from`, the range between the two values must not exceed 90 days.
- When used without `updated_date_from`, returns records from 90 days before `updated_date_to` (or from the
earliest available date if less than 90 days of data exists) up to `updated_date_to`.

## Header parameters:

  - `X-Practice-Id` (string, required)
    UUID of the **practice** in whose context the request is executed. The API
uses this to resolve data the caller is permitted to access for that practice.

## Response 200:

  - `200` (unknown)
    Paginated list of patients for the requested practice, ordered by creation time (latest first) and then by ID for a stable sort.

## Response 200 fields (application/json):

  - `data` (array, required)
    List of patients.

  - `data.created_at` (string, required)
    When the resource was created (UTC, ISO 8601) in UTC.
    Example: 2024-01-15T09:30:00Z

  - `data.updated_at` (string, required)
    When the resource was last updated (UTC, ISO 8601) in UTC.
    Example: 2024-06-20T14:05:22Z

  - `data.id` (string, required)
    Unique identifier for this patient within the practice.
    Example: 3fa85f64-5717-4562-b3fc-2c963f66afa6

  - `data.is_active` (boolean)
    Whether the patient record is active;
    Example: true

  - `data.address` (object, required)
    Patient postal address. See `components/schemas/address.yml` for field meanings.

  - `data.address.address_line_1` (string)
    Primary street line (building number, street name, or equivalent).
    Example: 42 High Street

  - `data.address.address_line_2` (string)
    Secondary street line (flat, suite, district, or equivalent), if applicable.
    Example: Suite 2

  - `data.address.address_line_3` (string)
    Third address line. Meaning varies by country: in some regions (for example Australia and New Zealand) this line typically holds **suburb**; elsewhere it may be any extra line needed after `address_line_1` and `address_line_2`.
    Example: Suburbia

  - `data.address.locality` (string)
    City, town, or other local place name, as used in that country.
    Example: London

  - `data.address.administrative_area` (string)
    First-level subdivision when applicable for that country (for example state, province, county, or region—whichever is conventional for that address).
    Example: Greater London

  - `data.address.postal_code` (string)
    Postal or ZIP code for that country, in the format stored for the address (not normalised to a single global format).
    Example: EC1A 1BB

  - `data.date_of_birth` (string, required)
    Date of birth in ISO 8601 calendar date form (`YYYY-MM-DD`).
    Example: 1990-04-12

  - `data.dentist_id` (string)
    Identifier of the dentist associated with this patient for recall or care routing.
    Example: 550e8400-e29b-41d4-a716-446655440001

  - `data.email_address` (string)
    Primary email address for contact.
    Example: jane.doe@example.com

  - `data.ethnicity` (string, required)
    NHS ethnicity code for the patient, expressed as a two-digit zero-padded string
(for example `"01"`). Ethnicity is collected for UK practices that support patient
ethnicity (England, Wales, Northern Ireland, Channel Islands, and Isle of Man).
**Post–April 2026 codes** (England and Wales practices with NHS contract reform)
- `01` — White: English or Welsh or Scottish or Northern Irish or British
- `02` — White: Irish
- `03` — White: Any other White background
- `04` — Mixed multiple ethnic groups: White and Black Caribbean
- `05` — Mixed multiple ethnic groups: White and Black African
- `06` — Mixed multiple ethnic groups: White and Asian
- `07` — Mixed multiple ethnic groups: Any other Mixed or Multiple ethnic background
- `08` — Asian or Asian British: Indian
- `09` — Asian or Asian British: Pakistani
- `10` — Asian or Asian British: Bangladeshi
- `11` — Asian or Asian British: Any other Asian background
- `12` — Black or African or Caribbean or Black British: Caribbean
- `13` — Black or African or Caribbean or Black British: African
- `14` — Black or African or Caribbean or Black British: Other Black or African or Caribbean background
- `15` — Asian or Asian British: Chinese
- `16` — Other Ethnic Group: Any other Ethnic Group
- `17` — White: Gypsy or Irish Traveller
- `18` — Other Ethnic Group: Arab
- `97` — Other: Ethnicity Not Stated
- `98` — Other: Patient Ethnicity Unknown
- `99` — Other: Patient declined
    Enum: "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "97", "98", "99"

  - `data.first_name` (string, required)
    Given (first) name as stored for the patient.
    Example: Jane

  - `data.middle_name` (string)
    Middle name or additional given name, when stored.
    Example: Marie

  - `data.last_name` (string, required)
    Family (last) name as stored for the patient.
    Example: Doe

  - `data.family_id` (string)
    Identifier linking this patient to a family or household group when used by the practice; otherwise `null`.
    Example: 660e8400-e29b-41d4-a716-446655440003

  - `data.biological_sex` (string)
    Biological sex when set on the patient record; `null` when unknown or not applicable.
    Enum: "male", "female"

  - `data.phones` (array, required)
    Home, mobile, and work contact numbers from the patient record.

  - `data.phones.phone_type` (string, required)
    Which patient phone slot this row maps to in Dentally.
    Enum: "home", "mobile", "work"

  - `data.phones.phone_number` (string)
    Raw number as stored for the practice (not necessarily E.164).
    Example: 01234567890

  - `data.phones.phone_country` (string)
    ISO-style country code for interpreting `phone_number`, when set.
    Example: NZ

  - `data.phones.phone_number_normalized` (string)
    Normalised representation (for example E.164) when available.
    Example: +641234567890

  - `data.hygienist_id` (string)
    Identifier of the hygienist associated with this patient for recall or care routing; `null` if not assigned.
    Example: 550e8400-e29b-41d4-a716-446655440004

  - `data.payment_plan_id` (string, required)
    Identifier of the payment plan assigned to this patient.
    Example: 6ba7b810-9dad-11d1-80b4-00c04fd430c8

  - `data.preferred_name` (string)
    Name the patient prefers to be called, when different from formal names.
    Example: Janey

  - `data.preferred_phone_type` (string)
    Preferred phone type for contact.
    Enum: "home", "mobile", "work"

  - `data.is_appointment_booking_prevented` (boolean)
    When `true`, online or automated appointment booking may be blocked for this patient per practice rules.
    Example: false

  - `data.communication` (object)
    Patient communication and marketing preferences.

  - `data.communication.is_marketing_enabled` (boolean, required)
    Whether the patient accepts marketing communications; `null` if unspecified.
    Example: true

  - `data.communication.is_email_enabled` (boolean, required)
    Whether the patient accepts email communications.
    Example: true

  - `data.communication.is_sms_enabled` (boolean, required)
    Whether the patient accepts SMS communications.
    Example: false

  - `data.recall` (object)
    Patient recall schedule and preferred contact method.

  - `data.recall.dentist` (object, required)
    Dentist recall schedule.

  - `data.recall.dentist.date` (string, required)
    Next dentist recall date (`YYYY-MM-DD`); `null` when not scheduled.
    Example: 2026-03-15

  - `data.recall.dentist.interval_months` (integer, required)
    Recall interval in months.
    Example: 6

  - `data.recall.hygienist` (object, required)
    Hygienist recall schedule.

  - `data.recall.hygienist.date` (string, required)
    Next hygienist recall date (`YYYY-MM-DD`); `null` when not scheduled.
    Example: 2026-04-01

  - `data.recall.hygienist.interval_months` (integer, required)
    Recall interval in months.
    Example: 6

  - `data.recall.method` (string, required)
    Preferred recall contact method; `null` if unspecified.
    Enum: "letter", "sms", "email", "phone"

  - `data.archived_reason` (string)
    Reason the patient was archived; `null` when the patient is active or no reason is recorded.
    Enum: "no_reason_given", "deceased", "lapsed", "duplicate", "discharged_failed_to_attend", "discharged_no_longer_meets_criteria", "discharged_treatment_complete", "legal_request_to_remove", "patient_in_arrears", "patient_moved_away", "patient_not_happy_with_service", "patient_opted_out_due_to_cost", "referral_patient", "test_or_created_in_error", "transferred_to_another_provider", "null"

  - `data.is_bad_debtor` (boolean)
    Whether the patient is flagged as a bad debtor; `null` if unspecified.
    Example: false

  - `data.site_id` (string, required)
    Default or primary site (location) this patient is associated with.
    Example: 7c9e6679-7425-40de-944b-e07fc1f90ae7

  - `data.title` (string, required)
    The different patient titles supported by Dentally.
    Enum: "Mr", "Mrs", "Miss", "Ms", "Dr", "Master", "Prof", "Hon", "Rev", "Sir", "Lady", "Lord", "Earl", "Judge", "Dame"

  - `meta` (object, required)
    Cursor-based pagination metadata. When an operation supports paging, pass `cursor` from this object on a subsequent request to continue after the current page.

  - `meta.cursor` (string, required)
    Opaque pagination cursor for the next page. Clients should treat this value as an opaque token.
    Example: eyJjdXJzb3IiOiJuZXh0In0

## Response 400:

  - `400` (unknown)
    Malformed Request ([ProblemDetails](https://tools.ietf.org/html/rfc7807))

## Response 400 fields (application/problem+json):

  - `type` (string)
    A URI reference [[RFC3986](https://tools.ietf.org/html/rfc3986)] that
identifies the problem type. It should provide human-readable
documentation for the problem type. When this member is not present, its
value is assumed to be "about:blank".
    Example: https://httpstatuses.io/400

  - `title` (string)
    A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization.
    Example: Bad Request

  - `status` (integer)
    The HTTP status code.
    Example: 400

  - `detail` (string)
    A human-readable explanation specific to this occurrence of the problem.
    Example: Missing required field 'address'

  - `instance` (string)
    A URI reference that identifies the specific occurrence of the problem.  It may or may not yield further information if de-referenced.
    Example: /v2/sites

## Response 401:

  - `401` (unknown)
    Unauthorized - Provide proof of identity ([ProblemDetails](https://tools.ietf.org/html/rfc7807))

## Response 401 fields (application/problem+json):

  - `type` (string)
    A URI reference [[RFC3986](https://tools.ietf.org/html/rfc3986)] that
identifies the problem type. It should provide human-readable
documentation for the problem type. When this member is not present, its
value is assumed to be "about:blank".
    Example: https://httpstatuses.io/400

  - `title` (string)
    A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization.
    Example: Bad Request

  - `status` (integer)
    The HTTP status code.
    Example: 400

  - `detail` (string)
    A human-readable explanation specific to this occurrence of the problem.
    Example: Missing required field 'address'

  - `instance` (string)
    A URI reference that identifies the specific occurrence of the problem.  It may or may not yield further information if de-referenced.
    Example: /v2/sites

## Response 4XX:

  - `4XX` (unknown)
    User Error ([ProblemDetails](https://tools.ietf.org/html/rfc7807))

## Response 4XX fields (application/problem+json):

  - `type` (string)
    A URI reference [[RFC3986](https://tools.ietf.org/html/rfc3986)] that
identifies the problem type. It should provide human-readable
documentation for the problem type. When this member is not present, its
value is assumed to be "about:blank".
    Example: https://httpstatuses.io/400

  - `title` (string)
    A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization.
    Example: Bad Request

  - `status` (integer)
    The HTTP status code.
    Example: 400

  - `detail` (string)
    A human-readable explanation specific to this occurrence of the problem.
    Example: Missing required field 'address'

  - `instance` (string)
    A URI reference that identifies the specific occurrence of the problem.  It may or may not yield further information if de-referenced.
    Example: /v2/sites

## Response 5XX:

  - `5XX` (unknown)
    Server Error ([ProblemDetails](https://tools.ietf.org/html/rfc7807))

## Response 5XX fields (application/problem+json):

  - `type` (string)
    A URI reference [[RFC3986](https://tools.ietf.org/html/rfc3986)] that
identifies the problem type. It should provide human-readable
documentation for the problem type. When this member is not present, its
value is assumed to be "about:blank".
    Example: https://httpstatuses.io/400

  - `title` (string)
    A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization.
    Example: Bad Request

  - `status` (integer)
    The HTTP status code.
    Example: 400

  - `detail` (string)
    A human-readable explanation specific to this occurrence of the problem.
    Example: Missing required field 'address'

  - `instance` (string)
    A URI reference that identifies the specific occurrence of the problem.  It may or may not yield further information if de-referenced.
    Example: /v2/sites

## Response 400 examples:

  - `Malformed or invalid request` (unknown)
    RFC 7807 problem details when validation fails (e.g. missing required field).

## Response 401 examples:

  - `Missing or invalid credentials` (unknown)
    RFC 7807 problem details when the caller is not authenticated.

## Response 4XX examples:

  - `Generic client error response` (unknown)
    RFC 7807 problem details for a generic client error (e.g. conflict, unsupported media type).

## Response 5XX examples:

  - `Unexpected server error` (unknown)
    RFC 7807 problem details for an internal failure.

