Node.js SDK for Cariva ASR
npm install @cariva/asr-sdk-node





Professional medical transcription SDK for Node.js server applications
A professional Node.js SDK for medical speech recognition in server environments. Purpose-built for
healthcare workflows with specialized medical vocabulary, file system integration, and secure
processing.
- Medical-First Design - SOAP notes, clinical records, and nursing documentation
- Server-Side Processing - File system integration with batch processing capabilities
- High Performance - Optimized audio compression and server-side processing
- Universal Audio Support - All major audio formats with automatic optimization
- Production Ready - Built for scalable server environments and enterprise workflows
- TypeScript Ready - Full type safety and comprehensive error handling
``bashnpm
npm install @cariva/asr-sdk-node
Requirements
- Node.js: >= 20.0.0
- FFmpeg: Optional (for advanced audio processing)
🚀 Quick Start
$3
`typescript
import { ASR, type AsrResponseMap } from '@cariva/asr-sdk-node';// Initialize with your credentials
const asr = new ASR({
key: process.env.CARIVA_API_KEY!, // Use environment variables
secret: process.env.CARIVA_API_SECRET!,
mode: 'doc-ipd-soap',
lang: 'en',
specialty: 'gen-practitioner', // Default specialty
});
// Process audio file from file system
const processAudioFile = async (audioPath: string) => {
try {
// Process with comprehensive callbacks
const result = await asr.process(audioPath, {
onProcessing: step => {
console.log(
Processing: ${step});
// Steps: "Creating transcription task..." -> "Uploading audio file..." -> "Processing audio..."
},
}); // Type-safe access to structured medical data
console.log('Medical data:', result);
return result;
} catch (error) {
console.error('ASR error:', error);
throw error;
}
};
// Example usage
await processAudioFile('./consultation-recording.wav');
`$3
`typescript
import fs from 'fs';
import path from 'path';const processBatch = async (audioDir: string) => {
const audioFiles = fs
.readdirSync(audioDir)
.filter(file => /\.(mp3|wav)$/i.test(file))
.map(file => path.join(audioDir, file));
const results = [];
for (const filePath of audioFiles) {
console.log(
Processing: ${path.basename(filePath)}); try {
const result = await asr.process(filePath);
results.push({ file: filePath, result });
} catch (error) {
console.error(
Failed to process ${filePath}:, error.message);
}
} return results;
};
`$3
`typescript
import express from 'express';
import multer from 'multer';
import { ASR } from '@cariva/asr-sdk-node';const app = express();
const upload = multer({ dest: 'uploads/' });
// Initialize ASR for different specialties
const asrInstances = {
cardiology: new ASR({
key: process.env.CARIVA_API_KEY!,
secret: process.env.CARIVA_API_SECRET!,
mode: 'doc-ipd-soap',
specialty: 'med-cardio',
}),
general: new ASR({
key: process.env.CARIVA_API_KEY!,
secret: process.env.CARIVA_API_SECRET!,
mode: 'doc-ipd-soap',
specialty: 'gen-practitioner',
}),
};
app.post('/transcribe/:specialty', upload.single('audio'), async (req, res) => {
try {
const { specialty } = req.params;
const asr = asrInstances[specialty] || asrInstances.general;
const result = await asr.process(req.file.path);
res.json({ success: true, data: result });
} catch (error) {
res.status(500).json({ success: false, error: error.message });
}
});
`Medical Modes
The SDK provides specialized transcription modes optimized for different healthcare workflows:
📋 SOAP Notes (doc-ipd-soap)
Best for: Physician documentation, clinical assessments
`typescript
const result: {
fastTranscription: string; // Raw speech-to-text transcription
subjective?: string; // Patient's reported symptoms and history
objective?: string; // Clinical findings and observations
assessment?: string; // Medical diagnosis and impressions
plan?: string; // Treatment plan and follow-up
} = await asr.process('./consultation.wav');
`Use cases: Hospital rounds, consultation notes, diagnostic evaluations
🏥 OPD Clinical Record (doc-opd-clinicalrecord)
Best for: Outpatient consultations, comprehensive examinations
`typescript
const result: {
chiefComplaint: string;
diagnosis: string;
familyHistory: string;
fastTranscription: string;
pastMedicalHistory: string;
physicalExamination: {
generalAppearance: string;
heent: string;
cardiovascular: string;
respiratory: string;
gastrointestinal: string;
neurological: string;
other: string;
vitalSign: string;
};
plan: string;
presentIllness: string;
rawNote: string;
treatment: string;
investigation: string;
} = await asr.process('./opd-consultation.wav');
`Use cases: Outpatient visits, specialist consultations, routine check-ups
👩⚕️ Nursing Notes - FAIE Start (nur-opd-nursenote-faie-start)
Best for: Beginning of shift assessments, patient handoffs
`typescript
const result: {
focus: string;
assessment: string;
intervention: string;
fastTranscription: string;
rawNote: string;
vitalSigns: {
heartRate: string;
respiratoryRate: string;
bloodPressure: string;
bodyTemperature: string;
oxygenSaturation: string;
};
} = await asr.process('./nursenote-faie-start.wav');
`Use cases: Shift handoffs, initial patient assessments, care planning
👩⚕️ Nursing Notes - FAIE End (nur-opd-nursenote-faie-end)
Best for: End of shift summaries, patient status updates
`typescript
const result: {
evaluation: string;
fastTranscription: string;
rawNote: string;
vitalSigns: {
heartRate: string;
respiratoryRate: string;
bloodPressure: string;
bodyTemperature: string;
oxygenSaturation: string;
};
} = await asr.process('./nursenote-faie-end.wav');
`Use cases: Shift summaries, patient status reports, care continuity
👩⚕️ Nursing Notes - ADPIE Start (nur-opd-nursenote-adpie-start)
Best for: Beginning of shift assessments, patient handoffs
`typescript
const result: {
fastTranscription: string;
rawNote: string;
assessment: {
objective: string;
subjective: string;
};
diagnosis: string;
planning: string;
intervention: string;
} = await asr.process('./nursenote-adpie-start.wav');
`Use cases: Shift handoffs, initial patient assessments, care planning
👩⚕️ Nursing Notes - ADPIE End (nur-opd-nursenote-adpie-end)
Best for: End of shift summaries, patient status updates
`typescript
const result: {
fastTranscription: string;
rawNote: string;
evaluation: string;
} = await asr.process('./nursenote-adpie-end.wav');
`Use cases: Shift summaries, patient status reports, care continuity
Medical Specialties
Improve transcription accuracy by up to 35% with specialty-specific medical vocabulary:
`typescript
const cardiologyASR = new ASR({
key: process.env.CARIVA_API_KEY!,
secret: process.env.CARIVA_API_SECRET!,
mode: 'doc-ipd-soap',
specialty: 'med-cardio', // Optimized for cardiology terminology
});
`$3
| Specialty | Code | Best For |
| ------------------------ | ------------------ | ------------------------------------ |
| General Practitioner |
gen-practitioner | Family medicine, routine checkups |
| General Medicine | gen-med | Internal medicine, hospitalist notes |
| Emergency Medicine | emergency | Trauma, urgent care, triage |
| General Pediatrics | gen-ped | Children's healthcare |$3
| Specialty | Code | Best For |
| --------------- | --------------- | ------------------------------------- |
| Cardiology |
med-cardio | Cardiac procedures, heart conditions |
| Pulmonology | med-pulmonary | Respiratory conditions, lung function |$3
| Specialty | Code | Best For |
| -------------------- | ------------ | ------------------------------------------ |
| Gastroenterology |
med-gastro | GI procedures, digestive disorders |
| Neurology | med-neuro | Neurological assessments, brain conditions |
| Nephrology | med-nephro | Kidney conditions, dialysis |
| Oncology | med-onco | Cancer treatment, oncology consultations |$3
| Specialty | Code | Best For |
| --------------------------- | ---------------- | ------------------------------------------ |
| General Surgery |
surgery | Surgical procedures, operative notes |
| Orthopedic | orthopedic | Bone, joint, and muscle conditions |
| Dermatology | med-skin | Skin conditions, dermatological procedures |
| Ophthalmology | ophthalmology | Eye conditions, vision care |
| Otolaryngology | otolaryngology | ENT procedures, hearing, speech |
| Obstetrics & Gynecology | ob-gyn | Women's health, pregnancy, childbirth |> 💡 Pro Tip: Choose the most specific specialty for your use case to maximize transcription
> accuracy.
📖 API Reference
$3
`typescript
interface ASRConfig {
key: string; // Required: Your Cariva API key
secret: string; // Required: Your Cariva API secret
mode: Mode; // Required: Transcription mode
lang?: string; // Optional: Language (default: 'en')
specialty?: MedicalSpecialty; // Optional: Medical specialty (default: 'gen-practitioner')
timeout?: number; // Optional: Request timeout in ms (default: 300000)
}// Usage
const asr = new ASR({
key: process.env.CARIVA_API_KEY!,
secret: process.env.CARIVA_API_SECRET!,
mode: 'doc-ipd-soap',
lang: 'en',
specialty: 'med-cardio',
timeout: 300000, // 5 minutes
});
`$3
`typescript
async process(
filePath: string, // Path to audio file
options?: {
onProcessing?: (step: string) => void; // Processing callback
}
): Promise
`$3
`typescript
interface ProcessOptions {
onProcessing?: (step: string) => void; // Optional: Processing step callback
}// Processing steps you'll receive:
// - "Creating transcription task..."
// - "Uploading audio file..."
// - "Processing audio..."
`$3
`typescript
// Fully typed responses based on selected mode
type AsrResponseMap = {
'doc-ipd-soap': {
data: {
fastTranscription: string;
subjective?: string;
objective?: string;
assessment?: string;
plan?: string;
};
};
'doc-opd-clinicalrecord': {
data: {
chiefComplaint: string;
diagnosis: string;
familyHistory: string;
fastTranscription: string;
pastMedicalHistory: string;
physicalExamination: {
generalAppearance: string;
heent: string;
cardiovascular: string;
respiratory: string;
gastrointestinal: string;
neurological: string;
other: string;
vitalSign: string;
};
plan: string;
presentIllness: string;
rawNote: string;
treatment: string;
investigation: string;
};
};
// ... other modes
};
`$3
`typescript
// Main processing method
async process(file: string | File | Blob, options?: NodeProcessOptions): Promise// Cancel ongoing transcription
async cancelASRTask(): Promise
// Rate transcription quality (1-5 scale with optional comment and categories)
async rateASRTask(score: number, comment?: string, categories?: string[]): Promise
// Initialize ASR instance
async create(): Promise
// Clear task state
clearTask(): void
// Getters for current state
readonly taskId: string // Current task ID (empty until processing starts)
readonly status: string // Current processing status
readonly isProcessing: boolean // Whether currently processing
`Audio Support
$3
- Audio: WAV, MP3, MP4, M4A, OGG, AAC, FLAC
- File System: Direct file path processing
- Compression: Server-side optimization using node-lame
$3
- Server-side audio compression reduces file size automatically
- Real-time progress tracking during upload
$3
`typescript
// The SDK automatically handles:
// - Format validation
// - Audio compression (MP3 encoding)
// - Duration detection
// - Progress trackingconst result = await asr.process('./consultation.wav', {
onProcessing: step => {
console.log(
Processing: ${step});
// Steps: "Creating transcription task..." -> "Uploading audio file..." -> "Processing audio..."
},
});
`Server Features
$3
`typescript
import fs from 'fs';
import path from 'path';// Process multiple files
const audioDir = './recordings/';
const files = fs
.readdirSync(audioDir)
.filter(file => file.endsWith('.mp3') || file.endsWith('.wav') || file.endsWith('.m4a'));
for (const file of files) {
const filePath = path.join(audioDir, file);
console.log(
Processing: ${file}); try {
const result = await asr.process(filePath, {
onProcessing: step => console.log(
${file}: ${step}),
}); // Save results
const outputPath = path.join('./results/',
${path.parse(file).name}.json);
fs.writeFileSync(outputPath, JSON.stringify(result, null, 2));
} catch (error) {
console.error(Failed to process ${file}:, error.message);
}
}
`$3
`typescript
import fs from 'fs';// Get file information before processing
const audioPath = './consultation.wav';
const stats = fs.statSync(audioPath);
console.log(
File size: ${(stats.size / 1024 / 1024).toFixed(2)} MB);
console.log(Processing: ${audioPath});const result = await asr.process(audioPath);
`Usage Examples
$3
`typescript
import { ASR } from '@cariva/asr-sdk-node';const asr = new ASR({
key: process.env.CARIVA_API_KEY!,
secret: process.env.CARIVA_API_SECRET!,
mode: 'doc-ipd-soap',
specialty: 'med-cardio',
});
`$3
`javascript
const { ASR } = require('@cariva/asr-sdk-node');const asr = new ASR({
key: process.env.CARIVA_API_KEY,
secret: process.env.CARIVA_API_SECRET,
mode: 'doc-ipd-soap',
specialty: 'gen-practitioner',
});
`$3
`typescript
import { ASR, type AsrResponseMap } from '@cariva/asr-sdk-node';const asr = new ASR({
key: process.env.CARIVA_API_KEY!,
secret: process.env.CARIVA_API_SECRET!,
mode: 'doc-ipd-soap',
specialty: 'med-cardio',
});
// Fully typed result
const result: AsrResponseMap['doc-ipd-soap']['data'] = await asr.process('./audio.wav');
`Progress Tracking
Monitor the transcription process with detailed callbacks:
`typescript
const result = await asr.process('./consultation.wav', {
onProcessing: step => {
// Processing steps
console.log(Step: ${step});
// Possible steps:
// - "Creating transcription task..."
// - "Uploading audio file..."
// - "Processing audio..."
},
});
`Error Handling
`typescript
import { AsrError } from '@cariva/asr-sdk-node';try {
const result = await asr.process('./audio.wav');
} catch (error) {
if (error instanceof AsrError) {
console.error(
ASR Error [${error.code}]:, error.message);
console.error('Status:', error.status);
console.error('Details:', error.details); // Handle specific error types
switch (error.code) {
case 'NETWORK_ERROR':
console.error('Check your internet connection');
break;
default:
console.error('Unexpected ASR error occurred');
}
} else {
console.error('Unexpected error:', error);
}
}
`$3
-
CREATE_TASK_FAILED - Failed to create transcription task
- UPLOAD_FAILED - Audio upload failed
- UPLOAD_ABORTED - Upload was cancelled or aborted
- TRANSCRIPTION_FAILED - Audio processing failed
- GET_STATUS_FAILED - Failed to retrieve task status
- PROCESS_FAILED - General processing failure
- PROCESSING_TIMED_OUT - General processing timeout
- NO_RESULT_DATA - No transcription data available
- RATING_FAILED - Failed to submit rating
- NO_TASK_ID - No task ID available for operation
- NO_API_CLIENT - API client not initialized
- NO_UPLOAD_METHOD - No upload method available
- NETWORK_ERROR - Connection or network issues
- CONSENT_REQUIRED - Your account has not accepted the latest Terms and Conditions and/or Privacy
Policy. Please log in at http://space.cariva.co.th to review and accept them to continue.-
INVALID_FILE_TYPE - Unsupported audio format
- ENOENT - File not found
- VALIDATION_ERROR - Invalid input parameters
- PROCESSING_ERROR - Audio processing error
- INVALID_SCORE - Invalid rating score (must be 1-5)Cancellation
Cancel long-running transcription tasks:
`typescript
// Start transcription
const transcriptionPromise = asr.process('./long-audio.wav');// Cancel after 5 minutes using instance method
const timeoutId = setTimeout(
async () => {
await asr.cancelASRTask();
console.log('Transcription cancelled due to timeout');
},
5 60 1000
);
try {
const result = await transcriptionPromise;
clearTimeout(timeoutId);
console.log('Transcription completed:', result);
} catch (error) {
clearTimeout(timeoutId);
console.error('Transcription failed or was cancelled:', error.message);
}
`Rating Transcriptions
Rate transcription quality to help improve the service:
`typescript
// Rate transcription quality (1-5 scale)
await asr.rateASRTask(5, 'Excellent medical transcription accuracy!');// Rate with just a score
await asr.rateASRTask(4);
// Rate with detailed feedback
await asr.rateASRTask(3, 'Good overall, but missed some medical terminology');
// Rate with comment and categories
await asr.rateASRTask(4, 'Good transcription', ['quality-improvement', 'accuracy']);
// Rate with categories only
await asr.rateASRTask(5, undefined, ['positive-feedback', 'excellent-quality']);
// Rate with multiple categories
await asr.rateASRTask(4, 'Good overall', ['medical-terminology', 'structure', 'completeness']);
`$3
- 5 Stars: Perfect transcription, no errors
- 4 Stars: Minor errors, easily corrected
- 3 Stars: Some errors, but mostly accurate
- 2 Stars: Multiple errors, needs significant correction
- 1 Star: Poor quality, major errors throughout
Complete Example
$3
`typitten
import { ASR } from '@cariva/asr-sdk-node';
import fs from 'fs/promises';
import path from 'path';class MedicalTranscriptionService {
private asrInstances: Record = {};
constructor() {
// Initialize different ASR instances for different specialties
this.asrInstances = {
cardiology: new ASR({
key: process.env.CARIVA_API_KEY!,
secret: process.env.CARIVA_API_SECRET!,
mode: 'doc-ipd-soap',
specialty: 'med-cardio',
}),
pulmonology: new ASR({
key: process.env.CARIVA_API_KEY!,
secret: process.env.CARIVA_API_SECRET!,
mode: 'doc-ipd-soap',
specialty: 'med-pulmonary',
}),
general: new ASR({
key: process.env.CARIVA_API_KEY!,
secret: process.env.CARIVA_API_SECRET!,
mode: 'doc-ipd-soap',
specialty: 'gen-practitioner',
}),
};
}
async processConsultation(audioPath: string, specialty: string = 'general') {
const asr = this.asrInstances[specialty] || this.asrInstances.general;
console.log(
Processing consultation audio: ${path.basename(audioPath)});
console.log(Using specialty: ${specialty}); const result = await asr.process(audioPath, {
onProcessing: step => {
console.log(
📋 ${step});
},
}); // Generate comprehensive report
const report = {
timestamp: new Date().toISOString(),
audioFile: path.basename(audioPath),
specialty: specialty,
transcription: result,
};
// Save to file
const reportPath =
./reports/${path.parse(audioPath).name}-${specialty}-report.json;
await fs.writeFile(reportPath, JSON.stringify(report, null, 2)); console.log(
✅ Report saved: ${reportPath});
return report;
} async processBatch(audioDir: string, specialty: string = 'general') {
const files = await fs.readdir(audioDir);
const audioFiles = files.filter(file => /\.(wav|mp3|m4a)$/i.test(file));
console.log(
📁 Found ${audioFiles.length} audio files to process); const results = [];
for (const file of audioFiles) {
const filePath = path.join(audioDir, file);
try {
const result = await this.processConsultation(filePath, specialty);
results.push(result);
} catch (error) {
console.error(
❌ Failed to process ${file}:, error.message);
}
} return results;
}
}
// Usage
const service = new MedicalTranscriptionService();
// Process single file
await service.processConsultation('./recordings/cardiology-consult.wav', 'cardiology');
// Process batch
await service.processBatch('./recordings/', 'general');
`$3
`typescript
import express from 'express';
import multer from 'multer';
import { ASR } from '@cariva/asr-sdk-node';const app = express();
const upload = multer({ dest: 'uploads/' });
// Configure ASR instances for different specialties
const asrConfig = {
key: process.env.CARIVA_API_KEY!,
secret: process.env.CARIVA_API_SECRET!,
mode: 'doc-ipd-soap' as const,
};
const asrInstances = {
cardiology: new ASR({ ...asrConfig, specialty: 'med-cardio' }),
pulmonology: new ASR({ ...asrConfig, specialty: 'med-pulmonary' }),
general: new ASR({ ...asrConfig, specialty: 'gen-practitioner' }),
};
app.post('/api/transcribe/:specialty?', upload.single('audio'), async (req, res) => {
try {
const specialty = req.params.specialty || 'general';
const asr = asrInstances[specialty] || asrInstances.general;
if (!req.file) {
return res.status(400).json({
success: false,
error: 'No audio file provided',
});
}
console.log(
Processing ${req.file.originalname} with ${specialty} specialty); const result = await asr.process(req.file.path, {
onProcessing: step => {
console.log(
[${req.file.originalname}] ${step});
},
}); // Clean up uploaded file
await fs.unlink(req.file.path);
res.json({
success: true,
data: {
filename: req.file.originalname,
specialty: specialty,
transcription: result,
processedAt: new Date().toISOString(),
},
});
} catch (error) {
console.error('Transcription error:', error);
res.status(500).json({
success: false,
error: error.message,
});
}
});
app.listen(3000, () => {
console.log('🎙️ Medical transcription API server running on port 3000');
});
`$3
| Node.js Version | Support Status | Notes |
| --------------- | ---------------- | ----------------------------- |
| 20.x | ✅ Full Support | Recommended LTS (minimum) |
| 21.x | ✅ Full Support | Current release |
| 22.x | ✅ Full Support | Latest release |
| 18.x | ❌ Not Supported | Upgrade to Node 20+ required |
| 16.x | ❌ Not Supported | End of life, upgrade required |
Requirements
$3
- Node.js: 20+ (ES2020+ support with modules)
- File System: For handling file uploads and processing
- Network: For API requests to Cariva services
- Memory: Sufficient RAM for audio file processing
$3
- TypeScript: 4.9+ (for type checking)
- Build Tools: Compatible with ES modules and CommonJS
$3
- Process Management: PM2, Docker, or similar for production deployment
- Error Monitoring: Recommended for production applications
- Log Management: Structured logging for troubleshooting
💡 Examples
Additional examples and integrations:
- Express.js Integration - Complete REST API server
- Microservice Architecture - Docker containerized service
- Batch Processing Scripts - Command-line batch processors
- Database Integration - Store results in MongoDB/PostgreSQL
- Queue Processing - Redis/Bull queue integration
Related Packages
| Package | Purpose |
| ------------------------------------------------------------------------------------ | ------------------------------ |
| @cariva/asr-sdk-browser | Browser client-side processing |
🆘 Support
For technical support and inquiries, please visit our
Contact Page.
Contributing
We welcome contributions! When reporting issues, please include:
- Node.js version and OS
- File size and type
- Error messages and stack traces
- Steps to reproduce
License
This project is licensed under the Apache License 2.0.
`
Copyright 2025 CarivaLicensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
``---