Scribe
Inspect Scribe's provider-session and artifact HTTP contracts using operation blocks rendered from its separate public OpenAPI schema.
Scribe has a separate API host and provider-principal access model. Use the base assigned to your deployment and the scope required by the operation. The public schema linked here is the US contract; its availability does not establish enrollment or deployment in another region.
Start with Capture to Finalized Note for the workflow and Scribe authentication for provider access. Sessions and Artifacts explain lifecycle and recovery semantics.
The operation blocks below render the canonical request and response contracts. Health and readiness probes are excluded from this customer reference. The Zoom OAuth callback is a redirect target for the authorization flow, not an operation to call directly.
List appointments over a rolling date-anchored window (workspace + provider read-scoped).
Phase 38 ships a deliberate static stub sourced from the superscribe-web seed (see
src/appointments.py); the response contract is stable so the source can later swap to a
downstream customer API via a managed External Integration without a wire change. TESTING STOPGAP
(phase 45a, SUPERSEDED BY PHASE 45): the stub emits a rolling window [today - back, today + forward] (env-tunable, defaults 14/30 → 360 items max) instead of today-only, so date-pinned
appointment ids stay in-list across day-rollovers and the phase-41 session join keeps linking a
session created on a prior day. Paginated to mirror the sibling list-sessions endpoint
(offset-based limit + opaque continuation_token); consumers page the full window and bucket
into past/today/upcoming client-side.
Optional date-range filter (phase 34): start_after (INCLUSIVE) and start_before (EXCLUSIVE) are
timezone-aware ISO-8601 datetime bounds on the appointment start (normalized to UTC; a naive,
date-only or malformed bound is a 422), forming the half-open window [start_after, start_before).
Either may be given alone; both omitted preserves the legacy behavior. The filter is applied
server-side over the window BEFORE pagination, so a client that needs only its today+tomorrow slice
fetches exactly that instead of paging a wide window and filtering client-side. An inverted range or
a span wider than _MAX_APPOINTMENT_RANGE returns 400 invalid_date_range.
EHR-backed workspaces (ehr-note-writeback phase 03 — the EHR-integrated workspace with its flag on)
fetch exactly the client's window, so BOTH start_after and start_before are REQUIRED there
(omitting either is 400 invalid_date_range); the window is never derived server-side.
50Successful Response
The start_after / start_before date range is inverted or too wide, or incomplete on an EHR-backed workspace (list-appointments requires both bounds there; get-appointment takes both or neither).
Bearer token is absent or invalid.
The principal is outside this workspace or provider scope.
Request validation failed.
GET /v1/{workspace_id}/appointments HTTP/1.1
Accept: */*
{
"items": [
{
"id": "text",
"session": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"status": "in-progress",
"external_appointment_id": "text",
"started_at": "2026-01-01T00:00:00.000Z",
"ended_at": "2026-01-01T00:00:00.000Z",
"created_at": "2026-01-01T00:00:00.000Z",
"updated_at": "2026-01-01T00:00:00.000Z"
},
"start": "2026-01-01T00:00:00.000Z",
"end": "2026-01-01T00:00:00.000Z",
"duration_minutes": 1,
"reason": "text",
"appointment_type": "text",
"patient_name": "text",
"patient_entity_id": "text",
"practitioner_name": "text",
"practitioner_entity_id": "text",
"location_name": "text",
"date_of_birth": "2026-01-01",
"mrn": "text",
"active_conditions": [
"text"
],
"medications_to_review": [
"text"
]
}
],
"has_more": true,
"continuation_token": null
}Get one appointment by id. An EHR-backed workspace reads the single appointment straight from the
EHR by id (ehr-note-writeback phase 59) — no schedule-window fetch-and-scan, so a busy provider's
window can't time out, the root cause of the appointments_unavailable 503. A genuine missing
appointment is 404; a failed EHR fetch is 503 appointments_unavailable (never masked as not-found).
Every other workspace resolves the id against the static seed.
Successful Response
Bearer token is absent or invalid.
The principal is outside this workspace or provider scope.
No provider-owned resource exists at this URL.
Generation cannot proceed for the current session state.
Request validation failed.
The EHR appointment could not be fetched (appointments_unavailable), or the linked session is temporarily unavailable.
GET /v1/{workspace_id}/appointments/{appointment_id} HTTP/1.1
Accept: */*
{
"id": "text",
"session": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"status": "in-progress",
"external_appointment_id": "text",
"started_at": "2026-01-01T00:00:00.000Z",
"ended_at": "2026-01-01T00:00:00.000Z",
"created_at": "2026-01-01T00:00:00.000Z",
"updated_at": "2026-01-01T00:00:00.000Z"
},
"start": "2026-01-01T00:00:00.000Z",
"end": "2026-01-01T00:00:00.000Z",
"duration_minutes": 1,
"reason": "text",
"appointment_type": "text",
"patient_name": "text",
"patient_entity_id": "text",
"practitioner_name": "text",
"practitioner_entity_id": "text",
"location_name": "text",
"date_of_birth": "2026-01-01",
"mrn": "text",
"active_conditions": [
"text"
],
"medications_to_review": [
"text"
]
}The calling provider's persisted scribe settings (currently the default Zoom meeting link).
Returns {zoom_meeting_link: null} when the provider has no settings row yet -- an unset link is a
valid state, never a 404. Provider-scoped via _provider_id; decoupled from the Zoom OAuth
connection, so a saved link persists whether or not Zoom is connected.
Successful Response
Response of GET/PUT /provider/settings (V366).
The provider's persisted scribe settings. zoom_meeting_link is the server-side default Zoom
meeting link, decoupled from the Zoom OAuth connection; null means the provider has never saved
one (or has cleared it) -- an unset link is a valid state, never a 404.
Validation Error
GET /v1/{workspace_id}/provider/settings HTTP/1.1
Accept: */*
{
"zoom_meeting_link": "text"
}Persist the calling provider's default Zoom meeting link (upsert), or clear it with a null.
The request model validates a non-null link (an http(s) zoom.us URL, personal-room aware, <=2048)
via the SAME ZoomMeetingLink type the create-zoom-session request uses, so both writes accept
identical links; a null clears the stored link. The normalized str(HttpUrl) form is stored
(HttpUrl lowercases the host and adds a trailing slash to a bare origin — a no-op for a real
meeting link, which always carries a path). Provider-scoped via _provider_id. Returns the
persisted settings.
Body of PUT /provider/settings.
Sets the provider's default Zoom meeting link, or clears it with an explicit null. A non-null
link is validated as a zoom.us http(s) URL (personal-room aware, <=2048) via the shared
ZoomMeetingLink type the create-zoom-session request also uses. The wire value stays a plain JSON
string; the handler stores the normalized str(HttpUrl).
Successful Response
Response of GET/PUT /provider/settings (V366).
The provider's persisted scribe settings. zoom_meeting_link is the server-side default Zoom
meeting link, decoupled from the Zoom OAuth connection; null means the provider has never saved
one (or has cleared it) -- an unset link is a valid state, never a 404.
Validation Error
PUT /v1/{workspace_id}/provider/settings HTTP/1.1
Content-Type: application/json
Accept: */*
Content-Length: 43
{
"zoom_meeting_link": "https://example.com"
}{
"zoom_meeting_link": "text"
}50Successful Response
Bearer token is absent or invalid.
The principal is outside this workspace or provider scope.
No provider-owned resource exists at this URL.
Generation cannot proceed for the current session state.
Request validation failed.
Clinical generation is temporarily unavailable.
GET /v1/{workspace_id}/sessions HTTP/1.1
Accept: */*
{
"items": [
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"status": "in-progress",
"mode": "in_person",
"external_appointment_id": "text",
"first_name": "text",
"last_name": "text",
"visit_type": "text",
"note_template": "amd-psych-intake",
"started_at": "2026-01-01T00:00:00.000Z",
"ended_at": "2026-01-01T00:00:00.000Z",
"created_at": "2026-01-01T00:00:00.000Z",
"updated_at": "2026-01-01T00:00:00.000Z",
"local_timezone": "text",
"artifacts": {
"transcript": "pending",
"note": "pending",
"summary": "pending",
"codes": "pending"
}
}
],
"has_more": true,
"continuation_token": null
}in_personPossible values: Successful Response
Modality of a scribe session: an in-person ("mic") recording or a Zoom meeting.
Bearer token is absent or invalid.
The principal is outside this workspace or provider scope.
external_id is already in use by another provider (conflict), or was reused with a different fingerprint (idempotency_key_conflict).
Request validation failed (validation_error); a non-in-person mode was requested (use_zoom_endpoint) — the generic create is in-person only, create a Zoom session via POST /v1/{workspace_id}/zoom/sessions; no canonical visit_type was supplied to resolve a supported amd-* template (note_template_required); or the visit_type/note_template does not map to a supported amd-* template (unsupported_note_template).
POST /v1/{workspace_id}/sessions HTTP/1.1
Content-Type: application/json
Accept: */*
Content-Length: 254
{
"external_appointment_id": "text",
"external_id": "text",
"mode": "in_person",
"metadata": {
"ANY_ADDITIONAL_PROPERTY": "anything"
},
"first_name": "text",
"last_name": "text",
"visit_type": "psych-intake",
"note_template": "amd-psych-intake",
"timezone": "Africa/Abidjan"
}{
"id": "123e4567-e89b-12d3-a456-426614174000",
"status": "in-progress",
"mode": "in_person",
"external_appointment_id": "text",
"first_name": "text",
"last_name": "text",
"visit_type": "text",
"note_template": "amd-psych-intake",
"started_at": "2026-01-01T00:00:00.000Z",
"ended_at": "2026-01-01T00:00:00.000Z",
"created_at": "2026-01-01T00:00:00.000Z",
"updated_at": "2026-01-01T00:00:00.000Z",
"local_timezone": "text",
"artifacts": {
"transcript": "pending",
"note": "pending",
"summary": "pending",
"codes": "pending"
}
}Successful Response
Modality of a scribe session: an in-person ("mic") recording or a Zoom meeting.
Bearer token is absent or invalid.
The principal is outside this workspace or provider scope.
No provider-owned resource exists at this URL.
Generation cannot proceed for the current session state.
Request validation failed.
Clinical generation is temporarily unavailable.
GET /v1/{workspace_id}/sessions/{session_id} HTTP/1.1
Accept: */*
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"status": "in-progress",
"mode": "in_person",
"external_appointment_id": "text",
"first_name": "text",
"last_name": "text",
"visit_type": "text",
"note_template": "amd-psych-intake",
"started_at": "2026-01-01T00:00:00.000Z",
"ended_at": "2026-01-01T00:00:00.000Z",
"created_at": "2026-01-01T00:00:00.000Z",
"updated_at": "2026-01-01T00:00:00.000Z",
"local_timezone": "text",
"artifacts": {
"transcript": "pending",
"note": "pending",
"summary": "pending",
"codes": "pending"
}
}Patch an owned session's mutable fields (external_appointment_id / metadata).
Idempotent; only fields present in the body are written (sending external_appointment_id: null
clears the link). A session's mode is fixed at create and is not a field on UpdateSessionRequest,
so PATCH cannot flip a session to zoom (that would mint a bot-less Zoom session that never went
through the saga at POST /zoom/sessions — the 5dca2633 failure class). Returns the full refreshed
session so callers see accurate artifact availability.
Mutable fields for PATCH /sessions/{id}. Only fields present in the body are updated.
A session's mode is fixed at create — it is deliberately NOT a field here, so PATCH cannot flip a
session to zoom (which would mint a bot-less Zoom session that never went through the saga — the
5dca2633 failure class). A Zoom session is created via POST /v1/{workspace_id}/zoom/sessions.
external_appointment_id is explicitly nullable — sending null clears the link — so the route
distinguishes "field omitted" (leave as-is) from "field set to null" via exclude_unset.
Successful Response
Modality of a scribe session: an in-person ("mic") recording or a Zoom meeting.
Bearer token is absent or invalid.
The principal is outside this workspace or provider scope.
No provider-owned resource exists at this URL.
Request validation failed (validation_error); or a PATCH of visit_type/note_template would leave the session without a supported amd-* template — no resolvable visit_type (note_template_required) or an unrecognized/legacy/mismatched pair (unsupported_note_template).
PATCH /v1/{workspace_id}/sessions/{session_id} HTTP/1.1
Content-Type: application/json
Accept: */*
Content-Length: 186
{
"external_appointment_id": "text",
"metadata": {
"ANY_ADDITIONAL_PROPERTY": "anything"
},
"first_name": "text",
"last_name": "text",
"visit_type": "psych-intake",
"note_template": "amd-psych-intake"
}{
"id": "123e4567-e89b-12d3-a456-426614174000",
"status": "in-progress",
"mode": "in_person",
"external_appointment_id": "text",
"first_name": "text",
"last_name": "text",
"visit_type": "text",
"note_template": "amd-psych-intake",
"started_at": "2026-01-01T00:00:00.000Z",
"ended_at": "2026-01-01T00:00:00.000Z",
"created_at": "2026-01-01T00:00:00.000Z",
"updated_at": "2026-01-01T00:00:00.000Z",
"local_timezone": "text",
"artifacts": {
"transcript": "pending",
"note": "pending",
"summary": "pending",
"codes": "pending"
}
}Reload-safe action-items poller (phase 09): the same job-state contract as the other artifacts.
Successful Response
Bearer token is absent or invalid.
The principal is outside this workspace or provider scope.
No provider-owned resource exists at this URL.
Generation cannot proceed for the current session state.
Request validation failed.
Clinical generation is temporarily unavailable.
GET /v1/{workspace_id}/sessions/{session_id}/actions HTTP/1.1
Accept: */*
{
"generation_status": "ready",
"error": {
"field": "text",
"message": "text"
},
"session_id": "123e4567-e89b-12d3-a456-426614174000",
"items": [
{
"id": "text",
"text": "text",
"kind": "text"
}
]
}Enqueue post-visit action-item generation for an owned session (explicit regenerate, phase 09).
Async ensure-semantics identical to codes/summary: derives the idempotency identity from the
canonical transcript + latest note (no request body), idempotently enqueues a scribe.generations
job (artifact_kind='actions'), and returns 202 with the job envelope or 200 with the artifact
when an identical job already succeeded. Actions are also auto-enqueued server-side when the note job
succeeds. Rejected once the session is terminal (409 invalid_session_state, post-finalize).
An identical job already succeeded; the actions are returned.
Successful Response
Bearer token is absent or invalid.
The principal is outside this workspace or provider scope.
No provider-owned resource exists at this URL.
Generation cannot proceed for the current session state.
Request validation failed.
Clinical generation is temporarily unavailable.
POST /v1/{workspace_id}/sessions/{session_id}/actions HTTP/1.1
Accept: */*
{
"actions": {
"session_id": "123e4567-e89b-12d3-a456-426614174000",
"items": [
{
"id": "text",
"text": "text",
"kind": "text"
}
]
},
"generation": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"model_provider": "text",
"model_name": "text",
"prompt_version": "text",
"generated_at": "2026-01-01T00:00:00.000Z"
}
}Allocate a scribe-streaming GameServer for an owned session and return {host, expires_at}.
The dispatcher leg of create -> allocate -> WS-attach (decision 3): the browser never allocates. The allocation is intentionally NOT persisted as a session mutation — a reconnect re-allocates a fresh GameServer, and the WS attach re-verifies ownership.
Successful Response
Bearer token is absent or invalid.
The principal is outside this workspace or provider scope.
No provider-owned resource exists at this URL.
The session is not in an allocatable state.
Validation Error
No streaming capacity is available; retry after the Retry-After interval.
POST /v1/{workspace_id}/sessions/{session_id}/allocate HTTP/1.1
Accept: */*
{
"host": "text",
"expires_at": "2026-01-01T00:00:00.000Z"
}Streaming Q&A over the session transcript + latest note (SPEC §3.3, header-auth fetch streaming).
Not persisted as an artifact — only a provenance row is recorded (its id is the generation_id in
the terminal done frame). Reuses generation.py's provider clients. Allowed on
a terminal session (post-visit Q&A is read-only; the post-finalize immutability guard applies only
to regenerate-section + actions generation).
Body of POST /sessions/{id}/ask — a streaming Q&A over the transcript + latest note.
The answer streams back as SSE delta {text} frames then a terminal done {generation_id}; the
response is not persisted as an artifact (only a provenance row is recorded).
A Server-Sent Event stream (header-authenticated fetch streaming, not EventSource): one or more delta frames each {text}, then a terminal done frame {generation_id}; a ping keepalive every 15 s, and an error frame if generation fails mid-stream. Each frame is event: <event>\ndata: <json>\n\n.
Bearer token is absent or invalid.
The principal is outside this workspace or provider scope.
No provider-owned resource exists at this URL.
Validation Error
Clinical generation is temporarily unavailable.
POST /v1/{workspace_id}/sessions/{session_id}/ask HTTP/1.1
Content-Type: application/json
Accept: */*
Content-Length: 61
{
"question": "text",
"history": [
{
"role": "user",
"text": "text"
}
]
}No content
Cancel an owned non-terminal session (-> cancelled); the saga-compensation / abort path.
Guarded so a terminal session no-ops with 409 invalid_session_state. Touches only status, never
transcript artifacts.
Successful Response
Modality of a scribe session: an in-person ("mic") recording or a Zoom meeting.
Bearer token is absent or invalid.
The principal is outside this workspace or provider scope.
No provider-owned resource exists at this URL.
The session is already terminal and cannot be cancelled (invalid_session_state).
Validation Error
POST /v1/{workspace_id}/sessions/{session_id}/cancel HTTP/1.1
Accept: */*
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"status": "in-progress",
"mode": "in_person",
"external_appointment_id": "text",
"first_name": "text",
"last_name": "text",
"visit_type": "text",
"note_template": "amd-psych-intake",
"started_at": "2026-01-01T00:00:00.000Z",
"ended_at": "2026-01-01T00:00:00.000Z",
"created_at": "2026-01-01T00:00:00.000Z",
"updated_at": "2026-01-01T00:00:00.000Z",
"local_timezone": "text",
"artifacts": {
"transcript": "pending",
"note": "pending",
"summary": "pending",
"codes": "pending"
}
}Read the session's checklist.
The checklist is instantiated from the session's visit type when the session is created and is the authoritative source of its items, so this returns them from the first frame — including before any transcript exists. Persisted per-item manual and auto toggle state is overlaid on the items. Returns 404 when the session has no checklist.
Successful Response
Bearer token is absent or invalid.
The principal is outside this workspace or provider scope.
No provider-owned resource exists at this URL.
Generation cannot proceed for the current session state.
Request validation failed.
Clinical generation is temporarily unavailable.
GET /v1/{workspace_id}/sessions/{session_id}/checklist HTTP/1.1
Accept: */*
{
"generation_status": "ready",
"error": {
"field": "text",
"message": "text"
},
"session_id": "123e4567-e89b-12d3-a456-426614174000",
"title": "text",
"status": "open",
"items": [
{
"id": "text",
"label": "text",
"category": "text",
"state": "open",
"evidence": "text",
"source": "manual",
"updated_by": "123e4567-e89b-12d3-a456-426614174000",
"updated_at": "2026-01-01T00:00:00.000Z"
}
],
"created_at": "2026-01-01T00:00:00.000Z",
"updated_at": "2026-01-01T00:00:00.000Z"
}Merge manual per-item toggles into the checklist state, each provenanced (who/when, source).
Requires a generated checklist (404 otherwise); every toggled id must belong to it (422 per-field otherwise). Toggles are idempotent upserts, re-toggleable until finalize; 409 invalid_session_state once the session is terminal. Auto-check state (phase 09) is written server-side, never here.
Body of PATCH /sessions/{id}/checklist (V340): manual per-item toggles.
Successful Response
Response of PATCH /sessions/{id}/checklist: the generated checklist with per-item manual
state + provenance overlaid, and status recomputed from the effective item states.
Bearer token is absent or invalid.
The principal is outside this workspace or provider scope.
No provider-owned resource exists at this URL.
The session is terminal and no longer accepts mutations (invalid_session_state).
Request validation failed.
PATCH /v1/{workspace_id}/sessions/{session_id}/checklist HTTP/1.1
Content-Type: application/json
Accept: */*
Content-Length: 60
{
"items": [
{
"id": "text",
"completed": true,
"source": "manual"
}
]
}{
"session_id": "123e4567-e89b-12d3-a456-426614174000",
"title": "text",
"status": "open",
"items": [
{
"id": "text",
"label": "text",
"category": "text",
"state": "open",
"evidence": "text",
"source": "manual",
"updated_by": "123e4567-e89b-12d3-a456-426614174000",
"updated_at": "2026-01-01T00:00:00.000Z"
}
],
"updated_at": "2026-01-01T00:00:00.000Z"
}LLM auto-check of the generated checklist against the (partial) transcript mid-session (phase 09).
Evaluates each generated checklist item against the best-available transcript and returns a per-item
matched verdict; matched items are persisted as source='auto' checklist state that COEXISTS with
manual PATCH /checklist toggles — the upsert preserves any manually-decided item and never
clobbers it. No generated checklist yet (or no transcript) → an empty {matches:[]}.
No-op guard (phase 88): the handler hashes the auto-check input (selected transcript + checklist
items) and compares it to the last-checked hash stored on the session. An unchanged input
short-circuits — no LLM call, no upsert — and returns the already-persisted source='auto' state; a
changed (or first) input runs the LLM as before and then, under the session row lock, persists both
the matched items and the new hash. This keeps a redundant re-check (client double-fire, reconnect,
or a fire ahead of a fresher server snapshot) cheap regardless of the client's cadence.
Successful Response
200 body of POST /sessions/{id}/checklist/auto-check: the LLM's per-item match verdict.
Matched items are also persisted server-side as source='auto' checklist state (coexisting with,
and never clobbering, manual PATCH /checklist toggles).
Bearer token is absent or invalid.
The principal is outside this workspace or provider scope.
No provider-owned resource exists at this URL.
The session is terminal and no longer accepts mutations (invalid_session_state).
Request validation failed.
POST /v1/{workspace_id}/sessions/{session_id}/checklist/auto-check HTTP/1.1
Accept: */*
{
"matches": [
{
"item_id": "text",
"category": "text",
"matched": true,
"evidence": "text"
}
]
}Reload-safe read of the session's ICD codes (phase 130: session-scoped, not generation-anchored).
Returns EVERY code owned by the caller on this session — both AI suggestions and provider-authored
rows — so provider codes are visible and the read no longer 404s when no codes generation ever ran.
generation_status is advisory metadata about the AI generation only (ready when none ran or
it succeeded, pending while running, failed with its error): the items are authoritative
regardless.
Successful Response
Bearer token is absent or invalid.
The principal is outside this workspace or provider scope.
No provider-owned resource exists at this URL.
Generation cannot proceed for the current session state.
Request validation failed.
Clinical generation is temporarily unavailable.
GET /v1/{workspace_id}/sessions/{session_id}/codes HTTP/1.1
Accept: */*
{
"generation_status": "ready",
"error": {
"field": "text",
"message": "text"
},
"session_id": "123e4567-e89b-12d3-a456-426614174000",
"items": [
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"code": "text",
"description": "text",
"rationale": "text",
"confidence": 1,
"decision": "approved",
"source": "ai"
}
]
}Enqueue ICD-10-CM code-suggestion generation for an owned session (explicit regenerate).
Async ensure-semantics: derives the idempotency identity from the canonical transcript + latest
note (no request body), then idempotently enqueues a scribe.generations job
(artifact_kind='codes'). The worker prompts the model, parses strict-JSON suggestions, and
persists one scribe.icd_suggestions row per code (an empty extraction is treated as a failed
generation). Returns 202 with the job envelope, or 200 with the codes if an identical job already
succeeded. Codes are also auto-enqueued server-side when the note job succeeds.
An identical job already succeeded; the codes are returned.
Successful Response
Bearer token is absent or invalid.
The principal is outside this workspace or provider scope.
No provider-owned resource exists at this URL.
Generation cannot proceed for the current session state.
Request validation failed.
Clinical generation is temporarily unavailable.
POST /v1/{workspace_id}/sessions/{session_id}/codes HTTP/1.1
Accept: */*
{
"codes": {
"session_id": "123e4567-e89b-12d3-a456-426614174000",
"items": [
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"code": "text",
"description": "text",
"rationale": "text",
"confidence": 1,
"decision": "approved",
"source": "ai"
}
]
},
"generation": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"model_provider": "text",
"model_name": "text",
"prompt_version": "text",
"generated_at": "2026-01-01T00:00:00.000Z"
}
}Add a provider-authored ICD-10 code to an owned session (phase 130).
Persists the code with source='provider', generation_id=NULL, and decision='approved'
(adding a code is an affirmative act → it counts toward the finalize diagnosis gate immediately),
owned by the caller. Does NOT require a codes generation to exist. 409 invalid_session_state once
the session is terminal (post-finalize immutable); scoped scribe:notes:rw_own.
Body of POST /sessions/{id}/codes/manual (phase 130): a provider-authored ICD code.
Persisted with source='provider', generation_id=NULL, and decision='approved' by default (adding a code is an affirmative act → it counts toward the finalize diagnosis gate immediately). Does not require a codes generation to exist.
""Successful Response
Bearer token is absent or invalid.
The principal is outside this workspace or provider scope.
No provider-owned resource exists at this URL.
The session is terminal and no longer accepts mutations (invalid_session_state).
Request validation failed.
POST /v1/{workspace_id}/sessions/{session_id}/codes/manual HTTP/1.1
Content-Type: application/json
Accept: */*
Content-Length: 51
{
"code": "text",
"description": "text",
"rationale": ""
}{
"id": "123e4567-e89b-12d3-a456-426614174000",
"code": "text",
"description": "text",
"rationale": "text",
"confidence": 1,
"decision": "approved",
"source": "ai"
}Record a provider's approve/reject decision and/or edit the text of one ICD suggestion.
Decision (approve/reject) applies to any owned row (SPEC §6.1 P4; idempotent, re-decidable until
finalize). Text edits (code/description/rationale, phase 130) are honored ONLY for provider-authored
rows — editing an AI suggestion's text is rejected with 422 invalid_code_edit (AI codes stay
approve/reject; reject + add a provider code to change one). 409 invalid_session_state once the
session is terminal. 404 when the suggestion is unknown or not owned by the provider.
Body of PATCH /sessions/{id}/codes/{suggestion_id}.
Carries the provider's per-suggestion decision (V340; idempotent, re-decidable until finalize) and, since phase 130, optional text edits (code/description/rationale). Text edits are honored only for provider-authored rows (AI suggestions stay approve/reject). At least one field must be present.
Successful Response
200 body for a persisted code decision/edit, with when it was decided (who is the caller).
Bearer token is absent or invalid.
The principal is outside this workspace or provider scope.
No provider-owned resource exists at this URL.
The session is terminal and no longer accepts mutations (invalid_session_state).
Request validation failed.
PATCH /v1/{workspace_id}/sessions/{session_id}/codes/{suggestion_id} HTTP/1.1
Content-Type: application/json
Accept: */*
Content-Length: 77
{
"decision": "approved",
"code": "text",
"description": "text",
"rationale": "text"
}{
"id": "123e4567-e89b-12d3-a456-426614174000",
"code": "text",
"decision": "approved",
"decided_at": "2026-01-01T00:00:00.000Z",
"source": "ai"
}End an owned session (created/in-progress -> in-review), guarded against a live stream.
Mic race guard (§3A.2): while a streaming worker is attached the WS worker is the sole finalizer,
so REST end returns 409 session_streaming and never touches transcript artifacts. Permitted
only for an abandoned/never-streamed session; the guarded flip cannot race the worker or reaper.
Successful Response
Modality of a scribe session: an in-person ("mic") recording or a Zoom meeting.
Bearer token is absent or invalid.
The principal is outside this workspace or provider scope.
No provider-owned resource exists at this URL.
A streaming worker is still attached (session_streaming) or the session is not in an endable state (invalid_session_state).
Validation Error
POST /v1/{workspace_id}/sessions/{session_id}/end HTTP/1.1
Accept: */*
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"status": "in-progress",
"mode": "in_person",
"external_appointment_id": "text",
"first_name": "text",
"last_name": "text",
"visit_type": "text",
"note_template": "amd-psych-intake",
"started_at": "2026-01-01T00:00:00.000Z",
"ended_at": "2026-01-01T00:00:00.000Z",
"created_at": "2026-01-01T00:00:00.000Z",
"updated_at": "2026-01-01T00:00:00.000Z",
"local_timezone": "text",
"artifacts": {
"transcript": "pending",
"note": "pending",
"summary": "pending",
"codes": "pending"
}
}Bridge the Zoom control plane's event stream to the browser as SSE, under provider-JWT auth.
Resolves the owned, live Zoom session to its bound bot, then relays the control plane's Redis-backed
event stream (bot_status / transcript frames) with a 15 s ping keepalive, forwarding
Last-Event-ID upstream for replay and closing cleanly after a terminal bot_status. 404 for a
non-Zoom, unknown, terminal, or bot-less session. The browser never talks to the control plane and
holds only its own JWT.
A live Server-Sent Event stream (header-authenticated fetch streaming, not EventSource). Emits bot_status, transcript_segment / interim_transcript, and transcript_finalized frames plus a ping keepalive every 15 s; replays recent events on reconnect via Last-Event-ID and closes after a terminal bot_status. Each frame is event: <event>\ndata: <json>\n\n.
One frame on the GET /sessions/{id}/events SSE stream (documents the wire contract for the SDK).
Each frame is delivered as event: <event>\ndata: <json>\n\n; ping carries an empty {} body
and is a keepalive only. The stream is header-authenticated fetch streaming (not EventSource),
replays recent events on reconnect via Last-Event-ID, and closes after a terminal bot_status.
transcript_finalized SSE frame payload: emitted once, with no body, when the transcript is done.
Bearer token is absent or invalid.
The principal is outside this workspace or provider scope.
No live Zoom event stream exists (non-Zoom, unknown, or terminal session).
Validation Error
GET /v1/{workspace_id}/sessions/{session_id}/events HTTP/1.1
Accept: */*
{
"event": "bot_status",
"data": {
"state": "joining",
"reason": "text"
}
}Successful Response
Reload-safe note poller: artifact fields present only when generation_status == "ready".
generation_status == "empty" is the phase-147 terminal state for a session ended with zero
usable transcript segments: no note was (or will be) generated, and no artifact fields are present.
Bearer token is absent or invalid.
The principal is outside this workspace or provider scope.
No provider-owned resource exists at this URL.
Generation cannot proceed for the current session state.
Request validation failed.
Clinical generation is temporarily unavailable.
GET /v1/{workspace_id}/sessions/{session_id}/note HTTP/1.1
Accept: */*
{
"generation_status": "ready",
"writeback_status": "succeeded",
"error": {
"field": "text",
"message": "text"
},
"session_id": "123e4567-e89b-12d3-a456-426614174000",
"type": "text",
"status": "draft",
"structured": {
"ANY_ADDITIONAL_PROPERTY": "anything"
},
"version": 1,
"generated_at": "2026-01-01T00:00:00.000Z",
"signed_at": "2026-01-01T00:00:00.000Z",
"updated_at": "2026-01-01T00:00:00.000Z",
"carry_forward_available": [
{
"amd_field_code": "text",
"label": "text",
"value": "text",
"source_note_id": 1,
"source_signed_at": "text"
}
],
"clinician_name": "text"
}An identical job already succeeded; the note is returned.
Successful Response
Bearer token is absent or invalid.
The principal is outside this workspace or provider scope.
No provider-owned resource exists at this URL.
Generation cannot proceed for the current session state.
Request validation failed.
Clinical generation is temporarily unavailable.
POST /v1/{workspace_id}/sessions/{session_id}/note HTTP/1.1
Content-Type: application/json
Accept: */*
Content-Length: 54
{
"note_type": "amd-psych-intake",
"instructions": "text"
}{
"note": {
"session_id": "123e4567-e89b-12d3-a456-426614174000",
"type": "text",
"status": "draft",
"structured": {
"ANY_ADDITIONAL_PROPERTY": "anything"
},
"version": 1,
"generated_at": "2026-01-01T00:00:00.000Z",
"signed_at": "2026-01-01T00:00:00.000Z",
"updated_at": "2026-01-01T00:00:00.000Z"
},
"generation": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"model_provider": "text",
"model_name": "text",
"prompt_version": "text",
"generated_at": "2026-01-01T00:00:00.000Z"
}
}Versioned structured-note autosave with optimistic concurrency (design §4.2).
Accepts {base_version, structured} only: a complete structured-document replacement, validated
as a full document against the pinned template (phase-71 registry) BEFORE the compare-and-set.
The CAS on version means two racing writers with the same base_version yield exactly one
success and one 409 version_conflict. Rejected once the session is terminal (append-only, 409
invalid_session_state). 404 when no note has been generated yet. An unsupported template is
rejected with 422 unsupported_note_template; a missing or invalid structured document with 422
validation_error carrying per-field details.
Body of PUT /sessions/{id}/note — versioned structured-note autosave (design §4.2).
The write is a complete structured-document replacement: send the full structured
envelope (every value) on each write, not a partial patch. base_version is the version
the client last read; a stale value loses the compare-and-set and returns
409 version_conflict.
Successful Response
200 body for a successful PUT /sessions/{id}/note: the new version + write time.
Bearer token is absent or invalid.
The principal is outside this workspace or provider scope.
No provider-owned resource exists at this URL.
The base_version is stale (version_conflict) or the session is terminal (invalid_session_state).
The pinned template is unknown or the version does not match (unsupported_note_template), or the structured document failed template validation (validation_error, per-field details).
PUT /v1/{workspace_id}/sessions/{session_id}/note HTTP/1.1
Content-Type: application/json
Accept: */*
Content-Length: 280
{
"base_version": 1,
"structured": {
"schema_version": 1,
"template_id": "text",
"template_version": "text",
"values": {
"ANY_ADDITIONAL_PROPERTY": {
"value": "text",
"rationale": "text",
"source": "scribe"
}
},
"review": {
"confirmed_sections": [
"text"
],
"acknowledgments": [
"text"
],
"amd_confirmed": false
}
}
}{
"version": 1,
"updated_at": "2026-01-01T00:00:00.000Z"
}Server-authoritative finalize (SPEC §6.1 P4): atomically submit the note + complete the session.
Phase 178: finalize accepts ANY stored note shape — there is no note-content/structural validation
gate. A note with missing required fields, no approved diagnosis, amd_confirmed=false, and/or a
structurally-off document finalizes 200. The only non-validation mechanics still enforced are
ownership/scope, base_version optimistic concurrency, already-submitted idempotency (200), and the
atomic session completion. An already-submitted note is an idempotent 200. A terminal
cancelled/failed session is 409 invalid_session_state and the note submit is rolled back with it (the
two writes are one unit of work).
EHR writeback (ehr-note-writeback phase 07): with scribe.note-writeback-enabled on for the workspace,
the note is POSTed to the EHR inside the same transaction, after the session completes and
before commit. Any writeback failure is ehr_writeback_failed (500 when the request can't be built, 502
when the EHR call fails) and rolls both writes back (note stays draft); success commits a note_writebacks provenance row with them. The already-submitted
short-circuit means a successful finalize never re-posts. A separate submit flag sets
submitToAmd: off, the writeback is a dry run (stored + mapped by the EHR, not written to AMD).
Body of POST /sessions/{id}/note/finalize (V340).
base_version is the note version the provider is finalizing; a stale value returns
409 version_conflict. Server-side gate validation runs on the stored document, not the
request, so a client cannot bypass required-field gates.
Successful Response
Bearer token is absent or invalid.
The principal is outside this workspace or provider scope.
No provider-owned resource exists at this URL.
The base_version is stale (version_conflict) or the session is terminal and cannot be completed by finalize (invalid_session_state).
Validation Error
The note could not be prepared for the workspace's EHR writeback (ehr_writeback_failed); the finalize was rolled back, so the note is still a draft and the session is not completed. details carries {field: 'reason', message: <reason>} with reason one of provider_email_missing, appointment_link_missing, unsupported_note.
The note could not be written back to the workspace's EHR (ehr_writeback_failed); the finalize was rolled back, so the note is still a draft and the session is not completed. details carries {field: 'reason', message: <reason>} with reason one of ehr_rejected, ehr_unavailable, chart_note_failed, chart_note_not_written (AMD submit on), plus {field: 'ehr_message', message: …} when the EHR returned an error message.
POST /v1/{workspace_id}/sessions/{session_id}/note/finalize HTTP/1.1
Content-Type: application/json
Accept: */*
Content-Length: 18
{
"base_version": 1
}{
"note": {
"session_id": "123e4567-e89b-12d3-a456-426614174000",
"type": "text",
"status": "draft",
"structured": {
"ANY_ADDITIONAL_PROPERTY": "anything"
},
"version": 1,
"generated_at": "2026-01-01T00:00:00.000Z",
"signed_at": "2026-01-01T00:00:00.000Z",
"updated_at": "2026-01-01T00:00:00.000Z"
},
"writeback_status": "succeeded",
"field_dispositions": [
{
"amd_field_code": "text",
"label": "text",
"disposition": "written",
"reason": "written_from_transcript",
"source": "transcript",
"source_note_id": 1,
"source_signed_at": "text",
"source_template_name": "text",
"display_value": "text"
}
]
}Regenerate a single section of the note as a new version (async ensure-semantics, phase 09).
Reuses the phase-08 note version for optimistic concurrency: a stale base_version (a manual edit
or another regen landed since the client read) is rejected up front with 409 version_conflict, and
the worker re-checks it under a compare-and-set at persist time so a race can never clobber a newer
note. Enqueues an artifact_kind='note' job whose params carry section_id/base_version; the
worker rewrites that section and persists base_version + 1. Returns 202 with the job envelope.
Rejected once the session is terminal (409 invalid_session_state, post-finalize immutability).
Body of POST /sessions/{id}/note/regenerate-section (SPEC §6.1 P4).
Regenerates a single named section of the current note. base_version is the note version the
client last read; a stale value returns 409 version_conflict (never clobbers a racing manual edit).
Successful Response
202 body for an enqueued (or collapsed-onto-in-flight) generation job.
Bearer token is absent or invalid.
The principal is outside this workspace or provider scope.
No provider-owned resource exists at this URL.
The base_version is stale (version_conflict) or the session is terminal (invalid_session_state).
The pinned template is unknown or the version does not match (unsupported_note_template), or the structured document failed template validation (validation_error, per-field details).
POST /v1/{workspace_id}/sessions/{session_id}/note/regenerate-section HTTP/1.1
Content-Type: application/json
Accept: */*
Content-Length: 60
{
"section_id": "text",
"instructions": "text",
"base_version": 1
}{
"generation": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"artifact_kind": "note",
"status": "pending"
}
}Successful Response
Bearer token is absent or invalid.
The principal is outside this workspace or provider scope.
No provider-owned resource exists at this URL.
Generation cannot proceed for the current session state.
Request validation failed.
Clinical generation is temporarily unavailable.
GET /v1/{workspace_id}/sessions/{session_id}/summary HTTP/1.1
Accept: */*
{
"generation_status": "ready",
"error": {
"field": "text",
"message": "text"
},
"session_id": "123e4567-e89b-12d3-a456-426614174000",
"summary": "text",
"generated_at": "2026-01-01T00:00:00.000Z",
"updated_at": "2026-01-01T00:00:00.000Z"
}An identical job already succeeded; the summary is returned.
Successful Response
Bearer token is absent or invalid.
The principal is outside this workspace or provider scope.
No provider-owned resource exists at this URL.
Generation cannot proceed for the current session state.
Request validation failed.
Clinical generation is temporarily unavailable.
POST /v1/{workspace_id}/sessions/{session_id}/summary HTTP/1.1
Accept: */*
{
"summary": {
"session_id": "123e4567-e89b-12d3-a456-426614174000",
"summary": "text",
"generated_at": "2026-01-01T00:00:00.000Z",
"updated_at": "2026-01-01T00:00:00.000Z"
},
"generation": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"model_provider": "text",
"model_name": "text",
"prompt_version": "text",
"generated_at": "2026-01-01T00:00:00.000Z"
}
}Mint a WS attach ticket for an owned, non-terminal session and return {ticket, expires_at}.
A thin server-side wrapper over identity's RFC 8693 token_exchange grant (the mint lives in
identity): it forwards the browser's raw provider JWT as subject_token so identity binds the
ticket to this session/workspace/provider (aud=scribe-streaming, scope
scribe:streams:connect, ~5-min TTL). Routing this through the Scribe API keeps the browser's
CORS surface a single service — CORS can't scope identity's /token to one grant type. The SDK
connectionProvider calls this on every (re)connect and presents the ticket at the streaming
worker's WS handshake.
Successful Response
Bearer token is absent or invalid.
Missing scribe:sessions:write, wrong provider, or identity rejected the subject token.
No provider-owned session exists at this URL.
The session is terminal; no attach ticket can be minted.
Validation Error
Ticket minting is temporarily unavailable; please retry.
POST /v1/{workspace_id}/sessions/{session_id}/ticket HTTP/1.1
Accept: */*
{
"ticket": "text",
"expires_at": "2026-01-01T00:00:00.000Z"
}Successful Response
Bearer token is absent or invalid.
The principal is outside this workspace or provider scope.
No provider-owned resource exists at this URL.
Generation cannot proceed for the current session state.
Request validation failed.
Clinical generation is temporarily unavailable.
GET /v1/{workspace_id}/sessions/{session_id}/transcript HTTP/1.1
Accept: */*
{
"session_id": "123e4567-e89b-12d3-a456-426614174000",
"segments": [
{
"speaker": "text",
"text": "text",
"start_ms": 1,
"end_ms": 1
}
]
}End a Zoom session: 202 immediately, then drain the bot + internally finalize in the background.
Returns {status: "draining"} right away; the background task stops the bot and runs the internal
zoom-finalize (promote the drained snapshot -> transcript.json, flip -> in-review) with a
bounded retry over the drain window. Idempotent: a second DELETE still 202s and no-ops (the drain
task sees the already-finalized session and skips promotion). 409 not_zoom_session for a mic
session.
Successful Response
Response of DELETE /sessions/{id}/zoom: acknowledges that the drain + internal zoom-finalize
is underway. The session flips to in-review asynchronously (reaper backstop).
Bearer token is absent or invalid.
The principal is outside this workspace or provider scope.
No provider-owned resource exists at this URL.
The session is not a Zoom session (not_zoom_session).
Validation Error
DELETE /v1/{workspace_id}/sessions/{session_id}/zoom HTTP/1.1
Accept: */*
{
"status": "text"
}Pause the Zoom capture bot bound to an owned session (proxies the control plane).
Successful Response
Response of POST /sessions/{id}/zoom/pause|resume: the bot's status after the proxied
control-plane command. The live status transition also arrives over the event stream (phase 06);
this is the synchronous ack.
Bearer token is absent or invalid.
The principal is outside this workspace or provider scope.
No provider-owned resource exists at this URL.
No live Zoom bot is bound to this session (bot_not_active).
Validation Error
The control plane failed to deliver the command (bot_command_failed).
POST /v1/{workspace_id}/sessions/{session_id}/zoom/pause HTTP/1.1
Accept: */*
{
"bot_status": "text"
}Resume the Zoom capture bot bound to an owned session (proxies the control plane).
Successful Response
Response of POST /sessions/{id}/zoom/pause|resume: the bot's status after the proxied
control-plane command. The live status transition also arrives over the event stream (phase 06);
this is the synchronous ack.
Bearer token is absent or invalid.
The principal is outside this workspace or provider scope.
No provider-owned resource exists at this URL.
No live Zoom bot is bound to this session (bot_not_active).
Validation Error
The control plane failed to deliver the command (bot_command_failed).
POST /v1/{workspace_id}/sessions/{session_id}/zoom/resume HTTP/1.1
Accept: */*
{
"bot_status": "text"
}Disconnect Zoom: best-effort revoke at Zoom, delete the row. Idempotent -- deleting a non-existent connection still returns 204.
Successful Response
No content
Bearer token is absent or invalid.
The principal is outside this workspace or provider scope.
Validation Error
DELETE /v1/{workspace_id}/zoom/connection HTTP/1.1
Accept: */*
No content
Whether the calling provider has a Zoom connection. NEVER returns token material.
Heals a near-expiry token on the poll (phase 35) so a connected-but-idle workspace never lets its
Zoom token lapse — the refresh + persist happen server-side before the status read, which then
reflects the outcome (reconnect_required is set when Zoom has rejected the stored credential).
Successful Response
Response of GET /zoom/connection. NEVER carries token material.
Deliberately holds only a boolean plus non-sensitive display fields; the
encrypted access/refresh tokens live only in scribe.zoom_connections and are
resolved server-side (phase 05) to dispatch a bot, never returned to a browser.
reconnect_required is true when Zoom rejected the stored refresh token (revoked/
expired), so the poll heals into a terminal state the UX can act on: the provider
is still connected on record, but must re-run the OAuth connect before a Zoom
start will succeed.
falseBearer token is absent or invalid.
The principal is outside this workspace or provider scope.
Validation Error
GET /v1/{workspace_id}/zoom/connection HTTP/1.1
Accept: */*
{
"connected": true,
"zoom_email": "text",
"connected_at": "2026-01-01T00:00:00.000Z",
"reconnect_required": false
}Begin the Zoom connect flow: mint a single-use server-held state + PKCE verifier bound to the provider/workspace and return the short-lived Zoom authorize URL the browser navigates to.
web_origin is the initiating web app's origin; if the code-level origin rule accepts it, it is
threaded through the state so the callback can 302 the browser back to it (phase 55). A missing or
rejected origin is dropped and the callback falls back to the configured return URL.
""Successful Response
Response of POST /zoom/oauth/authorize.
The browser navigates the top-level window to authorize_url (it cannot carry
the in-memory Bearer header on a redirect, so the single-use server-held state
embedded in the URL is the credential the unauthenticated callback trusts).
expires_at is when that state's short TTL lapses.
Bearer token is absent or invalid.
The principal is outside this workspace or provider scope.
Validation Error
Zoom connect is temporarily unavailable; retry.
POST /v1/{workspace_id}/zoom/oauth/authorize HTTP/1.1
Accept: */*
{
"authorize_url": "text",
"expires_at": "2026-01-01T00:00:00.000Z"
}Unauthenticated Zoom redirect target (NO Bearer -- the single-use state is the credential).
Validates + atomically consumes (GETDEL) the state, exchanges the code + PKCE verifier, and stores
the encrypted tokens. Every failure -- invalid/expired/replayed state, missing code, failed
exchange -- 302s to the web settings route with an error flag and renders no JSON to the human.
Opted out of the provider-JWT dependency simply by omitting claims: ScribeClaimsParam.
""""Redirect to the web settings route with a zoom_connected=true flag on success or a zoom_error=<reason> flag on an invalid/expired/replayed state or a failed exchange.
No content
Successful Response
Validation Error
GET /v1/{workspace_id}/zoom/oauth/callback HTTP/1.1
Accept: */*
No content
Run the whole Zoom capture saga server-side and return {session, bot_id} (201).
In order: validate the meeting link; friendly per-practitioner active-Zoom pre-check; resolve +
decrypt the STORED Zoom token (409 zoom_not_connected if absent); create the session (born
in-progress, mode=zoom, external_id idempotency); dispatch the bot via the control plane
with the resolved token. On dispatch failure the session is CANCELLED and any straggler bot reaped
(503 bot_dispatch_failed) so nothing is orphaned. A duplicate/idempotent create whose bot is
already running recovers that bot instead of dispatching a second one.
Body of POST /zoom/sessions — the whole Zoom capture saga behind one call.
The browser hands only a meeting_link + disclosure choice (never a zoomAccessToken): the
Scribe API creates the session, resolves the provider's STORED Zoom token, and dispatches the bot
server-side. external_id is the per-attempt idempotency key (same semantics as
CreateSessionRequest).
Successful Response
Response of POST /zoom/sessions: the created (mode=zoom, in-progress) session plus the
id of the dispatched control-plane bot the live stream is bound to.
meeting_link is not a valid Zoom meeting URL (invalid_meeting_link).
Bearer token is absent or invalid.
The principal is outside this workspace or provider scope.
The practitioner already has an active Zoom session (active_zoom_session_exists), the idempotency key was reused with a different fingerprint (idempotency_key_conflict), the provider has not connected Zoom (zoom_not_connected), Zoom rejected the stored credential and the provider must reconnect (zoom_reconnect_required), or the Zoom meeting hasn't started yet — start the meeting, then retry (zoom_meeting_not_started).
Request validation failed (validation_error); no canonical visit_type was supplied to resolve a supported amd-* template (note_template_required); or the visit_type/note_template does not map to a supported amd-* template (unsupported_note_template).
Bot dispatch failed; the session was compensated/cancelled (bot_dispatch_failed), or refreshing the stored Zoom token was temporarily unavailable (zoom_refresh_unavailable).
POST /v1/{workspace_id}/zoom/sessions HTTP/1.1
Content-Type: application/json
Accept: */*
Content-Length: 321
{
"meeting_link": "https://example.com",
"disclosure": {
"enabled": true,
"audio_key": "text"
},
"external_appointment_id": "text",
"external_id": "text",
"metadata": {
"ANY_ADDITIONAL_PROPERTY": "anything"
},
"first_name": "text",
"last_name": "text",
"visit_type": "psych-intake",
"note_template": "amd-psych-intake",
"timezone": "Africa/Abidjan"
}{
"session": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"status": "in-progress",
"mode": "in_person",
"external_appointment_id": "text",
"first_name": "text",
"last_name": "text",
"visit_type": "text",
"note_template": "amd-psych-intake",
"started_at": "2026-01-01T00:00:00.000Z",
"ended_at": "2026-01-01T00:00:00.000Z",
"created_at": "2026-01-01T00:00:00.000Z",
"updated_at": "2026-01-01T00:00:00.000Z",
"local_timezone": "text",
"artifacts": {
"transcript": "pending",
"note": "pending",
"summary": "pending",
"codes": "pending"
}
},
"bot_id": "text"
}Last updated
Was this helpful?

