@eka-care/ekascribe-ts-sdk-legacy
v3.0.3
Published
EkaScribe TypeScript SDK - ES6/ES2015 build with polyfills for legacy browser support
Downloads
778
Readme
EkaScribe TypeScript SDK
Browser SDK for capturing audio and generating structured medical documentation using Eka Care's voice transcription API.
Prerequisites
- Node 14+
npmoryarn- Microphone access via browser permissions
- Stable network connectivity
- Access token from Eka Care
Installation
npm install @eka-care/ekascribe-ts-sdk-legacy
# or
yarn add @eka-care/ekascribe-ts-sdk-legacyBundler Setup
The SDK uses a SharedWorker for background audio uploads. Modern bundlers handle this automatically.
Vite
Works out of the box.
import { getEkaScribeInstance } from '@eka-care/ekascribe-ts-sdk-legacy';Webpack 5
Works out of the box. The new URL(..., import.meta.url) pattern is natively supported.
import { getEkaScribeInstance } from '@eka-care/ekascribe-ts-sdk-legacy';Next.js
Ensure the SDK is only used on the client side:
'use client';
import { getEkaScribeInstance } from '@eka-care/ekascribe-ts-sdk-legacy';Browser (Script Tag)
<script type="module">
import { getEkaScribeInstance } from 'https://cdn.jsdelivr.net/npm/@eka-care/ekascribe-ts-sdk-legacy/dist/index.mjs';
</script>Instance Management
The SDK uses a singleton pattern. getEkaScribeInstance() always returns the same instance for a given env + clientId combination.
const ekascribe = getEkaScribeInstance(config);- Calling
getEkaScribeInstance()multiple times with the same config returns the same instance. - If
envorclientIdchanges, the old instance is automatically reset. - If only
access_tokenchanges, the token is updated on the existing instance without resetting. - The SDK supports one active recording at a time. Always call
endRecording()orcancelSession()before starting a new recording. If you callstartRecordingV2()while a recording is active, the SDK cleans up the old recording locally but does not end the session on the server — the old session will be left abandoned until it expires.
Integration Guide
Step 1: Initialize the SDK
import { getEkaScribeInstance } from '@eka-care/ekascribe-ts-sdk-legacy';
import type { EkaScribeConfig } from '@eka-care/ekascribe-ts-sdk-legacy';
const config: EkaScribeConfig = {
access_token: '<your_access_token>',
env: 'PROD', // 'PROD' | 'DEV'
clientId: '<your_client_id>', // optional
allianceConfig: {
baseUrl: 'https://api.eka.care/voice/v1', // required
useWorker: 'auto', // optional: true | false | 'auto'
debug: false, // optional
},
sharedWorkerUrl: workerUrl, // optional — see SharedWorker section
};
const ekascribe = getEkaScribeInstance(config);EkaScribeConfig
interface EkaScribeConfig {
access_token?: string; // Bearer token for authentication
env: 'PROD' | 'DEV'; // Environment
clientId?: string; // Your client identifier
mode?: 'http' | 'ipc'; // Transport mode (default: 'http')
ipcBridge?: IpcBridge; // Required when mode is 'ipc' (Electron apps)
enableTracking?: boolean; // Enable internal analytics tracking
flavour?: string; // Client flavour identifier
sharedWorkerUrl?: string; // URL to worker.bundle.js for background uploads
allianceConfig?: {
baseUrl?: string; // Scribe service URL (required)
useWorker?: boolean | 'auto'; // SharedWorker: true | false | 'auto' (default: 'auto')
debug?: boolean; // Enable debug logging (default: false)
};
widget?: WidgetConfig; // Widget configuration — see Widget section
}Step 2: Register Callbacks
Register callbacks before starting a recording. Events fire immediately once recording starts.
import type { EkaCallbackMap } from '@eka-care/ekascribe-ts-sdk-legacy';
// Token refresh — SDK calls this automatically on 401
ekascribe.registerCallback('onTokenRequired', async () => {
const newToken = await fetchFreshToken(); // your token refresh logic
return newToken; // must return the new token string
});
// Recording state changes
ekascribe.registerCallback('onRecordingStateChange', (event) => {
console.log('State:', event.type); // 'started' | 'paused' | 'resumed' | 'ended'
});
// Upload progress
ekascribe.registerCallback('onUploadEvent', (event) => {
if (event.type === 'progress') {
console.log(`Uploaded ${event.data.successCount}/${event.data.totalCount}`);
}
});
// Errors
ekascribe.registerCallback('onError', (event) => {
console.error(`[${event.error.code}] ${event.error.message}`);
});See Callbacks Reference for all callback types and payloads.
Step 3: Start Recording
Creates a session and starts the microphone in one call.
import type { RecordingOptions } from '@eka-care/ekascribe-ts-sdk-legacy';
const options: RecordingOptions = {
templates: ['template-id'], // required: template IDs for output
sessionMode: 'consultation', // optional: 'consultation' | 'dictation'
languageHint: ['en', 'hi'], // optional: input audio language hints
transcriptLanguage: 'en', // optional: output transcript language
model: 'pro', // optional: 'pro' | 'lite'
uploadType: 'chunked', // optional: 'chunked' (default) | 'single'
deviceId: microphoneId, // optional: specific microphone device ID
patientDetails: { // optional
name: 'John Doe',
age: '45',
gender: 'male',
},
additionalData: {}, // optional: any extra data for the session
};
const result = await ekascribe.startRecordingV2(options);
if (result.error_code) {
console.error(result.error_code, result.message);
return;
}
const sessionId = result.txn_id;
console.log('Recording started:', sessionId);RecordingOptions
interface RecordingOptions {
templates: string[]; // Template IDs for extraction (required)
model?: string; // Model ID ('pro' | 'lite')
languageHint?: string[]; // Language codes for audio input
transcriptLanguage?: string; // Language code for transcript output
uploadType?: string; // 'chunked' | 'single' (default: 'chunked')
communicationProtocol?: string; // 'http' (default)
additionalData?: Record<string, any>; // Extra data for the session
deviceId?: string; // Specific microphone device ID
sessionMode?: string; // 'consultation' | 'dictation'
patientDetails?: PatientDetails; // Patient info
sessionId?: string; // External session/transaction ID
}
interface PatientDetails {
oid?: string;
name?: string;
age?: string;
gender?: string;
mobile?: number;
}Response: TStartRecordingResponse
type TStartRecordingResponse = {
error_code?: ERROR_CODE; // present only on error
status_code: number;
message: string;
txn_id?: string; // session ID — present on success
business_id?: string;
oid?: string;
uuid?: string;
};Step 4: Pause / Resume
const pauseResult = ekascribe.pauseRecording();
// later...
const resumeResult = ekascribe.resumeRecording();Response: TPauseRecordingResponse
type TPauseRecordingResponse = {
status_code: number;
message: string;
error_code?: ERROR_CODE;
is_paused?: boolean;
};Step 5: End Recording
Stops the microphone, flushes pending audio, waits for all uploads, and ends the session on the server (triggers processing).
const endResult = await ekascribe.endRecording();
if (endResult.error_code) {
switch (endResult.error_code) {
case 'audio_upload_failed':
// Some audio files failed to upload — retry
await ekascribe.retryUploadRecording();
break;
case 'end_recording_failed':
case 'internal_server_error':
console.error(endResult.error_code, endResult.message);
break;
}
}Response: TEndRecordingResponse
type TEndRecordingResponse = {
error_code?: ERROR_CODE;
status_code: number;
message: string;
failed_files?: string[]; // files that failed to upload
total_audio_files?: string[]; // all audio files generated
};Step 6: Get Output
Use getSessionStatus() to poll for results after ending the recording.
const status = await ekascribe.getSessionStatus(sessionId, {
poll: {
maxAttempts: 60,
intervalMs: 2000,
signal: abortController.signal, // optional: cancel polling early
onProgress: (sessionData) => {
console.log('Status:', sessionData.status);
// Display partial results as they come in
if (sessionData.templates) {
console.log('Templates:', sessionData.templates);
}
},
},
});
if (status.success) {
console.log('Final status:', status.data.status);
console.log('Templates:', status.data.templates);
console.log('Transcript:', status.data.transcript);
}Response: SDKResult<GetSessionStatusResponse>
// All async Alliance methods return SDKResult — check result.success
type SDKResult<T> =
| { success: true; data: T; httpStatus?: number }
| { success: false; error: ScribeError };
type GetSessionStatusResponse = {
session_id: string;
status: SessionStatus;
created_at: string;
expires_at?: string | null;
completed_at?: string | null;
model_used?: string | null;
language_detected?: string | null;
audio_files_received: number;
audio_files: string[];
audio_files_processed?: number;
additional_data: Record<string, any>;
templates?: TemplateEntry[];
transcript?: string;
processing_errors?: ProcessingError[];
error?: { code: string; message: string };
};Step 7: Clean Up
// Reset the singleton — clears all state, destroys widget, removes callbacks
await ekascribe.resetInstance();After calling resetInstance(), you must call getEkaScribeInstance() again to get a new instance.
Flow Diagram
getEkaScribeInstance(config)
|
v
registerCallback() ── Set up event handlers before recording
|
v
startRecordingV2() ── Creates session + starts mic + begins upload
|
pause / resume ── Optional during recording
|
v
endRecording() ── Stops mic + flushes audio + ends session
|
v
getSessionStatus() ── Poll until completed/failed
|
v
Read results ── templates, transcript, errorsCallbacks Reference
Register with registerCallback(name, handler). Remove with removeCallback(name, handler).
onTokenRequired
Called automatically when the SDK receives a 401 from any API call. Your handler must return a fresh access token. The SDK will update its internal token and retry the failed request.
ekascribe.registerCallback('onTokenRequired', async () => {
// Call your auth service to get a fresh token
const newToken = await myAuthService.refreshToken();
return newToken; // return the token string
});Important:
- The handler must return
Promise<string>orstring - The SDK times out after 10 seconds — if your refresh takes longer, the request fails
- Once the token is returned, the SDK calls
updateAuthTokens()internally — you don't need to call it yourself - This replaces the old pattern of manually checking
status_code: 401in every response
Type
// Consumer-facing type (EkaScribe SDK)
onTokenRequired: () => Promise<string> | string;onRecordingStateChange
Fired when recording state transitions.
ekascribe.registerCallback('onRecordingStateChange', (event) => {
console.log(event.type); // 'started' | 'paused' | 'resumed' | 'ended'
});Type
interface RecordingStateChangeEvent {
type: 'started' | 'paused' | 'resumed' | 'ended';
timestamp: string;
data?: any;
}onAudioEvent
Fired for speech detection, silence warnings, chunk creation, and frame processing.
ekascribe.registerCallback('onAudioEvent', (event) => {
switch (event.type) {
case 'user_speech':
console.log('Speaking:', event.data.isSpeaking);
break;
case 'silence_warning':
console.log('Silence duration:', event.data.durationMs, 'ms');
break;
case 'chunk_ready':
console.log('Chunk:', event.data.fileName);
break;
case 'frame_processed':
// Raw audio frame data
break;
}
});Type
type AudioEvent =
| { type: 'user_speech'; timestamp: string; data: { isSpeaking: boolean } }
| { type: 'silence_warning'; timestamp: string; data: { durationMs: number } }
| { type: 'chunk_ready'; timestamp: string; data: { chunkIndex: number; fileName: string; chunkData: Uint8Array[] } }
| { type: 'frame_processed'; timestamp: string; data: { isSpeech: number; notSpeech: number; frame: Float32Array; duration: number } };onUploadEvent
Fired for upload progress, failures, and retries.
ekascribe.registerCallback('onUploadEvent', (event) => {
switch (event.type) {
case 'progress':
console.log(`${event.data.successCount}/${event.data.totalCount} uploaded`);
break;
case 'failed':
console.error(`Upload failed: ${event.data.fileName}`, event.data.error);
break;
case 'retry':
console.log(`Retrying ${event.data.fileName}, attempt ${event.data.attempt}`);
break;
}
});Type
type UploadEvent =
| { type: 'progress'; timestamp: string; data: { successCount: number; totalCount: number } }
| { type: 'failed'; timestamp: string; data: { fileName: string; error: string } }
| { type: 'retry'; timestamp: string; data: { fileName: string; attempt: number } };onSessionEvent
Fired on session lifecycle events.
ekascribe.registerCallback('onSessionEvent', (event) => {
switch (event.type) {
case 'created':
console.log('Session created:', event.data.session_id);
break;
case 'ended':
console.log('Session ended:', event.data.session_id);
break;
case 'status_update':
console.log('Status update:', event.data.status);
break;
case 'partial_result':
console.log('Partial result:', event.data);
break;
}
});Type
type SessionEvent =
| { type: 'created'; timestamp: string; data: CreateSessionResponse }
| { type: 'ended'; timestamp: string; data: EndSessionResponse }
| { type: 'status_update'; timestamp: string; data: GetSessionStatusResponse }
| { type: 'partial_result'; timestamp: string; data: any };onError
Fired on SDK errors — VAD failures, worker errors, network issues, validation errors.
ekascribe.registerCallback('onError', (event) => {
console.error(`[${event.type}] ${event.error.code}: ${event.error.message}`);
});Type
interface ErrorEvent {
type: 'vad_error' | 'worker_error' | 'transport_error' | 'validation_error';
timestamp: string;
error: {
code: string;
message: string;
details?: any;
};
}Removing Callbacks
const handler = (event) => { /* ... */ };
ekascribe.registerCallback('onUploadEvent', handler);
// later...
ekascribe.removeCallback('onUploadEvent', handler);Retry Failed Uploads
If endRecording() returns audio_upload_failed, retry the failed uploads:
const result = await ekascribe.retryUploadRecording();Response: TEndRecordingResponse
{
status_code: number;
message: string;
error_code?: ERROR_CODE;
failed_files?: string[]; // files still failing after retry
total_audio_files?: string[];
}Cancel a Session
Cancel a session without triggering server-side processing.
// Cancel current active session
await ekascribe.cancelSession();
// Or cancel a specific session by ID
await ekascribe.cancelSession('session-id');Response: SDKResult<PatchSessionResponse>
const result = await ekascribe.cancelSession();
if (result.success) {
console.log('Session cancelled');
}Pre-Recorded Audio Upload
Upload a pre-recorded audio file instead of live recording. Use this for non-real-time flows.
Flow:
- Create session via
ekascribe.sessions.createSession() - Upload audio via
processPreRecordedAudio() - End session via
ekascribe.sessions.endSession()
const result = await ekascribe.processPreRecordedAudio({
uploadUrl: session.upload_url, // from createSession response
audioFile: audioBlob, // File or Blob
});Request
{
uploadUrl: string; // S3 upload URL from session
audioFile: File | Blob; // the audio file
}Response: TStartRecordingResponse
{
status_code: number;
message: string;
error_code?: ERROR_CODE;
}Session Utils
getSessionHistory(request)
Fetch previous sessions.
const sessions = await ekascribe.sessions.getSessionHistory({
txn_count: 10, // number of sessions to fetch
oid: 'patient-oid', // optional: filter by patient oid
});Response: TGetTransactionHistoryResponse
{
data: Array<{
txn_id: string;
b_id: string;
created_at: string;
mode: string;
oid: string;
patient_details?: TPatientDetails;
processing_status: 'success' | 'system_failure' | 'request_failure' | 'cancelled' | 'in-progress';
user_status: 'init' | 'commit';
uuid: string;
}>;
status: string;
code: number;
message: string;
retrieved_count: number;
}getSessionDetails(request)
Get detailed information about a specific session, including documents, context, and presigned URLs.
const details = await ekascribe.sessions.getSessionDetails({
session_id: 'session-id',
presigned: true, // include presigned URLs for documents
});Each document in the response contains a presigned_url. To get the actual document content (notes, transcript, etc.), you need to fetch it from this URL:
const doc = details.data?.documents[0];
if (doc?.presigned_url) {
const response = await fetch(doc.presigned_url);
const content = await response.json();
}Presigned URLs are temporary — check
presigned_url_expires_at(epoch timestamp) before using. CallgetDocument(documentId)to get a fresh presigned URL if expired.
Request
type TGetV1SessionDetailsRequest = {
session_id: string;
presigned?: boolean; // default: false
};Response: TGetV1SessionDetailsResponse
type TGetV1SessionDetailsResponse = {
data?: {
schema_version: string;
session_id: string;
uuid: string;
wid: string;
created_at: number;
expires_at: number;
upload_url: string;
status: string;
user_status: 'init' | 'recording_started' | 'commit' | string;
transfer: string;
flavour: string;
patient_details: TPatientDetails | Record<string, unknown>;
audio_matrix: Record<string, unknown>;
additional_data: {
input_languages?: { id: string; name: string }[];
output_format_template?: {
template_id: string;
template_name?: string;
template_type?: string;
}[];
[key: string]: unknown;
};
documents: Array<{
document_id: string;
session_id: string;
template_id: string;
document_name: string;
document_type: 'notes' | 'context' | 'transcript' | 'integration';
type: string;
status: string;
errors: Array<{ type: string | null; code: string; msg: string }>;
warnings: Array<{ type: string | null; code: string; msg: string }>;
publish: Record<string, unknown>;
created_at: number;
presigned_url: string | null;
presigned_url_expires_at: number | null;
vault_doc_id: string | null;
lang?: string;
}>;
context: {
past_sessions?: Array<{ date_epoch: number; session_id: string }>;
documents?: string[];
attachments?: Array<{ id: string; patient_oid?: string }>;
};
};
status_code: number;
message?: string;
};getDocument(documentId)
Fetch a single document by ID. Use this to get a fresh presigned URL if the previous one has expired.
const doc = await ekascribe.documents.getDocument('document-id');
if (doc.data?.presigned_url) {
const response = await fetch(doc.data.presigned_url);
const content = await response.json();
}Response: TPostV1DocumentResponse
type TPostV1DocumentResponse = {
status_code: number;
status?: string;
message?: string;
data?: {
document_id: string;
session_id: string;
template_id: string;
document_name: string;
type: string;
status: string;
errors: unknown[];
warnings: unknown[];
usage_information: Record<string, unknown>;
document_path: {
bucket: string;
folder: string;
filename: string;
};
presigned_url: string;
created_at: string;
updated_at: number;
publish: Record<string, unknown>;
};
};patchSessionStatus(request, sessionId?)
Update session properties (patient details, status, templates).
await ekascribe.sessions.patchSessionStatus({
patient_details: { name: 'Jane Doe', age: '30', gender: 'female' },
additional_data: { notes: 'Follow-up visit' },
templates: ['soap', 'prescription'],
}, sessionId);Discovery
getDiscoveryDocument()
Get the raw discovery document fetched during initialization. Contains server capabilities (supported models, languages, upload methods, audio formats).
const discovery = ekascribe.sessions.getDiscoveryDocument();Returns DiscoveryDocument | null.
getDiscoveryConfig()
Get the resolved configuration derived from the discovery document.
const config = ekascribe.sessions.getDiscoveryConfig();
if (config.success) {
console.log('Resolved config:', config.data);
}Returns SDKResult<ResolvedConfig>.
Widget
The SDK provides an optional pre-built recording UI. When enabled, the SDK injects a floating widget into your page via Shadow DOM — you write zero UI code.
Integration
Step 1: Enable the widget in SDK config with session defaults and callbacks:
const ekascribe = getEkaScribeInstance({
access_token: token,
env: 'PROD',
allianceConfig: { baseUrl: '...' },
widget: {
enabled: true,
orientation: 'horizontal', // 'horizontal' | 'vertical'
zIndex: 9999, // optional
position: { bottom: 20, right: 20 }, // optional
sessionDefaults: {
input_language: ['en'],
output_format_template: [{ template_id: 'soap' }],
model_type: 'pro',
mode: 'consultation',
},
callbacks: {
onRecordingStart: ({ txn_id }) => {},
onRecordingStop: ({ txn_id, duration }) => {},
onProcessingComplete: ({ txn_id, sessionData }) => {
// sessionData contains templates, transcript, etc.
},
onError: ({ error_code, message }) => {},
},
},
});Step 2: Call startForPatient() for each patient — the widget appears and the user interacts with it directly (pause, resume, stop). You receive results via callbacks.
await ekascribe.startForPatient({
txn_id: 'unique-session-id',
patient_details: { // optional
username: 'John Doe',
age: 45,
biologicalSex: 'M',
},
additional_data: {}, // optional
});That's it. The widget handles startRecordingV2(), pauseRecording(), resumeRecording(), endRecording(), and getSessionStatus() internally.
Behavior
- Draggable — the widget can be repositioned anywhere on screen.
- One recording at a time — calling
startForPatient()while a recording is active returns an error. If the widget is in DONE or ERROR state, it auto-resets and starts the new session. - Done state — after processing, the widget expands to show transcript and rendered markdown notes. If both are available, they appear in separate tabs.
Widget State Flow
COLLAPSED ──> RECORDING ──> PAUSED ──> RECORDING ──> PROCESSING ──> DONE
^ │ │ │
│ └──── (user clicks stop) ───────────────┘ │
│ │
└──────────── (user clicks close) ────────────────────────────────┘
│
ERRORTypes
interface WidgetConfig {
enabled: boolean;
theme?: 'light' | 'dark';
zIndex?: number;
primaryColor?: string;
position?: { bottom?: number; right?: number; top?: number; left?: number };
orientation?: 'horizontal' | 'vertical';
callbacks?: WidgetCallbacks;
sessionDefaults: {
input_language: string[];
output_format_template: { template_id: string; template_name?: string; template_type?: string }[];
model_type: string;
mode: string;
};
}
interface StartForPatientConfig {
txn_id: string;
patient_details?: {
username?: string;
age?: number;
biologicalSex?: string;
mobile?: string;
};
additional_data?: Record<string, unknown>;
}
interface WidgetCallbacks {
onRecordingStart?: (data: { txn_id: string }) => void;
onRecordingPause?: (data: { txn_id: string; duration: number }) => void;
onRecordingResume?: (data: { txn_id: string }) => void;
onRecordingStop?: (data: { txn_id: string; duration: number }) => void;
onProcessingStart?: (data: { txn_id: string }) => void;
onProcessingComplete?: (data: { txn_id: string; sessionData: unknown }) => void;
onError?: (data: { error_code: string; message: string }) => void;
onWidgetClose?: (data: { txn_id: string }) => void;
}Authentication
updateAuthTokens(token)
Manually update the access token. This propagates the token to all internal transports and the worker.
ekascribe.updateAuthTokens({ access_token: 'new-token' });If you have
onTokenRequiredregistered, the SDK handles 401s automatically. You only needupdateAuthTokens()for proactive token rotation (e.g., before expiry).
SharedWorker Configuration
The SDK offloads audio compression and upload to a SharedWorker for better main-thread performance. If SharedWorker is unavailable or fails, the SDK silently falls back to main-thread processing.
Setup
import { createWorkerBlobUrl } from '@eka-care/ekascribe-ts-sdk-legacy';
// Option 1: Use the built-in helper (recommended)
const workerUrl = await createWorkerBlobUrl();
// Option 2: Fetch from CDN
async function getWorkerUrl() {
const res = await fetch(
'https://cdn.jsdelivr.net/npm/@eka-care/ekascribe-ts-sdk-legacy@latest/dist/worker.bundle.js'
);
const script = await res.text();
const blob = new Blob([script], { type: 'application/javascript' });
return URL.createObjectURL(blob);
}
const workerUrl = await getWorkerUrl();
// Option 3: Copy to public directory
// cp node_modules/@eka-care/ekascribe-ts-sdk-legacy/dist/worker.bundle.js public/
const workerUrl = '/worker.bundle.js';Pass the URL in config:
const ekascribe = getEkaScribeInstance({
// ...
sharedWorkerUrl: workerUrl,
});Notes:
- The worker URL must be accessible from the same origin or have proper CORS headers
- Remember to revoke blob URLs when done:
URL.revokeObjectURL(workerUrl) - If
sharedWorkerUrlis not provided, the SDK uses the main thread (no SharedWorker)
Error Codes
| Error Code | Description |
|---|---|
| microphone | Microphone access error (permission denied or unavailable) |
| txn_init_failed | Failed to initialize session |
| txn_limit_exceeded | Maximum concurrent sessions exceeded |
| internal_server_error | Unexpected server-side error |
| end_recording_failed | Failed to end recording |
| audio_upload_failed | Audio file upload to server failed |
| txn_commit_failed | Commit call failed |
| txn_status_mismatch | Invalid operation for current session state |
| network_error | Network connectivity issue |
| unknown_error | Unclassified error |
| unauthorized | Authentication failed (invalid or expired token) |
| forbidden | Insufficient permissions |
Deprecated Methods
These methods are from the older SDK version. They still work but are not recommended for new integrations.
| Deprecated Method | Use Instead |
|---|---|
| initTransaction() + startRecording() | startRecordingV2() |
| getTemplateOutput() | getSessionStatus() with polling |
| getOutputTranscription() | getSessionStatus() with polling |
| commitTransactionCall() | Handled automatically by endRecording() |
| stopTransactionCall() | Handled automatically by endRecording() |
initTransaction(request)
Creates a session on the server. Must be followed by startRecording().
const result = await ekascribe.initTransaction({
mode: 'consultation',
input_language: ['en-IN'],
output_format_template: [{ template_id: 'template-id' }],
txn_id: 'unique-id',
transfer: 'chunked',
model_type: 'pro',
patient_details: { // optional
username: 'John Doe',
age: 45,
biologicalSex: 'M',
},
});
// result: { status_code, message, txn_id?, error_code? }startRecording(microphoneID?)
Starts recording for an already initialized session.
const result = await ekascribe.startRecording();
// result: { status_code, message, txn_id?, error_code? }getTemplateOutput(request)
Fetches processed template output for a session.
const result = await ekascribe.getTemplateOutput({ txn_id: 'session-id' });
// result: { status_code, message?, response? }getOutputTranscription(request)
Fetches the transcription output for a session.
const result = await ekascribe.getOutputTranscription({ txn_id: 'session-id' });
// result: { status_code, message?, response? }commitTransactionCall()
Commits the current transaction on the server.
const result = await ekascribe.commitTransactionCall();
// result: { status_code, message, error_code?, failed_files? }stopTransactionCall()
Stops the current transaction on the server.
const result = await ekascribe.stopTransactionCall();
// result: { status_code, message, error_code? }Full Example
import {
getEkaScribeInstance,
type EkaScribeConfig,
type RecordingOptions,
} from '@eka-care/ekascribe-ts-sdk-legacy';
// 1. Initialize
const config: EkaScribeConfig = {
access_token: token,
env: 'PROD',
allianceConfig: {
baseUrl: 'https://api.eka.care/voice/v1',
},
};
const ekascribe = getEkaScribeInstance(config);
// 2. Register callbacks
ekascribe.registerCallback('onTokenRequired', async () => {
return await refreshToken();
});
ekascribe.registerCallback('onUploadEvent', (event) => {
if (event.type === 'progress') {
updateProgressUI(event.data.successCount, event.data.totalCount);
}
});
ekascribe.registerCallback('onError', (event) => {
showErrorToast(event.error.message);
});
// 3. Start recording
const startResult = await ekascribe.startRecordingV2({
templates: ['soap'],
sessionMode: 'consultation',
languageHint: ['en'],
patientDetails: { name: 'John Doe', age: '45', gender: 'male' },
});
if (startResult.error_code) {
showError(startResult.message);
return;
}
const sessionId = startResult.txn_id!;
// 4. User interacts...
// pauseBtn.onclick = () => ekascribe.pauseRecording();
// resumeBtn.onclick = () => ekascribe.resumeRecording();
// 5. End recording
const endResult = await ekascribe.endRecording();
if (endResult.error_code === 'audio_upload_failed') {
await ekascribe.retryUploadRecording();
}
// 6. Get results
const status = await ekascribe.getSessionStatus(sessionId, {
poll: {
maxAttempts: 60,
intervalMs: 2000,
onProgress: (s) => updateStatusUI(s.status),
},
});
if (status.success) {
displayResults(status.data.templates, status.data.transcript);
}
// 7. Cleanup on unmount
await ekascribe.resetInstance();Contribution Guidelines
This is a continually updated, open source project. Contributions are welcome!
Refer EkaScribe TS SDK for SDK implementation.
