Docs

Changelog

Track changes to the Doctronic API contract and build clients that stay compatible as it grows.

The Doctronic API is served under /api/v1, and the OpenAPI contract is the source of truth for its operations, fields, responses, and schemas. Download the current contract from /openapi/doctronic-v1.json; resources has a curl command for scripts.

The API reference is generated from the deployed production contract, which is checked daily for changes.

Compatibility

The API grows additively within /api/v1: new fields, response members, SSE event names, and enum values can appear without a new version path. Build clients that keep working when they do.

  • Ignore JSON fields, SSE event names, and enum values you don't recognize.
  • Read only documented fields, and never depend on field order.
  • Treat operation IDs, error codes, event names, and enum values as case-sensitive wire values.
  • Review the OpenAPI diff before you update generated clients or validators, or upgrade an SDK to pick up the change, and test changed behavior in staging before production. The SDKs are 0.x releases, so pin the exact version and read the SDK's changelog before each upgrade; see versioning.

Contract changes

2026-10-25

  • Breaking: The X-Doctronic-User-ID check no longer returns 403 error.member.forbidden. A user-scoped request without the header returns 400 error.member.header_required, and a user ID that doesn't exist, isn't active, or isn't one of your organization's users returns 404 error.member.not_found. Production has returned these since 2026-10-21. Where you handled error.member.forbidden, send the header on every user-scoped request and treat error.member.not_found as a stale patient-to-user mapping; see request headers.
  • 403 now means only error.auth.insufficient_scope: the token lacks the scope the operation requires, and data.requiredScope names it. Every operation's 403 response carries data.requiredScope, and POST /users/ and POST /pharmacy/search/ gained a 403 response. Tokens Doctronic issues today hold every scope; see scopes.
  • The 400 responses of GET /chats/, GET /chats/{chatId}/, GET /chats/{chatId}/messages/, and GET /artifacts/{artifactId}/ now describe error.member.header_required. Validation failures on these operations are unchanged: they still return error.validation_error with data[].field, data[].message, and data[].code.
  • Added 400 and 404 responses to GET /users/.
  • Added 404 response to PATCH /users/, POST /chats/, GET /chats/, and PUT /coverage/.
  • Added 400 response to GET /address/.
  • When a reply fails partway through a turn, POST /chats/{chatId}/stream/ now sends an error event with errorCode error.internal and then ends the stream. See stream errors.
  • Added error codes: error.auth.insufficient_scope, error.member.header_required, and error.member.not_found. The contract now also lists error.consultation_not_ready, which the stream already sent.

2026-10-19

  • Changed: the CreateUserRequest schema now lists dateOfBirth, with firstName, lastName, and phoneNumber, among the fields required before appointment booking.

2026-10-17

  • Added operations: PATCH /users/, PUT /coverage/, and GET /appointments/{appointment_id}/result/. PATCH /users/ and PUT /coverage/ accept Idempotency-Key.
  • Added fields: appointmentDemographicsComplete and missingAppointmentFields on the POST /users/ response.
  • Added the field validation error shape: 400 error.validation_error, with data listing {field, message, code} entries such as error.validation.missing.
  • Added stream responses: 409 error.partner.chat_stream_in_progress and 503 error.partner.chat_stream_unavailable on POST /chats/{chatId}/stream/.
  • Added error codes: error.validation.phone_number.unavailable (503 on POST /users/ and PATCH /users/), error.appointments.result_unavailable, and error.coverage.missing_patient_demographics.
  • Changed: the POST /pharmacy/search/ request requires latitude and longitude. searchTerm is optional.

2026-08-28

  • Added 401 and 403 responses to the appointment operations, and 403 responses to PUT /address/ and PUT /pharmacy/.

2026-08-25

  • Added operation: GET /address/, with 404 error.address.not_found.
  • Added Idempotency-Key to POST /users/, POST /chats/, POST /appointments/scheduled/, POST /appointments/asap/, POST /appointments/{appointment_id}/cancel/, POST /appointments/{appointment_id}/reschedule/, PUT /address/, POST /pharmacy/search/, and PUT /pharmacy/, with 409 idempotency-conflict and 503 responses. See idempotent requests.
  • Changed: the maximum length of conversationPromptContext on POST /chats/ and of messagePromptContext on POST /chats/{chatId}/stream/ rose from 2,000 to 50,000 characters.

2026-08-07

  • Added: the first published contract, with 18 operations across users, chats and streaming, appointments, address, pharmacy, and artifacts.

On this page