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 with "domain": "medical-v1" for purpose-built accuracy on medical terminology, drug names, and clinical language.
1 import requests 2 import time 3 4 # ── Config ──────────────────────────────────────────────────── 5 base_url = "https://api.assemblyai.com" 6 headers = {"authorization": "YOUR_API_KEY"} 7 8 audio_url = "https://assembly.ai/wildfires.mp3" # Replace with your clinical audio 9 10 # ── Step 1: Transcribe with Medical Mode + speaker labels + entity detection ── 11 data = { 12 "audio_url": audio_url, 13 "speech_models": ["universal-3-pro"], 14 "domain": "medical-v1", 15 "speaker_labels": True, 16 "entity_detection": True, 17 } 18 19 response = requests.post(base_url + "/v2/transcript", headers=headers, json=data) 20 response.raise_for_status() 21 transcript_id = response.json()["id"] 22 23 while True: 24 result = requests.get(f"{base_url}/v2/transcript/{transcript_id}", headers=headers).json() 25 if result["status"] == "completed": 26 break 27 elif result["status"] == "error": 28 raise RuntimeError(f"Transcription failed: {result['error']}") 29 time.sleep(3) 30 31 # ── Step 2: Identify speakers by role ── 32 understanding_response = requests.post( 33 "https://llm-gateway.assemblyai.com/v1/understanding", 34 headers=headers, 35 json={ 36 "transcript_id": transcript_id, 37 "speech_understanding": { 38 "request": { 39 "speaker_identification": { 40 "speaker_type": "role", 41 "known_values": ["Provider", "Patient"], 42 } 43 } 44 }, 45 }, 46 ) 47 understanding_response.raise_for_status() 48 identified = understanding_response.json() 49 50 # ── Step 3: Extract detected entities ── 51 entities = result.get("entities", []) 52 entity_summary = "\n".join( 53 f"- {e['entity_type']}: {e['text']}" for e in entities 54 ) 55 56 # ── Step 4: Format identified transcript ── 57 speaker_transcript = "\n".join( 58 f"{u['speaker']}: {u['text']}" for u in identified["utterances"] 59 ) 60 61 # ── Step 5: Generate SOAP note via LLM Gateway ── 62 llm_response = requests.post( 63 "https://llm-gateway.assemblyai.com/v1/chat/completions", 64 headers=headers, 65 json={ 66 "model": "claude-sonnet-4-5-20250929", 67 "messages": [ 68 { 69 "role": "user", 70 "content": ( 71 "You are a medical scribe. Given the clinical encounter transcript and " 72 "detected entities below, generate a structured SOAP note.\n\n" 73 "Format the note with these sections:\n" 74 "- **Subjective**: Patient's reported symptoms and history\n" 75 "- **Objective**: Clinical observations and measurements\n" 76 "- **Assessment**: Diagnosis or clinical impression\n" 77 "- **Plan**: Treatment plan, prescriptions, and follow-up\n\n" 78 f"Detected entities:\n{entity_summary}\n\n" 79 f"Transcript:\n{speaker_transcript}" 80 ), 81 } 82 ], 83 "max_tokens": 2000, 84 }, 85 ) 86 llm_response.raise_for_status() 87 88 print("=== SOAP Note ===\n") 89 print(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 guides.
See the End-to-end examples overview for all available pipelines.