### Install Humain Voice SDK Source: https://docs.voice.humain.com/en/quickstart Install the required SDK version using npm. ```bash npm install @humain-voice/sdk@0.18.0 ``` -------------------------------- ### Diarization Audio Stream Packet Examples Source: https://docs.voice.humain.com/en/api-guides/asyncapi/realtime Binary packet examples for starting and finishing a diarization stream. ```text 12ab34cd56ef789012ab34cd56ef7890 01 01 ``` ```text 12ab34cd56ef789012ab34cd56ef7890 02 00 ``` -------------------------------- ### Queued Job Response Example Source: https://docs.voice.humain.com/en/api-reference/md/batch/submit-transcription-job Example of a successful response body when a job is queued. ```yaml queued: value: jobId: 7f51f2c2-e7bc-41c8-a850-f848df2ddfc8 status: queued ``` -------------------------------- ### Transcription Result Examples Source: https://docs.voice.humain.com/en/api-guides/asyncapi/realtime JSON examples for non-final and final transcription result events. ```json { "id": "7f51f2c2-e7bc-41c8-a850-f848df2ddfc8", "seq": 0, "transcription": "hello wor", "words": [ { "start_time": 0, "end_time": 0.45, "word": "hello" } ], "is_final": false, "is_speech_final": false } ``` ```json { "id": "7f51f2c2-e7bc-41c8-a850-f848df2ddfc8", "seq": 0, "transcription": "hello world", "words": [ { "start_time": 0, "end_time": 0.45, "word": "hello" }, { "start_time": 0.46, "end_time": 0.9, "word": "world" } ], "is_final": true, "is_speech_final": true } ``` -------------------------------- ### Error Response Examples Source: https://docs.voice.humain.com/en/api-reference/md/batch/submit-transcription-job Example JSON responses for different scenarios where the request limit is exceeded. ```yaml declared_too_large: summary: Content-Length already exceeds the limit value: error: error.api.error.request.too_large code: PAYLOAD_TOO_LARGE detail: error.api.error.request.too_large retryable: false timestamp: 2026-01-15T10:30:00Z request_id: 4bf92f3577b34da6a3ce929d0e0e4736 data: limit: 536870912 observed: 1073741824 unit: bytes bound: request_bytes unvalidatable_tail: summary: Too much data beyond the recording to finish checking the limits value: error: error.api.error.request.unvalidatable_tail code: PAYLOAD_TOO_LARGE detail: error.api.error.request.unvalidatable_tail retryable: false timestamp: 2026-01-15T10:30:00Z data: limit: 524288 observed: 524289 unit: bytes bound: unvalidatable_tail_bytes overran_while_reading: summary: Body overran the limit mid-stream value: error: error.api.error.request.too_large code: PAYLOAD_TOO_LARGE detail: error.api.error.request.too_large retryable: false timestamp: 2026-01-15T10:30:00Z data: limit: 536870912 observed: 536870913 unit: bytes bound: request_bytes ``` -------------------------------- ### client.startStream(language, options) Source: https://docs.voice.humain.com/en/sdk/javascript Starts a new transcription stream. ```APIDOC ## Method: startStream(language, options) ### Description Initiates a streaming session for audio transcription. ### Parameters - **language** (Language) - Required - The language code for transcription. - **options** (Object) - Optional - Configuration object containing callbacks: onConnect, onDisconnect, onResponse, onError, and subtitles. ``` -------------------------------- ### Audio Stream Packet Examples Source: https://docs.voice.humain.com/en/api-guides/asyncapi/realtime Binary packet examples for different stages of an audio stream, including language and flag settings. ```text 12ab34cd56ef789012ab34cd56ef7890 01 01 ``` ```text 12ab34cd56ef789012ab34cd56ef7890 00 00 ``` ```text 12ab34cd56ef789012ab34cd56ef7890 02 01 ``` -------------------------------- ### 401 Unauthorized Missing Key Example Source: https://docs.voice.humain.com/en/api-reference/md/batch/submit-transcription-job An example of a 401 Unauthorized error response triggered by a missing authentication key. ```yaml missing_key: value: error: auth.unauthorized message: unauthorized code: AUTH_UNAUTHORIZED retryable: false timestamp: 2026-01-15T10:30:00Z ``` -------------------------------- ### Build a live speaker timeline with RealtimeDiarizationClient Source: https://docs.voice.humain.com/en/sdk/javascript This example demonstrates initializing the client, streaming PCM audio, and handling diarization updates. It includes logic for writing the final timeline to an RTTM file or a partial file if the stream ends prematurely. ```typescript import { readFile, writeFile } from 'node:fs/promises'; import { DIARIZATION_RECOMMENDED_CHUNK_BYTES, RealtimeDiarizationClient, type SpeakerSegment, toRttm, } from '@humain-voice/sdk'; function requiredEnv(name: 'API_KEY' | 'API_PATH' | 'API_URL'): string { const value = process.env[name]; if (!value) throw new Error(`${name} is required`); return value; } async function pause(milliseconds: number): Promise { await new Promise((resolve) => setTimeout(resolve, milliseconds)); } async function main(): Promise { const inputPath = process.argv[2] ?? 'meeting.pcm'; const outputPath = process.argv[3] ?? 'meeting.rttm'; const client = new RealtimeDiarizationClient({ api_url: requiredEnv('API_URL'), api_path: requiredEnv('API_PATH'), api_key: requiredEnv('API_KEY'), }); try { let finalObserved = false; const stream = await client.startStream({ onError: (error) => console.error('server error:', error.code, error.message), onUpdate: (update) => { finalObserved ||= update.isFinal; for (const segment of update.newlyFinalized) { console.info(segment.speaker, segment.start_time, segment.end_time); } }, }); const pcm = await readFile(inputPath); if (pcm.length === 0 || pcm.length % 2 !== 0) { throw new Error('Input must be nonempty PCM16 with an even byte length'); } for ( let offset = 0; offset < pcm.length; offset += DIARIZATION_RECOMMENDED_CHUNK_BYTES ) { await stream.send( pcm.subarray(offset, offset + DIARIZATION_RECOMMENDED_CHUNK_BYTES), ); await pause(480); } // close() returns the best-known reconciled timeline after five seconds, // even when no isFinal update arrived. A callback avoids leaving an async // iterator waiting forever on that timeout path. const timeline: SpeakerSegment[] = await stream.close(5); const destination = finalObserved ? outputPath : `${outputPath}.partial`; await writeFile(destination, toRttm(timeline, 'meeting'), 'utf8'); if (!finalObserved) { console.warn(`Final result not observed; wrote incomplete output to ${destination}`); } } finally { await client.disconnect(); } } void main().catch((error: unknown) => { console.error(error); process.exitCode = 1; }); ``` -------------------------------- ### Realtime ASR Response Examples Source: https://docs.voice.humain.com/en/api-reference/realtime-http/realtime-asr Examples of partial and final transcription records returned in the NDJSON stream. ```json { "id": "7f51f2c2-e7bc-41c8-a850-f848df2ddfc8", "seq": 0, "transcription": "hello wor", "words": [ { "start_time": 0, "end_time": 0.45, "word": "hello" } ], "is_speech_final": false, "is_final": false } ``` ```json { "id": "7f51f2c2-e7bc-41c8-a850-f848df2ddfc8", "seq": 0, "transcription": "hello world", "words": [ { "start_time": 0, "end_time": 0.45, "word": "hello" }, { "start_time": 0.46, "end_time": 0.9, "word": "world" } ], "is_speech_final": true, "is_final": true } ``` -------------------------------- ### Speaker ID Result Example Source: https://docs.voice.humain.com/en/api-guides/asyncapi/realtime JSON example for the obsolete speaker ID result. ```json { "id": "7f51f2c2-e7bc-41c8-a850-f848df2ddfc8", "speaker": "speaker-1" } ``` -------------------------------- ### Verify SDK Version and Environment Configuration Source: https://docs.voice.humain.com/en/troubleshooting Commands to check the installed SDK version and verify that required environment variables are set without exposing sensitive keys. ```bash npm ls @humain-voice/sdk --depth=0 python -c 'from importlib.metadata import version; print(version("humain-voice"))' for name in API_URL API_KEY; do if [ -n "$(printenv "$name")" ]; then printf "%s=set\n" "$name" else printf "%s=missing\n" "$name" fi done ``` -------------------------------- ### Transcription Response Examples Source: https://docs.voice.humain.com/en/api-reference/realtime-http/fast-transcription Examples of partial and final transcription records returned in the NDJSON stream. ```json { "id": "7f51f2c2-e7bc-41c8-a850-f848df2ddfc8", "seq": 0, "transcription": "hello wor", "words": [ { "start_time": 0, "end_time": 0.45, "word": "hello" } ], "is_final": false } ``` ```json { "id": "7f51f2c2-e7bc-41c8-a850-f848df2ddfc8", "seq": 0, "transcription": "hello world", "words": [ { "start_time": 0, "end_time": 0.45, "word": "hello" }, { "start_time": 0.46, "end_time": 0.9, "word": "world" } ], "is_final": true } ``` -------------------------------- ### 422 Error Response Examples Source: https://docs.voice.humain.com/en/api-reference/md/batch/submit-transcription-job Example JSON payloads for various 422 error scenarios including file corruption and limit violations. ```yaml unsupported_audio: value: error: unsupported or corrupt audio input for conversion code: VALIDATION_FILE_CORRUPT detail: unsupported or corrupt audio input for conversion retryable: false timestamp: 2026-01-15T10:30:00Z audio_too_long: summary: Decoded audio exceeds the duration limit value: error: error.api.error.audio.duration_exceeded code: AUDIO_DURATION_EXCEEDED detail: error.api.error.audio.duration_exceeded retryable: false timestamp: 2026-01-15T10:30:00Z request_id: 4bf92f3577b34da6a3ce929d0e0e4736 data: limit: 14400 observed: 21600 unit: seconds bound: audio_duration too_many_files: summary: More than one audio part was submitted value: error: error.api.error.multipart.file.count_exceeded code: FILE_COUNT_EXCEEDED detail: error.api.error.multipart.file.count_exceeded retryable: false timestamp: 2026-01-15T10:30:00Z data: limit: 1 observed: 2 unit: files bound: file_parts too_many_parts: summary: More multipart parts than the request allows value: error: error.api.error.multipart.part.count_exceeded code: FILE_COUNT_EXCEEDED detail: error.api.error.multipart.part.count_exceeded retryable: false timestamp: 2026-01-15T10:30:00Z data: limit: 8 observed: 9 unit: parts bound: multipart_parts ``` -------------------------------- ### Scope Denied Error Example Source: https://docs.voice.humain.com/en/api-reference/md/batch/submit-transcription-job An example of a 403 Forbidden error response indicating that the API key lacks the necessary scope. ```yaml scope_denied: value: error: error.api_key.scope_denied code: AUTH_FORBIDDEN detail: scope not permitted retryable: false timestamp: 2026-01-15T10:30:00Z ``` -------------------------------- ### 400 Error Response Examples Source: https://docs.voice.humain.com/en/api-reference/md/batch/submit-transcription-job Example payloads for various 400 error scenarios including invalid language, content type, missing files, and unknown ASR models. ```yaml invalid_language: summary: Invalid language value: error: error.language.invalid code: VALIDATION_INVALID_LANGUAGE detail: error.language.invalid retryable: false timestamp: 2026-01-15T10:30:00Z invalid_content_type: summary: Request is not multipart form data value: error: error.api.error.request.invalid_format code: VALIDATION_INVALID_FORMAT detail: error.api.error.request.invalid_format retryable: false timestamp: 2026-01-15T10:30:00Z missing_file: summary: First multipart field is not file value: error: error.api.error.multipart.file.missing code: VALIDATION_REQUIRED_FIELD detail: error.api.error.multipart.file.missing retryable: false timestamp: 2026-01-15T10:30:00Z unknown_asr_model: summary: ASR model is not configured value: error: error.asr_model.not_found code: ASR_MODEL_NOT_FOUND detail: error.asr_model.not_found retryable: false timestamp: 2026-01-15T10:30:00Z ``` -------------------------------- ### 429 Rate Limit Example Source: https://docs.voice.humain.com/en/api-reference/md/batch/submit-transcription-job Example of a 429 response body indicating rate limit exhaustion. ```yaml limited: value: error: error.rate_limit code: RATE_LIMIT_EXCEEDED detail: error.rate_limit retryable: true timestamp: 2026-01-15T10:30:00Z data: capacity: 120.5 ``` -------------------------------- ### Credits Exhausted Error Example Source: https://docs.voice.humain.com/en/api-guides/asyncapi/realtime Example of a terminal, non-retryable error indicating that account credits have been exhausted. ```json { "id": "7f51f2c2-e7bc-41c8-a850-f848df2ddfc8", "code": "CREDITS_EXHAUSTED", "message": "insufficient credits", "retryable": false, "timestamp": "2026-01-15T10:30:00Z" } ``` -------------------------------- ### Billing Authorization Unavailable Error Example Source: https://docs.voice.humain.com/en/api-guides/asyncapi/realtime Example of a terminal error that is retryable after a wait, occurring when billing authorization fails. ```json { "id": "7f51f2c2-e7bc-41c8-a850-f848df2ddfc8", "code": "BILLING_AUTHORIZATION_UNAVAILABLE", "message": "billing authorization unavailable", "retryable": true, "timestamp": "2026-01-15T10:30:00Z" } ``` -------------------------------- ### GET · Get a job (V1 legacy) Source: https://docs.voice.humain.com/en/api-reference/batch Legacy response format used by the JavaScript and Python SDK 0.18.0 helpers. ```APIDOC ## GET /v1/transcribe/{job_id} ### Description Legacy response used by the JavaScript and Python SDK 0.18.0 helpers. ### Method GET ### Endpoint /v1/transcribe/{job_id} ### Parameters #### Path Parameters - **job_id** (string) - Required - The unique identifier for the transcription job. ``` -------------------------------- ### Diarization parameter examples Source: https://docs.voice.humain.com/en/api-reference/md/batch/submit-transcription-job Provides valid values for configuring speaker diarization. ```yaml enable: value: "1" disable: value: "0" enable_boolean: value: "true" disable_boolean: value: "false" d1: value: d1 d2: value: d2 ``` -------------------------------- ### ITN parameter examples Source: https://docs.voice.humain.com/en/api-reference/md/batch/submit-transcription-job Provides valid values for enabling or disabling Inverse Text Normalization. ```yaml enable: value: "1" disable: value: "0" enable_boolean: value: "true" disable_boolean: value: "false" ``` -------------------------------- ### POST /v1/transcribe/codeswitch Source: https://docs.voice.humain.com/en/authentication Example of an authenticated Batch REST operation requiring an API key. ```APIDOC ## POST /v1/transcribe/codeswitch ### Description Performs a transcription operation using the codeswitch endpoint. Requires an API key for authentication. ### Method POST ### Endpoint $API_URL/v1/transcribe/codeswitch ### Parameters #### Query Parameters - **asr** (string) - Required - The ASR model identifier (e.g., bayan_cs_ar_en). #### Request Body - **file** (binary) - Required - The audio file to be transcribed. ### Request Example curl -X POST "$API_URL/v1/transcribe/codeswitch?asr=bayan_cs_ar_en" \ -H "x-api-key: $API_KEY" \ -F "file=@meeting.wav" ``` -------------------------------- ### TTS request using voice references Source: https://docs.voice.humain.com/en/api-guides/asyncapi/tts Example showing how to provide a base64-encoded audio reference and its transcript for voice adaptation. ```json { "id": "7f51f2c2-e7bc-41c8-a850-f848df2ddfc8", "text": "Hello", "model": "nebula", "voice_references": [ { "audio": "UklGRiYAAABXQVZFZm10IBAAAAABAAEAwF0AAIC7AAACABAAZGF0YQIAAAAAAA==", "text": "Reference text" } ] } ``` -------------------------------- ### Basic TTS request Source: https://docs.voice.humain.com/en/api-guides/asyncapi/tts A minimal request example using only the required ID, text, and model fields. ```json { "id": "7f51f2c2-e7bc-41c8-a850-f848df2ddfc8", "text": "Hello from HUMAIN Voice", "model": "nebula" } ``` -------------------------------- ### Perform Fast Transcription Request Source: https://docs.voice.humain.com/en/api-reference/realtime-http/fast-transcription Example cURL command to initiate a transcription request with a multipart file upload. ```bash curl -sS --fail-with-body --connect-timeout 10 --max-time 120 -N -X POST \ "https://api.voice.humain.com/realtime/http/stt?id=497f6eca-6276-4993-bfeb-53cbbbba6f08" \ -H "Origin: https://api.voice.humain.com" \ -F "file=@meeting.wav" ``` -------------------------------- ### Example NDJSON Response Stream Source: https://docs.voice.humain.com/en/api-guides/realtime-http Shows the structure of the application/x-ndjson response stream returned by the transcription endpoint. ```json {"id":"7f51f2c2-e7bc-41c8-a850-f848df2ddfc8","seq":0,"transcription":"hello wor","words":[{"start_time":0.0,"end_time":0.45,"word":"hello"}],"is_final":false} {"id":"7f51f2c2-e7bc-41c8-a850-f848df2ddfc8","seq":0,"transcription":"hello world","words":[{"start_time":0.0,"end_time":0.45,"word":"hello"},{"start_time":0.46,"end_time":0.9,"word":"world"}],"is_final":true} ``` -------------------------------- ### TTS request with a specific voice profile Source: https://docs.voice.humain.com/en/api-guides/asyncapi/tts Example demonstrating how to specify a pre-defined voice profile using a UUID. ```json { "id": "7f51f2c2-e7bc-41c8-a850-f848df2ddfc8", "text": "Hello from HUMAIN Voice", "model": "nebula", "voice_id": "19965876-8cd6-4b8c-9af4-35cbec69ff1d" } ``` -------------------------------- ### new RealtimeClient({ api_url, api_key, api_path? }) Source: https://docs.voice.humain.com/en/sdk/javascript Initializes a new instance of the RealtimeClient. ```APIDOC ## Constructor: new RealtimeClient({ api_url, api_key, api_path? }) ### Description Creates a new client instance to interact with the transcription service. ### Parameters - **api_url** (string) - Required - The base URL of the API. - **api_key** (string) - Required - The authentication key. - **api_path** (string) - Optional - The specific API path. ``` -------------------------------- ### Synthesize and save audio to WAV Source: https://docs.voice.humain.com/en/sdk/python Demonstrates initializing the TTSClient, listing available voices, synthesizing text to PCM, and wrapping the output in a WAV file. ```python from __future__ import annotations import asyncio import os import sys import wave from pathlib import Path from humain_voice import stt, tts def required_env(name: str) -> str: value = os.environ.get(name) if not value: raise RuntimeError(f"{name} is required") return value def write_pcm16_wav(path: Path, pcm: bytes, sample_rate: int) -> None: with wave.open(str(path), "wb") as wav_file: wav_file.setnchannels(1) wav_file.setsampwidth(2) wav_file.setframerate(sample_rate) wav_file.writeframes(pcm) def handle_error(error: stt.ErrorResponse | None) -> None: if error is not None: print("server error:", error.code, error.message) async def main() -> None: output_path = Path(sys.argv[1] if len(sys.argv) > 1 else "speech.wav") async with tts.TTSClient( api_url=required_env("API_URL"), api_path=required_env("API_PATH"), api_key=required_env("API_KEY"), ) as client: voices = await client.list_voices(timeout_seconds=5.0) if not voices: raise RuntimeError("No TTS voices are available") voice = next((item for item in voices if item.get("profile")), voices[0]) if profile := voice.get("profile"): print( "profile:", voice["label"], profile["speaker"]["dialect"], profile["languages"], ) model = tts.TtsModel.Nebula pcm = await client.synthesize( "Hello from HUMAIN Voice", voice_id=voice["id"], model=model, # This is an inactivity timeout applied while awaiting each chunk. timeout_seconds=30.0, on_error=handle_error, ) write_pcm16_wav(output_path, pcm, tts.get_sample_rate(model)) if __name__ == "__main__": asyncio.run(main()) ``` -------------------------------- ### Diarization Stream Response Examples Source: https://docs.voice.humain.com/en/api-reference/realtime-http/realtime-diarization Examples of NDJSON records returned during the diarization stream. ```json { "id": "7f51f2c2-e7bc-41c8-a850-f848df2ddfc8", "final_segments": [ { "start_time": 0, "end_time": 1.5, "speaker": "SPEAKER_01" } ], "active_segments": [ { "start_time": 1.5, "end_time": 3, "speaker": "SPEAKER_02" } ], "is_final": false } ``` ```json { "id": "7f51f2c2-e7bc-41c8-a850-f848df2ddfc8", "final_segments": [ { "start_time": 1.5, "end_time": 3, "speaker": "SPEAKER_02" } ], "active_segments": [ { "start_time": 3, "end_time": 3.4, "speaker": "SPEAKER_01" } ], "is_final": true } ``` -------------------------------- ### 500 Transcription Failed Example Source: https://docs.voice.humain.com/en/api-reference/md/batch/submit-transcription-job Example of a 500 response body indicating a transcription failure. ```yaml transcription_failed: value: error: error.api.transcription code: ASR_TRANSCRIPTION_FAILED detail: error.api.transcription retryable: true timestamp: 2026-01-15T10:30:00Z ``` -------------------------------- ### new FastTranscriptionClient({ api_url, api_key, api_path?, onConnect?, onFileUpload?, onError? }) Source: https://docs.voice.humain.com/en/sdk/javascript Initializes a new instance of the FastTranscriptionClient. ```APIDOC ## Constructor: new FastTranscriptionClient(options) ### Description Initializes the client for fast transcription services. ### Parameters - **api_url** (string) - Required - The base URL for the API. - **api_key** (string) - Required - The authentication key. - **api_path** (string) - Optional - The specific API path. - **onConnect** (function) - Optional - Callback triggered upon successful connection. - **onFileUpload** (function) - Optional - Callback triggered when file upload is acknowledged. - **onError** (function) - Optional - Callback triggered on error events. ``` -------------------------------- ### Synthesize Text to WAV File Source: https://docs.voice.humain.com/en/recipes/text-to-speech-to-file Demonstrates the full workflow of initializing the client, discovering voices, synthesizing text, and wrapping raw PCM data in a WAV header. ```typescript import { writeFile } from 'node:fs/promises'; import { TTSClient, TtsModel, getSampleRate, } from '@humain-voice/sdk'; function requiredEnv(name: 'API_KEY' | 'API_PATH' | 'API_URL'): string { const value = process.env[name]; if (!value) throw new Error(`${name} is required`); return value; } function pcm16ToWav(pcm: Uint8Array, sampleRate: number): Buffer { const header = Buffer.alloc(44); header.write('RIFF', 0); header.writeUInt32LE(36 + pcm.byteLength, 4); header.write('WAVE', 8); header.write('fmt ', 12); header.writeUInt32LE(16, 16); header.writeUInt16LE(1, 20); // Linear PCM. header.writeUInt16LE(1, 22); // Mono. header.writeUInt32LE(sampleRate, 24); header.writeUInt32LE(sampleRate * 2, 28); header.writeUInt16LE(2, 32); header.writeUInt16LE(16, 34); header.write('data', 36); header.writeUInt32LE(pcm.byteLength, 40); return Buffer.concat([ header, Buffer.from(pcm.buffer, pcm.byteOffset, pcm.byteLength), ]); } async function main(): Promise { const outputPath = process.argv[2] ?? 'speech.wav'; const client = new TTSClient({ api_url: requiredEnv('API_URL'), api_path: requiredEnv('API_PATH'), api_key: requiredEnv('API_KEY'), }); try { const voices = await client.listVoices({ timeoutSeconds: 5 }); const voice = voices.find((candidate) => candidate.profile) ?? voices[0]; if (!voice) throw new Error('No TTS voices are available'); if (voice.profile) { console.log( 'profile:', voice.label, voice.profile.speaker.dialect, voice.profile.languages, ); } const model = TtsModel.Nebula; const pcm = await client.synthesize('Hello from HUMAIN Voice', { voice_id: voice.id, model, // This is an inactivity timeout applied while awaiting each audio chunk. timeoutSeconds: 30, onError: (error) => console.error('server error:', error.code, error.message), }); await writeFile(outputPath, pcm16ToWav(pcm, getSampleRate(model))); } finally { await client.close(); } } void main().catch((error: unknown) => { console.error(error); process.exitCode = 1; }); ``` -------------------------------- ### RealtimeClient Constructor Source: https://docs.voice.humain.com/en/sdk/python Initializes a new instance of the RealtimeClient to manage audio streaming connections. ```APIDOC ## RealtimeClient(api_url, api_key, api_path=None, verbose=False) ### Description Initializes the client for real-time transcription services. ### Parameters - **api_url** (str) - Required - The base URL of the API. - **api_key** (str) - Required - The authentication key for the API. - **api_path** (str) - Optional - The specific path for the API endpoint. - **verbose** (bool) - Optional - Enables verbose logging if set to True. ``` -------------------------------- ### Speaker Identification Request Example Source: https://docs.voice.humain.com/en/api-guides/asyncapi/realtime Example of the obsolete speaker identification binary packet. ```text 12ab34cd56ef789012ab34cd56ef7890 ``` -------------------------------- ### new BatchTranscribeClient(config) Source: https://docs.voice.humain.com/en/sdk/javascript Initializes a new instance of the BatchTranscribeClient. ```APIDOC ## new BatchTranscribeClient({ api_url, api_key, api_version, maxRetries? }) ### Description Initializes the client with the necessary API credentials and configuration. ### Parameters - **api_url** (string) - Required - The base URL for the API. - **api_key** (string) - Required - The API key for authentication. - **api_version** (string) - Optional - The API version to use (default: "v1"). - **maxRetries** (number) - Optional - Deprecated and ignored. ``` -------------------------------- ### Inspect and Convert Audio Files Source: https://docs.voice.humain.com/en/troubleshooting Use ffprobe to verify stream metadata and ffmpeg to normalize audio to the required PCM format. ```bash ffprobe -v error -select_streams a:0 \ -show_entries stream=codec_name,sample_rate,channels,sample_fmt \ -of default=noprint_wrappers=1 input.wav ffmpeg -i input.wav -ar 16000 -ac 1 -c:a pcm_s16le \ -f s16le realtime.pcm ``` -------------------------------- ### Transcribe audio with FastTranscriptionClient Source: https://docs.voice.humain.com/en/sdk/javascript Demonstrates initializing the client, connecting, and performing a transcription with a custom deadline wrapper. Ensure environment variables for API configuration are set before execution. ```typescript import { readFile, writeFile } from 'node:fs/promises'; import { FastTranscriptionClient, FastTranscriptionModel, Language, Subtitles, } from '@humain-voice/sdk'; function requiredEnv(name: 'API_KEY' | 'API_PATH' | 'API_URL'): string { const value = process.env[name]; if (!value) throw new Error(`${name} is required`); return value; } async function withDeadline(operation: Promise, milliseconds: number): Promise { let timer: ReturnType | undefined; try { return await Promise.race([ operation, new Promise((_, reject) => { timer = setTimeout(() => reject(new Error('Fast transcription deadline exceeded')), milliseconds); }), ]); } finally { if (timer) clearTimeout(timer); } } async function main(): Promise { const inputPath = process.argv[2] ?? 'short-call.wav'; const outputPath = process.argv[3] ?? 'short-call.srt'; const client = new FastTranscriptionClient({ api_url: requiredEnv('API_URL'), api_path: requiredEnv('API_PATH'), api_key: requiredEnv('API_KEY'), }); try { await client.connect(); const result = await withDeadline( client.transcribe( await readFile(inputPath), Language.Ar, FastTranscriptionModel.BayanAr, { onFileUpload: (response) => console.info('uploaded:', response?.id), onResponse: (response) => { console.info(response.is_final ? 'final:' : 'partial:', response.transcription); }, onError: (error) => console.error('server error:', error.code, error.message), }, ), 60_000, ); if (!result) throw new Error('Fast transcription ended without a final result'); await writeFile(outputPath, Subtitles.fromResponse(result).toSrt(), 'utf8'); } finally { await client.close(); } } void main().catch((error: unknown) => { console.error(error); process.exitCode = 1; }); ``` -------------------------------- ### Configure Realtime Streams Source: https://docs.voice.humain.com/en/troubleshooting Use language selection instead of model selection when initiating a realtime stream. ```text RealtimeClient.startStream() / start_stream() ``` -------------------------------- ### Configure environment variables for SDK 0.18.0 Source: https://docs.voice.humain.com/en/sdk Set these environment variables in your server runtime to authenticate and connect to the Humain Voice API. ```bash export API_URL="https://api.voice.humain.com" export API_KEY="YOUR_API_KEY" export API_VERSION="v1" ``` -------------------------------- ### Invalid Data Type Error Example Source: https://docs.voice.humain.com/en/api-guides/asyncapi/realtime Example of a non-retryable validation error due to an invalid data format. ```json { "code": "VALIDATION_INVALID_FORMAT", "message": "Invalid data type", "retryable": false, "timestamp": "2025-05-07T10:00:00.000Z" } ``` -------------------------------- ### FastTranscriptionClient(api_url, api_key, api_path=None, on_connect=None, on_file_upload=None, on_error=None, verbose=False) Source: https://docs.voice.humain.com/en/sdk/python Constructor for initializing the FastTranscriptionClient. It establishes the connection parameters required for the transcription service. ```APIDOC ### Constructor `FastTranscriptionClient(api_url, api_key, api_path=None, on_connect=None, on_file_upload=None, on_error=None, verbose=False)` ### Parameters - **api_url** (str) - Required - The base URL of the transcription service. - **api_key** (str) - Required - The authentication key for the service. - **api_path** (str) - Optional - The specific API path. - **on_connect** (callable) - Optional - Callback function triggered upon connection. - **on_file_upload** (callable) - Optional - Callback function triggered when a file is uploaded. - **on_error** (callable) - Optional - Callback function triggered on error events. - **verbose** (bool) - Optional - Enables verbose logging if set to True. ``` -------------------------------- ### Concurrency Limit Exceeded Error Example Source: https://docs.voice.humain.com/en/api-guides/asyncapi/realtime Example of a retryable error indicating that the account has reached its concurrent stream limit. ```json { "id": "7f51f2c2-e7bc-41c8-a850-f848df2ddfc8", "code": "CONCURRENCY_LIMIT_EXCEEDED", "message": "too many concurrent operations for this account", "retryable": true, "timestamp": "2026-01-15T10:30:00Z", "retry_after_seconds": 5, "data": { "limit": 8, "observed": 8, "unit": "operations", "bound": "account_concurrency_realtime_asr" } } ``` -------------------------------- ### RealtimeDiarizationClient Constructor Source: https://docs.voice.humain.com/en/sdk/javascript Initializes a new instance of the diarization client with the required API configuration. ```APIDOC ## new RealtimeDiarizationClient({ api_url, api_key, api_path? }) ### Description Creates a client instance to interact with the diarization service. ### Parameters - **api_url** (string) - Required - The base URL of the diarization service. - **api_key** (string) - Required - The authentication key for the service. - **api_path** (string) - Optional - The specific API path for the service. ``` -------------------------------- ### connect() and close() Source: https://docs.voice.humain.com/en/sdk/javascript Lifecycle methods for managing the Socket.IO connection. ```APIDOC ## Methods: connect(), close() ### Description - **connect()**: Establishes the connection to the transcription service. - **close()**: Terminates the connection and performs necessary cleanup. ``` -------------------------------- ### Perform Realtime Diarization Source: https://docs.voice.humain.com/en/sdk/python Demonstrates streaming PCM audio to the diarization service and processing updates via a callback. The client manages the connection lifecycle and handles partial results if the stream closes before finalization. ```python from __future__ import annotations import asyncio import os import sys from pathlib import Path from humain_voice import stt from humain_voice.stt.constants import DIARIZATION_RECOMMENDED_CHUNK_BYTES def required_env(name: str) -> str: if not value: raise RuntimeError(f"{name} is required") return value async def main() -> None: input_path = Path(sys.argv[1] if len(sys.argv) > 1 else "meeting.pcm") output_path = Path(sys.argv[2] if len(sys.argv) > 2 else "meeting.rttm") client = stt.RealtimeDiarizationClient( api_url=required_env("API_URL"), api_path=required_env("API_PATH"), api_key=required_env("API_KEY"), ) async with client: final_observed = False def on_update(update: stt.DiarizationUpdate) -> None: nonlocal final_observed final_observed = final_observed or update.is_final for segment in update.newly_finalized: print(segment.speaker, segment.start_time, segment.end_time) stream = await client.start_stream( on_update=on_update, on_error=lambda error: print("server error:", error), ) pcm = input_path.read_bytes() if not pcm or len(pcm) % 2: raise ValueError("Input must be nonempty PCM16 with an even byte length") for offset in range(0, len(pcm), DIARIZATION_RECOMMENDED_CHUNK_BYTES): await stream.send( pcm[offset : offset + DIARIZATION_RECOMMENDED_CHUNK_BYTES] ) await asyncio.sleep(0.48) # close() returns the best-known reconciled timeline after five seconds, # even when no is_final update arrived. A callback avoids leaving an async # iterator waiting forever on that timeout path. timeline = await stream.close(timeout_seconds=5.0) destination = output_path if final_observed else Path(f"{output_path}.partial") destination.write_text(stt.to_rttm(timeline, uri="meeting"), encoding="utf-8") if not final_observed: print(f"Final result not observed; wrote incomplete output to {destination}") if __name__ == "__main__": asyncio.run(main()) ``` -------------------------------- ### GET · Get a job (V2) Source: https://docs.voice.humain.com/en/api-reference/batch Recommended direct HTTP lookup for a transcription job using the standard success wrapper. ```APIDOC ## GET /v1/transcribe/{job_id} ### Description Recommended direct HTTP lookup with the standard success wrapper. ### Method GET ### Endpoint /v1/transcribe/{job_id} ### Parameters #### Path Parameters - **job_id** (string) - Required - The unique identifier for the transcription job. ``` -------------------------------- ### Configure API environment variables Source: https://docs.voice.humain.com/en/api-reference/md Set the base URL and API key as environment variables for use in subsequent requests. ```bash export API_URL="https://api.voice.humain.com" export API_KEY="YOUR_API_KEY" ``` -------------------------------- ### Configure environment variables Source: https://docs.voice.humain.com/en/quickstart Set required API credentials and endpoint configuration in the shell environment. ```bash export API_URL="https://api.voice.humain.com" export API_PATH="/socket.io" export API_KEY="YOUR_API_KEY" export API_VERSION="v1" test -n "$API_URL" && test -n "$API_PATH" && test -n "$API_KEY" && echo "HUMAIN Voice environment ready" ``` -------------------------------- ### GET /v1/transcribe/{job_id} Source: https://docs.voice.humain.com/en/recipes/transcribe-a-recording Polls the status of a transcription job. ```APIDOC ## GET /v1/transcribe/{job_id} ### Description Retrieves the status and results of a transcription job. ### Method GET ### Endpoint /v1/transcribe/{job_id} ### Parameters #### Path Parameters - **job_id** (string) - Required - The unique identifier for the transcription job. #### Query Parameters - **save_result** (boolean) - Optional - If set to true, preserves the result for retrieval after the job reaches a terminal state. ``` -------------------------------- ### Perform fast transcription with FastTranscriptionClient Source: https://docs.voice.humain.com/en/sdk/python Demonstrates how to use the FastTranscriptionClient to transcribe a complete audio unit, handle upload progress, process partial and final responses, and generate SRT subtitles. ```python from __future__ import annotations import asyncio import os import sys from pathlib import Path from humain_voice import stt def required_env(name: str) -> str: value = os.environ.get(name) if not value: raise RuntimeError(f"{name} is required") return value def handle_response(response: stt.FtTranscribeResponse) -> None: kind = "final" if response.is_final else "partial" print(f"{kind}:", response.transcription) def handle_upload(response: stt.FileUploadedResponse) -> None: print("uploaded:", response.id) def handle_error(error: stt.ErrorResponse | None) -> None: if error is not None: print("server error:", error.code, error.message) async def main() -> None: input_path = Path(sys.argv[1] if len(sys.argv) > 1 else "short-call.wav") output_path = Path(sys.argv[2] if len(sys.argv) > 2 else "short-call.srt") async with stt.FastTranscriptionClient( api_url=required_env("API_URL"), api_path=required_env("API_PATH"), api_key=required_env("API_KEY"), ) as client: result = await client.transcribe( input_path.read_bytes(), stt.Language.Ar, stt.FastTranscriptionModel.BayanAr, on_response=handle_response, on_file_upload=handle_upload, on_error=handle_error, timeout_seconds=60.0, ) if result is None: raise RuntimeError("Fast transcription ended without a final result") output_path.write_text( stt.Subtitles.from_response(result).to_srt(), encoding="utf-8", ) if __name__ == "__main__": asyncio.run(main()) ``` -------------------------------- ### Select Bayan Model Versions Source: https://docs.voice.humain.com/en/troubleshooting Use the unversioned alias for the default model, or specify versioned variants for intentional model selection. ```text BayanArEn BayanArEnV1 BayanArEnV2 ``` -------------------------------- ### Retrieve Transcription Job Request Source: https://docs.voice.humain.com/en/api-reference/batch/get-transcription-job Example request to fetch a transcription job by its ID. ```bash curl -sS --fail-with-body --connect-timeout 10 --max-time 120 -X GET \ "https://example.com/transcribe/497f6eca-6276-4993-bfeb-53cbbbba6f08" \ -H "Origin: https://example.com" ``` -------------------------------- ### TTSClient Constructor Source: https://docs.voice.humain.com/en/sdk/python Initializes the TTS client with API credentials and optional configuration. ```APIDOC ## TTSClient(api_url, api_key, api_path=None, verbose=False, on_connect=None, on_error=None) ### Description Initializes a new instance of the TTSClient to interact with the HUMAIN Voice service. ### Parameters - **api_url** (str) - Required - The base URL of the API. - **api_key** (str) - Required - The authentication key. - **api_path** (str) - Optional - The specific API path. - **verbose** (bool) - Optional - Enable verbose logging. - **on_connect** (callable) - Optional - Callback triggered on connection. - **on_error** (callable) - Optional - Callback triggered on error. ``` -------------------------------- ### GET /v1/transcribe/{job_id} Source: https://docs.voice.humain.com/en/api-guides/batch-rest Retrieves transcription results using the V2 result structure. ```APIDOC ## GET /v1/transcribe/{job_id} ### Description Retrieves the transcription result for a specific job using the V2 response shape. ### Method GET ### Endpoint /v1/transcribe/{job_id} ### Parameters #### Path Parameters - **job_id** (string) - Required - The unique identifier of the transcription job. #### Query Parameters - **save_result** (boolean) - Optional - If set to true, the result remains retrievable after the initial read. Defaults to false. ``` -------------------------------- ### GET /transcribe/{job_id}/{lang} Source: https://docs.voice.humain.com/en/api-reference/batch/get-transcription-job-legacy Retrieves the status or result of a legacy transcription job. ```APIDOC ## GET /transcribe/{job_id}/{lang} ### Description Legacy compatibility operation used by JavaScript and Python SDK 0.18.0. New direct HTTP integrations should use GET /transcribe/{job_id} (V2). ### Method GET ### Endpoint /transcribe/{job_id}/{lang} ### Parameters #### Path Parameters - **job_id** (string) - Required - Transcription job ID (UUID format). - **lang** (string) - Required - Legacy compatibility segment. The current V1 handler does not use or validate this value. ### Authorization - **x-api-key** (header) - Required - API Key Authentication ### Response #### Success Response (200) - **status** (string) - The current status of the job (queued, processing, done, failed, or cleared). - **results** (object) - Contains transcript and offsets if status is done. ``` -------------------------------- ### Select Batch Transcription Models Source: https://docs.voice.humain.com/en/troubleshooting Use batch-specific models for telephony audio to avoid empty transcription results in the fast pipeline. ```text BatchTranscriptionModel.NidaArTelephony ```