# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.75.0] - 2026-09-17

### Changed

- API version updated to 1.75.0.


## [1.74.0] - 2026-09-16

### Changed

- API version updated to 1.74.0 with no breaking changes to the public contract.


## [1.73.0] - 2026-09-15

### Changed

- API version updated to 1.73.0.


## [1.72.0] - 2026-09-14

### Changed

- API version bump only — no public contract changes.


## [1.71.0] - 2026-09-10

### Changed

- Added a `200` success response to an endpoint.


## [1.70.0] - 2026-09-08

### Added

- Optional fields `avatar`, `height`, `insiMissingTraits`, `isConventionne`, `referringPractitioner`, `treatingPhysician`, and `weight` in request and response schemas
- New schema components `Image-organization.read_organization.read_users_user.read_organization_role_organization.read_logo_organization_user.read_user.list_user.read_avatar_image.list`, `Image.jsonld-organization.read_organization.read_users_user.read_organization_role_organization.read_logo_organization_user.read_user.list_user.read_avatar_image.list`, and `Image.multipart-organization.read_organization.read_users_user.read_organization_role_organization.read_logo_organization_user.read_user.list_user.read_avatar_image.list`


### Changed

- Breaking change detected: version incremented from `1.69.0` to `1.70.0` without a major version bump
- Removed schemas `Image-organization.read_organization.read_users_user.read_organization_role_organization.read_logo_organization_user.read_user.list_image.list`, `Image.jsonld-organization.read_organization.read_users_user.read_organization_role_organization.read_logo_organization_user.read_user.list_image.list`, `Image.multipart-organization.read_organization.read_users_user.read_organization_role_organization.read_logo_organization_user.read_user.list_image.list`, `Organization-organization.read_organization.read_users_user.read_organization_role_organization.read_logo_organization_user.read_user.list_image.list`, `Organization.jsonld-organization.read_organization.read_users_user.read_organization_role_organization.read_logo_organization_user.read_user.list_image.list`, `Organization.multipart-organization.read_organization.read_users_user.read_organization_role_organization.read_logo_organization_user.read_user.list_image.list`, `User-organization.read_organization.read_users_user.read_organization_role_organization.read_logo_organization_user.read_user.list_image.list`, `User.jsonld-organization.read_organization.read_users_user.read_organization_role_organization.read_logo_organization_user.read_user.list_image.list`, and `User.multipart-organization.read_organization.read_users_user.read_organization_role_organization.read_logo_organization_user.read_user.list_image.list`


## [1.69.0] - 2026-09-07

### Changed

- API version bump only — no public contract changes.


## [1.68.0] - 2026-09-03

### Changed

- API version bump only — no public contract changes.


## [1.67.0] - 2026-09-02

### Changed

- API version bump only — no public contract changes.


## [1.66.0] - 2026-09-02

### Changed

- API version bump only — no public contract changes.


## [1.65.0] - 2026-09-02

### Changed

- API version bump only — no public contract changes.


## [1.64.0] - 2026-09-01

> *Auto-generated from the OpenAPI diff (oasdiff). Review wording before release.*


### Added

- Optional field `isOrganizationAdmin`
- Optional field `undefined`


### Changed

- **(breaking)** the response property `documents/items/documentIntegrations/items/claimedByClient/anyOf[#/components/schemas/Client-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/clientTypes` became nullable for the status `200` (media type: application/json)
- **(breaking)** the response property `documents/items/documentIntegrations/items/claimedByClient/anyOf[#/components/schemas/Client-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/clientTypes/items/` became nullable for the status `200` (media type: application/json)
- **(breaking)** the response property `documents/items/documentIntegrations/items/claimedByClient/anyOf[#/components/schemas/Client-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/countries` became nullable for the status `200` (media type: application/json)
- **(breaking)** the response property `documents/items/documentIntegrations/items/claimedByClient/anyOf[#/components/schemas/Client-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/specialties` became nullable for the status `200` (media type: application/json)
- **(breaking)** the response property `documents/items/documentIntegrations/items/claimedByClient/anyOf[#/components/schemas/Client-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/specialties/items/` became nullable for the status `200` (media type: application/json)
- **(breaking)** the response property `documents/items/documentIntegrations/items/claimedByClient/anyOf[#/components/schemas/Client-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/systems` became nullable for the status `200` (media type: application/json)
- **(breaking)** the response property `documents/items/documentIntegrations/items/claimedByClient/anyOf[#/components/schemas/Client-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/systems/items/` became nullable for the status `200` (media type: application/json)
- **(breaking)** the response property `documents/items/documentIntegrations/items/claimedByClient/anyOf[#/components/schemas/Client.multipart-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/clientTypes` became nullable for the status `200` (media type: multipart/form-data)
- **(breaking)** the response property `documents/items/documentIntegrations/items/claimedByClient/anyOf[#/components/schemas/Client.multipart-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/clientTypes/items/` became nullable for the status `200` (media type: multipart/form-data)
- **(breaking)** the response property `documents/items/documentIntegrations/items/claimedByClient/anyOf[#/components/schemas/Client.multipart-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/countries` became nullable for the status `200` (media type: multipart/form-data)
- **(breaking)** the response property `documents/items/documentIntegrations/items/claimedByClient/anyOf[#/components/schemas/Client.multipart-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/specialties` became nullable for the status `200` (media type: multipart/form-data)
- **(breaking)** the response property `documents/items/documentIntegrations/items/claimedByClient/anyOf[#/components/schemas/Client.multipart-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/specialties/items/` became nullable for the status `200` (media type: multipart/form-data)
- **(breaking)** the response property `documents/items/documentIntegrations/items/claimedByClient/anyOf[#/components/schemas/Client.multipart-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/systems` became nullable for the status `200` (media type: multipart/form-data)
- **(breaking)** the response property `documents/items/documentIntegrations/items/claimedByClient/anyOf[#/components/schemas/Client.multipart-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/systems/items/` became nullable for the status `200` (media type: multipart/form-data)
- **(breaking)** the response property `documents/items/documentIntegrations/items/client/anyOf[#/components/schemas/Client-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/clientTypes` became nullable for the status `200` (media type: application/json)
- **(breaking)** the response property `documents/items/documentIntegrations/items/client/anyOf[#/components/schemas/Client-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/clientTypes/items/` became nullable for the status `200` (media type: application/json)
- **(breaking)** the response property `documents/items/documentIntegrations/items/client/anyOf[#/components/schemas/Client-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/countries` became nullable for the status `200` (media type: application/json)
- **(breaking)** the response property `documents/items/documentIntegrations/items/client/anyOf[#/components/schemas/Client-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/specialties` became nullable for the status `200` (media type: application/json)
- **(breaking)** the response property `documents/items/documentIntegrations/items/client/anyOf[#/components/schemas/Client-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/specialties/items/` became nullable for the status `200` (media type: application/json)
- **(breaking)** the response property `documents/items/documentIntegrations/items/client/anyOf[#/components/schemas/Client-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/systems` became nullable for the status `200` (media type: application/json)
- **(breaking)** the response property `documents/items/documentIntegrations/items/client/anyOf[#/components/schemas/Client-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/systems/items/` became nullable for the status `200` (media type: application/json)
- **(breaking)** the response property `documents/items/documentIntegrations/items/client/anyOf[#/components/schemas/Client.multipart-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/clientTypes` became nullable for the status `200` (media type: multipart/form-data)
- **(breaking)** the response property `documents/items/documentIntegrations/items/client/anyOf[#/components/schemas/Client.multipart-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/clientTypes/items/` became nullable for the status `200` (media type: multipart/form-data)
- **(breaking)** the response property `documents/items/documentIntegrations/items/client/anyOf[#/components/schemas/Client.multipart-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/countries` became nullable for the status `200` (media type: multipart/form-data)
- **(breaking)** the response property `documents/items/documentIntegrations/items/client/anyOf[#/components/schemas/Client.multipart-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/specialties` became nullable for the status `200` (media type: multipart/form-data)
- **(breaking)** the response property `documents/items/documentIntegrations/items/client/anyOf[#/components/schemas/Client.multipart-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/specialties/items/` became nullable for the status `200` (media type: multipart/form-data)
- **(breaking)** the response property `documents/items/documentIntegrations/items/client/anyOf[#/components/schemas/Client.multipart-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/systems` became nullable for the status `200` (media type: multipart/form-data)
- **(breaking)** the response property `documents/items/documentIntegrations/items/client/anyOf[#/components/schemas/Client.multipart-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/systems/items/` became nullable for the status `200` (media type: multipart/form-data)
- the response property `allOf[subschema #2]/documents/items/allOf[subschema #2]/documentIntegrations/items/allOf[subschema #2]/claimedByClient/anyOf[#/components/schemas/Client.jsonld-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/allOf[subschema #2]/clientTypes` became nullable for the status `200` (media type: application/ld+json)
- the response property `allOf[subschema #2]/documents/items/allOf[subschema #2]/documentIntegrations/items/allOf[subschema #2]/claimedByClient/anyOf[#/components/schemas/Client.jsonld-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/allOf[subschema #2]/clientTypes/items/` became nullable for the status `200` (media type: application/ld+json)
- the response property `allOf[subschema #2]/documents/items/allOf[subschema #2]/documentIntegrations/items/allOf[subschema #2]/claimedByClient/anyOf[#/components/schemas/Client.jsonld-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/allOf[subschema #2]/countries` became nullable for the status `200` (media type: application/ld+json)
- the response property `allOf[subschema #2]/documents/items/allOf[subschema #2]/documentIntegrations/items/allOf[subschema #2]/claimedByClient/anyOf[#/components/schemas/Client.jsonld-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/allOf[subschema #2]/specialties` became nullable for the status `200` (media type: application/ld+json)
- the response property `allOf[subschema #2]/documents/items/allOf[subschema #2]/documentIntegrations/items/allOf[subschema #2]/claimedByClient/anyOf[#/components/schemas/Client.jsonld-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/allOf[subschema #2]/specialties/items/` became nullable for the status `200` (media type: application/ld+json)
- the response property `allOf[subschema #2]/documents/items/allOf[subschema #2]/documentIntegrations/items/allOf[subschema #2]/claimedByClient/anyOf[#/components/schemas/Client.jsonld-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/allOf[subschema #2]/systems` became nullable for the status `200` (media type: application/ld+json)
- the response property `allOf[subschema #2]/documents/items/allOf[subschema #2]/documentIntegrations/items/allOf[subschema #2]/claimedByClient/anyOf[#/components/schemas/Client.jsonld-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/allOf[subschema #2]/systems/items/` became nullable for the status `200` (media type: application/ld+json)
- the response property `allOf[subschema #2]/documents/items/allOf[subschema #2]/documentIntegrations/items/allOf[subschema #2]/client/anyOf[#/components/schemas/Client.jsonld-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/allOf[subschema #2]/clientTypes` became nullable for the status `200` (media type: application/ld+json)
- the response property `allOf[subschema #2]/documents/items/allOf[subschema #2]/documentIntegrations/items/allOf[subschema #2]/client/anyOf[#/components/schemas/Client.jsonld-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/allOf[subschema #2]/clientTypes/items/` became nullable for the status `200` (media type: application/ld+json)
- the response property `allOf[subschema #2]/documents/items/allOf[subschema #2]/documentIntegrations/items/allOf[subschema #2]/client/anyOf[#/components/schemas/Client.jsonld-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/allOf[subschema #2]/countries` became nullable for the status `200` (media type: application/ld+json)
- the response property `allOf[subschema #2]/documents/items/allOf[subschema #2]/documentIntegrations/items/allOf[subschema #2]/client/anyOf[#/components/schemas/Client.jsonld-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/allOf[subschema #2]/specialties` became nullable for the status `200` (media type: application/ld+json)
- the response property `allOf[subschema #2]/documents/items/allOf[subschema #2]/documentIntegrations/items/allOf[subschema #2]/client/anyOf[#/components/schemas/Client.jsonld-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/allOf[subschema #2]/specialties/items/` became nullable for the status `200` (media type: application/ld+json)
- the response property `allOf[subschema #2]/documents/items/allOf[subschema #2]/documentIntegrations/items/allOf[subschema #2]/client/anyOf[#/components/schemas/Client.jsonld-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/allOf[subschema #2]/systems` became nullable for the status `200` (media type: application/ld+json)
- the response property `allOf[subschema #2]/documents/items/allOf[subschema #2]/documentIntegrations/items/allOf[subschema #2]/client/anyOf[#/components/schemas/Client.jsonld-audio.read_audio.read_user_user.list_audio.read_images_image.list_patient.list_audio.read_documents_document.read_document.read_integrations_client.list_document.read_pdf_pdf.list]/allOf[subschema #2]/systems/items/` became nullable for the status `200` (media type: application/ld+json)
- a breaking change was detected but the major version did not increase, from `1.63.0` to `1.64.0`


### Removed

- Field `socialSecurityNumber`


## [1.63.0] - 2026-08-31

### Changed

- API version bump only — no public contract changes.


## [1.62.0] - 2026-08-31

### Added

- New `client_error_unclaimed` enum value added to the `errorCode` field in **Document Integrations** responses.


## [1.61.0] - 2026-08-26

### Changed

- API version bump only — no public contract changes.


## [1.60.0] - 2026-08-25

### Changed

- API version bump only — no public contract changes.


## [1.59.0] - 2026-08-24

### Added

- Optional field `officePhotos` in response bodies.


## [1.58.0] - 2026-08-20

### Changed

- API version bump only — no public contract changes.


## [1.57.0] - 2026-08-18

### Changed

- API version bump only — no public contract changes.


## [1.56.0] - 2026-08-18

### Added

- Optional `primaryColor` field added to multiple response schemas.


### Removed

- `GET /public/directory/facets`
- `GET /public/directory/nearby-practitioners`
- `GET /public/directory/nearby`
- `GET /public/directory/search`
- `GET /public/directory/suggestions`
- `POST /public/directory/claims`
- `POST /public/directory/sheet/read`
- `POST /public/directory/sheet/update`


## [1.55.0] - 2026-08-18

### Changed

- API version updated to 1.55.0.


## [1.54.0] - 2026-08-17

### Changed

- API version bumped to 1.54.0.


## [1.53.0] - 2026-08-13

### Added

- New endpoint `GET /public/directory/nearby-practitioners`
- Optional field `bookingEnabledCount` in response


### Changed

- Added optional `bookingEnabled` query parameter to `GET /public/directory/nearby-practitioners`


## [1.52.0] - 2026-08-12

### Added

- **Patients**: `GET /patients` accepts five new optional query parameters to filter on the date of the last consultation: `lastConsultationAt[gt]`, `lastConsultationAt[gte]`, `lastConsultationAt[lt]`, `lastConsultationAt[lte]`, and `lastConsultationAt[between]` (an inclusive `"<min>..<max>"` range). All take an RFC 3339 date-time, and they combine with the existing filters and sorts.
The consultation date is the most recent recording made **by the caller** for that patient: the same value the `lastConsultationAt` property already exposes, so the filter and the field can never disagree.
⚠️ Because the filter reads a date that only exists once the caller has recorded something, **patients the caller has no recording for are excluded as soon as any of these operators is used**, whichever operator it is. This is deliberate: a patient with no consultation has no date to compare against, and silently treating "never" as "very old" would put them in every `lastConsultationAt[lt]` result. To list those patients, omit the filter.
Purely additive: no existing parameter, field, or default changed, and a request that does not pass one of these five behaves exactly as before.
- Optional `insMatriculeType` field to **Patient** responses.
- Optional `patientEmailStatus` query parameter for filtering.


## [1.51.0] - 2026-08-11

### Added

- Optional query parameter `expand[]`
- Optional field `insValidatedAt` to **User** responses
- Optional field `insValidationDocumentType` to **User** responses
- Optional field `patientEmailStatus` to **User** responses


### Changed

- **User** response schemas now include minimal variants (`User-patient.read_patient.read_record_user.minimal`, `User-patient.read_user.minimal`, `User.jsonld-patient.read_patient.read_record_user.minimal`, `User.jsonld-patient.read_user.minimal`, `User.multipart-patient.read_patient.read_record_user.minimal`, `User.multipart-patient.read_user.minimal`) in place of list variants


### Removed

- Request fields `insQualifiedAt`, `insSource`, and `insStatus` from **User**
- List schema variants for **Patient** and **User** (`Patient-patient.read_patient.read_record_user.list`, `Patient-patient.read_user.list`, `Patient.jsonld-patient.read_patient.read_record_user.list`, `Patient.jsonld-patient.read_user.list`, `Patient.multipart-patient.read_patient.read_record_user.list`, `Patient.multipart-patient.read_user.list`, `User-patient.read_patient.read_record_user.list`, `User-patient.read_user.list`, `User.jsonld-patient.read_patient.read_record_user.list`, `User.jsonld-patient.read_user.list`, `User.multipart-patient.read_patient.read_record_user.list`, `User.multipart-patient.read_user.list`)


## [1.50.0] - 2026-08-10

### Added

- Optional query parameter `facilityTypes` to filter results
- Optional field `facilityTypes` in response bodies


## [1.49.0] - 2026-08-06

### Added

- **Patients**: the patient record now carries a real civil status. `civility` (`mr` | `mrs` | `dr` | `pr` | `none`) is stored rather than inferred from `gender`: a gender is not a form of address, and a patient who is a doctor is addressed "Dr" whatever theirs is. `null` means nobody has declared one, and clients are expected to fall back to the gender-derived form themselves.
`birthGivenNames` holds the civil-status given names in order, the first being the birth first name. It is deliberately separate from `firstName`, which stays the name the patient actually goes by: the two are different fields, and a feuille de soins needs the civil-status spelling while every screen keeps showing the used one.
`birthPlaceCode` carries the INSEE (COG) code of the birthplace. Five characters and a string: Corsican codes are `2A`/`2B` and a birth abroad carries a `99xxx` country code, so anything parsing it as a number is already wrong.
- **Patients**: national health identity (INS), modelled as a value plus its qualification rather than a bare string: `insMatricule`, `insOid` (`1.2.250.1.213.1.4.8` for a NIR, `…4.9` for a temporary NIA), `insStatus` (`provisional` | `validated` | `retrieved` | `qualified`), `insSource` (`manual` | `vitale` | `insi` | `import`) and `insQualifiedAt`. Only a **qualified** identity may be carried into an interoperable exchange, and a matricule on its own cannot say whether this one may.
⚠️ `insMatricule` is **not** `socialSecurityNumber`. Both are fifteen characters and often hold the same number, but the NIR on a record is the number the patient is *covered under* (a minor carries a parent's), while the INS identifies the *patient themselves*. The two are stored separately and neither ever falls back to the other; reading one as the other is how sibling records get merged.
- **Patients**: `phones[]` and `emails[]` list every way of reaching a patient, primary first, each entry carrying `uuid`, `label` and `isPrimary`. Phone entries also carry `smsCapable`, true only for a number labelled `mobile`.
**Backward compatible:** the existing `phone` and `email` fields are unchanged and keep being served: they are now the projection of the primary entry. No client has to migrate, and nothing was removed.
- **Patients**: `photoUrl` and `photoThumbnailUrl` expose the patient's identification photo as short-lived pre-signed URLs. They expire: display them, never store them. `null` when the record has no photo.
- **Patients**: `rightsVerified` and `rightsVerifiedAt` report whether the applicable coverage was certified by an online rights check (Vitale, ADRi or ApCV). Read-only and derived from the patient's coverages, so a `certifiedAt` sitting on a merely declared coverage is *not* reported as a verification.
- **Patients**: `todo` lists what the record still needs, as stable codes (`postal_address_missing`, `rights_to_verify`). Codes and not sentences: the wording belongs to the client's locale files.


## [1.48.0] - 2026-08-06

### Added

- `POST /public/directory/sheet/read` endpoint
- `POST /public/directory/sheet/update` endpoint
- Optional `specialties` query parameter to **Directory** endpoints
- Optional `specialties` field to **Directory** response bodies


## [1.47.0] - 2026-08-05

### Added

- `POST /public/directory/claims` endpoint for submitting claims


## [1.46.0] - 2026-07-29

### Added

- **Directory** — `GET /public/directory/nearby`: resolves a pair of coordinates (`lat`, `lng`) to the nearest city hub and its canonical path, so a browser geolocation can be turned into a directory destination. Anonymous like the rest of the public directory surface, rate-limited per IP. Returns `200` with `area: null` when nothing is in range — "no city nearby" is an answer, not an error; a missing or malformed coordinate is a `400`.


### Changed

- **Directory** — the profile and listing payloads (`profile`, `sites`, `openingHours`, `team`, facets, autocomplete) now publish their field names instead of an opaque `additionalProperties: anyOf[…]`. Documentation-only: not a single byte of any response changed, no field was added or removed.


## [1.45.0] - 2026-07-29

### Changed

- API version updated to 1.45.0.


## [1.44.0] - 2026-07-28

### Changed

- API version updated to 1.44.0 with no breaking changes to the public contract.


## [1.43.0] - 2026-07-27

### Added

- **Directory** — `GET /public/directory/search`: polymorphic autocomplete across localités, practitioners and cabinets, returned as one heterogeneous list with each item tagged by type. Requires a query of at least 2 characters.
- **Directory** — `GET /public/directory/facets`: total result count for the current area and selection, plus per-term counts for every facet, so a filter panel can be rendered before the filter is applied.
- **Directory** — `GET /public/directory/suggestions`: most-populated localités for the search field's empty state (no query string required).


## [1.42.0] - 2026-07-27

### Changed

- Internal API version updated; no breaking changes to public endpoints or schemas.


## [1.40.0] - 2026-07-22

### Changed

- Internal API version updated; no breaking changes to public endpoints or schemas.


## [1.39.0] - 2026-07-21

### Added

- Optional `maidenName` field
- Optional `medicalAlert` field
- Optional `notes` field


## [1.32.0] - 2026-07-16

### Changed

- Internal API version updated; no breaking changes to public endpoints or schemas.


## [1.31.0] - 2026-07-13

### Changed

- Internal API version updated; no breaking changes to public endpoints or schemas.


## [1.30.0] - 2026-07-07

### Added

- `administrative_report` enum value to document type fields
- `panoramic_report` enum value to document type fields


## [1.29.0] - 2026-07-02

### Added

- Optional `validatedAt` field in response schemas


### Changed

- **(breaking)** Collection view navigation properties (`first`, `last`, `next`, `previous`) are now nullable in 200 responses
- Request property `city` now has a maximum length of 255 characters
- Request property `postalCode` now has a maximum length of 10 characters
- Request property `streetAddress` now has a maximum length of 255 characters
- **Webhook** -- `certificateVerificationDisabled` is no longer writable via `PATCH /webhooks/{uuid}` (security hardening — disabling TLS certificate verification is now an admin-only operation). The field remains readable in webhook responses; requests that still include it are silently ignored.


## [1.25.0] - 2026-06-11

### Added

- **Patient** -- Four new optional fields on the patient resource: `recordNumber` (practice folder number), `streetAddress`, `postalCode`, `city`. Available on both requests (create/update, including the bulk import `POST /patients/bulk`) and responses. All nullable — existing integrations are unaffected.


## [1.20.1] - 2026-06-01

### Changed

- **Patient** -- `POST /patients` (create-or-update) no longer matches an existing patient by `externalId`. A patient is now considered existing only by social security number or by the combination of `firstName` + `lastName` + `dateOfBirth`. The `externalId` is still stored but never decides create-vs-update, because some source systems reassign external folder numbers and a reused `externalId` previously overwrote an unrelated patient's record. A reused `externalId` now creates a new patient.


## [1.20.0] - 2026-06-01

### Added

- **Patient** -- New optional field `socialSecurityNumber` (French NIR, 15 characters, nullable) on patient resources, with strict control-key validation (requests with an invalid checksum are rejected). The NIR is used as a high-priority deduplication key when creating or updating patients (server-side; it is not exposed as a public query filter).
- **Client** -- OAuth client schema (embedded in public resources) now exposes four targeting fields: `systems` (array of `mac` / `windows` / `web`), `countries` (ISO 3166-1 alpha-2 codes), `specialties` (medical specialty enums), `clientTypes` (`business_software`, `productivity`). Used by app catalogs like Askara Hub to filter visible apps per platform.


## [1.11.0] - 2026-05-06

### Added

- **Document** -- New value `intervention_report` in the `document.type` enum, used for the new "Compte-rendu d'intervention" document type covering the broad spectrum of clinical interventions (extraction, treatment, follow-up, surgical procedures).


### Changed

- **Document** -- The user-facing label of the `operative_report` document type was renamed from "Compte-rendu opératoire" to "Compte-rendu de pose d'implant" in all locales. The enum value (`operative_report`) and the API contract are unchanged — this is a label-only change visible to users in the application UI. Any client displaying this label from translations should refresh its translation bundle.


## [1.4.0] - 2026-04-07

### Added

- **User** -- New fields `professionCode` (nullable string) and `professionLabel` (nullable string) on user profile, sourced from PSC (Pro Santé Connect) identity provider.
- **Patient** -- New filter parameters `finess` and `finess[]` on `GET /patients` for FINESS establishment filtering.


### Changed

- **User** -- RPPS validation relaxed from strict 11-digit numeric (`^\d{11}$`) to flexible alphanumeric (`^[A-Za-z0-9]+$`, maxLength: 20) to support international practitioner identifiers.
- **User** -- Fields `gender` and `phone` are no longer required on the user profile.


## [1.3.0] - 2026-03-30

*No public API changes. Internal-only: added `write:sts_tokens` OAuth scope for Electron STS token management.*

## [1.2.0] - 2026-03-30

### Added

- **Audio** -- New filter parameter `exists[meeting]` on `GET /audios` to filter audios by meeting association.
- **Patient** -- New filter parameter `exists[meeting]` on `GET /patients`.
- **Document** -- New filter parameter `exists[meeting]` on `GET /documents`.


## [1.1.0] - 2026-02-24

### Added

- **Note** -- New read-only resource with two endpoints: retrieve a collection of notes (`GET /notes`) and retrieve a single note (`GET /notes/{uuid}`). Filterable by uuid, type, patient, audio, createdAt, updatedAt. Sortable by uuid, type, createdAt, updatedAt. Scope: `read:notes`.


### Removed

- **Audio** -- Removed filter parameters `summary` and `summary[]` from `GET /audios`.


## [1.0.0] - 2025-04-29

### Added

#### Askara API Reference (`api.askara.ai`)

- Published the OpenAPI 3.1.0 specification for the Askara public API with OAuth2 authorization code security scheme.
- **Audio** -- Endpoints to retrieve a collection of audios and retrieve a single audio by UUID (read-only). Supports pagination, ordering, text search, and patient expand filters.
- **Contact** -- Endpoints to list, create, retrieve, and update contacts. Supports pagination, ordering, text search, and archive filtering.
- **Document** -- Endpoints to list documents, retrieve a single document, and set a document synchronization status. Supports filtering by synchronization state for integration workflows.
- **Organization** -- Endpoints to list organizations and retrieve a single organization by UUID (read-only).
- **Patient** -- Endpoints to list, create or update (upsert), retrieve, and patch patients. Supports pagination, ordering, text search, external ID matching, and archive filtering.
- **User** -- Endpoints to retrieve the current authenticated user (`/me`) and retrieve a user by UUID (read-only).
- **Webhook** -- Endpoints to list, create, retrieve, update, and delete webhooks for event-driven integrations.


#### SpeechToText API Reference (`stt.askara.ai/v2`)

- Published the OpenAPI 3.1.0 specification for the Askara SpeechToText API, secured via API key (`X-API-KEY` header).
- **Transcription** -- Asynchronous endpoint to submit an audio file URL for speech-to-text processing with a callback URL for result delivery.