# List fee schedules

Returns a paginated list of fee schedules for the practice identified by
`X-Practice-Id`. Dentally's user interface in the United Kingdom sometimes
calls these payment plans.
When `site_id` is supplied, the response includes only schedules assigned
to that site. Schedules with a null `site_id` are not included.
When `is_active` is `true`, results are restricted to active schedules.
When `false`, results are restricted to inactive schedules. When omitted,
all schedules are returned.
Results are ordered by **creation time** and ID, newest first (`created_at`
descending, then `id` descending). Use `limit` and the `meta.cursor` value
from the response to retrieve further pages.

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

## Security:

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

## Query parameters:

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

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

  - `is_active` (boolean)
    - When `true`, only records with `active: true` are returned.
- When `false`, only records with `active: false` are returned.
- When omitted, all records are returned.

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

## 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 fee schedules for the requested practice.

## Response 200 fields (application/json):

  - `data` (array, required)
    Fee schedules in the current page.

  - `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 fee schedule within the practice.
    Example: 6ba7b810-9dad-11d1-80b4-00c04fd430c8

  - `data.name` (string, required)
    Staff-facing name of the fee schedule as shown in Dentally.
    Example: Private

  - `data.patient_friendly_name` (string, required)
    Optional name for patient-facing documents such as estimates. `null` when unset; callers that need a patient-facing label may fall back to `name`.
    Example: null

  - `data.is_active` (boolean, required)
    Whether the fee schedule is active. Inactive schedules remain assigned to existing patients but are not offered for new assignments in Dentally.
    Example: true

  - `data.site_id` (string, required)
    Site this fee schedule is tied to. `null` when the schedule is shared across the practice.
    Example: a11df716-ce65-4210-be87-8b8ec448f85c

  - `data.account_code` (string, required)
    Accounting code used for financial reporting.
    Example: 200

  - `data.funding` (object, required)
    How treatment fees on this fee schedule are split between the patient and any third party, and whether Dentally treats the schedule as a national scheme.

  - `data.funding.type` (string, required)
    Who is expected to pay fees charted against this fee schedule.
- `private` - the patient pays the full fee. No third-party claim is
filed through this funding model (NHS dentistry uses a separate claims
process, even when `scheme` is `nhs`).
- `co_payment_split` - a third party meets part of the fee and the
patient pays the remainder.
- `insurance_funded` - a third party is expected to meet the full fee.
    Enum: "private", "co_payment_split", "insurance_funded"

  - `data.funding.scheme` (string, required)
    National care scheme Dentally recognises for this fee schedule, when one
applies. `null` when the schedule is practice-defined and is not a
recognised scheme.
Known values:
- `nhs` - UK NHS
- `nz_moh_sds` - New Zealand Ministry of Health, Special Dental Services
- `nz_moh_ohsa` - New Zealand Ministry of Health, Oral Health Services Adolescents
- `nz_moh_ohsa_hc` - New Zealand Ministry of Health, High Caries
- `nz_acc` - New Zealand Accident Compensation Corporation

Additional values may be added in the future, this is an open set.
    Example: nhs

  - `data.funding.claim_timing` (string, required)
    When a third-party claim is filed for items on this fee schedule. `null` when
`type` is `private`, including NHS plans, because this funding model does
not file claims through this process.
- `on_completion` - a claim is filed when the treatment plan is completed.
- `on_charge` - a claim is filed each time treatment is charged.
    Enum: "on_completion", "on_charge", "null"

  - `data.default_appointment_duration` (object, required)
    Default appointment lengths, in minutes, used when booking common visit types for a patient on this fee schedule (examination, scale and polish, both together, or emergency). These are booking defaults, not per-treatment durations.

  - `data.default_appointment_duration.exam_minutes` (integer, required)
    Default length in minutes for an examination appointment.
    Example: 10

  - `data.default_appointment_duration.scale_and_polish_minutes` (integer, required)
    Default length in minutes for a scale and polish appointment.
    Example: 10

  - `data.default_appointment_duration.exam_scale_and_polish_minutes` (integer, required)
    Default length in minutes for a combined examination and scale and polish appointment.
    Example: 20

  - `data.default_appointment_duration.emergency_minutes` (integer, required)
    Default length in minutes for an emergency appointment.
    Example: 10

  - `data.patient_default` (object, required)
    Suggested recall and communication values for a **new** patient assigned to
this fee schedule. Dentally's own user interface copies these onto the patient
form when a receptionist creates a patient.
They are never applied automatically by the API or by the server. Creating or
updating a patient with a `payment_plan_id` leaves the patient's own `recall`
and `communication` fields unchanged. Integrations that want the same starting
point as the Dentally UI must copy these values onto the patient record
themselves. Existing patients keep the values already stored on their record;
changing this fee schedule later does not cascade.

  - `data.patient_default.recall` (object, required)
    Default recall schedule and contact method to copy onto a new patient.

  - `data.patient_default.recall.dentist_interval_months` (integer, required)
    Default months between dentist recalls. `0` means no dentist recall interval is suggested.
    Example: 6

  - `data.patient_default.recall.hygienist_interval_months` (integer, required)
    Default months between hygienist recalls. `0` means no hygienist recall interval is suggested.
    Example: 6

  - `data.patient_default.recall.method` (string, required)
    Preferred method for patient recall communications.
    Enum: "letter", "sms", "email", "phone"

  - `data.patient_default.communication` (object, required)
    Default email and SMS contact flags to copy onto a new patient. These are not the patient's live preferences.

  - `data.patient_default.communication.is_email_enabled` (boolean, required)
    Whether a new patient should default to accepting email contact.
    Example: true

  - `data.patient_default.communication.is_sms_enabled` (boolean, required)
    Whether a new patient should default to accepting SMS contact.
    Example: true

  - `data.membership` (object, required)
    Monthly membership (subscription) configuration for this fee schedule. A `monthly_fee` of `0` means the schedule is not a membership plan. Membership is optional practice configuration; many fee schedules never use it.

  - `data.membership.monthly_fee` (number, required)
    Monthly membership price. `0` when the plan is not sold as a subscription.
    Example: 0

  - `data.membership.exam_appointments_included` (integer, required)
    Number of examination appointments included per year.
    Example: 0

  - `data.membership.hygiene_appointments_included` (integer, required)
    Number of hygiene appointments included per year.
    Example: 0

  - `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 200 examples:

  - `First page of fee schedules` (unknown)
    Paginated list with a cursor for the next page.

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

