Skip to main content
The Clinical Documentation Workflow API provides a comprehensive solution for managing patient-doctor conversation transcriptions, AI-powered clinical note extraction, and structured clinical documentation.

Workflow Overview

The clinical documentation workflow consists of three main stages:
  1. Create Transcription - Store raw audio-to-text transcription from patient-doctor conversations
  2. Create Thread & Execute Runs - Process transcriptions with AI to extract clinical information
  3. Update Clinical Notes - Store and manage AI-generated clinical documentation

1. Create Transcription

Endpoint

POST https://{your_api_url}/v1/transcriptions/create

Purpose

Creates a new transcription record for audio-to-text conversion from patient-doctor conversations. This is the first step in the clinical documentation workflow - stores the raw transcription before AI processing.

Required headers

Content-Type: application/json
Authorization: Bearer YOUR_API_KEY
x-doctor: dr_123

Optional headers

x-patient: pt_456

Request body

{
  "duration_seconds": 180,
  "original_transcript": "The patient is a 45-year-old male presenting with chest pain radiating to left arm for the past 2 hours. Pain started while climbing stairs. No previous cardiac history. Vital signs: BP 140/90, HR 88, RR 18, O2 sat 98% on room air.",
  "language_used": "en"
}

Request fields

FieldTypeRequiredDescription
duration_secondsnumberYesDuration of the recording in seconds (min: 0)
original_transcriptstringYesThe transcribed text from the conversation
language_usedstringNoLanguage code (e.g., ‘en’, ‘es’, ‘fr’)

Success response (HTTP 201)

{
  "message": "Transcription created successfully",
  "transcription": {
    "id": "trans_abc123xyz",
    "user_id": "usr_123456789",
    "group_id": "grp_987654321",
    "duration_seconds": 180,
    "language_used": "en",
    "original_transcript": "The patient is a 45-year-old male...",
    "created_at": "2023-10-09T10:00:00.000Z",
    "updated_at": "2023-10-09T10:00:00.000Z"
  }
}

Example - Python

import requests

url = "https://{your_api_url}/v1/transcriptions/create"
headers = {
    "Authorization": "Bearer YOUR_TOKEN",
    "Content-Type": "application/json",
    "x-doctor": "dr_123",  # REQUIRED
    "x-patient": "pt_456"  # OPTIONAL
}

payload = {
    "duration_seconds": 180,
    "original_transcript": "The patient is a 45-year-old male presenting with chest pain...",
    "language_used": "en"
}

response = requests.post(url, json=payload, headers=headers)
result = response.json()

print(f"Transcription created: {result['transcription']['id']}")

Example - JavaScript

const axios = require('axios');

const url = 'https://{your_api_url}/v1/transcriptions/create';
const headers = {
  'Authorization': 'Bearer YOUR_TOKEN',
  'Content-Type': 'application/json',
  'x-doctor': 'dr_123',   // REQUIRED
  'x-patient': 'pt_456'   // OPTIONAL
};

const payload = {
  duration_seconds: 180,
  original_transcript: 'The patient is a 45-year-old male presenting with chest pain...',
  language_used: 'en'
};

axios.post(url, payload, { headers })
  .then(response => {
    console.log('Transcription created:', response.data.transcription.id);
  })
  .catch(error => {
    console.error('Error:', error.response?.data || error.message);
  });

2. Create Conversation Thread

Endpoint

POST https://{your_api_url}/v1/lang-graph/threads

Purpose

Creates a new conversation thread for AI-powered interactions (chat or clinical extraction). Initializes a stateful conversation session with the AI assistant. The thread maintains context across multiple interactions and is required before executing any conversation runs.

Required headers

Content-Type: application/json
Authorization: Bearer YOUR_API_KEY
x-doctor: dr_123

Optional headers

x-patient: pt_456

Request body

No request body required (empty POST).
{}

Success response (HTTP 201)

{
  "thread_id": "thread-abc123",
  "created_at": "2023-10-09T10:00:00.000Z",
  "status": "active"
}

Example - Python

import requests

url = "https://{your_api_url}/v1/lang-graph/threads"
headers = {
    "Authorization": "Bearer YOUR_TOKEN",
    "Content-Type": "application/json",
    "x-doctor": "dr_123",  # REQUIRED
    "x-patient": "pt_456"  # OPTIONAL
}

response = requests.post(url, json={}, headers=headers)
result = response.json()

print(f"Thread created: {result['thread_id']}")

Example - JavaScript

const axios = require('axios');

const url = 'https://{your_api_url}/v1/lang-graph/threads';
const headers = {
  'Authorization': 'Bearer YOUR_TOKEN',
  'Content-Type': 'application/json',
  'x-doctor': 'dr_123',   // REQUIRED
  'x-patient': 'pt_456'   // OPTIONAL
};

axios.post(url, {}, { headers })
  .then(response => {
    console.log('Thread created:', response.data.thread_id);
  })
  .catch(error => {
    console.error('Error:', error.response?.data || error.message);
  });

3. Execute Conversation Run

Endpoint

POST https://{your_api_url}/v1/lang-graph/threads/{threadId}/runs

Purpose

Executes a conversation run within an existing thread to process AI interactions. This is the core AI processing endpoint - sends messages to the AI assistant and initiates processing. Used for both real-time chat interactions and clinical note extraction from transcriptions. The run executes asynchronously and can be monitored via the join endpoint.

Required headers

Content-Type: application/json
Authorization: Bearer YOUR_API_KEY
x-doctor: dr_123

Optional headers

x-is-chat: true      (Boolean flag: true = chat/scribe, false = extraction)
x-patient: pt_456    (Patient identifier for tracking and auditing)

Path parameters

ParameterTypeRequiredDescription
threadIdstringYesThe thread identifier to execute the run in

Request body

{
  "input": {
    "messages": [
      {
        "role": "user",
        "content": "Hello, how can you help me today?"
      }
    ]
  },
  "config": {
    "configurable": {
      "thread_id": "thread-abc123"
    }
  }
}

Request fields

FieldTypeRequiredDescription
input.messagesarrayYesArray of conversation messages
input.messages[].rolestringYesRole of message sender (user, assistant, system)
input.messages[].contentstringYesMessage content
config.configurable.thread_idstringYesThread identifier for this run

Success response (HTTP 201)

{
  "run_id": "run-xyz789",
  "thread_id": "thread-abc123",
  "status": "pending",
  "created_at": "2023-10-09T10:00:00.000Z"
}

Example - Clinical extraction

import requests

base_headers = {
    "Authorization": "Bearer YOUR_TOKEN",
    "Content-Type": "application/json",
    "x-doctor": "dr_123",  # REQUIRED
    "x-patient": "pt_456"  # OPTIONAL
}

# First, create a thread
thread_url = "https://{your_api_url}/v1/lang-graph/threads"
thread_response = requests.post(thread_url, json={}, headers=base_headers)
thread_id = thread_response.json()['thread_id']

# Execute a run for clinical extraction (x-is-chat: false)
run_url = f"https://{your_api_url}/v1/lang-graph/threads/{thread_id}/runs"
run_headers = {
    **base_headers,
    "x-is-chat": "false"  # false = clinical extraction
}

payload = {
    "input": {
        "messages": [
            {
                "role": "user",
                "content": "Extract clinical information from: Patient reports chest pain radiating to left arm..."
            }
        ]
    },
    "config": {
        "configurable": {
            "thread_id": thread_id
        }
    }
}

response = requests.post(run_url, json=payload, headers=run_headers)
result = response.json()

print(f"Run created: {result['run_id']}")
print(f"Status: {result['status']}")

Example - Chat interaction

const axios = require('axios');

// Create thread first
const threadUrl = 'https://{your_api_url}/v1/lang-graph/threads';

const baseHeaders = {
  'Authorization': 'Bearer YOUR_TOKEN',
  'Content-Type': 'application/json',
  'x-doctor': 'dr_123',   // REQUIRED
  'x-patient': 'pt_456'   // OPTIONAL
};

const threadResponse = await axios.post(threadUrl, {}, { headers: baseHeaders });
const threadId = threadResponse.data.thread_id;

// Execute a chat run (x-is-chat: true)
const runUrl = `https://{your_api_url}/v1/lang-graph/threads/${threadId}/runs`;
const runHeaders = {
  ...baseHeaders,
  'x-is-chat': 'true'  // true = chat/scribe mode
};

const payload = {
  input: {
    messages: [
      {
        role: 'user',
        content: 'Hello, how can you help me today?'
      }
    ]
  },
  config: {
    configurable: {
      thread_id: threadId
    }
  }
};

axios.post(runUrl, payload, { headers: runHeaders })
  .then(response => {
    console.log('Run created:', response.data.run_id);
    console.log('Status:', response.data.status);
  })
  .catch(error => {
    console.error('Error:', error.response?.data || error.message);
  });

4. Update Clinical Note

Endpoint

PATCH https://{your_api_url}/v1/clinical-notes/{id}

Purpose

Updates an existing clinical note with AI-generated content, feedback, or metadata. Used to store AI-generated clinical documentation, link to conversation threads, and capture user feedback for quality improvement.

Required headers

Content-Type: application/json
Authorization: Bearer YOUR_API_KEY
x-doctor: dr_123

Optional headers

x-patient: pt_456

Path parameters

ParameterTypeRequiredDescription
idstring (UUID)YesThe clinical note UUID

Request body

All fields are optional - update only what’s needed:
{
  "template": "SOAP",
  "ai_generated_content": {
    "subjective": "Patient reports chest pain radiating to left arm",
    "objective": "BP 140/90, HR 88, RR 18, O2 sat 98% on RA",
    "assessment": "R/O myocardial infarction",
    "plan": "Admit to CCU, serial troponins, cardiology consult"
  },
  "feedback": "Well structured note",
  "report_thread_id": "thread_xyz789",
  "report_run_id": ["run_001", "run_002"]
}

Request fields

FieldTypeRequiredDescription
templatestringNoClinical note format (SOAP, BIRP, DAP, GIRP)
ai_generated_contentobjectNoStructured clinical data (schema varies by template)
feedbackstringNoUser comments or feedback on the note
report_thread_idstringNoThread ID that generated this content
report_run_idarrayNoArray of run IDs involved in generating content

Success response (HTTP 200)

{
  "id": "note_def456ghi",
  "user_id": "usr_123456789",
  "group_id": "grp_987654321",
  "transcription_id": "trans_abc123xyz",
  "template": "SOAP",
  "ai_generated_content": {
    "subjective": "Patient reports chest pain radiating to left arm",
    "objective": "BP 140/90, HR 88, RR 18, O2 sat 98% on RA",
    "assessment": "R/O myocardial infarction",
    "plan": "Admit to CCU, serial troponins, cardiology consult"
  },
  "feedback": "Well structured note",
  "report_thread_id": "thread_xyz789",
  "report_run_id": ["run_001", "run_002"],
  "created_at": "2023-10-09T10:00:00.000Z",
  "updated_at": "2023-10-09T10:05:00.000Z"
}

Example - Python

import requests

note_id = "note_def456ghi"
url = f"https://{your_api_url}/v1/clinical-notes/{note_id}"
headers = {
    "Authorization": "Bearer YOUR_TOKEN",
    "Content-Type": "application/json",
    "x-doctor": "dr_123",  # REQUIRED
    "x-patient": "pt_456"  # OPTIONAL
}

payload = {
    "template": "SOAP",
    "ai_generated_content": {
        "subjective": "Patient reports chest pain radiating to left arm",
        "objective": "BP 140/90, HR 88, RR 18, O2 sat 98% on RA",
        "assessment": "R/O myocardial infarction",
        "plan": "Admit to CCU, serial troponins, cardiology consult"
    },
    "feedback": "Well structured note",
    "report_thread_id": "thread_xyz789",
    "report_run_id": ["run_001", "run_002"]
}

response = requests.patch(url, json=payload, headers=headers)
result = response.json()

print(f"Clinical note updated: {result['id']}")
print(f"Template: {result['template']}")

Example - JavaScript

const axios = require('axios');

const noteId = 'note_def456ghi';
const url = `https://{your_api_url}/v1/clinical-notes/${noteId}`;
const headers = {
  'Authorization': 'Bearer YOUR_TOKEN',
  'Content-Type': 'application/json',
  'x-doctor': 'dr_123',   // REQUIRED
  'x-patient': 'pt_456'   // OPTIONAL
};

const payload = {
  template: 'SOAP',
  ai_generated_content: {
    subjective: 'Patient reports chest pain radiating to left arm',
    objective: 'BP 140/90, HR 88, RR 18, O2 sat 98% on RA',
    assessment: 'R/O myocardial infarction',
    plan: 'Admit to CCU, serial troponins, cardiology consult'
  },
  feedback: 'Well structured note',
  report_thread_id: 'thread_xyz789',
  report_run_id: ['run_001', 'run_002']
};

axios.patch(url, payload, { headers })
  .then(response => {
    console.log('Clinical note updated:', response.data.id);
    console.log('Template:', response.data.template);
  })
  .catch(error => {
    console.error('Error:', error.response?.data || error.message);
  });

Complete Workflow Example

Here’s a complete example of the entire clinical documentation workflow:

Python - Complete workflow

import requests

BASE_URL = "https://{your_api_url}"
headers = {
    "Authorization": "Bearer YOUR_TOKEN",
    "Content-Type": "application/json",
    "x-doctor": "dr_123",  # REQUIRED
    "x-patient": "pt_456"  # OPTIONAL
}

# Step 1: Create transcription
transcription_data = {
    "duration_seconds": 180,
    "original_transcript": "The patient is a 45-year-old male presenting with chest pain...",
    "language_used": "en"
}

transcription_response = requests.post(
    f"{BASE_URL}/v1/transcriptions/create",
    json=transcription_data,
    headers=headers
)
transcription = transcription_response.json()
transcription_id = transcription['transcription']['id']
print(f"✅ Step 1: Transcription created: {transcription_id}")

# Step 2: Create thread
thread_response = requests.post(
    f"{BASE_URL}/v1/lang-graph/threads",
    json={},
    headers=headers
)
thread = thread_response.json()
thread_id = thread['thread_id']
print(f"✅ Step 2: Thread created: {thread_id}")

# Step 3: Execute run for clinical extraction
run_headers = {
    **headers,
    "x-is-chat": "false"  # Clinical extraction mode
}

run_data = {
    "input": {
        "messages": [
            {
                "role": "user",
                "content": f"Extract clinical information: {transcription_data['original_transcript']}"
            }
        ]
    },
    "config": {
        "configurable": {
            "thread_id": thread_id
        }
    }
}

run_response = requests.post(
    f"{BASE_URL}/v1/lang-graph/threads/{thread_id}/runs",
    json=run_data,
    headers=run_headers
)
run = run_response.json()
run_id = run['run_id']
print(f"✅ Step 3: Run executed: {run_id}")

# Step 4: Update clinical note (assuming note_id exists)
note_id = "note_def456ghi"  # This would be created elsewhere
note_data = {
    "template": "SOAP",
    "ai_generated_content": {
        "subjective": "Patient reports chest pain radiating to left arm",
        "objective": "BP 140/90, HR 88, RR 18, O2 sat 98% on RA",
        "assessment": "R/O myocardial infarction",
        "plan": "Admit to CCU, serial troponins, cardiology consult"
    },
    "report_thread_id": thread_id,
    "report_run_id": [run_id]
}

note_response = requests.patch(
    f"{BASE_URL}/v1/clinical-notes/{note_id}",
    json=note_data,
    headers=headers
)
note = note_response.json()
print(f"✅ Step 4: Clinical note updated: {note['id']}")
print(f"\n🎉 Workflow complete!")

Supported Clinical Templates

The template field in clinical notes supports multiple formats:

SOAP (Subjective, Objective, Assessment, Plan)

{
  "subjective": "Patient's reported symptoms and history",
  "objective": "Physical examination findings and vital signs",
  "assessment": "Clinical diagnosis or impression",
  "plan": "Treatment plan and follow-up"
}

BIRP (Behavior, Intervention, Response, Plan)

{
  "behavior": "Observed patient behaviors",
  "intervention": "Actions taken by healthcare provider",
  "response": "Patient's response to intervention",
  "plan": "Future treatment plan"
}

DAP (Data, Assessment, Plan)

{
  "data": "Objective and subjective data gathered",
  "assessment": "Clinical assessment and diagnosis",
  "plan": "Treatment and follow-up plan"
}

Custom Templates

You can also use custom templates based on your organization’s requirements. The ai_generated_content field accepts any valid JSON object structure.

Error Handling

Common errors

CodeErrorDescriptionSolution
400Bad RequestMissing required fields or invalid dataVerify all required fields are provided
401UnauthorizedInvalid or expired tokenCheck your Bearer token
404Not FoundThread or clinical note not foundVerify the ID exists
500Internal Server ErrorServer errorRetry with exponential backoff

Error response format

{
  "success": false,
  "error": "Bad Request",
  "details": "duration_seconds and original_transcript are required"
}

Next steps