Encounter Document Draft
Status:
stableCategory:trinityassistAdded:2026-07-16Last reviewed:2026-07-16
Summary
Generate a complete clinical encounter document from one visit
transcript. Where /api/encounters/soap/draft
returns just the SOAP note, this endpoint returns every content and
attestation section a clinician reviews and signs off for a full visit: the
SOAP note, the injury and patient baselines (initial visit), the
since-last-visit block (follow-up visit), next-visit goals, work-relatedness
inputs, work status, and disposition.
The response carries only the drafted sections. It is designed to be dropped straight into a sign-off surface: content fields are drafted from the transcript, and clinician-owned attestations (work status, disposition, work-relatedness, prior-goal scoring) are pre-filled proposals the clinician confirms or edits before signing.
This is a sibling of the SOAP-draft endpoint, not a replacement. The SOAP endpoint still serves the live mid-call proposal feed; this endpoint produces the whole document at review time.
Endpoint
| Field | Value |
|---|---|
| Method | POST |
| Path | /api/encounters/document/draft |
| Full URL | https://engine.tripod-health.com/api/encounters/document/draft |
| Authentication | API key (required) |
| Request body | application/json |
| Response body | application/json |
| Idempotent | No (each call may return a slightly different draft) |
| Rate-limited | Yes |
Purpose
The endpoint exists so a consumer can assemble a fully pre-filled clinician sign-off surface from a visit transcript in one call, instead of stitching together a SOAP note, goals, baselines, work status, and disposition from separate surfaces. The clinician reviews the drafted document, edits anything, and signs -- sign-off is the only moment the data becomes a clinical record on the consumer's side.
The engine returns a plain JSON object whose keys are the document's sections. The consumer owns the surrounding envelope (the document's schema version, its encounter id, the delivery medium, and the patient contact values) and fills those in itself; the engine never sees or returns them.
Authentication
Standard API key. Set apikey: $ENGINE_API_KEY on the request. See
authentication.md. A missing or unknown key returns
401 Unauthenticated at the gateway before the request reaches the engine.
Request
Headers
| Header | Required | Notes |
|---|---|---|
apikey | Yes | Your engine API key. |
Content-Type | Yes | application/json. |
X-Request-ID | No | Echoed in the X-Request-ID response header; lets you correlate logs. |
Body
{
"sessions": [
{
"session_id": "00000000-0000-0000-0000-000000000001",
"started_at": "2026-05-12T14:02:00.000Z",
"segments": [
{
"speaker": "provider",
"speaker_label": "Provider",
"text": "Hello, can you describe what brings you in today?",
"started_at_ms": 0,
"ended_at_ms": 3500
},
{
"speaker": "patient",
"speaker_label": "Patient",
"text": "I've had lower-back pain for about a week. It started after I was lifting boxes at work.",
"started_at_ms": 3500,
"ended_at_ms": 14000
}
]
}
],
"encounter_meta": {
"visit_type": "initial",
"encounter_type": "telephonic"
},
"open_prior_goals": []
}
| Field | Type | Always present | Description |
|---|---|---|---|
sessions | array | Yes | Diarized transcript sessions in chronological order. At least one segment across all sessions is required. Max 32 sessions. |
sessions[].session_id | string | Yes | Consumer-supplied opaque session id. Max 64 chars. |
sessions[].started_at | string | Yes | ISO 8601 timestamp of the session's first segment. |
sessions[].segments | array | Yes | Diarized transcript turns in chronological order. Max 4,096 per session. |
sessions[].segments[].speaker | enum | Yes | One of provider, patient, other, unknown. |
sessions[].segments[].speaker_label | string | null | No | Optional human-readable label. Opaque to the engine. Max 128 chars. |
sessions[].segments[].text | string | Yes | Utterance text. Max 8,000 chars. |
sessions[].segments[].started_at_ms | integer | Yes | Milliseconds since session start. |
sessions[].segments[].ended_at_ms | integer | Yes | Milliseconds since session start. |
encounter_meta | object | Yes | Encounter context. |
encounter_meta.visit_type | enum | Yes | One of initial, follow_up. Selects which document sections are returned. |
encounter_meta.encounter_type | string | Yes | The delivery medium as an opaque categorical (e.g. telephonic, messaging, telemedicine). May be an empty string. Max 64 chars. |
open_prior_goals | array | No | The currently-open goals from prior visits that a follow-up may score. Empty (or omitted) for initial visits. Max 64. |
open_prior_goals[].goal_id | string | Yes | Opaque id of an open prior goal. The engine only ever references these ids back in sinceLastVisit.priorGoalScores. Max 64 chars. |
open_prior_goals[].measure_key | string | Yes | The controlled measure key of that goal. Max 64 chars. |
At least one transcript segment MUST be present; a request with no segments
returns 400 ValidationError: "At least one transcript segment is required".
The body MUST NOT contain identifier-shaped values. The engine's inbound
de-identification middleware rejects any such payload with 400 DeIdentificationViolation. session_id, speaker_label, and
open_prior_goals[].goal_id are opaque to the engine -- use consumer-side
surrogates, never patient identifiers. See
conventions.md.
Response
The response is a JSON object whose top-level keys are the document sections
for the requested visit_type. All keys are camelCase. The engine returns
only the sections below -- it never returns schemaVersion, encounterId,
medium, purpose, or contact; the consumer owns those and fills them in
around the drafted sections.
Sections by visit type:
initial:soap,injuryBaseline,patientBaseline,workRelatedness,nextVisitGoals,workStatus,disposition.follow_up:soap,sinceLastVisit,nextVisitGoals,workStatus,disposition.
Content fields (soap, baselines, sinceLastVisit.grocScore,
nextVisitGoals) are drafted from the transcript. Attestation fields
(workStatus.status, disposition.decision, workRelatedness,
sinceLastVisit.priorGoalScores) are clinician-owned proposals: the engine
pre-fills them only when the transcript supports a valid value and every
dependency is satisfied, and leaves them null otherwise for the clinician to
decide.
Success -- 200 OK (initial visit)
The example below is a real production response generated from a synthetic
single-session transcript covering one week of work-related lower-back pain,
called with encounter_meta.visit_type: "initial".
{
"soap": {
"subjective": "The patient presents with a chief complaint of lower-back pain for approximately one week. The patient reports onset following a full day of lifting and moving inventory boxes at work. Pain is rated 6/10 at baseline, spiking to 8/10 with forward bending. Symptoms are worse in the morning and improve somewhat with movement. The patient denies any numbness, tingling, or lower-extremity weakness. No current medications reported. No known drug allergies.",
"objective": "Range of motion is mildly limited in lumbar flexion. Straight-leg raise is negative bilaterally. No focal neurological deficits noted.",
"assessment": "The patient presents with acute lumbar strain following an occupational lifting incident approximately one week prior. Pain pattern is consistent with mechanical low-back pain. Absence of radicular symptoms, negative straight-leg raise, and no neurological deficits suggest no radiculopathy at this time. Functional limitation is present, particularly with forward flexion and lifting activities.",
"plan": "Initiate NSAID therapy for pain management. Begin home exercise program focusing on lumbar mobility. Modified duty work restrictions with no lifting over 10 lbs. Follow-up in two weeks to reassess pain, range of motion, and functional progress.",
"structuredExtraction": {
"chiefComplaint": "Lower-back pain after lifting boxes at work",
"vitals": [],
"assessments": [
{ "summary": "Acute lumbar strain, occupational onset, mechanical pain pattern, no radicular signs", "confidence": 0.9 }
],
"planItems": [
{ "summary": "Initiate NSAID therapy for pain management", "kind": "medication" },
{ "summary": "Begin home exercise program with lumbar mobility exercises", "kind": "exercise" },
{ "summary": "Modified duty: no lifting over 10 lbs", "kind": "work_restriction" },
{ "summary": "Follow-up visit in two weeks to reassess pain, ROM, and functional tolerance", "kind": "followup" }
],
"followUp": "Two weeks",
"icd10Candidates": [
{ "code": "M54.50", "label": "Low back pain, unspecified", "confidence": 0.85 },
{ "code": "M54.59", "label": "Other low back pain", "confidence": 0.7 },
{ "code": "S39.012A", "label": "Strain of muscle, fascia and tendon of lower back, initial encounter", "confidence": 0.8 }
]
}
},
"injuryBaseline": {
"mechanismCategory": "lifting_overexertion",
"bodyRegion": "spine_lumbar",
"injuryType": "strain_sprain",
"laterality": "na",
"onsetAt": "2026-05-05",
"incidentOccurredAt": "2026-05-05T00:00:00Z",
"natureOfIllnessNote": "Patient reports acute onset of lower-back pain following a full day of lifting and moving inventory boxes at work. Pain worsens with forward bending and is most prominent in the morning."
},
"patientBaseline": {
"medications": [],
"allergies": [],
"chronicConditions": [],
"priorSurgeries": [],
"pastMedicalHistoryNarrative": "No current medications reported. No known drug allergies. No additional past medical, surgical, or chronic condition history elicited during this visit."
},
"workRelatedness": {
"initialAssessment": "likely",
"patientClaim": "yes",
"employerClaim": null
},
"nextVisitGoals": [
{ "measureKey": "pain_intensity", "qualifierKey": null, "targetMedicationId": null, "baselineValue": 6, "targetValue": 3, "targetDirectionKey": null, "priority": "primary" },
{ "measureKey": "lifting_tolerance", "qualifierKey": null, "targetMedicationId": null, "baselineValue": 10, "targetValue": 20, "targetDirectionKey": null, "priority": "secondary" },
{ "measureKey": "rom_limitation", "qualifierKey": null, "targetMedicationId": null, "baselineValue": 1, "targetValue": 0, "targetDirectionKey": null, "priority": "secondary" },
{ "measureKey": "hep_adherence", "qualifierKey": null, "targetMedicationId": null, "baselineValue": 0, "targetValue": 3, "targetDirectionKey": null, "priority": "secondary" }
],
"workStatus": {
"status": "modified_duty",
"effectiveFrom": "2026-05-12",
"effectiveThrough": "2026-05-26",
"restrictions": {
"structured": ["no_lifting_over_10_lbs"],
"custom": "No lifting over 10 lbs. Patient to remain on modified duty pending reassessment in two weeks."
},
"mmiDate": null,
"returnToWorkAt": null
},
"disposition": {
"decision": "schedule_followup",
"followupAt": "2026-05-26T00:00:00Z",
"followupChannel": "sms",
"closeReason": null
}
}
Success -- 200 OK (follow-up visit)
A real production response for a follow-up visit. The request supplied three
open_prior_goals; the engine returns a sinceLastVisit block that scores or
carries each forward, and omits the injury and patient baselines (those
persist from the initial visit).
{
"soap": {
"subjective": "The patient reports significant overall improvement in lower-back pain since the last visit two weeks ago. The patient self-rates global change as approximately +4 on the change scale. Worst pain in the last 24 hours is reported at 3/10. The patient notes improved ability to lift at work without pain flaring up.",
"objective": "Provider notes range of motion is close to full at today's visit.",
"assessment": "The patient is demonstrating meaningful progress with lower-back pain, reporting reduced pain intensity (3/10) and improved lifting tolerance at work. ROM appears near full per provider observation. The trajectory is positive on a modified-duty course with continued home exercise program.",
"plan": "Continue home exercise program. Target pain intensity of 1/10 and lifting tolerance of 30 lbs by next visit. Maintain modified-duty work status. Follow-up in two weeks.",
"structuredExtraction": {
"chiefComplaint": "Lower-back pain follow-up",
"vitals": [],
"assessments": [
{ "summary": "Lower-back pain -- improving, pain now 3/10, ROM near full, lifting tolerance improving with modified duty maintained.", "confidence": 0.95 }
],
"planItems": [
{ "summary": "Continue home exercise program as directed.", "kind": "exercise" },
{ "summary": "Maintain modified-duty work status.", "kind": "work_status" },
{ "summary": "Follow-up visit in two weeks.", "kind": "followup" }
],
"followUp": "Two weeks.",
"icd10Candidates": [
{ "code": "M54.50", "label": "Low back pain, unspecified", "confidence": 0.9 }
]
}
},
"sinceLastVisit": {
"grocScore": 4,
"priorGoalScores": [
{ "goalId": "11111111-1111-1111-1111-111111111111", "scoredValue": null, "scoredOutcomeKey": null, "carryForward": true },
{ "goalId": "22222222-2222-2222-2222-222222222222", "scoredValue": null, "scoredOutcomeKey": null, "carryForward": true },
{ "goalId": "33333333-3333-3333-3333-333333333333", "scoredValue": null, "scoredOutcomeKey": null, "carryForward": true }
]
},
"nextVisitGoals": [
{ "measureKey": "pain_intensity", "qualifierKey": null, "targetMedicationId": null, "baselineValue": 3, "targetValue": 1, "targetDirectionKey": null, "priority": null },
{ "measureKey": "lifting_tolerance", "qualifierKey": null, "targetMedicationId": null, "baselineValue": 0, "targetValue": 30, "targetDirectionKey": null, "priority": null },
{ "measureKey": "hep_adherence", "qualifierKey": null, "targetMedicationId": null, "baselineValue": 2, "targetValue": 3, "targetDirectionKey": null, "priority": null }
],
"workStatus": {
"status": "modified_duty",
"effectiveFrom": null,
"effectiveThrough": null,
"restrictions": {
"structured": [],
"custom": "Clinician to specify applicable lifting and activity restrictions consistent with modified duty."
},
"mmiDate": null,
"returnToWorkAt": null
},
"disposition": {
"decision": "schedule_followup",
"followupAt": "2026-06-09T00:00:00Z",
"followupChannel": "sms",
"closeReason": null
}
}
Response fields
soap (both visit types)
Identical shape to the SOAP draft response, but
nested under soap and with camelCase keys (structuredExtraction,
chiefComplaint, planItems, icd10Candidates, followUp).
| Field | Type | Always present | Description |
|---|---|---|---|
soap.subjective | string | null | Yes | Patient-reported history in clinical voice. Null when the transcript is too thin. |
soap.objective | string | null | Yes | Observed findings during the visit. |
soap.assessment | string | null | Yes | Clinical judgment integrating subjective + objective. |
soap.plan | string | null | Yes | Next steps. |
soap.structuredExtraction | object | Yes | Structured read of the note; inner arrays may be empty. |
soap.structuredExtraction.chiefComplaint | string | null | No | One-line presenting complaint. |
soap.structuredExtraction.vitals[] | array | Yes | { name, value, unit, ts } entries. Up to 32. |
soap.structuredExtraction.assessments[] | array | Yes | { summary, confidence }. Up to 32. |
soap.structuredExtraction.planItems[] | array | Yes | { summary, kind }. Up to 32. |
soap.structuredExtraction.followUp | string | null | No | Free-text follow-up summary. |
soap.structuredExtraction.icd10Candidates[] | array | Yes | { code, label, confidence }. Up to 32. |
injuryBaseline (initial only)
| Field | Type | Always present | Description |
|---|---|---|---|
injuryBaseline.mechanismCategory | enum | null | Yes | One of lifting_overexertion, fall_slip_trip, struck_by, caught_in, repetitive_motion, motor_vehicle, laceration_cut, burn, exposure, other. |
injuryBaseline.bodyRegion | string | null | Yes | A controlled body-region code, or null when the engine cannot map one confidently. |
injuryBaseline.injuryType | string | null | Yes | A controlled injury-type code, or null. |
injuryBaseline.laterality | enum | null | Yes | One of left, right, bilateral, na. |
injuryBaseline.onsetAt | string | null | Yes | ISO date (YYYY-MM-DD). |
injuryBaseline.incidentOccurredAt | string | null | Yes | ISO date-time. |
injuryBaseline.natureOfIllnessNote | string | null | Yes | Free-text description of how the injury occurred. |
patientBaseline (initial only)
| Field | Type | Always present | Description |
|---|---|---|---|
patientBaseline.medications[] | array | Yes | { name, dose, frequency, route, status }; status is active or discontinued. |
patientBaseline.allergies[] | array | Yes | Strings. |
patientBaseline.chronicConditions[] | array | Yes | Strings. |
patientBaseline.priorSurgeries[] | array | Yes | Strings. |
patientBaseline.pastMedicalHistoryNarrative | string | null | Yes | Free-text history summary. |
workRelatedness (initial only)
Clinician inputs only -- the engine never returns a derived work-relatedness verdict; the consumer recomputes the binary decision from these inputs.
| Field | Type | Always present | Description |
|---|---|---|---|
workRelatedness.initialAssessment | enum | null | Yes | One of definitely, likely, unsure, unlikely, absolutely_not. When unsure, patientClaim is non-null. |
workRelatedness.patientClaim | enum | null | Yes | One of yes, maybe, no. |
workRelatedness.employerClaim | enum | null | Yes | One of yes, maybe, no. |
sinceLastVisit (follow-up only)
| Field | Type | Always present | Description |
|---|---|---|---|
sinceLastVisit.grocScore | integer | null | Yes | Patient-reported global change, -7..+7. |
sinceLastVisit.priorGoalScores[] | array | Yes | One entry per supplied open_prior_goals id. |
sinceLastVisit.priorGoalScores[].goalId | string | Yes | An id from the request's open_prior_goals; the engine references no other ids. |
sinceLastVisit.priorGoalScores[].scoredValue | number | null | No | Objective score, when the transcript clearly supports one. |
sinceLastVisit.priorGoalScores[].scoredOutcomeKey | string | null | No | Subjective outcome, when supported. |
sinceLastVisit.priorGoalScores[].carryForward | boolean | Yes | true (the safe default) rolls the goal into the next interval unscored. |
nextVisitGoals (both visit types)
Each entry is a goal to set for the next visit. measureKey is always a valid
controlled measure key; objective measures carry a baselineValue and
targetValue within the measure's scale, subjective measures carry a
targetDirectionKey. When nothing is well-supported the array is empty.
| Field | Type | Always present | Description |
|---|---|---|---|
nextVisitGoals[].measureKey | string | Yes | A valid controlled measure key. |
nextVisitGoals[].qualifierKey | string | null | No | Required controlled qualifier for measures that declare one; null otherwise. |
nextVisitGoals[].targetMedicationId | string | null | No | Always null (the engine holds no chart medication ids). |
nextVisitGoals[].baselineValue | number | null | No | Objective measures: the value on the measure's scale. |
nextVisitGoals[].targetValue | number | null | No | Objective measures: the target on the measure's scale. |
nextVisitGoals[].targetDirectionKey | string | null | No | Subjective measures: the chosen target direction. |
nextVisitGoals[].priority | string | null | No | primary or secondary, or null. |
workStatus (both visit types) -- attestation
| Field | Type | Always present | Description |
|---|---|---|---|
workStatus.status | enum | null | Yes | One of full_duty, modified_duty, off_work, mmi_reached, or null (clinician decides). modified_duty always carries restrictions; mmi_reached always carries mmiDate. |
workStatus.effectiveFrom | string | null | Yes | ISO date. |
workStatus.effectiveThrough | string | null | Yes | ISO date; null means "until next visit". |
workStatus.restrictions | object | null | Yes | { structured: string[], custom: string } when status is modified_duty, else null. |
workStatus.mmiDate | string | null | Yes | ISO date; present when status is mmi_reached. |
workStatus.returnToWorkAt | string | null | Yes | ISO date; optional clinician-set milestone. |
disposition (both visit types) -- attestation
| Field | Type | Always present | Description |
|---|---|---|---|
disposition.decision | enum | null | Yes | One of schedule_followup, close_case, or null. schedule_followup always carries followupAt + followupChannel and requires at least one nextVisitGoals entry; close_case requires workStatus.status = mmi_reached + a closeReason. |
disposition.followupAt | string | null | Yes | ISO date-time. |
disposition.followupChannel | enum | null | Yes | One of sms, email. |
disposition.closeReason | string | null | Yes | Present when decision is close_case. |
Generated free-text passes the engine's outbound de-identification scan before
returning; identifier-shaped output fails the call with 502 UpstreamError
rather than being silently scrubbed. The structured date, code, and enum
fields above are not free text and are validated against the contract, not the
de-id scan.
Status codes
| Code | Meaning | When |
|---|---|---|
200 | OK | Document generated. |
400 | ValidationError | Body shape, enum violation, or no transcript segments. |
400 | DeIdentificationViolation | Body carries an identifier-shaped value. |
401 | Unauthenticated | Missing or invalid API key. |
413 | PayloadTooLarge | Body exceeds 512 KB. |
415 | UnsupportedMediaType | Content-Type is not application/json. |
429 | RateLimited | Per-consumer rate limit exceeded. |
500 | InternalError | Unexpected failure. |
502 | UpstreamError | Upstream model call failed, or generated text failed the outbound de-id pass. |
503 | ServiceUnavailable | Service temporarily unhealthy. |
504 | UpstreamTimeout | Upstream model call exceeded the engine's generation budget. |
Error envelope
{
"timestamp": "2026-07-16T07:04:30.558Z",
"error": "UpstreamError",
"message": "Generated text failed safety check: appears to contain a phone number",
"request_id": "bf63b5f3-b809-46fb-8d3b-c4b146fd1ecd"
}
See errors.md for the full code list.
Examples
curl -- initial visit
curl -sS -X POST "https://engine.tripod-health.com/api/encounters/document/draft" \
-H "apikey: $ENGINE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"sessions": [
{
"session_id": "00000000-0000-0000-0000-000000000001",
"started_at": "2026-05-12T14:02:00.000Z",
"segments": [
{ "speaker": "provider", "speaker_label": "Provider", "text": "What brings you in today?", "started_at_ms": 0, "ended_at_ms": 3500 },
{ "speaker": "patient", "speaker_label": "Patient", "text": "Lower-back pain for a week, started lifting boxes at work. Worst pain about a six.", "started_at_ms": 3500, "ended_at_ms": 14000 }
]
}
],
"encounter_meta": { "visit_type": "initial", "encounter_type": "telephonic" },
"open_prior_goals": []
}'
curl -- follow-up visit (scoring open prior goals)
curl -sS -X POST "https://engine.tripod-health.com/api/encounters/document/draft" \
-H "apikey: $ENGINE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"sessions": [
{
"session_id": "00000000-0000-0000-0000-0000000000f1",
"started_at": "2026-05-26T14:00:00.000Z",
"segments": [
{ "speaker": "patient", "speaker_label": "Patient", "text": "Quite a bit better, maybe a plus four. Worst pain is down to a three and I can lift more at work.", "started_at_ms": 0, "ended_at_ms": 12000 }
]
}
],
"encounter_meta": { "visit_type": "follow_up", "encounter_type": "telephonic" },
"open_prior_goals": [
{ "goal_id": "11111111-1111-1111-1111-111111111111", "measure_key": "pain_intensity" },
{ "goal_id": "22222222-2222-2222-2222-222222222222", "measure_key": "lifting_tolerance" }
]
}'
Python (requests)
import os, requests
resp = requests.post(
"https://engine.tripod-health.com/api/encounters/document/draft",
headers={"apikey": os.environ["ENGINE_API_KEY"]},
json={
"sessions": [
{
"session_id": "00000000-0000-0000-0000-000000000001",
"started_at": "2026-05-12T14:02:00.000Z",
"segments": [
{"speaker": "patient", "speaker_label": "Patient",
"text": "Lower-back pain for a week after lifting boxes at work.",
"started_at_ms": 0, "ended_at_ms": 8000},
],
}
],
"encounter_meta": {"visit_type": "initial", "encounter_type": "telephonic"},
"open_prior_goals": [],
},
timeout=60,
)
resp.raise_for_status()
doc = resp.json()
print(doc["soap"]["subjective"])
for goal in doc["nextVisitGoals"]:
print(goal["measureKey"], goal.get("baselineValue"), "->", goal.get("targetValue"))
Intended use
- Assemble a pre-filled clinician sign-off surface for a full visit: render each section as editable fields, let the clinician confirm attestations, and persist on your side at sign-off.
- Pass
encounter_meta.visit_typeto select the document shape --initialfor a first encounter (with baselines and work-relatedness),follow_upfor a continuing visit (with the since-last-visit block). - On a follow-up, supply the open prior goals in
open_prior_goals; render the returnedsinceLastVisit.priorGoalScoresfor the clinician to confirm or adjust. The safe default carries each goal forward unscored. - Treat
workStatusanddispositionas pre-filled proposals; a nullstatusordecisionmeans the engine deliberately left the decision to the clinician.
Mistaken use
- Persisting the document without clinician review. Every field is a draft or a proposal; sign-off is where the clinical record is created.
- Reading
workRelatednessas a decision. It is the clinician's input set; the binary work-relatedness determination is recomputed on your side. - Using this endpoint for the live mid-call proposal feed. That is
/api/encounters/soap/draft; this endpoint is the full-document review-time draft. - Scoring goals that were not supplied in
open_prior_goals. The engine only references the ids you send; any other id is ignored.
Debugging
- Capture the
X-Request-IDresponse header (or therequest_idin an error envelope) before anything else. 400 ValidationError "At least one transcript segment is required"-- the request had no segments across any session.502 UpstreamError "Generated text failed safety check: ..."-- the model produced identifier-shaped free text; the engine refused to return it. Retry; if it persists, open a ticket with therequest_id.504 UpstreamTimeout-- the document generation exceeded the engine's budget. The engine's budget sits below the recommended 60s client timeout.
Rate limits
Per-consumer limits are enforced at the gateway. See
rate-limits.md. Responses include standard RateLimit-*
headers.
Related
POST /api/encounters/soap/draft-- the SOAP note alone, for the live mid-call proposal feed.POST /api/encounters/transcript/trim-- periodic condensation of a live-call transcript window.- conventions.md -- de-identification contract, request IDs, timestamp shape.
- errors.md -- error envelope and code list.
Change history
| Date | Change |
|---|---|
| 2026-07-16 | Initial publication. |