<!-- Carebit docs: Changelog and versioning -->

# Changelog and versioning

The Developer Platform is path-versioned. Every URL starts with `/v1`.
A new major version only ships when a change cannot be made additively.

## Guarantees inside `/v1`

- New fields and endpoints may be added at any time. Your integration
  must ignore unknown fields.
- Existing fields will not change type or meaning.
- Enum values will only be added, never removed inside `v1`. New values
  may appear at any time - handle unknown values gracefully.
- Deprecations are announced in advance in this changelog and on the
  relevant reference page.

## Webhook versioning

The webhook envelope carries an `api_version` field (currently `"v1"`).
The same additive rules apply to webhook payloads. If Carebit introduces
another version, endpoint-level version selection and migration guidance
will be added before that version is available.

## Change log

### 15 October 2026

- You can use AI agents as part of a private integration that your
  organisation deploys, controls and operates. Do not give
  custom-integration credentials to third-party products.
- Carebit does not email organisation staff when a PatientConnectionRequest
  is created. The `202` payload includes `links.dashboard`, which opens the
  Patient connection requests list in Carebit. Send that URL if you want
  someone to review pending requests.

### 6 October 2026

- Transmission objects include an embedded `message_template` when Carebit
  can resolve the MessageTemplate from the Workflow or Booking that sent
  the Transmission. Recipient (`to`), date sent (`sent_at`), and delivery
  `status` were already on the object.

### 25 September 2026

- A Patient created with an email address gets a Patient Portal account for
  that email. Carebit does not send the portal welcome email. Adding an
  email later with `PATCH /v1/patients/{id}` does the same when the Patient
  does not already have a portal account.
- Letters, BookingForms, Photos, and TestResults accept
  `assigned_staff_member_id`, `created_at`, and `sent_at` on create.
  Photos and BookingForms also accept them on update. Responses include
  `assigned_staff_member` and `sent_at`. Setting `sent_at` marks the
  document complete. Omit `created_at` to use the current time.
- `GET /v1/transmissions` accepts `patient_id`, `document_id`, `invoice_id`,
  `quote_id`, `booking_id`, `digital_form_response_id`, and `resource_type`.
  Supply at least one. A `patient_id` filter with no other filter returns
  every Transmission for that Patient. `resource_type=digital_form_response`
  still limits the list to DigitalFormResponse emails.
- `POST /v1/bookings` and `PATCH /v1/bookings/{id}` accept `notify_patient`.
  Omit it to keep the default, which is `true`. Confirmation, update, and
  cancellation emails use this value once the Booking is confirmed.

### 24 September 2026

- An unconnected match from `POST /v1/patients` always creates a
  PatientConnectionRequest and returns `202`. Carebit never connects it as
  part of the create call, even when a supplied contact field agrees. The
  previous `409 patient_match_requires_review` response is no longer used.
- `GET /v1/patient_connection_requests` and
  `GET /v1/patient_connection_requests/{id}` list and retrieve those requests.
  Requires `patients.read`. Pending payloads omit `patient_id` and expose only
  the strongest candidate. Only matching demographic field names are
  disclosed; contact and NHS number classifications remain private.
- Any project in the organisation can use
  `POST /v1/patient_connection_requests/{id}/actions` with
  `connect_existing_patient`, `create_new_patient`, or `deny`. If you
  are ready to connect the recommended Patient immediately, POST
  `connect_existing_patient`; Carebit connects the strongest current
  recommendation. Acting uses `patients.create`; there is no separate
  grant scope.
- Webhook events `patient_connection_request.created`,
  `patient_connection_request.granted`, `patient_connection_request.denied`,
  and `patient_connection_request.expired` are required system events.
  Carebit always delivers them to every enabled webhook endpoint on the
  project that created the request. Other projects do not receive them.
  You do not subscribe to them, and they do not appear in the
  subscription picker. Connecting an existing candidate or creating a
  separate Patient also emits `patient_connection.created`.
- See [Creating and connecting Patients](/guides/creating-patients).

### 22 September 2026

- `GET /v1/lead_form_responses` lists the forms a Lead submitted,
  newest first. Requires `leads.read` and Carebit Pro. `lead_id` is
  required. Lost Leads are included. Enquiries a staff member recorded
  by hand are not returned, because they have no form.
- `GET /v1/lead_form_responses/{id}` returns one submission with its
  questions and answers, the referral data captured with it, and its
  marketing attribution in `tracking`. Match answers on `field_name`
  rather than on `label`, which an Organization can reword at any time.
  A `multiselect` question returns its selected option values in
  `values` and null in `value`. 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`.
- Lead objects include `form_responses`, a summary of each submission,
  oldest first, with a `url` to the full response. Lead objects also
  include `referred_by_clinician_id` and `referred_by_organization_id`,
  taken from the Lead's first submission that identified one.
  Per-submission values are on the LeadFormResponse.
- Webhook event `lead.form_response_submitted` fires for every
  submission, including the one that creates the Lead. A repeat
  submission from someone already in the pipeline emits only this
  event, because reusing an existing Lead does not change it and so
  does not emit `lead.updated`.
- `POST /v1/patients` and `PATCH /v1/patients/{id}` accept `nhs_number`.
  Send a 10-digit NHS number without spaces or other formatting. The
  number must pass the NHS check digit. Set it to `null` to clear it.

### 21 September 2026

- `POST /v1/quotes` creates a draft Quote. Requires `quotes.create`.
  Supply `patient_id` for a Patient Quote, or omit it and supply
  `alternative_payor_id` to quote another organisation. Supply
  `booking_ids` to generate line items from Bookings, or `line_items`
  with `title` and `unit_price` in minor currency units. Bookings
  require a Patient. Sending, accepting, and converting remain in the
  Carebit staff and Patient Portal interfaces.
- Webhook events `quote.created` and `quote.accepted` are now available.
  `quote.created` fires when a Quote is first persisted. `quote.accepted`
  fires after acceptance creates the linked Invoice. The accepted Quote
  object includes `invoice_id` and `links.invoice`.
- `GET /v1/invoices/{id}` returns one Invoice. Requires
  `invoices.read`. Use this to follow Invoice links on Quote objects.

### 18 September 2026

- `GET /v1/patients/{id}/payment_methods` lists stored card
  PaymentMethods for a connected Patient. Requires `payment_methods.read`.
  Only PaymentMethods that the Organization has ResourcePermissions to
  access are returned. Expired cards are included and marked with
  `is_expired`.
- `POST /v1/payments` creates a card Payment for a connected Patient.
  Requires `payments.create`. Supply `amount` in minor currency units
  and `payment_method_type`. Supply `payment_method_id` to charge a
  specific stored card from the Patient's PaymentMethods list. When
  `payment_method_id` is omitted, Carebit charges the Patient's default
  stored card. If the Patient has no stored card, the request fails.
  Send the Patient to `patient_portal_add_payment_method_url` on the
  Patient object so they can add a card in the Patient Portal. If
  Stripe requires extra authentication, Carebit emails the Patient a
  Patient Portal link to complete it. Other payment method types are
  not accepted.
- Payment objects include `payment_method_id` when a stored card was
  charged.
- Patient objects include `patient_portal_add_payment_method_url`. This
  is the Patient Portal URL where the Patient can add a stored card
  PaymentMethod for the Organization. Use this URL to collect a card
  before calling `POST /v1/payments`.
- `POST /v1/payments/{id}/refunds` creates a Refund against a
  card Payment. Requires `refunds.create`. Supply `amount` in minor
  currency units and `reason`. Carebit returns the funds to the original
  card through Stripe. The Refund starts as `processing`. Other payment
  method types are not accepted.
- Webhook event `refund.failed` fires when Stripe rejects a card or
  Klarna Refund to the original payment method. The Refund object
  includes `error` and `next_steps`. Carebit does not retry the Refund
  automatically. Refund objects also include `next_steps` on list
  payloads when a Refund has failed in this way.
- Invoice objects include `payment_url`. This is the Patient Portal URL
  where the Patient can pay the Invoice. The value is null when the
  Invoice has no `invoice_number`. Webhook events `invoice.finalized`,
  `invoice.sent`, and `invoice.settled` carry the same Invoice object.

### 16 September 2026

- Patient objects include `patient_number`. This is the clinic-specific
  identifier from this Organization's PatientConnection. It is
  read-only. The value is null when numbering is disabled or no number
  has been assigned.
- Webhook events `invoice.finalized`, `invoice.sent`, `invoice.settled`,
  and `payment.paid` are now available. `invoice.finalized` fires when
  an Invoice leaves draft. `invoice.sent` fires when a send record is
  created for the Invoice. `invoice.settled` fires the first time the
  Invoice has no outstanding balance. `payment.paid` fires when a
  Payment is recorded as paid.
- `POST /v1/invoices` creates a self-pay Invoice for a connected
  Patient. Requires `invoices.create`. Supply `line_items` with
  `title` and `unit_price` in minor currency units. Set `tax_rate_id`
  on a line item to apply a TaxRate from the Organization. `payor_type`
  must be `patient`. Automated billing and insurance-submission
  attributes are not accepted.

### 15 September 2026

- `GET /v1/patients/{patient_id}/connections` lists PatientConnections
  this Organization already has ResourcePermissions for (unlocked
  connections). Locked connections, including a GP that has not been
  unlocked in Carebit, are omitted. Create and update use
  `patient_connections.create` and `patient_connections.update`. Create
  connects the Patient to an existing Organization, such as a GP
  practice. If the Patient is already connected, Carebit returns that
  PatientConnection and grants this Organization access. This does not
  create Organizations. Update may change only this Organization's
  PatientConnection, not an unlocked GP or other Organization's
  connection.
- `GET /v1/organizations` searches active Organizations by `name` or
  `postcode`. Optionally filter with `organization_type`, for example
  `gp_practice`. At least one of `name` or `postcode` is required.
  Requires `organization.search`. Email, subdomain, phone, currency, and
  time_zone are null so a search cannot harvest contact details. Creating
  Organizations through the API is not permitted.
- `POST /v1/patients/{patient_id}/payors` accepts `set_as_default_payor`.
  When `true`, Carebit creates the Payor and selects it on this
  Organization's PatientConnection in the same request.

### 13 September 2026

- `GET /v1/token` confirms the current access token and returns the
  Organization, project, granted scopes, and expiry. Any valid token
  can call it. It does not require `organization.read`. The response
  does not include the token secret.
- `GET /v1/invoices` no longer requires `booking_id` or `patient_id`.
  Those filters remain optional.
- `GET /v1/payments` lists Payments. Filter optionally by `patient_id`
  and by `paid_at_from` / `paid_at_to`. Each Payment includes
  `internal_notes`, `invoice_id`, `patient_id`, and nested `refunds`. Requires
  `payments.read`.
- Lead objects include `internal_notes`, `referral_notes`, and
  `referral_source`. These fields are writable on create and update so
  an API-created enquiry can match one entered in Carebit.
  `internal_notes` is the Notes box next to presenting problem.
  `referral_source` uses the same values as the Carebit referral source
  list, such as `gp_practice` or `website`.

### 12 September 2026

- Diary Booking lists accept a `start_time` window of up to 30 days
  (90 days when filtering by `patient_id`).
- `GET /v1/bookings` no longer requires `start_time_from` and
  `start_time_to` when `status` is a recall status (`awaiting_recall`,
  `overdue_for_recall`, `recall_expired`, or `recall_canceled`). Those
  lists are ordered by `recall_due_date`. `did_not_attend` and other
  diary queries still require the date window.
- Booking objects include `recall_due_date`.
- Lists are available at `/v1/lists`, including create, update, and
  delete. Membership is nested at `/v1/lists/{list_id}/members`. Add a
  member with `member_type` and `member_id`; currently `member_type`
  accepts only `patient`. Nested List objects on `list.member_added`
  and `list.member_removed` now match the List resource, including
  timestamps, notes, color, Clinician, and links.
- `POST /v1/bookings/{id}/cancellations` cancels a Booking.
  It requires `bookings.cancel`, which is independent of `bookings.update`.
  `cancellation_reason` is required when the Organization requires
  cancellation reasons. API cancellations use `cancellation_source` `api`
  and automatically apply attendance penalty invoices, except when the
  Booking was awaiting payment. Booking objects include `canceled_at`,
  `cancellation_reason`, `cancellation_information`, and
  `cancellation_source`.
- `refund.created` is emitted when a Refund is created.

Entries appear here as the platform grows. The published OpenAPI
document at `/openapi.json` is the source of truth for the current
surface.
