Medical imaging report generation and patient communication letter creation
- Published
Medical imaging reports are dense. Radiologists generate them quickly, but patients rarely understand what the technical language means. A patient receives a report saying "5mm nodule with spiculated margins in the right upper lobe" and either panics or ignores it. Clinical staff must then spend time on the phone or writing emails to explain findings in plain language. This is repetitive, time-consuming, and creates bottlenecks in patient communication workflows.
The gap between clinical accuracy and patient understanding is real. You cannot simplify a radiology report by hand for every patient, nor should you. Yet many practices still do exactly that: a radiologist writes the report, a nurse reads it, and then manually drafts a patient letter. This approach wastes staff time and delays patient communication by days.
What if you could generate both the clinical report and a plain-language patient communication letter automatically, with all the medical terminology converted to accessible language, recorded as audio for patients who prefer listening, and delivered with zero manual handoff? This is possible today using four AI tools: medical imaging analysis (HyperWrite), text-to-speech conversion (ElevenLabs and Resemble AI), and an orchestration layer to wire them together. This post shows you how to build this workflow. For more on this, see ElevenLabs vs Resemble AI vs iSpeech: Best AI Voice Synth....
The Automated Workflow
Architecture Overview
The workflow takes imaging data (DICOM files or radiology reports) as input and produces three outputs: a structured clinical report, a plain-language patient letter, and an audio version of that letter. Data flows through four stages: ingestion, analysis, transformation, and delivery. We will use n8n as the orchestration backbone because it handles file uploads, API calls, and branching logic without requiring code changes when you swap tools.
Here is the overall sequence:
- A radiology report (or imaging metadata) lands in your system.
- HyperWrite analyses the report and extracts key findings.
- A second HyperWrite call generates a plain-language version of those findings.
- ElevenLabs converts the letter to audio with medical-grade voice stability.
- Resemble AI creates a backup audio version with different voice characteristics.
- Both versions are saved to your patient portal or email system.
No human touches the file between steps 1 and 6.
Choosing Your Orchestration Tool
For this workflow, n8n is the best choice. Zapier works but has strict file size limits (5 MB for most operations) and higher per-task costs. Make (Integromat) supports files better than Zapier but has a steeper learning curve. n8n runs on your own infrastructure, gives you full control over execution, and charges a flat fee per month rather than per operation. If you process hundreds of reports monthly, n8n saves money. If you process fewer than 50 per month, Zapier's simplicity might justify the higher cost.
Claude Code is not an orchestration tool in the traditional sense, but it can run the entire workflow in one session if you paste API keys and file data. We will focus on n8n here, but we will include a Claude Code example at the end.
Stage 1: Ingestion and Report Parsing
The first node in n8n waits for an HTTP POST request containing the report. This can be triggered by a DICOM upload, a form submission from your imaging software, or a manual upload by clinic staff.
POST /webhook/imaging-report
Content-Type: application/json
{
"patient_id": "PAT-12345",
"report_text": "5mm nodule with spiculated margins in the right upper lobe...",
"modality": "CT",
"body_part": "Chest",
"timestamp": "2024-01-15T10:30:00Z"
}
Your n8n workflow starts with a Webhook node that listens for this POST. Add a JSON Parse node downstream to extract the report_text field.
Stage 2: Extract Key Findings with HyperWrite
HyperWrite does not have a dedicated medical imaging API, but its text generation API can be prompted to extract structured data from unstructured reports. You will send the report text to HyperWrite and ask it to return a JSON object with findings, severity, and clinical recommendations.
First, create a HyperWrite API key at https://www.hyperwrite.com/api. Then configure an HTTP Request node in n8n as follows:
POST https://api.hyperwrite.com/v1/text/generate
Authorization: Bearer YOUR_HYPERWRITE_API_KEY
Content-Type: application/json
{
"prompt": "Extract the key findings from this radiology report. Return a JSON object with these fields: primary_finding (string), severity (critical|moderate|mild), secondary_findings (array of strings), and recommendation (string). Report text: {{report_text}}",
"model": "claude-3-haiku",
"max_tokens": 500
}
The response will be a JSON object. Extract the findings using a JSON Parse node. Store this in a variable called structured_findings.
Stage 3: Generate Patient-Friendly Letter
Now you have structured findings. Pass them to a second HyperWrite call that generates a patient letter. The prompt should ask for plain language, short sentences, and no medical jargon.
POST https://api.hyperwrite.com/v1/text/generate
Authorization: Bearer YOUR_HYPERWRITE_API_KEY
Content-Type: application/json
{
"prompt": "Write a one-paragraph patient communication letter based on these findings. Use simple language. Avoid medical jargon. Explain what the findings mean in everyday terms. Include a sentence about next steps. Findings: {{structured_findings.primary_finding}}. Severity: {{structured_findings.severity}}. Recommendations: {{structured_findings.recommendation}}",
"model": "claude-3-haiku",
"max_tokens": 300
}
Store the response as patient_letter.
Stage 4: Convert to Audio with ElevenLabs
ElevenLabs has a straightforward text-to-speech API. Sign up at https://elevenlabs.io and generate an API key. You will use the voice ID "Rachel" (a clear, professional-sounding voice suitable for medical communication).
POST https://api.elevenlabs.io/v1/text-to-speech/21m00Tcm4TlvDq8ikWAM
Authorization: xi-api-key: YOUR_ELEVENLABS_API_KEY
Content-Type: application/json
{
"text": "{{patient_letter}}",
"voice_settings": {
"stability": 0.75,
"similarity_boost": 0.75
}
}
The endpoint URL uses the voice ID for Rachel. The stability and similarity_boost values are set to 0.75 to ensure consistent, clear speech. ElevenLabs returns an MP3 file in binary format. Store this as audio_elevenlabs and save it to your file storage (AWS S3, Google Cloud Storage, or local disk).
Stage 5: Create Backup Audio with Resemble AI
Resemble AI offers similar text-to-speech but with different voices and cloning capabilities. This gives you redundancy; if one service is slow, you have a backup. Sign up at https://www.resemble.ai and create an API key.
POST https://api.resemble.ai/v2/projects/12345/clips
Authorization: Bearer YOUR_RESEMBLE_API_KEY
Content-Type: application/json
{
"body": "{{patient_letter}}",
"voice_uuid": "default-voice-uuid",
"is_public": false
}
Replace 12345 with your Resemble project ID and default-voice-uuid with the UUID of your chosen voice (find this in your Resemble dashboard). Resemble returns a clip UUID. Use a second request to fetch the rendered audio file once it is ready (Resemble renders asynchronously, so you may need to poll the status endpoint).
Stage 6: Delivery and Storage
Create two more HTTP Request nodes, one for each audio file. Send them to your patient portal API or email system. Here is an example payload for a patient portal:
POST https://your-portal-api.com/v1/patient/{{patient_id}}/documents
Authorization: Bearer YOUR_PORTAL_API_KEY
Content-Type: application/json
{
"document_type": "imaging_communication",
"title": "Your {{modality}} Report Summary",
"patient_letter": "{{patient_letter}}",
"audio_url_elevenlabs": "{{audio_elevenlabs.url}}",
"audio_url_resemble": "{{audio_resemble.url}}",
"created_at": "{{timestamp}}"
}
Alternatively, send an email to the patient using an n8n Email node or Sendgrid integration:
{
"to": "{{patient_email}}",
"subject": "Your {{modality}} Report Summary",
"html_body": "<p>Hello,</p><p>{{patient_letter}}</p><p><a href='{{audio_elevenlabs.url}}'>Listen to this summary (ElevenLabs)</a> or <a href='{{audio_resemble.url}}>Alternative audio</a></p>"
}
Complete n8n Workflow JSON
Here is a simplified n8n workflow export you can import directly:
{
"nodes": [
{
"parameters": {
"path": "/imaging-report"
},
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 1,
"position": [250, 300]
},
{
"parameters": {
"url": "https://api.hyperwrite.com/v1/text/generate",
"authentication": "genericCredentialType",
"genericCredentials": {
"credentialsType": "bearerToken",
"password": "{{ $env.HYPERWRITE_API_KEY }}"
},
"requestMethod": "POST",
"contentType": "application/json",
"body": "{\"prompt\": \"Extract key findings from this report. Return JSON with primary_finding, severity, secondary_findings, recommendation. Report: {{ $node.Webhook.json.report_text }}\", \"model\": \"claude-3-haiku\", \"max_tokens\": 500}"
},
"name": "Extract Findings with HyperWrite",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.1,
"position": [450, 300]
},
{
"parameters": {
"url": "https://api.hyperwrite.com/v1/text/generate",
"authentication": "genericCredentialType",
"genericCredentials": {
"credentialsType": "bearerToken",
"password": "{{ $env.HYPERWRITE_API_KEY }}"
},
"requestMethod": "POST",
"contentType": "application/json",
"body": "{\"prompt\": \"Write a patient-friendly one-paragraph summary. Use simple language. No medical jargon. Primary finding: {{ $node['Extract Findings with HyperWrite'].json.primary_finding }}. Recommendation: {{ $node['Extract Findings with HyperWrite'].json.recommendation }}\", \"model\": \"claude-3-haiku\", \"max_tokens\": 300}"
},
"name": "Generate Patient Letter",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.1,
"position": [650, 300]
},
{
"parameters": {
"url": "https://api.elevenlabs.io/v1/text-to-speech/21m00Tcm4TlvDq8ikWAM",
"authentication": "genericCredentialType",
"headers": {
"xi-api-key": "={{ $env.ELEVENLABS_API_KEY }}"
},
"requestMethod": "POST",
"contentType": "application/json",
"body": "{\"text\": \"{{ $node['Generate Patient Letter'].json.response }}\", \"voice_settings\": {\"stability\": 0.75, \"similarity_boost\": 0.75}}"
},
"name": "ElevenLabs TTS",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.1,
"position": [850, 250]
},
{
"parameters": {
"url": "https://api.resemble.ai/v2/projects/{{ $env.RESEMBLE_PROJECT_ID }}/clips",
"authentication": "genericCredentialType",
"genericCredentials": {
"credentialsType": "bearerToken",
"password": "{{ $env.RESEMBLE_API_KEY }}"
},
"requestMethod": "POST",
"contentType": "application/json",
"body": "{\"body\": \"{{ $node['Generate Patient Letter'].json.response }}\", \"voice_uuid\": \"{{ $env.RESEMBLE_VOICE_UUID }}\", \"is_public\": false}"
},
"name": "Resemble AI TTS",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.1,
"position": [850, 400]
},
{
"parameters": {
"url": "https://your-portal-api.com/v1/patient/{{ $node.Webhook.json.patient_id }}/documents",
"authentication": "genericCredentialType",
"genericCredentials": {
"credentialsType": "bearerToken",
"password": "{{ $env.PORTAL_API_KEY }}"
},
"requestMethod": "POST",
"contentType": "application/json",
"body": "{\"document_type\": \"imaging_communication\", \"title\": \"Your Report Summary\", \"patient_letter\": \"{{ $node['Generate Patient Letter'].json.response }}\", \"audio_elevenlabs\": \"{{ $node['ElevenLabs TTS'].json.audio_url }}\", \"audio_resemble\": \"{{ $node['Resemble AI TTS'].json.clip_uuid }}\"}"
},
"name": "Save to Patient Portal",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.1,
"position": [1050, 300]
}
],
"connections": {
"Webhook": {
"main": [[{"node": "Extract Findings with HyperWrite", "type": "main", "index": 0}]]
},
"Extract Findings with HyperWrite": {
"main": [[{"node": "Generate Patient Letter", "type": "main", "index": 0}]]
},
"Generate Patient Letter": {
"main": [[{"node": "ElevenLabs TTS", "type": "main", "index": 0}, {"node": "Resemble AI TTS", "type": "main", "index": 0}]]
},
"ElevenLabs TTS": {
"main": [[{"node": "Save to Patient Portal", "type": "main", "index": 0}]]
},
"Resemble AI TTS": {
"main": [[{"node": "Save to Patient Portal", "type": "main", "index": 0}]]
}
}
}
Import this into your n8n instance, set your environment variables, and activate the workflow. Test it with a sample radiology report.
The Manual Alternative
If you prefer to retain human oversight at specific points, you can pause the workflow and require approval before sending audio files to patients. Insert a "Wait for Webhook" node between the "Save to Patient Portal" step and an approval email to the radiologist. This lets clinicians review the patient letter before it is delivered, trading automation speed for quality assurance.
Alternatively, build the workflow to generate all outputs but store them in a staging folder (e.g., an AWS S3 bucket) rather than your production patient portal. Have a human review the letter and audio files, then manually approve them for delivery. This adds a day to the process but gives you full control.
You can also skip Resemble AI entirely and rely only on ElevenLabs, reducing complexity and cost. The redundancy is nice but not essential if ElevenLabs meets your uptime requirements.
Pro Tips
Error Handling and Retries
HyperWrite and ElevenLabs are reliable, but network errors happen. In n8n, add a "Set" node after each API call to catch and log errors. Configure each HTTP Request node with a retry policy: 3 retries with exponential backoff (starting at 2 seconds). If the workflow fails after 3 retries, send a Slack message to your team alerting them to the failure, including the patient ID and error message.
Example Slack alert configuration:
{
"channel": "#imaging-alerts",
"text": "Workflow failed for patient {{patient_id}}. Error: {{error_message}}. Manual review required."
}
Rate Limits
HyperWrite allows 100 requests per minute on free plans. ElevenLabs allows 50,000 characters per month on free plans. Resemble AI allows 10,000 characters per month on free plans. If you process more than 50 reports per day, upgrade to paid plans immediately. For HyperWrite, a Pro plan ($20/month) gives you unlimited API calls. For ElevenLabs, a Creator plan ($11/month) gives you 100,000 characters per month. For Resemble, a Pro plan ($99/month) gives you 1,000,000 characters per month. Budget accordingly.
Avoiding Duplicate Audio Files
If your workflow runs twice for the same patient ID, you will create duplicate audio files. Add a "Check Database" node before the ElevenLabs step that queries your patient portal database to see if audio already exists for this report. If it does, skip the TTS steps and reuse the existing file. This saves money and time.
Storing API Keys Securely
Never hardcode API keys in your n8n workflow. Use environment variables instead. Set them in your n8n instance settings (Admin > Settings > Environment Variables) and reference them as {{ $env.VARIABLE_NAME }} in your nodes.
Monitoring Workflow Performance
Enable n8n's built-in execution history. After running the workflow on 50 reports, review the logs to identify bottlenecks. Typically, HyperWrite text generation takes 2-3 seconds, ElevenLabs TTS takes 5-10 seconds depending on text length, and Resemble AI takes 10-15 seconds. If any step is slower, check your API tier and consider upgrading.
Cost Breakdown
| Tool | Plan Needed | Monthly Cost | Notes |
|---|---|---|---|
| HyperWrite | Pro | £15 | Unlimited API calls. Text generation for report analysis and patient letter. |
| ElevenLabs | Creator | £9 | 100,000 characters per month. One audio file per report (typically 200-300 characters). Sufficient for 330+ reports monthly. |
| Resemble AI | Pro | £75 | 1,000,000 characters per month. Backup audio. Overkill for most practices but ensures redundancy. |
| n8n | Cloud Pro | £30 | Unlimited workflows and executions. Self-hosted is free but requires DevOps skills. |
| Total | £129 per month | Scales linearly with volume. Cost per report: ~£0.30 for 50 reports/month, ~£0.08 for 500 reports/month. |
If you have fewer than 100 reports per month and cost is a concern, skip Resemble AI (saves £75/month) and use only ElevenLabs. The redundancy is nice but not critical if uptime is acceptable. If you process over 1,000 reports per month, consider self-hosting n8n to save £30/month and negotiate volume discounts with HyperWrite and ElevenLabs.
More Recipes
Automated Podcast Production Workflow
Automated Podcast Production Workflow: From Raw Audio to Published Episode
Build an Automated YouTube Channel with AI
Build an Automated YouTube Channel with AI
Medical device regulatory documentation from technical specifications
Medtech companies spend significant resources translating technical specs into regulatory-compliant documentation.