# Access and environments (/docs/access-and-environments)
Access is currently provisioned manually. Contact your Doctronic business or implementation
contact to request credentials, rotate a secret, revoke access, or add a production integration.
If you do not have a Doctronic contact yet, email
[business@doctronic.ai](mailto:business@doctronic.ai?subject=Developer%20API%20access) to start the
conversation. Do not include credentials or patient information in email.
Doctronic will coordinate credential delivery through the secure channel agreed with your
organization. Do not send credentials through an unapproved messaging channel.
## Base URLs [#base-urls]
| Environment | Base URL | Use |
| ----------- | ---------------------------------------------- | -------------------------------------- |
| Staging | `https://staging-partners.doctronic.ai/api/v1` | Integration development and validation |
| Production | `https://partners.doctronic.ai/api/v1` | Approved production traffic |
The legacy word `partners` remains in the current API hostnames, operation IDs, some wire-level
error values, and deprecated schema aliases retained for compatibility. In these docs,
**organization** means the authenticated business or product integrating with Doctronic.
Staging and production credentials are distinct. Keep separate secrets, configuration, user-ID
mappings, logs, and deployment controls for each environment.
## Request access [#request-access]
When contacting Doctronic, identify:
* Your organization and technical owner.
* The environment you need.
* The product flow you are building.
* Whether the integration includes conversations, artifacts, or appointments.
* Who should receive the credential through the agreed secure channel.
Confirm permitted staging data and the production-readiness process with your Doctronic business
or implementation contact. The public API contract does not define a self-service approval
workflow.
## Store credentials [#store-credentials]
The Bearer token authenticates your organization. Store it in a server-side secret manager and
inject it only into the backend service that calls Doctronic.
```http
Authorization: Bearer YOUR_ORGANIZATION_TOKEN
```
Do not expose the token in browser code, mobile binaries, source control, client-visible
configuration, logs, traces, screenshots, or analytics events.
For user-scoped endpoints, also send the Doctronic user ID returned by `POST /users/`:
```http
X-Doctronic-User-ID: user-id-returned-by-doctronic
```
The `/users/` resource is this Doctronic record scoped to your organization. Maintain an explicit
mapping between the record and the patient identity in your system. Do not accept a
client-supplied Doctronic user ID without verifying that mapping on your backend.
## Rotate or revoke access [#rotate-or-revoke-access]
Coordinate rotation and revocation with your Doctronic business or implementation contact. Before
a rotation, ensure your service can switch the stored secret without embedding it in a new client
release. Afterward, verify a request in the target environment and remove the previous secret from
your systems according to the agreed process.
## Next steps [#next-steps]
* [Make your first request](/docs/getting-started)
* [Authentication](/docs/authentication)
* [Test your integration](/docs/guides/test-your-integration)
* [Production readiness](/docs/production-readiness)
# Docs for coding tools (/docs/agent-resources)
Use these files when a coding assistant, client generator, or contract validator needs the public
API definition without the rendered site navigation.
| Resource | URL | Best use |
| ---------------------- | ---------------------------------------------------------- | ----------------------------------------------------------- |
| OpenAPI 3.1 | [`/openapi/doctronic-v1.json`](/openapi/doctronic-v1.json) | Operations, parameters, schemas, responses, and server URLs |
| Documentation index | [`/llms.txt`](/llms.txt) | Discover documentation pages and their Markdown URLs |
| Complete documentation | [`/llms-full.txt`](/llms-full.txt) | Load the public documentation as one text resource |
| Page Markdown | `/llms.mdx/docs/{page}/content.md` | Load one documentation page without site navigation |
For example, the Markdown version of this page is available at
[`/llms.mdx/docs/agent-resources/content.md`](/llms.mdx/docs/agent-resources/content.md).
## Choose the right source [#choose-the-right-source]
Use OpenAPI as the contract for HTTP operations and JSON shapes. Use the Markdown documentation
for workflow guidance, SSE compatibility rules, and production considerations.
The SSE stream is represented as `text/event-stream` in OpenAPI. Its published event examples and
the [streaming guide](/docs/conversations/streaming) define the event names and payloads that an
integration should recognize.
## Download the contract [#download-the-contract]
```bash
curl --fail --location \
"https://docs.doctronic.ai/openapi/doctronic-v1.json" \
--output doctronic-openapi.json
```
Validate the downloaded file before using it to update a generated client, schema validator, or
tool definition. Review contract changes before deployment rather than updating production
behavior automatically.
## Keep runtime credentials separate [#keep-runtime-credentials-separate]
These resources describe the API but do not grant API access. Runtime calls still require a
Bearer token provisioned manually by Doctronic and, for user-scoped operations, the correct
`X-Doctronic-User-ID`.
Keep the token in an organization-controlled backend. Do not place it in a model prompt, browser
session, client application, generated artifact, trace, or documentation corpus.
## Control automated callers [#control-automated-callers]
If an automated system can initiate API calls:
* Allow only the operations required for its workflow.
* Resolve the user identity in trusted backend code.
* Validate requests against OpenAPI before sending them.
* Define product-controlled handling for any emitted `guardian` and `skill_code.cta` events.
* Use documented idempotency keys for supported mutations and reconcile unsupported operations
before replaying them.
* Record operation and outcome metadata without copying unrestricted patient content.
* Keep a human-visible fallback for errors and unknown events.
The documentation formats do not change the clinical API's authorization or safety boundaries.
## MCP and tool calling [#mcp-and-tool-calling]
Doctronic does not currently publish a public MCP server. If your application exposes Doctronic
operations to an agent or tool-calling model, put a narrow tool in your backend instead of giving
the model an organization token. The backend should resolve the patient, enforce an operation
allowlist, validate input against OpenAPI, and return only the fields required by the calling
workflow.
The public API does not provide delegated agent authorization. A caller must not select an
arbitrary `X-Doctronic-User-ID` or expand its own permissions.
## Related documentation [#related-documentation]
* [Access and environments](/docs/access-and-environments)
* [API reference](/docs/api-reference)
* [Patient context and handoffs](/docs/patient-context-and-handoffs)
* [Handle safety and escalation](/docs/guides/safety-and-escalation)
* [Production readiness](/docs/production-readiness)
# Appointments (/docs/appointments)
The Doctronic API supports scheduled and ASAP appointments for a user in your organization.
Every appointment request must include the API Bearer token and the user's
`X-Doctronic-User-ID` header.
## Scheduled care [#scheduled-care]
1. Set a complete user address with `PUT /address/` before requesting availability or booking.
2. List available slots with `GET /appointments/scheduled/available-slots/`.
3. Book the selected slot with `POST /appointments/scheduled/`.
4. Persist the returned appointment ID in your system.
Do not assume a previously listed slot is still available at booking time. Handle a booking
failure as the current source of truth and request availability again when appropriate.
## ASAP care [#asap-care]
Use `POST /appointments/asap/` when the user should enter the next available care queue
rather than select a future time. Supply an `Idempotency-Key` when booking.
## Appointment management [#appointment-management]
* List appointments with `GET /appointments/`.
* Retrieve one appointment with `GET /appointments/{appointment_id}/`.
* Cancel with `POST /appointments/{appointment_id}/cancel/`.
* Reschedule with `POST /appointments/{appointment_id}/reschedule/`.
A user can be created with partial demographics, but first name, last name, and phone number
are required when booking an appointment. Booking also requires an address with `line1`, `city`,
`state`, and `postalCode`.
Scheduled booking, ASAP booking, cancellation, and rescheduling accept `Idempotency-Key`.
If a request times out, retry the same body with the same key. Use a new key only when the user
intends a different change. Results are retained for 24 hours.
The API returns `Idempotency-Replayed: true` when it replays a stored result. A reused key with a
different payload, or a key whose first request is still being processed, returns `409`. If
idempotency coordination is temporarily unavailable, the API returns `503` without starting the
mutation.
See [Errors and retries](/docs/errors#idempotent-mutations) for the complete endpoint list and retry
rules.
# Authentication (/docs/authentication)
The Doctronic API uses two request values with different responsibilities. User-scoped
operations require both values.
API tokens and related secrets are provisioned manually. Contact your Doctronic business or
implementation contact for initial staging access, production credentials, rotation, or revocation.
| Request value | Purpose | Sent as |
| ----------------- | -------------------------------------------- | ------------------------- |
| API token | Authenticates your organization | `Authorization: Bearer …` |
| Doctronic user ID | Selects the patient within your organization | `X-Doctronic-User-ID: …` |
## API Bearer token [#api-bearer-token]
The API token is a server credential and must only be used from infrastructure you control.
```http
Authorization: Bearer YOUR_API_TOKEN
```
Do not call the Doctronic API directly from browser JavaScript or a mobile application. Route
requests through your backend so an end user cannot extract the token.
Doctronic does not currently provide a self-service credential dashboard. Coordinate token
delivery and rotation with your Doctronic business or implementation contact using the agreed
secure channel.
## User scope [#user-scope]
After creating a user, send the returned `data.id` with user-scoped requests:
```http
X-Doctronic-User-ID: USER_ID_FROM_CREATE_RESPONSE
```
The user ID does not replace the Bearer token. Send both headers on every user-scoped request.
Doctronic verifies that the selected user belongs to the authenticated organization. Changing
the header cannot grant access to a user outside that scope.
## Failure modes [#failure-modes]
* `401 error.auth.unauthorized`: The Bearer token is missing, invalid, or inactive.
* `403 error.member.forbidden`: The authenticated organization cannot act on the selected user.
* `404` on scoped resources: The resource is missing or is outside the authenticated scope.
Staging and production credentials are distinct. Do not reuse tokens across environments.
# Consultation documents (/docs/clinical-artifacts)
When a consultation completes, the stream emits `ai_consultation.complete` with stable IDs for its
long summary, short summary, and SOAP note.
The API represents each of these documents as an `artifact`. This is the resource name used in
the completion event and retrieval endpoint.
The event confirms consultation completion and identifies the artifacts. It does not guarantee
that each artifact is ready to retrieve. A request can return `202` while generation continues.
```text
event: ai_consultation.complete
data: {"type":"ai_consultation.complete","artifacts":{"longSummary":"art_01K6JGGM2G2DB4Y9KB9H9MJJ6Q","shortSummary":"art_01K6JGGP7Q4R8S2T5V7W9X1Y3","soapNote":"art_01K6JGGR9Z6B2C4D6F8H0J2K4M"}}
```
Store each ID with the chat and the user-scoped identity that received the event. Retrieve an
artifact with:
```http
GET /artifacts/{artifactId}/
Authorization: Bearer YOUR_ORGANIZATION_TOKEN
X-Doctronic-User-ID: USER_ID
```
## Document types [#document-types]
| Completion key | `artifactType` | Intended representation |
| -------------- | --------------- | -------------------------- |
| `longSummary` | `long_summary` | Long consultation summary |
| `shortSummary` | `short_summary` | Short consultation summary |
| `soapNote` | `soap_note` | SOAP note |
A ready response contains `data.artifactId`, `data.artifactType`, and `data.content`. The content
object includes the originating `chatId`, `createdAt`, and a Markdown `body`.
```json title="Ready artifact response"
{
"code": "success",
"message": "Request successful",
"data": {
"artifactType": "short_summary",
"artifactId": "art_01K6JGGP7Q4R8S2T5V7W9X1Y3",
"content": {
"chatId": "chat-id-from-the-consultation",
"createdAt": "2026-08-16T15:30:00Z",
"body": "## Consultation summary\n\n..."
}
}
}
```
Artifact bodies contain the consultation document. They do not contain private model reasoning.
## Handle generation state [#handle-generation-state]
Artifact generation can finish after the completion event. Handle each status explicitly:
| Status | Meaning | Integration behavior |
| ------ | ----------------------------------------------------------------- | ----------------------------------------------------------- |
| `200` | The artifact is ready. | Validate `artifactType` and render or store `content.body`. |
| `202` | The artifact is still being generated. | Retry later with bounded backoff. |
| `404` | The artifact is absent or outside the organization or user scope. | Stop polling and verify the stored identity mapping. |
| `500` | Artifact generation failed permanently. | Stop polling and enter the integration's failure path. |
The contract does not specify a response body or retry delay for `202`. Do not assume one is
present. Choose a bounded polling policy with your Doctronic business or implementation contact.
## Preserve scope and provenance [#preserve-scope-and-provenance]
The artifact endpoint checks both the authenticated organization and the selected user. A missing
artifact and an artifact outside that scope both return `404`, preventing resource discovery
across integrations.
Verify that `data.content.chatId` matches the chat associated with the completion event before
attaching the artifact to a local record.
## Render Markdown defensively [#render-markdown-defensively]
Treat `content.body` as untrusted Markdown at the presentation boundary. Use a renderer configured
for your product, sanitize any generated HTML, and do not execute scripts or embedded content.
Preserve the original artifact ID and timestamp separately from the rendered display.
## Related documentation [#related-documentation]
* [Consultation lifecycle](/docs/conversations/lifecycle)
* [Artifact endpoint](/docs/api-reference/endpoints/artifacts)
* [Test your integration](/docs/guides/test-your-integration)
# Errors, idempotency, and retries (/docs/errors)
JSON errors contain a stable machine-readable `code` and a human-readable `message`. Some errors
also include `data`.
```json
{
"code": "error.auth.unauthorized",
"message": "Unauthorized."
}
```
## HTTP status guidance [#http-status-guidance]
| Status | Meaning | Handling |
| ----------- | --------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
| `400` | The request is invalid for the current workflow | Correct the request. Do not retry it unchanged. |
| `401` | API authentication failed | Stop using the credential and coordinate replacement or rotation with Doctronic. |
| `403` | The organization cannot act on the selected user | Stop and verify the patient-to-user mapping. |
| `404` | The resource is absent from the authenticated scope | Treat it as unavailable without revealing whether it exists elsewhere. |
| `409` | State or idempotency conflict | Inspect the endpoint error code before deciding whether to refresh or retry. |
| `422` | The request shape failed validation | Correct field types and constraints. |
| `503` | The operation cannot start safely or the service is temporarily unavailable | Retry only according to the endpoint contract. |
| Other `5xx` | Service failure | Retry safe reads with bounded exponential backoff and jitter. |
Individual endpoints can define more specific behavior. Artifact retrieval returns `202` while a
document is processing and uses `500` for a permanent generation failure. Use the endpoint
reference as the source of truth.
## Idempotent mutations [#idempotent-mutations]
These operations accept an `Idempotency-Key` header:
* `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/`
* `PUT /pharmacy/`
Generate a unique, opaque key for one intended operation. If the response is lost, retry the exact
same method, path, and body with the same key. The stored result is available for 24 hours and a
replayed response includes:
```http
Idempotency-Replayed: true
```
Do not reuse a key for a different request. A key used with a different payload, or a first request
that is still being processed, returns `409`. If the API cannot coordinate idempotency safely, it
returns `503` and does not start the mutation.
The chat streaming operation does not accept an idempotency key. After an interrupted stream,
inspect `GET /chats/{chatId}/messages/` before allowing an explicit user retry.
## Stream errors [#stream-errors]
Before SSE begins, the stream endpoint can return an ordinary JSON error response. After SSE has
started, a recoverable failure can arrive as an `error` event. Its documented fields are
`errorCode`, `message`, and optional `retryAfterSeconds`.
Handle a stream `error` separately from assistant content. If `retryAfterSeconds` is present, wait
at least that long. Do not automatically resend a turn after partial output because the first
attempt may already have created work.
## Retry checklist [#retry-checklist]
* Retry reads only for failures the endpoint identifies as temporary.
* Preserve the same idempotency key and body when retrying a supported mutation.
* Reconcile the resource before replaying a mutation that does not accept an idempotency key.
* Set a maximum number of attempts and elapsed time.
* Add exponential backoff and jitter.
* Treat the end of an SSE connection as transport completion, not consultation completion.
* Retain `X-Request-ID` with local request metadata for investigation.
# Evaluation approach (/docs/evaluation)
Evaluation is part of implementation and release review. The goal is to show that the clinical
behavior and the surrounding integration work as intended for the approved use case.
## What to evaluate [#what-to-evaluate]
| Area | Questions to answer |
| ---------------------- | ----------------------------------------------------------------------------------------------------- |
| Clinical correctness | Is the response medically appropriate for the information available? |
| Safety behavior | Do expected safety conditions produce the correct observable event and patient experience? |
| Intent and disposition | Does the workflow identify what the patient needs and reach an appropriate next step? |
| Grounding | Are clinical statements supported by the information available to the workflow? |
| Instruction following | Does the experience respect the approved scope and integration context? |
| Contract behavior | Are events, error states, artifacts, and API responses handled according to the documented interface? |
| Regression risk | Does a change preserve previously accepted behavior across the test set? |
## Doctronic-wide and integration evidence [#doctronic-wide-and-integration-evidence]
Doctronic maintains evaluation and regression processes for the clinical system.
An implementation also needs tests for its own identity mapping, context, event handling, routing,
copy, and failure behavior. A general result does not prove that a product-specific integration is
correct.
Before launch, agree with your Doctronic implementation contact on:
* The intended patient population and use case.
* In-scope and out-of-scope scenarios.
* Safety and escalation cases.
* Expected dispositions and handoffs.
* Data and context available to the workflow.
* Acceptance criteria and required human review.
* The evidence required after a material model, prompt, workflow, or integration change.
## Build a useful test set [#build-a-useful-test-set]
Include representative primary paths, uncommon but important presentations, ambiguous inputs,
out-of-scope requests, safety conditions, incomplete patient data, and failures in downstream
systems. Keep evaluation cases versioned and record which API, workflow, and application versions
produced each result.
Do not put production credentials or unrestricted patient records into a test set. Confirm the
permitted data source and de-identification process with your security and implementation teams.
## Review results [#review-results]
Automated checks are useful for repeatable contract, safety, and regression coverage. Clinical
review is still needed where the acceptance decision requires medical judgment. Record failures by
category and preserve enough context to reproduce them without copying secrets into the record.
Doctronic can review detailed methodology and implementation-specific evidence through the
implementation process. Public documentation does not publish internal prompts, private datasets,
or security-sensitive thresholds.
# Make your first request (/docs/getting-started)
This walkthrough takes a user from account creation through consultation completion and
document retrieval. The API returns each consultation summary or SOAP note as an `artifact`.
## Before you begin [#before-you-begin]
You need an API Bearer token provisioned by Doctronic. Credential provisioning is currently
manual. Contact your Doctronic business or implementation contact to request staging or
production access. If you do not have a contact yet, email
[business@doctronic.ai](mailto:business@doctronic.ai?subject=Developer%20API%20access). Do not send
credentials or patient information by email.
There is no self-service token dashboard. Tell your Doctronic contact which environment you
need and who should receive the credential through the agreed secure channel.
Store the token server-side and never expose it in browser code, mobile binaries, logs, or
analytics events.
```bash title="Set local variables"
export DOCTRONIC_API_URL="https://staging-partners.doctronic.ai/api/v1"
export DOCTRONIC_API_TOKEN="replace-with-your-token"
export DOCTRONIC_CREATE_USER_KEY="replace-with-a-unique-key"
```
## 1. Create a user [#1-create-a-user]
Create the Doctronic identity that corresponds to the patient in your system.
```bash
curl --request POST "$DOCTRONIC_API_URL/users/" \
--header "Authorization: Bearer $DOCTRONIC_API_TOKEN" \
--header "Idempotency-Key: $DOCTRONIC_CREATE_USER_KEY" \
--header "Content-Type: application/json" \
--data '{
"firstName": "Avery",
"lastName": "Chen",
"dateOfBirth": "1990-06-15",
"email": "avery@example.com",
"phoneNumber": "+15555550100",
"sex": "female"
}'
```
Save the returned `data.id`. Pass it as `X-Doctronic-User-ID` for every user-scoped request.
## 2. Create a chat [#2-create-a-chat]
```bash
export DOCTRONIC_USER_ID="user-id-from-step-one"
export DOCTRONIC_CREATE_CHAT_KEY="replace-with-a-different-unique-key"
curl --request POST "$DOCTRONIC_API_URL/chats/" \
--header "Authorization: Bearer $DOCTRONIC_API_TOKEN" \
--header "X-Doctronic-User-ID: $DOCTRONIC_USER_ID" \
--header "Idempotency-Key: $DOCTRONIC_CREATE_CHAT_KEY" \
--header "Content-Type: application/json" \
--data '{
"timezone": "America/New_York",
"conversationPromptContext": "The user entered from the primary-care intake flow."
}'
```
Save the returned `data.id` for each streaming request.
The create-user and create-chat operations retain an `Idempotency-Key` result for 24 hours. If a
request times out before you receive a response, retry the same operation with the same body and
key. Use a different key for a different user or chat.
## 3. Stream a turn [#3-stream-a-turn]
```bash
export DOCTRONIC_CHAT_ID="chat-id-from-step-two"
curl --no-buffer --request POST \
"$DOCTRONIC_API_URL/chats/$DOCTRONIC_CHAT_ID/stream/" \
--header "Authorization: Bearer $DOCTRONIC_API_TOKEN" \
--header "X-Doctronic-User-ID: $DOCTRONIC_USER_ID" \
--header "Content-Type: application/json" \
--header "Accept: text/event-stream" \
--data '{
"userEvent": {
"type": "user_message",
"userInput": "I have had a sore throat and fever since yesterday."
},
"timezone": "America/New_York"
}'
```
The response remains open for the assistant turn and emits Server-Sent Events such as
`message.start`, `message.content`, and `message.stop`.
A stopped assistant message is not a completed consultation. Continue the consultation by
sending each new user turn to the same stream endpoint. Treat `guardian`,
`conversation.end`, `skill_code.cta`, `error`, and `ai_consultation.complete` as explicit
control events. Never infer their meaning from assistant text or from the connection closing.
If a `guardian` event arrives, route it through the safety behavior approved for your
integration. Pause any routine local flow that conflicts with that behavior, and keep the
event's stable `guardianId` in your integration logs. Your approved behavior determines how
and where the supplied `message` is presented.
## 4. Detect consultation completion [#4-detect-consultation-completion]
Continue sending user turns until the stream emits `ai_consultation.complete`. Its payload
contains stable IDs for the consultation artifacts:
```text
event: ai_consultation.complete
data: {"type":"ai_consultation.complete","artifacts":{"longSummary":"art_01K6JGGM2G2DB4Y9KB9H9MJJ6Q","shortSummary":"art_01K6JGGP7Q4R8S2T5V7W9X1Y3","soapNote":"art_01K6JGGR9Z6B2C4D6F8H0J2K4M"}}
```
Persist the artifact IDs with your consultation record. The completion event does not guarantee
that every artifact is ready to retrieve. The end of an HTTP response only marks the end of that
transport stream. It does not mean the consultation is complete.
## 5. Retrieve a consultation document [#5-retrieve-a-consultation-document]
Use an artifact ID from the completion event:
```bash
export DOCTRONIC_ARTIFACT_ID="artifact-id-from-completion-event"
curl --request GET \
"$DOCTRONIC_API_URL/artifacts/$DOCTRONIC_ARTIFACT_ID/" \
--header "Authorization: Bearer $DOCTRONIC_API_TOKEN" \
--header "X-Doctronic-User-ID: $DOCTRONIC_USER_ID"
```
A `200` response identifies the artifact with `data.artifactType` and provides its Markdown
content in `data.content.body`. The type is `long_summary`, `short_summary`, or `soap_note`.
If the API returns `202`, the artifact is still being generated. Wait before requesting it
again. Treat `404` as unavailable and `500` as a permanent generation failure.
Ignore event types you do not recognize. New event names may be added without breaking
existing consumers.
## Next steps [#next-steps]
# Implementation and rollout (/docs/implementation-and-rollout)
Use a staged rollout even when the API operations are already available. Each stage should have a
clear entry condition, owner, evidence set, and rollback action.
## Define the workflow [#define-the-workflow]
Document:
* The patient population and entry point.
* The public API operations and configured capabilities required.
* The identity source and Doctronic user mapping.
* Context passed into the clinical conversation.
* Safety, CTA, error, and return-to-caller behavior.
* Consultation-document and appointment destinations.
* Patient messaging, support, and operational ownership.
Mark any EHR delivery, proactive outreach, custom routing, or other co-developed behavior as a
separate dependency. Do not treat it as part of the public API until a contract is defined.
## Build in staging [#build-in-staging]
1. Request staging credentials and any configured webhook events.
2. Implement the backend trust boundary and patient mapping.
3. Complete the primary workflow with approved test data.
4. Exercise safety, error, timeout, duplicate, and unknown-event cases.
5. Collect the evaluation and operational evidence agreed with Doctronic.
6. Review the patient experience, attribution, accessibility, and support path.
## Prepare production [#prepare-production]
Before production access is enabled, confirm:
* Production credentials are stored separately and can be rotated without a client release.
* Traffic limits and expected usage are understood.
* Dashboards and alerts cover the API, stream, webhook, and local workflow failures you own.
* On-call contacts and escalation channels are recorded.
* A pause or rollback can be applied without corrupting patient state.
* The [production-readiness checklist](/docs/production-readiness) is complete.
## Increase traffic deliberately [#increase-traffic-deliberately]
Begin with a bounded population or traffic allocation agreed with Doctronic. Review clinical,
integration, and operational evidence before increasing exposure. Stop or reduce traffic when an
acceptance condition fails, then reconcile incomplete chats, appointments, webhook events, and
documents before resuming.
The public API does not provide a self-service production approval or rollout dashboard. Coordinate
production enablement and material scope changes with your Doctronic implementation contact.
# Overview (/docs)
The Doctronic API lets your backend create patients, run streamed clinical conversations, handle
safety and workflow events, book appointments, and retrieve consultation summaries and SOAP
notes.
## Key terms [#key-terms]
| Term | Meaning |
| -------------- | --------------------------------------------------------------------- |
| User | The Doctronic record associated with a patient in your system |
| Chat | One clinical conversation for that user |
| SSE event | A named update sent while a chat response is streaming |
| Guardian event | A safety signal that follows the handling agreed for your integration |
| Artifact | The API resource containing a consultation summary or SOAP note |
## How an integration works [#how-an-integration-works]
The API is called from your backend. The organization token must not be sent to a browser or mobile
application.
1. Create a Doctronic user and store its ID with the patient in your system.
2. Create a chat and send patient turns to its streaming endpoint.
3. Render assistant text from `message.*` events and handle control events in separate code paths.
4. When `ai_consultation.complete` arrives, retrieve the documents your workflow needs.
5. If applicable, continue into an appointment or pharmacy workflow.
## What the public API supports [#what-the-public-api-supports]
| Capability | API surface |
| --------------------------- | ----------------------------------------------------------------------------- |
| Patient records | Create and retrieve users scoped to your organization |
| Clinical conversations | Create chats, stream turns, list chats, and restore transcripts |
| Safety and workflow events | Handle guardian, conversation, call-to-action, error, and completion events |
| Appointments and pharmacies | Find availability, manage scheduled or ASAP appointments, and save a pharmacy |
| Consultation documents | Retrieve long summaries, short summaries, and SOAP notes by artifact ID |
Some capabilities, including outbound webhooks and implementation-specific routing, are configured
by Doctronic. Other workflows require joint design. The
[integration patterns](/docs/integration-patterns) page labels each category.
## Start building [#start-building]
* [Request access and choose an environment](/docs/access-and-environments)
* [Run the quickstart](/docs/getting-started)
* [Read the production checklist](/docs/production-readiness)
* [Download the OpenAPI 3.1 contract](/openapi/doctronic-v1.json)
Credentials are provisioned manually. Contact your Doctronic business or implementation contact
for staging or production access. If you do not have a contact, email
[business@doctronic.ai](mailto:business@doctronic.ai?subject=Developer%20API%20access). Do not
include credentials or patient information in email.
# Choose an integration pattern (/docs/integration-patterns)
Start with the workflow your product needs. The public API covers the common patient, conversation,
appointment, pharmacy, and consultation-document operations. Some delivery and routing behavior is
configured by Doctronic. Workflows outside the public contract are designed with your implementation
team.
## Availability [#availability]
| Pattern | Availability | What to use |
| -------------------------------------------------------------------------- | ----------------------- | --------------------------------------------------------------------------------------------------------- |
| Patient starts a clinical conversation in your product | Public API | Create a user and chat, then consume the SSE stream from your backend. |
| Your workflow passes prior context into a conversation | Public API | Use `conversationPromptContext` for chat-level context or `messagePromptContext` for one turn. |
| Your application reacts to safety or next-step signals | Public API | Handle `guardian`, `conversation.end`, `skill_code.cta`, and related typed events. |
| Your workflow books Doctronic care | Public API | Use the address, appointment, and pharmacy operations where enabled for your integration. |
| Your system receives appointment or artifact updates asynchronously | Configured by Doctronic | Register an HTTPS webhook URL, secret, and event subscriptions with your implementation contact. |
| A separate agent hands work to Doctronic | Backend-mediated | Resolve the user in trusted code, pass relevant context, and return typed outcomes to the calling system. |
| Results are delivered into an EHR, FHIR server, or another clinical system | Co-developed | Define the destination, data mapping, authorization, and operational ownership with Doctronic. |
| Proactive outreach starts from an external trigger | Co-developed | Define the trigger, consent, channel, safety behavior, and return path with Doctronic. |
“Public API” means the operation is present in the published OpenAPI contract. It does not mean
that credentials, geography, clinical workflow, or production access are enabled automatically.
## Patient-facing conversations [#patient-facing-conversations]
Your frontend sends patient input to your backend. Your backend authenticates the patient, maps the
patient to a Doctronic user ID, and calls the Doctronic API. It can relay the documented stream events
to the frontend without exposing the organization token.
Use explicit events for product state. Do not infer a safety state, conversation end, or care action
from assistant text.
## Agent and workflow handoffs [#agent-and-workflow-handoffs]
The current public API does not provide delegated agent credentials or a direct agent-to-agent
session protocol. A calling agent should invoke a narrow tool in your backend. That backend should:
1. Authenticate the caller and resolve the patient.
2. Select the allowed Doctronic operation.
3. Pass only the context required for the clinical task.
4. Enforce the same safety and authorization rules as any other caller.
5. Return structured events or documents to the calling system.
See [Patient context and handoffs](/docs/patient-context-and-handoffs) for the current context
fields and trust boundary.
## Configured and co-developed work [#configured-and-co-developed-work]
For configured or co-developed capabilities, agree on these items before implementation:
* The patient identity and consent boundary.
* The source and destination of clinical data.
* Required events, documents, and failure states.
* Which system owns patient messaging and escalation.
* Test data, acceptance evidence, rollout controls, and operational contacts.
Contact your Doctronic business or implementation contact to confirm availability for a specific
workflow.
# Patient context and handoffs (/docs/patient-context-and-handoffs)
The API accepts context at two points:
| Field | Scope | Limit |
| --------------------------- | ------------------------ | ----------------- |
| `conversationPromptContext` | Applies to the chat | 50,000 characters |
| `messagePromptContext` | Applies to one user turn | 50,000 characters |
Both fields are clinical input. They are not credentials, executable instructions, or a substitute
for structured patient identity.
## Keep the trust boundary on your backend [#keep-the-trust-boundary-on-your-backend]
Your backend should resolve the current patient to the Doctronic user ID stored for your
organization. Do not accept a Doctronic user ID from a browser, mobile client, agent, or external
workflow without validating that mapping.
Do not put an API token, webhook secret, or another system credential in either context field.
## Pass useful context [#pass-useful-context]
Good context is relevant to the clinical task and attributable to its source. Examples include:
* The reason the patient entered the workflow.
* Answers collected in a prior intake step.
* A concise handoff from another approved clinical workflow.
* Constraints the patient explicitly selected, such as language or location.
Avoid copying an entire application state, unrestricted chart export, hidden routing commands, or
content that the current workflow is not authorized to use.
```json title="Chat-level context"
{
"timezone": "America/New_York",
"conversationPromptContext": "The patient entered from a sore-throat intake flow and reported symptoms beginning yesterday."
}
```
```json title="Turn-level context"
{
"userEvent": {
"type": "user_message",
"userInput": "My fever is 101.5 F.",
"messagePromptContext": "Temperature was entered in the intake form immediately before this turn."
},
"timezone": "America/New_York"
}
```
## Return control to the caller [#return-control-to-the-caller]
Treat typed stream events as the return contract:
* Relay `message.*` events when the calling experience displays the conversation.
* Route `guardian` through the safety behavior approved for the integration.
* Use `conversation.offtopic` or `conversation.end` to return to an appropriate local flow.
* Map supported `skill_code.cta` values to explicit actions.
* Store artifact IDs from `ai_consultation.complete` and retrieve the required documents.
* Ignore unknown events and record enough metadata to investigate them.
The API does not provide a general-purpose agent callback or arbitrary routing endpoint. Keep
caller-specific orchestration in your system unless a separate contract is established with
Doctronic.
# Patient experience (/docs/patient-experience)
Doctronic API calls must originate from your backend. A web or mobile client can display the
conversation and send patient input through your application, but it must not receive the
organization token.
## Required interface states [#required-interface-states]
Plan explicit behavior for:
* Starting and reconnecting a conversation.
* Streaming an assistant message.
* A `guardian` event.
* A call to action from `skill_code.cta`.
* A conversation that ends without a consultation document.
* Consultation documents that are still processing.
* Appointment state changes.
* A recoverable stream error or network interruption.
* An event name your current client does not recognize.
Use event types and API responses for these states. Do not parse assistant text to decide whether
to escalate, end a conversation, or book care.
## Brand and attribution [#brand-and-attribution]
Patient-facing implementations must use the Doctronic name and attribution approved for the
integration. Confirm the current lockup, placement, and wording with your Doctronic implementation
contact before launch. Do not remove or alter required attribution.
Your product can retain its own navigation, account, and support patterns around the Doctronic
experience. Agree on which system owns each patient message, error state, and support handoff.
## Accessibility [#accessibility]
* Announce streamed content without repeatedly moving keyboard focus.
* Provide visible status text in addition to color or animation.
* Keep safety messages and calls to action available to assistive technology.
* Support keyboard navigation and sufficient target sizes on mobile.
* Let users recover from a dropped connection without losing the visible transcript.
* Test long clinical content, large text sizes, reduced motion, and narrow screens.
## Data in the client [#data-in-the-client]
Send only the information the interface needs. Do not place the organization token, webhook
secret, unrestricted clinical documents, or internal routing details in client-visible state,
analytics, crash reports, or logs.
# Production readiness (/docs/production-readiness)
Use this review after completing an end-to-end staging integration. Production access and
credentials are provisioned manually by Doctronic.
## Access and identity [#access-and-identity]
* Store the organization Bearer token in a server-side secret manager.
* Keep staging and production credentials and user-ID mappings separate.
* Verify the local patient identity before selecting `X-Doctronic-User-ID`.
* Restrict which backend services and operators can read or use the token.
* Coordinate token delivery, rotation, and revocation with your Doctronic business or
implementation contact.
* Confirm the production base URL is `https://partners.doctronic.ai/api/v1`.
## Conversation streaming [#conversation-streaming]
* Parse SSE across arbitrary network chunk boundaries.
* Build assistant messages from `message.start`, `message.content`, and `message.stop`.
* Key message assembly by `messageId`.
* Ignore unknown event names so additive contract changes remain compatible.
* Treat the HTTP connection ending as transport completion only.
* Reconcile the transcript before replaying an interrupted turn.
* Do not automatically replay an interrupted chat turn. The stream operation does not accept an
idempotency key.
## Safety and workflow events [#safety-and-workflow-events]
* If `guardian` is emitted, route it through the safety behavior approved for your integration.
* Map supported `skill_code.cta` values to explicit product actions.
* Provide safe fallbacks for unknown guardian IDs, CTA values, and event names.
* Treat `conversation.end` and `ai_consultation.complete` as separate signals.
* Keep clinical workflow decisions out of free-form text parsing.
* Exercise these paths in staging before production access.
## Artifacts [#artifacts]
* Store artifact IDs from `ai_consultation.complete` with their chat and user scope.
* Handle `202` with bounded polling.
* Stop retrying on `404` and permanent `500` responses.
* Verify the returned `chatId` before attaching content to a local record.
* Render Markdown according to your product's content-safety rules.
## Appointments [#appointments]
* Collect required demographics and a complete address before booking.
* Refresh availability after `409 error.appointments.slot_unavailable`.
* Retrieve an existing appointment before retrying when a waiting-room error supplies an
`appointmentId`.
* Treat a waiting-room URL as a rotating, expiring value rather than a permanent identifier.
* Send a unique `Idempotency-Key` for booking, cancellation, and rescheduling.
* Preserve the same request body and key across retries of one intended change.
## Errors and recovery [#errors-and-recovery]
* Correct `400` and `422` requests instead of retrying unchanged.
* Stop on `401` or `403` and verify credentials and identity scope.
* Respect `retryAfterSeconds` in stream errors when present.
* Apply bounded exponential backoff and jitter only to errors documented as temporary.
* Retain the `X-Request-ID` response header with local request metadata.
* Define a user-visible fallback for prolonged service or network failure.
* Monitor failures by endpoint, status, and machine-readable error code.
## Webhooks [#webhooks]
* Verify `X-Doctronic-Signature` against the exact raw body before parsing JSON.
* Deduplicate processing with the stable `eventId`.
* Return a `2xx` response promptly and process work asynchronously.
* Ignore unknown event names without returning an error.
* Monitor permanent delivery failures and out-of-order events.
* Coordinate endpoint, subscriptions, and secret rotation with Doctronic.
## Data and observability [#data-and-observability]
* Keep Bearer tokens out of source control, client code, logs, traces, and analytics.
* Minimize patient content in operational telemetry.
* Restrict access to logs that contain user IDs, chat IDs, appointment IDs, or artifact IDs.
* Record enough event metadata to investigate stream ordering and integration failures.
* Confirm permitted production and staging data practices with Doctronic before launch.
## Contract management [#contract-management]
* Validate requests and responses against the published
[OpenAPI 3.1 contract](/openapi/doctronic-v1.json).
* Review the contract when updating generated clients or validators.
* Do not branch on undocumented fields or internal naming.
* Verify your consumer continues when it receives an unknown SSE event.
## Evaluation and rollout [#evaluation-and-rollout]
* Record the intended population, workflow, and out-of-scope behavior.
* Complete the clinical, safety, contract, and integration-specific evaluation set agreed with
Doctronic.
* Confirm approved Doctronic attribution and patient-facing copy.
* Start with bounded production traffic and a documented pause or rollback action.
* Record Doctronic and integration-owner operational contacts.
## Launch review [#launch-review]
Share the completed staging evidence, expected traffic pattern, supported workflows, escalation
behavior, and operational contact with your Doctronic business or implementation contact.
Production enablement is coordinated directly with Doctronic rather than through a public
self-service flow.
## Related documentation [#related-documentation]
* [Access and environments](/docs/access-and-environments)
* [Handle safety and escalation](/docs/guides/safety-and-escalation)
* [Test your integration](/docs/guides/test-your-integration)
* [Errors and retries](/docs/errors)
* [Webhooks](/docs/webhooks)
* [Evaluation approach](/docs/evaluation)
* [Implementation and rollout](/docs/implementation-and-rollout)
# Safety and responsibilities (/docs/safety-and-responsibilities)
Doctronic sends clinical content and typed control events. Your integration decides how those
events appear in its interface, how users move between systems, and how operational teams respond
when a workflow cannot continue.
## Doctronic provides [#doctronic-provides]
* Assistant content through `message.*` events.
* A `guardian` event when a documented safety condition is emitted.
* Explicit conversation, call-to-action, error, and consultation-completion events.
* Organization and user scoping on API resources.
* Consultation documents identified by the IDs in the completion event.
* A staging environment for approved integration testing.
## Your integration owns [#your-integration-owns]
* Authenticating the current patient before selecting a Doctronic user ID.
* Keeping the organization token and webhook secret on trusted infrastructure.
* Rendering clinical content and events without changing their meaning.
* The patient-facing fallback when a stream, appointment, or document workflow fails.
* Mapping supported call-to-action values to approved product behavior.
* Operational monitoring, local audit records, and access controls in your systems.
* Testing the complete user experience before production traffic is enabled.
## Decide together [#decide-together]
Document these items with your Doctronic implementation contact:
* Guardian presentation and escalation behavior.
* Supported CTA values and fallback behavior.
* Patient messaging and support ownership.
* Permitted clinical context and data destinations.
* Webhook events and operational contacts.
* Integration-specific evaluation cases and launch evidence.
* Rollout, pause, and rollback controls.
The public API does not define an external emergency-service integration, a guardian
acknowledgement endpoint, or a general-purpose escalation destination. Do not invent one by
parsing assistant text or replaying a patient turn.
## Use explicit state [#use-explicit-state]
Treat these signals independently:
| Signal | Meaning |
| -------------------------- | ------------------------------------------------ |
| `message.stop` | One assistant message finished. |
| `conversation.end` | The conversation ended with the supplied reason. |
| `guardian` | The approved safety path should run. |
| `skill_code.cta` | A documented product action is available. |
| `ai_consultation.complete` | Stable consultation-document IDs are available. |
| HTTP stream closes | The transport for the current turn closed. |
See [Handle safety and escalation](/docs/guides/safety-and-escalation) for event handling examples.
# Security and privacy (/docs/security-and-privacy)
The organization token authorizes access to your Doctronic API scope. Treat it as a production
secret. The `X-Doctronic-User-ID` selects a user inside that scope but is not a credential by
itself.
## Integration boundary [#integration-boundary]
* Call the Doctronic API from infrastructure you control.
* Store tokens and webhook secrets in a server-side secret manager.
* Authenticate the current patient before resolving a Doctronic user ID.
* Keep staging and production credentials, users, logs, and configuration separate.
* Restrict access to clinical content and identifiers according to job need.
* Use the documented HTTPS endpoints and validate TLS normally.
Do not place a token or secret in browser code, a mobile binary, a model prompt, source control,
client-visible configuration, analytics, screenshots, or logs.
## Data minimization [#data-minimization]
Send only the patient information and clinical context required for the approved workflow. Keep
credentials and internal routing instructions out of prompt context. Limit operational telemetry
to the identifiers and event metadata needed to investigate an issue.
Consultation documents can contain sensitive clinical information. Apply your approved access,
retention, display, export, and deletion controls when storing or presenting them.
## Logging and support [#logging-and-support]
Retain the `X-Request-ID` response header with local request metadata. It helps Doctronic trace a
request without requiring you to send credentials or unrestricted patient content through email.
When reporting a problem, provide the environment, endpoint, UTC time, response status, error code,
and request ID. Send patient information only through a channel approved for the integration.
## Review before production [#review-before-production]
Security, privacy, permitted data, retention, and incident procedures depend on the implementation
and governing agreement. Confirm them with your Doctronic business or implementation contact. Do
not infer enterprise commitments from the consumer privacy notice or from this public technical
documentation.
For a detailed security review or supporting documentation, contact your Doctronic implementation
contact. If you do not have one, email
[business@doctronic.ai](mailto:business@doctronic.ai?subject=Developer%20security%20review) without
including credentials or patient information.
# Versioning and support (/docs/versioning-and-support)
The current API uses the `/api/v1` path. The downloadable OpenAPI file is the source of truth for
HTTP operations, request fields, responses, and schemas.
## Compatibility rules [#compatibility-rules]
* Ignore JSON fields and SSE event names your client does not recognize.
* Do not depend on response field order or undocumented fields.
* Treat operation IDs, error codes, event names, and enum values as case-sensitive wire values.
* Review OpenAPI changes before updating generated clients or validators.
* Test changed behavior in staging before deploying it to production.
Additive fields, response members, event names, and enum values can appear without changing the
versioned path. A client that rejects unknown values will be harder to operate safely.
## Capture request details [#capture-request-details]
Keep the `X-Request-ID` response header with your local request record. For an SSE request, also
retain the chat ID, user ID, event names received, UTC timestamps, and whether the HTTP stream
closed normally. Do not log the Bearer token or unrestricted patient content.
## Report an API problem [#report-an-api-problem]
Send your Doctronic implementation contact:
* Staging or production environment.
* HTTP method and path.
* UTC time and `X-Request-ID`.
* Response status and machine-readable error code.
* Whether a retry used the same `Idempotency-Key`.
* The last safe workflow state, without credentials or unnecessary patient content.
If you do not have an implementation contact, email
[business@doctronic.ai](mailto:business@doctronic.ai?subject=Developer%20API%20support). Do not send
credentials or patient information by email.
## Contract updates [#contract-updates]
The public reference is generated from the deployed production OpenAPI contract and checked daily
for changes. Download the current contract from
[`/openapi/doctronic-v1.json`](/openapi/doctronic-v1.json). Coordinate material workflow changes
with Doctronic before enabling them in production.
# Webhooks (/docs/webhooks)
Doctronic can send signed HTTP `POST` requests when selected appointment or consultation-document
events occur. Webhooks are configured manually. Provide your HTTPS endpoint and event subscriptions
to your Doctronic implementation contact. Doctronic will provide the signing secret through the
agreed secure channel.
There is no public endpoint or dashboard for registering a webhook, rotating its secret, viewing
deliveries, or replaying an event. Coordinate those actions with your implementation contact.
## Event envelope [#event-envelope]
Every request uses this camelCase envelope:
```json
{
"eventId": "0f8fad5b-d9cb-469f-a165-70867728950e",
"event": "appointment.waiting_room_ready",
"occurredAt": "2026-08-25T18:30:00Z",
"data": {
"appointmentId": "appointment-id",
"userId": "doctronic-user-id",
"waitingRoomUrl": "https://dctd.co/r/example/"
}
}
```
`eventId` remains the same across delivery attempts. Use it as the idempotency key for processing.
`occurredAt` records when the event occurred, not when a particular attempt reached your endpoint.
## Available events [#available-events]
| Event | `data` fields | Meaning |
| --------------------------------- | ------------------------------------------------ | ---------------------------------------------------------------------------------------------------- |
| `appointment.waiting_room_ready` | `appointmentId`, `userId`, `waitingRoomUrl` | A join URL is ready. The URL currently expires one hour after issuance and can rotate when reissued. |
| `appointment.practitioner_joined` | `appointmentId`, `userId` | A practitioner joined the appointment. |
| `appointment.call_ended` | `appointmentId`, `userId` | The appointment call ended. |
| `artifact.ready` | `artifactId`, `artifactType`, `chatId`, `userId` | A consultation document is ready for retrieval. `userId` can be `null`. |
Only events enabled for your integration are sent. Ignore unknown event names so additive changes
do not break your receiver.
## Verify the signature [#verify-the-signature]
The `X-Doctronic-Signature` header contains a lowercase hexadecimal HMAC-SHA256 digest of the exact
request body bytes, signed with your webhook secret.
Verify the signature before parsing or processing the JSON. Do not reserialize the body first.
```ts title="Node.js signature verification"
import { createHmac, timingSafeEqual } from 'node:crypto';
export async function verifyDoctronicWebhook(
request: Request,
secret: string,
) {
const body = Buffer.from(await request.arrayBuffer());
const supplied = request.headers.get('x-doctronic-signature') ?? '';
const expected = createHmac('sha256', secret).update(body).digest('hex');
const suppliedBytes = Buffer.from(supplied, 'utf8');
const expectedBytes = Buffer.from(expected, 'utf8');
const valid =
suppliedBytes.length === expectedBytes.length &&
timingSafeEqual(suppliedBytes, expectedBytes);
if (!valid) throw new Error('Invalid Doctronic webhook signature');
return JSON.parse(body.toString('utf8'));
}
```
```py title="Python signature verification"
import hashlib
import hmac
import json
def verify_doctronic_webhook(body: bytes, supplied: str, secret: str) -> dict:
expected = hmac.new(secret.encode("utf-8"), body, hashlib.sha256).hexdigest()
if not hmac.compare_digest(supplied, expected):
raise ValueError("Invalid Doctronic webhook signature")
return json.loads(body)
```
## Process deliveries safely [#process-deliveries-safely]
1. Read and preserve the raw request body.
2. Verify `X-Doctronic-Signature` with a constant-time comparison.
3. Validate the event envelope and expected `data` fields.
4. Insert `eventId` into a durable uniqueness store.
5. If it was already processed, return a success response without applying the change again.
6. Queue the work and return any `2xx` response promptly.
7. Apply the event only to the matching organization and user records in your system.
The current signature has no separate delivery timestamp header. The signed `occurredAt` value can
support a workflow-specific freshness check, but it may be several hours old during retries. Do
not use freshness alone as replay protection. Signature verification and durable `eventId`
deduplication are both required.
## Delivery behavior [#delivery-behavior]
* Network failures, `429`, and `5xx` responses are retried with exponential backoff.
* Other `4xx` responses are treated as permanent failures and are not retried.
* The general retry window is up to six hours.
* `appointment.waiting_room_ready` has a shorter retry window of up to five minutes and stops when
the event is no longer useful for the appointment.
* Appointment lifecycle retries can stop when the appointment has ended.
Do not rely on a specific number of attempts. Keep the receiver available, idempotent, and fast.
## Rotate a webhook secret [#rotate-a-webhook-secret]
Secret rotation is coordinated with Doctronic. Plan a short maintenance procedure that can accept
the agreed secret at the agreed cutover point, verify a signed test delivery, and remove the prior
secret from your systems. Do not send the secret in email or an unapproved messaging channel.
## Test before production [#test-before-production]
Ask your implementation contact to enable the required events in staging. Verify:
* Valid signatures succeed and changed bodies fail verification.
* Duplicate `eventId` values do not repeat side effects.
* Unknown event names return success without blocking other events.
* Your endpoint responds correctly to retries and out-of-order events.
* A waiting-room URL replaces an older URL rather than becoming a permanent identifier.
* Processing failures are visible to your on-call team without logging secrets or unrestricted
patient content.
# API overview (/docs/api-reference)
The endpoint pages in this section are generated from the deployed Doctronic API schema. They
include authentication requirements, parameters, request and response models, and code examples.
[Download the OpenAPI 3.1 JSON contract](/openapi/doctronic-v1.json)
## Contract source [#contract-source]
The reference and downloadable OpenAPI file are generated from the deployed production API schema
and checked daily for changes. Use OpenAPI for operation and data shapes. Use the guides for
multi-step workflows, streaming behavior, testing, and production preparation.
# Consultation lifecycle (/docs/conversations/lifecycle)
A consultation begins with a user record and a chat. Each patient turn is sent
to the chat's streaming endpoint. The stream carries assistant content, explicit control
events, safety signals, calls to action, and consultation artifact IDs.
```text
User record
└── Chat
├── User turn
├── Assistant message stream
├── Safety and control events
└── Consultation completion
└── Long summary, short summary, and SOAP note
```
## Resource ownership [#resource-ownership]
Every chat belongs to both the authenticated organization and the selected Doctronic user.
List, retrieve, message, and stream operations enforce both parts of that scope. Send the
Bearer token and `X-Doctronic-User-ID` on every user-scoped request.
## A typical turn [#a-typical-turn]
1. POST the user's message to `/chats/{chatId}/stream/`.
2. Open the `text/event-stream` response.
3. Create an assistant message when `message.start` arrives.
4. Append text from each `message.content` event with the same `messageId`.
5. Finalize that assistant message on `message.stop`.
6. Handle safety and control events as independent events, even if they arrive between message events.
7. Close local transport state when the HTTP response ends.
8. Send the next user turn to the same endpoint until an explicit completion event arrives.
`message.stop` completes one assistant message. It does not complete the consultation. Likewise,
the HTTP connection ending only completes the current transport stream.
## Safety and control events [#safety-and-control-events]
Your event handler must not treat every frame as display text.
| Event | Integration behavior |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `guardian` | If emitted, enter the safety behavior approved for your integration, pause conflicting routine flows, and retain the stable `guardianId` in your logs. |
| `conversation.offtopic` | Record the classification and continue consuming the stream. Do not treat it as consultation completion. |
| `conversation.end` | Mark the conversation as ended using the supplied `reason`. Do not infer this state from message wording. |
| `skill_code.cta` | Present the supplied `widget` action and optional `text`, associated with its `skillCode`. |
| `error` | Handle the stream error separately from HTTP failures. Respect `retryAfterSeconds` when present. |
| `ai_consultation.complete` | Persist the artifact IDs and begin artifact retrieval. |
## Completion and artifacts [#completion-and-artifacts]
Only `ai_consultation.complete` identifies consultation completion. Its `artifacts` object
contains `longSummary`, `shortSummary`, and `soapNote` IDs. Retrieve each required artifact
with `GET /artifacts/{artifactId}/` using the same user scope. The completion event provides
stable IDs, but it does not mean every artifact is ready.
A successful artifact response identifies the type in `data.artifactType` and places Markdown
content in `data.content.body`. A `202` response means generation is still in progress, so wait
before requesting that artifact again. A `500` response means generation failed permanently.
# Stream chat responses (/docs/conversations/streaming)
The chat stream uses Server-Sent Events (SSE). Each frame contains an `event` name and a
camelCase JSON `data` payload. The payload's `type` matches the SSE event name.
```text
event: message.content
data: {"type":"message.content","messageId":"ac_hist_...","content":"Hello"}
```
## Event contract [#event-contract]
| Event | Documented payload | Integration behavior |
| -------------------------- | ----------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| `message.start` | `role`, `messageId`, `messageTimestamp` | Begin an assistant message. |
| `message.content` | `messageId`, `content` | Append the text chunk to the matching message. |
| `message.stop` | `messageId` | Finish that assistant message, not the consultation. |
| `conversation.offtopic` | `messageId` | Record the off-topic classification and keep consuming the stream. |
| `conversation.end` | `messageId`, `reason` | Mark the conversation as ended using the supplied reason. |
| `guardian` | `guardianId`, `message` | If emitted, enter the safety behavior approved for your integration and pause conflicting routine flows. |
| `error` | `errorCode`, `message`, optional `retryAfterSeconds` | Handle the stream error and respect the retry delay when present. |
| `skill_code.change_path` | `path` | Record a conversation path change. |
| `skill_code.cta` | `skillCode`, `widget`, optional `text` | Present the supplied next-step action. |
| `ai_consultation.complete` | `artifacts.longSummary`, `artifacts.shortSummary`, `artifacts.soapNote` | Persist the artifact IDs and start artifact retrieval. |
If `guardian` arrives, handle it independently from assistant message assembly and retain its
stable `guardianId` in your integration logs. Pause any routine local flow that conflicts with
the safety behavior approved for your integration. That approved behavior determines how the
supplied `message` is presented.
## Browser implementation [#browser-implementation]
The endpoint is a `POST`, so the browser's native `EventSource` interface is not sufficient.
Use `fetch()` and parse the response stream, or consume it from your backend and relay only
the events your frontend needs. Keep the API token on your backend.
```ts
const response = await fetch(`${baseUrl}/chats/${chatId}/stream/`, {
method: 'POST',
headers: {
Authorization: `Bearer ${apiToken}`,
'X-Doctronic-User-ID': userId,
'Content-Type': 'application/json',
Accept: 'text/event-stream',
},
body: JSON.stringify({
userEvent: { type: 'user_message', userInput },
timezone: 'America/New_York',
}),
});
if (!response.ok || !response.body) {
throw new Error(`Stream failed: ${response.status}`);
}
```
## Stream state [#stream-state]
Track state at three different levels:
* `message.stop` finishes one assistant message.
* `conversation.end` reports that the assistant ended the conversation.
* `ai_consultation.complete` makes stable consultation artifact IDs available. An artifact can
still return `202` while generation is in progress.
The HTTP response ending only closes the current transport stream. It does not imply any of
those application states.
## Compatibility and retry rules [#compatibility-and-retry-rules]
* Ignore event names you do not recognize.
* Do not infer safety, conversation end, or completion from assistant text.
* Key UI behavior from explicit event types and their documented fields.
* Preserve event order within a single HTTP stream.
* Associate message chunks by `messageId`.
* If an `error` includes `retryAfterSeconds`, wait at least that long before retrying.
* Do not automatically resend a user turn after partial output. A replay can duplicate work.
# Build a clinical conversation (/docs/guides/embed-clinical-intelligence)
A clinical conversation connects four API resources: a user, a chat, a stream of typed events,
and the artifacts produced when the consultation completes.
```text
User
-> Chat
-> Streamed turns
-> Safety and workflow events
-> Consultation artifacts
```
The `/users/` resource is the Doctronic record associated with the patient identity in your
system. The Bearer token scopes that record to your organization.
## Build the server-side flow [#build-the-server-side-flow]
1. Create the user with `POST /users/` and save `data.id` in your identity mapping.
2. Send that ID as `X-Doctronic-User-ID` on every user-scoped request.
3. Create a chat with `POST /chats/` and save the returned `data.id`.
4. Send each patient turn to `POST /chats/{chatId}/stream/`.
5. Parse the response as Server-Sent Events until the HTTP stream closes.
6. Act on explicit safety, workflow, and completion events.
Both credentials belong in your backend. Do not put the organization Bearer token in browser
code, mobile binaries, client-visible configuration, logs, or analytics events.
## Add integration context [#add-integration-context]
When creating a chat, `conversationPromptContext` can provide context that applies to the full
conversation. For a single turn, use `messagePromptContext` inside `userEvent`.
```json title="Create-chat context"
{
"timezone": "America/New_York",
"conversationPromptContext": "The user entered from the primary-care intake flow."
}
```
```json title="Per-message context"
{
"userEvent": {
"type": "user_message",
"userInput": "I have had a sore throat and fever since yesterday.",
"messagePromptContext": "This turn follows the integration's symptom intake form."
},
"timezone": "America/New_York"
}
```
Both context fields accept at most 50,000 characters. Treat them as clinical input, not as a
place for credentials, routing instructions, or unbounded application state. Invalid timezones
return `400`; the default timezone is `UTC`.
## Drive the interface from events [#drive-the-interface-from-events]
The stream separates assistant text from control signals.
| Event | Integration behavior |
| -------------------------- | --------------------------------------------------------------------- |
| `message.start` | Start a local assistant message using `messageId`. |
| `message.content` | Append the `content` chunk to that message. |
| `message.stop` | Mark the message complete. |
| `guardian` | If emitted, enter the integration's approved safety path. |
| `skill_code.cta` | Present the next-step action described by the event. |
| `conversation.end` | Record the explicit end state and its supplied `reason`. |
| `ai_consultation.complete` | Store the artifact IDs and begin retrieval. |
| `error` | Handle the stream error and respect `retryAfterSeconds` when present. |
Artifact IDs in `ai_consultation.complete` are stable, but an artifact can still return `202`
while generation is in progress.
Do not infer workflow state from the wording of `message.content`. The HTTP connection closing
ends the transport for one turn, but it does not by itself mean the consultation is complete.
Ignore event names you do not recognize. Do not fail the stream when Doctronic adds a new
event type.
## Restore an existing conversation [#restore-an-existing-conversation]
Use `GET /chats/` to list the user's chats and `GET /chats/{chatId}/messages/` to rebuild the
visible transcript. The message list contains `user` and `assistant` messages. Consultation
artifacts use their own retrieval endpoint.
## Next steps [#next-steps]
* [Handle safety and escalation](/docs/guides/safety-and-escalation)
* [Guide patients to care](/docs/guides/guide-patients-to-care)
* [Retrieve consultation documents](/docs/clinical-artifacts)
* [Inspect the chat endpoints](/docs/api-reference/endpoints/chats)
# Guide patients to care (/docs/guides/guide-patients-to-care)
The conversation stream can emit a `skill_code.cta` event with a `skillCode`, `widget`, and
optional `text`. Use that typed event to decide which approved action to present. Do not infer a
care action from assistant prose.
```text title="Example call to action"
event: skill_code.cta
data: {"type":"skill_code.cta","skillCode":"112","widget":"cta_doctor_visit_in_person_widget","text":"Book an in-person visit"}
```
The exact mapping from `skillCode` and `widget` to your interface is part of your integration.
Agree on supported mappings with your Doctronic business or implementation contact and provide a
safe fallback for values your application does not recognize.
## Prepare the user for booking [#prepare-the-user-for-booking]
Appointment creation requires:
* A user record with `firstName`, `lastName`, and `phoneNumber`.
* An address containing `line1`, `city`, `state`, and `postalCode`.
* The `chatId` associated with the clinical conversation.
* A US state in the appointment `location`.
* A chat that is ready for appointment booking.
Set or replace the user's address with `PUT /address/`. Although the request accepts partial
fields, booking rejects a missing or incomplete address.
## Offer scheduled care [#offer-scheduled-care]
1. Request availability with `GET /appointments/scheduled/available-slots/?state=NY`.
2. Optionally bound the search with `datetimeFrom` and `datetimeTo` ISO 8601 timestamps.
3. Present one of the returned `slots` without changing its timestamp.
4. Book it with `POST /appointments/scheduled/`, using the same state.
```json title="Scheduled appointment request"
{
"chatId": "chat-id-from-the-consultation",
"startsAt": "2026-08-20T15:00:00Z",
"location": {
"state": "NY"
}
}
```
A slot can become unavailable between selection and booking. On
`409 error.appointments.slot_unavailable`, refresh availability and ask the user to choose
again. Do not silently substitute another time.
Send a unique `Idempotency-Key` with the booking. If the response is lost, retry the same request
body with the same key.
## Offer ASAP care [#offer-asap-care]
Use `POST /appointments/asap/` when the approved workflow calls for the next available care
queue rather than a future slot.
```json title="ASAP appointment request"
{
"chatId": "chat-id-from-the-consultation",
"location": {
"state": "NY"
}
}
```
There is no guaranteed wait time. A successful response includes `waitingRoomUrl`. The URL
currently expires one hour after issuance and can rotate when reissued, so avoid treating it as
a permanent identifier.
If booking returns `502 error.appointments.waiting_room_unavailable`, the response can include
an `appointmentId` for an appointment that was already booked. Retrieve that appointment before
deciding what to show the user. If you retry the same booking request, reuse its idempotency key.
## Track the appointment [#track-the-appointment]
Use the appointment resource, not local assumptions, to show current state:
* `GET /appointments/` lists the user's appointments.
* `GET /appointments/{appointment_id}/` retrieves the latest detail.
* `POST /appointments/{appointment_id}/cancel/` cancels a booking.
* `POST /appointments/{appointment_id}/reschedule/` moves a scheduled booking to a new slot.
The public status values are `booked`, `cancelled`, `fulfilled`, `noshow`, and `unknown`.
Booking, cancellation, and rescheduling accept `Idempotency-Key`. Use one key for one intended
change, and preserve it across network retries. See [Errors and retries](/docs/errors#idempotent-mutations).
## Add a pharmacy when the workflow requires one [#add-a-pharmacy-when-the-workflow-requires-one]
Search with `POST /pharmacy/search/`, then save a result using its seven-digit `ncpdpId` with
`PUT /pharmacy/`. Setting a pharmacy requires `firstName`, `lastName`, `dateOfBirth`, and `sex`
on the user record.
A `guardian` event is not a booking instruction. Route it through the safety behavior agreed
for your integration, even if another event or message suggests a routine next step.
## Related documentation [#related-documentation]
* [Handle safety and escalation](/docs/guides/safety-and-escalation)
* [Appointments](/docs/appointments)
* [Appointment endpoints](/docs/api-reference/endpoints/appointments)
# Guides overview (/docs/guides)
These guides connect individual API operations into complete workflows. Start with the clinical
conversation, then add the care and operational paths required by your integration.
## Recommended order [#recommended-order]
1. Complete the [quickstart](/docs/getting-started).
2. Implement [clinical conversation streaming](/docs/conversations/streaming).
3. Add [safety and escalation behavior](/docs/guides/safety-and-escalation).
4. Retrieve and validate [consultation documents](/docs/clinical-artifacts).
5. Add supported [care workflows](/docs/guides/guide-patients-to-care).
6. Run the [integration test plan](/docs/guides/test-your-integration) and
[production checklist](/docs/production-readiness).
# Handle safety and escalation (/docs/guides/safety-and-escalation)
Doctronic returns assistant text and typed control events on the same Server-Sent Events stream.
Your integration should render text and make workflow decisions through separate code paths.
The documented safety interface is the published event stream, including `guardian`, `conversation.end`,
`conversation.offtopic`, `skill_code.cta`, `ai_consultation.complete`, and `error`.
## Handle guardian events explicitly [#handle-guardian-events-explicitly]
A guardian event contains a stable `guardianId` and a `message` for the integration's approved
safety behavior.
```text
event: guardian
data: {"type":"guardian","guardianId":"emergency_breathing","message":"Please call emergency services now."}
```
If it arrives:
1. Stop any routine local flow that conflicts with your approved safety behavior.
2. Apply the presentation or escalation behavior defined for your integration.
3. Record the event type, `guardianId`, chat ID, and timestamp in your operational telemetry.
4. Avoid placing the Bearer token or unrestricted patient content in logs.
5. Follow the escalation behavior agreed with your Doctronic business or implementation contact.
The API does not define a guardian acknowledgement endpoint. Do not invent an acknowledgement by
replaying the chat turn or sending another message automatically.
## Branch on event type [#branch-on-event-type]
```ts
function handleClinicalEvent(event: ClinicalEvent) {
switch (event.type) {
case 'message.start':
return messages.begin(event.messageId);
case 'message.content':
return messages.append(event.messageId, event.content);
case 'message.stop':
return messages.finish(event.messageId);
case 'guardian':
return safety.enter(event.guardianId, event.message);
case 'skill_code.cta':
return actions.present(event);
case 'conversation.end':
return conversation.finish(event.reason);
case 'ai_consultation.complete':
return artifacts.capture(event.artifacts);
case 'error':
return streamErrors.handle(event);
default:
return;
}
}
```
`ClinicalEvent` in this example is an integration-owned type. Generate or maintain it from the
published event examples, and keep an unknown-event branch so additive changes do not break the
stream.
## Distinguish the end states [#distinguish-the-end-states]
| Signal | Meaning | What not to assume |
| -------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
| `message.stop` | One assistant message has finished. | The consultation is complete. |
| `conversation.end` | The assistant ended the conversation and supplied a `reason`. | That any artifact is ready. |
| `ai_consultation.complete` | Stable artifact IDs are available. | That every artifact is ready; retrieval can return `202` while generation continues. |
| HTTP stream closes | Transport for the turn ended. | A clinical or workflow outcome occurred. |
Use these signals independently. For example, capture artifact IDs only from
`ai_consultation.complete`, then retrieve each artifact through its resource endpoint.
## Handle recoverable errors [#handle-recoverable-errors]
An `error` event can arrive after the HTTP response has already started. Parse it separately from
HTTP failures. If the event includes `retryAfterSeconds`, wait at least that long before retrying.
Do not automatically replay a chat turn after a network interruption. The stream operation does
not accept an idempotency key, so first reconcile the transcript with
`GET /chats/{chatId}/messages/` or ask the user to retry through an explicit interface.
## Define a local fallback [#define-a-local-fallback]
Before production, agree on behavior for:
* An unknown guardian ID.
* An unknown CTA widget or skill code.
* A stream that ends before `message.stop`.
* A recoverable `error` without `retryAfterSeconds`.
* A prolonged loss of connectivity.
* A user who returns to a conversation after `conversation.end`.
These are integration decisions. The public API does not prescribe the user interface or an
external escalation destination.
## Related documentation [#related-documentation]
* [Stream chat responses](/docs/conversations/streaming)
* [Test your integration](/docs/guides/test-your-integration)
* [Errors and retries](/docs/errors)
# Test your integration (/docs/guides/test-your-integration)
Use the staging environment to exercise the full workflow before requesting production access.
Staging credentials are provisioned manually by Doctronic and are separate from production
credentials.
```bash
export DOCTRONIC_API_URL="https://staging-partners.doctronic.ai/api/v1"
export DOCTRONIC_API_TOKEN="replace-with-your-staging-token"
```
Ask your Doctronic business or implementation contact what test data is permitted in your staging
integration. Do not assume production records or credentials work in staging.
## Validate the primary path [#validate-the-primary-path]
Run at least one complete test that:
1. Creates a user and stores `data.id`.
2. Creates a chat for that user.
3. Streams several patient turns.
4. Reassembles assistant content by `messageId`.
5. Handles all recognized control events separately from content.
6. Detects consultation completion only from `ai_consultation.complete`.
7. Retrieves each returned artifact ID, including a temporary `202` response.
8. Lists the chat messages and verifies the displayed transcript can be restored.
The transcript endpoint returns the visible user and assistant transcript. Consultation artifacts
use their own retrieval endpoint and should be tested independently.
## Exercise identity boundaries [#exercise-identity-boundaries]
Confirm your backend always sends the correct credentials for the current user.
| Test | Expected result |
| ---------------------------------------------------- | --------------------------------------------------------------------------------------------- |
| Missing or invalid Bearer token | `401 error.auth.unauthorized` |
| User ID outside the authenticated organization | Access is denied or the resource is masked as unavailable according to the endpoint contract. |
| Chat ID belonging to another user | `404 error.partner.chat_not_found` |
| Artifact ID outside the current organization or user | `404 error.artifact.not_found` |
Do not log the credential values during these tests.
## Stress the stream parser [#stress-the-stream-parser]
SSE frames can be split across network chunks. Test a parser that:
* Buffers partial lines and partial JSON payloads.
* Supports multiple frames in one network chunk.
* Preserves frame order within one HTTP response.
* Associates content with its `messageId`.
* Ignores unknown event names.
* Handles a connection ending before a complete frame.
* Treats an `error` event differently from an HTTP error response.
* Respects `retryAfterSeconds` when it is present.
Do not use the browser's native `EventSource` interface for this endpoint because the stream is a
`POST`. Use `fetch()` or consume the stream on your backend.
## Validate negative inputs [#validate-negative-inputs]
Include cases for:
* An invalid IANA timezone, which returns `400` for chat creation or streaming.
* Context longer than 50,000 characters.
* Invalid pagination values.
* A malformed user field such as an invalid email or date.
* A request body that does not match the OpenAPI schema.
* An unrecognized event type, which your consumer should ignore.
## Exercise care workflows [#exercise-care-workflows]
If your integration offers appointments, test:
* Missing required user demographics.
* Missing or incomplete address fields.
* A chat that is not ready for appointment booking.
* No available practitioners in the requested state.
* A scheduled slot becoming unavailable, which returns `409`.
* An ASAP booking whose waiting-room URL is temporarily unavailable.
* Retrieval before retry when the error contains an existing `appointmentId`.
* Cancellation and rescheduling from the latest appointment state.
Verify booking, cancellation, and rescheduling with a unique `Idempotency-Key`. Repeat the same
request with the same key and confirm `Idempotency-Replayed: true`, then confirm that changing the
payload while reusing the key returns `409`.
## Define release evidence [#define-release-evidence]
Before production access, retain evidence that your integration can:
* If a `guardian` event is emitted, route it through the safety behavior approved for your
integration.
* Restore a transcript after reconnecting.
* Distinguish stream completion from consultation completion.
* Handle artifact `202`, `404`, and `500` responses.
* Apply the documented idempotency behavior and bound retries for temporary failures.
* Retain `X-Request-ID` for failed requests.
* Verify signed webhook delivery and duplicate `eventId` handling if webhooks are enabled.
* Keep tokens and user-scoped identifiers out of client code and unrestricted logs.
* Continue safely when a new SSE event name appears.
Use [Production readiness](/docs/production-readiness) for the final review and coordinate
production credentials with your Doctronic business or implementation contact.
# Get a user's address (/docs/api-reference/endpoints/address/get-address)
{/* Generated from the deployed OpenAPI contract. Do not edit by hand. */}
# Address (/docs/api-reference/endpoints/address)
{/* Generated from the deployed OpenAPI contract. Do not edit by hand. */}
# Set a user's address (/docs/api-reference/endpoints/address/put-address)
{/* Generated from the deployed OpenAPI contract. Do not edit by hand. */}
# Get appointment details (/docs/api-reference/endpoints/appointments/get-appointments-appointment-id)
{/* Generated from the deployed OpenAPI contract. Do not edit by hand. */}
# List available scheduled appointment slots (/docs/api-reference/endpoints/appointments/get-appointments-scheduled-available-slots)
{/* Generated from the deployed OpenAPI contract. Do not edit by hand. */}
# List appointments (/docs/api-reference/endpoints/appointments/get-appointments)
{/* Generated from the deployed OpenAPI contract. Do not edit by hand. */}
# Appointments (/docs/api-reference/endpoints/appointments)
{/* Generated from the deployed OpenAPI contract. Do not edit by hand. */}
# Cancel appointment (/docs/api-reference/endpoints/appointments/post-appointments-appointment-id-cancel)
{/* Generated from the deployed OpenAPI contract. Do not edit by hand. */}
# Reschedule appointment (/docs/api-reference/endpoints/appointments/post-appointments-appointment-id-reschedule)
{/* Generated from the deployed OpenAPI contract. Do not edit by hand. */}
# Book an ASAP appointment (/docs/api-reference/endpoints/appointments/post-appointments-asap)
{/* Generated from the deployed OpenAPI contract. Do not edit by hand. */}
# Book a scheduled appointment (/docs/api-reference/endpoints/appointments/post-appointments-scheduled)
{/* Generated from the deployed OpenAPI contract. Do not edit by hand. */}
# Get a consultation artifact (/docs/api-reference/endpoints/artifacts/get-artifacts-artifact-id)
{/* Generated from the deployed OpenAPI contract. Do not edit by hand. */}
# Artifacts (/docs/api-reference/endpoints/artifacts)
{/* Generated from the deployed OpenAPI contract. Do not edit by hand. */}
# List chat messages (/docs/api-reference/endpoints/chats/get-chats-chat-id-messages)
{/* Generated from the deployed OpenAPI contract. Do not edit by hand. */}
# Get a chat (/docs/api-reference/endpoints/chats/get-chats-chat-id)
{/* Generated from the deployed OpenAPI contract. Do not edit by hand. */}
# List chats (/docs/api-reference/endpoints/chats/get-chats)
{/* Generated from the deployed OpenAPI contract. Do not edit by hand. */}
# Chats (/docs/api-reference/endpoints/chats)
{/* Generated from the deployed OpenAPI contract. Do not edit by hand. */}
# Stream a chat turn (SSE) (/docs/api-reference/endpoints/chats/post-chats-chat-id-stream)
{/* Generated from the deployed OpenAPI contract. Do not edit by hand. */}
# Create a chat (/docs/api-reference/endpoints/chats/post-chats)
{/* Generated from the deployed OpenAPI contract. Do not edit by hand. */}
# Pharmacy (/docs/api-reference/endpoints/pharmacy)
{/* Generated from the deployed OpenAPI contract. Do not edit by hand. */}
# Search pharmacies (/docs/api-reference/endpoints/pharmacy/post-pharmacy-search)
{/* Generated from the deployed OpenAPI contract. Do not edit by hand. */}
# Set a user's pharmacy (/docs/api-reference/endpoints/pharmacy/put-pharmacy)
{/* Generated from the deployed OpenAPI contract. Do not edit by hand. */}
# Get user details (/docs/api-reference/endpoints/users/get-users)
{/* Generated from the deployed OpenAPI contract. Do not edit by hand. */}
# Users (/docs/api-reference/endpoints/users)
{/* Generated from the deployed OpenAPI contract. Do not edit by hand. */}
# Create a user (/docs/api-reference/endpoints/users/post-users)
{/* Generated from the deployed OpenAPI contract. Do not edit by hand. */}