Transcription Documentation

Medical Transcription API

The Nuxera Medical Transcription API converts audio recordings of medical consultations into accurate text transcripts with structured clinical information. This API uses a chunked processing approach, allowing you to send audio in segments and receive a comprehensive AI Medical Note customized for your medical specialty upon completion.

Key Features

  • Chunked Processing: Send audio in multiple chunks for real-time processing
  • Specialty-Specific Notes: AI Medical Notes tailored to your medical specialty
  • Stateless & Scalable: Each session is tracked but the system remains stateless for easy scaling
  • Privacy-First: No audio data stored, only metadata is retained for accounting
  • HTTPS Required: All data transmission must be over secure HTTPS connections

Endpoint

URL: /api/transcribe

Method: POST

Content-Type: multipart/form-data

Protocol: HTTPS (Required)

Authentication

Include your API key in the x-api-key header:

x-api-key: YOUR_API_KEY

Important: A valid API key is required for all requests. Missing or invalid API keys will return a 401 Unauthorized error.

Processing Flow

  1. First Chunk: Send your initial audio chunk with required parameters
  2. Subsequent Chunks: Send additional audio chunks
  3. Final Chunk: Mark the last chunk with isFinalChunk: true to receive the complete AI Medical Note

Request Parameters

ParameterTypeRequiredDescription
audioFileYesAudio file chunk in WAV or MP3 format (WAV recommended)
specialitystringYesMedical specialty (see /supported-specialities for valid options)
userIdstringNoUnique identifier for the user
doctorNamestringNoName of the doctor conducting the consultation
patientNamestringNoName of the patient (improves accuracy)
patientIdstringNoUnique identifier for the patient
modelstringNoTranscription model to use (default: "new-large")
skipDiarizationstringNoSet to "true" to skip speaker separation (recommended)
removeSilencestringNoSet to "true" to remove silence from audio (recommended)
sessionIdstringNoEmpty for first chunk only. Will be sent for all subsequent chunks.
isFinalChunkstringNoSet to "true" for the last chunk to trigger AI Medical Note generation

Supported Specialities

Get the list of supported specialities and their internal names:

Endpoint: /api/specialities/supported

Method: GET

Authentication

Include your API key in the x-api-key header:

x-api-key: YOUR_API_KEY

Response Example:

{
  "specialities": [
    {
      "value": "general_practice",
      "label": "General Practice",
      "description": "General medical practice covering primary care services"
    },
    {
      "value": "internal_medicine",
      "label": "Internal Medicine",
      "description": "Medical specialty dealing with prevention, diagnosis, and treatment of adult diseases"
    },
    {
      "value": "gynaecology",
      "label": "Gynaecology",
      "description": "Medical specialty focusing on women's reproductive health"
    },
    {
      "value": "emergency",
      "label": "Emergency Medicine",
      "description": "Medical specialty focused on emergency care and acute illnesses"
    },
    {
      "value": "in_patient",
      "label": "In-Patient Care",
      "description": "Medical care provided to patients admitted to a hospital"
    }
  ]
}

Medical Note Generation

Get medical note for transcribed text:

Endpoint: /api/transcribe/medical-note

Method: POST

Content-Type: application/json

Authentication: Include your API key in the x-api-key header:

x-api-key: YOUR_API_KEY

Request Parameters

ParameterTypeRequiredDescription
transcribedTextstringYesTranscribed text which needs medical note.
userIdstringYesUnique identifier for the user
specialitystringYesMedical specialty (see /supported-specialities for valid options)
patientNamestringNoName of the patient (improves accuracy)
doctorNamestringNoName of the doctor conducting the consultation
skipDiarizationstringNoSet to "true" to skip speaker separation (recommended)

Request Example

{
  "transcribedText": "The patient reports persistent headaches and blurry vision over the past two weeks. No signs of fever or nausea. BP measured at 130/85.",
  "userId": "99",
  "speciality": "internal_medicine",
  "patientName": "Alice Johnson",
  "doctorName": "Dr. Raymond Lin",
  "skipDiarization": "true"
}

Response Example

{
  "success": true,
  "classifiedInfo": {
    "ICD-10 Code": ["F48.0"],
    "Chief Complaint": ["Tension-type headache"],
    "History Of Present Illness": [],
    "Current Medications": ["Zithromax", "Multivitamins"],
    "Imaging Results": [],
    "Assessment": ["Possible iron deficiency", "Possible thyroid problem"],
    "Diagnosis": [],
    "Prescriptions": ["Vitamin B", "Panadol"],
    "Plan": [
      "Increase intake of iron-rich foods",
      "Take adequate rest",
      "Follow up in 1 week after blood test"
    ],
    "Follow-up": ["1 week after blood test"]
  },
  "speciality": "internal_medicine",
  "metadata": {
    "patientName": "Alice Johnson",
    "doctorName": "Dr. Raymond Lin",
    "userId": "99",
    "processedAt": "2025-07-01T14:25:36.812Z"
  }
}

cURL Example

curl -X POST 'https://nuxera.cloud/api/tanscribe/medical-note' \
  -H 'Content-Type: application/json' \
  -H 'x-api-key: YOUR_API_KEY' \
  -d '{
  "transcribedText": "The patient reports persistent headaches and blurry vision over the past two weeks. No signs of fever or nausea. BP measured at 130/85.",
  "userId": "99",
  "speciality": "neurology",
  "patientName": "Alice Johnson",
  "doctorName": "Dr. Raymond Lin",
  "skipDiarization": "true"
}'

ICD-10 Code Lookup

Get ICD-10 codes for specific diagnoses or symptoms:

Endpoint: /api/medical-codes/icd-10

Method: POST

Content-Type: application/json

Authentication: Include your API key in the x-api-key header:

x-api-key: YOUR_API_KEY

Request Parameters

ParameterTypeRequiredDescription
diagnosisstringYesThe diagnosis or symptom to get ICD-10 code for

Request Example

{
  "diagnosis": "Type 2 diabetes mellitus, Headache"
}

Response Example

[
  {
    "code": "E11",
    "description": "Type 2 diabetes mellitus"
  }
]

cURL Example

curl -X POST 'https://nuxera.cloud/api/medical-codes/icd-10' \
  -H 'Content-Type: application/json' \
  -H 'x-api-key: YOUR_API_KEY' \
  -d '{
    "diagnosis": "Type 2 diabetes mellitus"
  }'

Response Formats

Intermediate Chunks Response

For non-final chunks, you receive a simple transcription:

{
  "transcription": "Transcripted text",
  "model": "new-large",
  "sessionId": 349,
  "processingTimes": {
    "transcriptionMs": 5113,
    "totalProcessingMs": 5343
  }
}

Final Chunk Response (Complete AI Medical Note)

When isFinalChunk is set to true, you receive the complete AI Medical Note:

{
  "transcription": "Doctor: Hello, how are you feeling today?\nPatient: I've been having severe headaches for the past week, especially in the morning.\nDoctor: I see. Have you noticed any other symptoms along with the headaches?\nPatient: Yes, I sometimes feel nauseous, and bright lights bother me.",
  "labeledText": "Doctor: Hello, how are you feeling today?\nPatient: I've been having severe headaches for the past week, especially in the morning.\nDoctor: I see. Have you noticed any other symptoms along with the headaches?\nPatient: Yes, I sometimes feel nauseous, and bright lights bother me.",
  "classifiedInfo": {
    "speciality": "general_practice",
    "classifiedInfo": {
      "ICD-10 Code": ["F48.0"],
      "Chief Complaint": ["Constant fatigue", "Light sleep", "Decreased appetite"],
      "History Of Present Illness": [],
      "Current Medications": ["Zithromax", "Multivitamins"],
      "Imaging Results": [],
      "Assessment": ["Possible iron deficiency", "Possible thyroid problem"],
      "Diagnosis": [],
      "Prescriptions": ["Vitamin B", "Panadol"],
      "Plan": [
        "Increase intake of iron-rich foods",
        "Take adequate rest",
        "Follow up in 1 week after blood test"
      ],
      "Follow-up": ["1 week after blood test"]
    },
    "generatedAt": "2025-07-08T16:11:37.722Z"
  },
  "model": "new-large",
  "sessionId": 348,
  "processingTimes": {
    "transcriptionMs": 7038,
    "finalChunkProcessingMs": 8035,
    "totalProcessingMs": 15298
  }
}

Response Structure

Processing Times

The final response includes detailed processing metrics:

  • transcriptionMs: Time spent on transcription processing
  • finalChunkProcessingMs: Time spent on final AI analysis
  • totalProcessingMs: Total processing time for the session

Classified Information Structure

FieldDescriptionExample
ICD-10 CodeStandard diagnostic codes["F48.0"]
Chief ComplaintPrimary reasons for visit["Constant fatigue", "Light sleep"]
History Of Present IllnessDetailed symptom history["Patient reports developing symptoms 3 days ago..."]
Current MedicationsActive medications["Zithromax", "Multivitamins"]
Imaging ResultsFindings from any imaging["Chest X-ray shows no acute abnormalities"]
AssessmentClinical evaluation["Possible iron deficiency", "Possible thyroid problem"]
DiagnosisMedical diagnoses["Acute asthma exacerbation"]
PrescriptionsNew medications prescribed["Vitamin B", "Panadol"]
PlanTreatment and next steps["Increase intake of iron-rich foods", "Take adequate rest"]
Follow-upRecommended follow-up timing["1 week after blood test"]

Example Usage

JavaScript - Complete Flow

class NuxeraTranscriber {
  constructor(apiKey) {
    this.apiKey = apiKey;
    this.baseUrl = "https://nuxera.cloud";
    this.currentTranscription = "";
    this.sessionId = null;
  }

  async sendChunk(audioChunk, params, isFinalChunk = false) {
    const formData = new FormData();
    formData.append("audio", audioChunk);
    formData.append("userId", params.userId);
    formData.append("speciality", params.speciality);
    formData.append("doctorName", params.doctorName);

    if (params.patientName) {
      formData.append("patientName", params.patientName);
    }

    if (params.patientId) {
      formData.append("patientId", params.patientId);
    }

    formData.append("skipDiarization", "true");
    formData.append("removeSilence", "true");

    if (isFinalChunk) {
      formData.append("isFinalChunk", "true");
    }

    try {
      const response = await fetch(`${this.baseUrl}/api/transcribe`, {
        method: "POST",
        headers: {
          "x-api-key": this.apiKey,
        },
        body: formData,
      });

      if (!response.ok) {
        if (response.status === 401) {
          throw new Error("Invalid API key");
        }
        const errorData = await response.json();
        throw new Error(errorData.error || "Transcription failed");
      }

      const result = await response.json();

      // Update transcription for next chunk
      this.currentTranscription = result.transcription;
      this.sessionId = result.sessionId;

      return result;
    } catch (error) {
      throw error;
    }
  }

  async getSupportedSpecialities() {
    const response = await fetch(`${this.baseUrl}/api/specialities/supported`, {
      headers: {
        "x-api-key": this.apiKey,
      },
    });

    if (!response.ok) {
      throw new Error("Failed to fetch specialities");
    }

    return await response.json();
  }

  async getICD10Code(diagnosis) {
    const response = await fetch(`${this.baseUrl}/api/medical-codes/icd-10`, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "x-api-key": this.apiKey,
      },
      body: JSON.stringify({ diagnosis }),
    });

    if (!response.ok) {
      if (response.status === 401) {
        throw new Error("Invalid API key");
      }
      const errorData = await response.json();
      throw new Error(errorData.error || "ICD-10 lookup failed");
    }

    return await response.json();
  }
}

// Example usage
async function transcribeConsultation() {
  const transcriber = new NuxeraTranscriber("your-api-key");

  // Get supported specialities
  const specialities = await transcriber.getSupportedSpecialities();
  console.log("Available specialities:", specialities);

  const params = {
    userId: "59",
    speciality: "general_practice",
    doctorName: "Dr. Smith",
    patientName: "John Doe",
    patientId: "32",
  };

  // Send first chunk
  const firstChunk = document.getElementById("audio-chunk-1").files[0];
  const firstResult = await transcriber.sendChunk(firstChunk, params);
  console.log("First chunk transcription:", firstResult.transcription);

  // Send second chunk
  const secondChunk = document.getElementById("audio-chunk-2").files[0];
  const secondResult = await transcriber.sendChunk(secondChunk, params);
  console.log("Updated transcription:", secondResult.transcription);

  // Send final chunk and get AI Medical Note
  const finalChunk = document.getElementById("audio-chunk-3").files[0];
  const finalResult = await transcriber.sendChunk(finalChunk, params, true);

  console.log("Complete AI Medical Note:", finalResult.classifiedInfo);
  console.log("Processing times:", finalResult.processingTimes);

  // Get ICD-10 codes for any diagnoses found
  if (finalResult.classifiedInfo?.classifiedInfo?.Diagnosis?.length > 0) {
    for (const diagnosis of finalResult.classifiedInfo.classifiedInfo.Diagnosis) {
      const icd10Result = await transcriber.getICD10Code(diagnosis);
      console.log(`ICD-10 codes for "${diagnosis}":`, icd10Result.icd10_codes);
    }
  }
}

Python - Complete Flow

import requests

class NuxeraTranscriber:
    def __init__(self, api_key):
        self.api_key = api_key
        self.base_url = 'https://nuxera.cloud'
        self.current_transcription = ''
        self.session_id = None

    def send_chunk(self, audio_file_path, params, is_final_chunk=False):
        """Send an audio chunk for transcription"""

        files = {'audio': open(audio_file_path, 'rb')}

        data = {
            'userId': params['userId'],
            'speciality': params['speciality'],
            'doctorName': params.get('doctorName', ''),
            'skipDiarization': 'true',
            'removeSilence': 'true'
        }

        if params.get('patientName'):
            data['patientName'] = params['patientName']

        if params.get('patientId'):
            data['patientId'] = params['patientId']

        if is_final_chunk:
            data['isFinalChunk'] = 'true'

        headers = {'x-api-key': self.api_key}

        response = requests.post(
            f'{self.base_url}/api/transcribe',
            headers=headers,
            files=files,
            data=data
        )

        if response.status_code == 401:
            raise Exception('Invalid API key')
        elif response.status_code != 200:
            error_data = response.json()
            raise Exception(error_data.get('error', 'Transcription failed'))

        result = response.json()

        # Update transcription for next chunk
        self.current_transcription = result['transcription']
        self.session_id = result.get('sessionId')

        return result

    def get_supported_specialities(self):
        """Get list of supported medical specialities"""
        response = requests.get(
            f'{self.base_url}/supported-specialities',
            headers={'x-api-key': self.api_key}
        )

        if response.status_code != 200:
            raise Exception('Failed to fetch specialities')

        return response.json()

    def get_icd10_code(self, diagnosis):
        """Get ICD-10 codes for a specific diagnosis"""
        response = requests.post(
            f'{self.base_url}/api/medical-codes/icd-10',
            headers={
                'Content-Type': 'application/json',
                'x-api-key': self.api_key
            },
            json={'diagnosis': diagnosis}
        )

        if response.status_code == 401:
            raise Exception('Invalid API key')
        elif response.status_code != 200:
            error_data = response.json()
            raise Exception(error_data.get('error', 'ICD-10 lookup failed'))

        return response.json()

# Example usage
def transcribe_consultation():
    transcriber = NuxeraTranscriber('your-api-key')

    # Get supported specialities
    specialities = transcriber.get_supported_specialities()
    print('Available specialities:', specialities)

    params = {
        'userId': '59',
        'speciality': 'general_practice',
        'doctorName': 'Dr. Smith',
        'patientName': 'John Doe',
        'patientId': '32'
    }

    try:
        # Send first chunk
        first_result = transcriber.send_chunk('./chunk1.wav', params)
        print('First chunk transcription:', first_result['transcription'])

        # Send second chunk
        second_result = transcriber.send_chunk('./chunk2.wav', params)
        print('Updated transcription:', second_result['transcription'])

        # Send final chunk and get AI Medical Note
        final_result = transcriber.send_chunk('./chunk3.wav', params, is_final_chunk=True)

        print('Complete AI Medical Note:', final_result['classifiedInfo'])
        print('Processing times:', final_result['processingTimes'])

        # Get ICD-10 codes for any diagnoses found
        if final_result.get('classifiedInfo', {}).get('classifiedInfo', {}).get('Diagnosis'):
            for diagnosis in final_result['classifiedInfo']['classifiedInfo']['Diagnosis']:
                icd10_result = transcriber.get_icd10_code(diagnosis)
                print(f'ICD-10 codes for "{diagnosis}":', icd10_result['icd10_codes'])

    except Exception as e:
        print(f'Error: {str(e)}')

if __name__ == '__main__':
    transcribe_consultation()

cURL - Example Requests

# Get supported specialities
curl -X GET 'https://nuxera.cloud/supported-specialities' \
  -H 'x-api-key: YOUR_API_KEY'

# Send first chunk
curl -X POST 'https://nuxera.cloud/api/transcribe' \
  -H 'x-api-key: YOUR_API_KEY' \
  -F 'audio=@chunk1.wav' \
  -F 'userId=59' \
  -F 'speciality=general_practice' \
  -F 'doctorName=Dr. Smith' \
  -F 'patientName=John Doe' \
  -F 'skipDiarization=true' \
  -F 'removeSilence=true'

# Send subsequent chunk with previous transcription
curl -X POST 'https://nuxera.cloud/api/transcribe' \
  -H 'x-api-key: YOUR_API_KEY' \
  -F 'audio=@chunk2.wav' \
  -F 'userId=59' \
  -F 'speciality=general_practice' \
  -F 'doctorName=Dr. Smith' \
  -F 'skipDiarization=true' \
  -F 'removeSilence=true'

# Send final chunk to get AI Medical Note
curl -X POST 'https://nuxera.cloud/api/transcribe' \
  -H 'x-api-key: YOUR_API_KEY' \
  -F 'audio=@chunk3.wav' \
  -F 'userId=59' \
  -F 'speciality=general_practice' \
  -F 'doctorName=Dr. Smith' \
  -F 'isFinalChunk=true' \
  -F 'skipDiarization=true' \
  -F 'removeSilence=true'

Privacy & Security

  • HTTPS Required: All API calls must be made over HTTPS
  • No Data Storage: Audio data is not stored on our servers
  • Metadata Only: Only session metadata is retained for accounting purposes
  • Stateless Design: Each session is independent, allowing for easy scaling
  • Session Tracking: Every chunk and session is accounted for billing and monitoring

Best Practices

  1. Audio Quality

    • Record in a quiet environment with minimal background noise
    • Use good quality microphone positioned close to speakers
    • Aim for clear speech with minimal overlapping conversation
    • Prefer WAV format over MP3 for best transcription accuracy (lossless vs. compressed)
  2. Chunking Strategy

    • Send audio in logical segments (e.g., every 30-60 seconds)
    • Ensure chunks contain complete sentences when possible
    • Mark the final chunk accurately to trigger AI Medical Note generation
  3. Specialty Selection

    • Always check /api/specialities/supported for current options
    • Use the correct value for the specialty parameter
    • Choose the most specific specialty for best results
  4. Error Handling

    • Always check for 401 errors indicating invalid API keys
    • Implement retry logic for network failures
    • Validate API responses before processing

Error Handling

Error CodeDescriptionResolution
401Invalid API keyCheck that x-api-key header contains valid API key
400Missing required fieldsEnsure all required parameters are included
400Invalid audio formatUpload audio in WAV or MP3 format
400Invalid specialtyCheck /supported-specialities for valid options
413Audio file too largeReduce chunk size or split recording further
500Transcription failedCheck audio quality and try again

Limitations

  • Maximum audio chunk size: 25MB per request
  • Maximum session length: 120 minutes total
  • Supported languages: English and Arabic, with Urdu and Hindi in development
  • Supported audio formats: WAV and MP3 (WAV recommended for lossless quality and wide compatibility)
  • API rate limits apply (contact support for details)

Next Steps

Continue to the Dictation API documentation to learn about specialized medical dictation processing.