Getting startedEnd-to-end examples

Medical scribe

Transcribe a clinical encounter using Medical Mode with speaker labels and entity detection, identify speakers by role, then use LLM Gateway to generate a structured SOAP note.

Products used: Pre-recorded STT + Medical Mode + speaker diarization + Speaker Identification + entity detection + LLM Gateway

Model selection: Uses universal-3-pro-medical for purpose-built accuracy on medical terminology, drug names, and clinical language.

Medical Mode requires a signed BAA with AssemblyAI. Contact sales@assemblyai.com for access.

1import requests
2import time
3
4# ── Config ────────────────────────────────────────────────────
5base_url = "https://api.assemblyai.com"
6headers = {"authorization": "YOUR_API_KEY"}
7
8audio_url = "https://assembly.ai/wildfires.mp3" # Replace with your clinical audio
9
10# ── Step 1: Transcribe with Medical Mode + speaker labels + entity detection ──
11data = {
12 "audio_url": audio_url,
13 "speech_models": ["universal-3-pro-medical"],
14 "speaker_labels": True,
15 "entity_detection": True,
16}
17
18response = requests.post(base_url + "/v2/transcript", headers=headers, json=data)
19response.raise_for_status()
20transcript_id = response.json()["id"]
21
22while True:
23 result = requests.get(f"{base_url}/v2/transcript/{transcript_id}", headers=headers).json()
24 if result["status"] == "completed":
25 break
26 elif result["status"] == "error":
27 raise RuntimeError(f"Transcription failed: {result['error']}")
28 time.sleep(3)
29
30# ── Step 2: Identify speakers by role ──
31understanding_response = requests.post(
32 "https://llm-gateway.assemblyai.com/v1/understanding",
33 headers=headers,
34 json={
35 "transcript_id": transcript_id,
36 "speech_understanding": {
37 "request": {
38 "speaker_identification": {
39 "speaker_type": "role",
40 "known_values": ["Provider", "Patient"],
41 }
42 }
43 },
44 },
45)
46understanding_response.raise_for_status()
47identified = understanding_response.json()
48
49# ── Step 3: Extract detected entities ──
50entities = result.get("entities", [])
51entity_summary = "\n".join(
52 f"- {e['entity_type']}: {e['text']}" for e in entities
53)
54
55# ── Step 4: Format identified transcript ──
56speaker_transcript = "\n".join(
57 f"{u['speaker']}: {u['text']}" for u in identified["utterances"]
58)
59
60# ── Step 5: Generate SOAP note via LLM Gateway ──
61llm_response = requests.post(
62 "https://llm-gateway.assemblyai.com/v1/chat/completions",
63 headers=headers,
64 json={
65 "model": "claude-sonnet-4-5-20250929",
66 "messages": [
67 {
68 "role": "user",
69 "content": (
70 "You are a medical scribe. Given the clinical encounter transcript and "
71 "detected entities below, generate a structured SOAP note.\n\n"
72 "Format the note with these sections:\n"
73 "- **Subjective**: Patient's reported symptoms and history\n"
74 "- **Objective**: Clinical observations and measurements\n"
75 "- **Assessment**: Diagnosis or clinical impression\n"
76 "- **Plan**: Treatment plan, prescriptions, and follow-up\n\n"
77 f"Detected entities:\n{entity_summary}\n\n"
78 f"Transcript:\n{speaker_transcript}"
79 ),
80 }
81 ],
82 "max_tokens": 2000,
83 },
84)
85llm_response.raise_for_status()
86
87print("=== SOAP Note ===\n")
88print(llm_response.json()["choices"][0]["message"]["content"])
=== SOAP Note ===
## Subjective
Patient reports exposure to wildfire smoke over the past several days. Describes
worsening cough, shortness of breath, and eye irritation. Symptoms began
approximately 3 days ago coinciding with elevated air quality alerts in the region.
## Objective
- AQI reading: 150 micrograms per cubic meter (10x annual average)
- Particulate matter levels classified as "unhealthy"
- Patient appears alert and oriented
## Assessment
Acute respiratory irritation secondary to wildfire smoke exposure.
Environmental exposure consistent with regional air quality emergency.
## Plan
1. Advise patient to remain indoors with windows closed
2. Recommend N95 mask for any necessary outdoor activity
3. Prescribe albuterol inhaler PRN for acute bronchospasm
4. Follow up in 1 week or sooner if symptoms worsen
5. Refer to pulmonology if symptoms persist beyond 2 weeks

For more on building clinical documentation apps, see the Medical Scribe Best Practices guide.


See the End-to-end examples overview for all available pipelines.