clarion.uz

API documentation

The Clarion API turns Uzbek speech into punctuated text with word-level timestamps and sound events: files over REST, live audio over WebSocket. It is OpenAI-compatible, so with the OpenAI SDK only base_url changes.

Base URLhttps://api.uzasr.uz/v1

Authentication

Send the key in a header with every request.

Keys look like uzasr_live_… and are shown once. Keep yours on the server, never in a browser or client app.

HTTP
Authorization: Bearer uzasr_live_…

Quickstart

Transcribe a file with a single request.

import os from openai import OpenAI client = OpenAI(    base_url="https://api.uzasr.uz/v1",    api_key=os.environ["UZASR_API_KEY"],) result = client.audio.transcriptions.create(    model="uzasr-large",    file=open("call.mp3", "rb"),    response_format="verbose_json",    timestamp_granularities=["word"],)print(result.text)

Synchronous transcription

Files up to 10 minutes. The response comes back in the same request.

POST/v1/audio/transcriptions

ParameterTypeDescription
filefileAudio or video: wav, mp3, m4a, ogg, flac, mp4, webm.
modelstringuzasr-large or uzasr-base, or an exact version.
response_formatstringjson, text or verbose_json. Defaults to json.
timestamp_granularities[]stringword: word-level timestamps, only with verbose_json.
languagestringOptional. Only uz is supported.

Response format

verbose_json with word-level timestamps and sound events.

ParameterTypeDescription
textstringPunctuated text in Latin script.
words[]objectword, start, end: the word and its boundaries in seconds.
segments[]objectRecording segments with boundaries and text.
events[]objectlabel, start, end, score. Labels: laughter, applause, music. Ignore unknown labels.
verbose_json
{  "task": "transcribe",  "language": "uz",  "duration": 28.0,  "text": "Oyoqdagi yechish bilan shunaqa ovoz chiqaradiki, …",  "segments": [    { "id": 0, "start": 0.0, "end": 9.8, "text": "Oyoqdagi yechish bilan …" }  ],  "words": [    { "word": "Oyoqdagi", "start": 0.12, "end": 0.64 }  ],  "events": [    { "label": "laughter", "start": 2.28, "end": 2.52, "score": 0.557 },    { "label": "applause", "start": 19.28, "end": 21.04, "score": 0.659 }  ]}

The X-Uzasr-Processing-Seconds header contains pure GPU processing time, excluding queueing and startup.

Async jobs

Files up to 3 hours. Create a job and poll its status.

POST/v1/jobs

GET/v1/jobs/{id}

Retrying with the same Idempotency-Key returns the original job. Statuses: queued, succeeded, failed.

import osimport time import requests API = "https://api.uzasr.uz/v1"headers = {"Authorization": f"Bearer {os.environ['UZASR_API_KEY']}"} job = requests.post(    f"{API}/jobs",    headers={**headers, "Idempotency-Key": "call-2026-10-21-0042"},    files={"file": open("meeting.mp3", "rb")},    data={"model": "uzasr-large"},).json() while job["status"] == "queued":    time.sleep(5)    job = requests.get(f"{API}/jobs/{job['id']}", headers=headers).json() print(job["result"]["text"])

Realtime mode

WebSocket: stream PCM in, receive text events out.

WS/v1/realtime?model=uzasr-large

EventDirectionDescription
ready← serverSession opened, with the exact model version.
partial← serverThe current phrase. The stable field won't change; the rest may be refined.
final← serverPhrase finalized after a 0.8 s pause, with punctuation.
event← serverA sound event, 1–1.5 s after it ends.
done← serverSession closed, with audio_seconds for billing.
binary→ clientPCM s16le, 16 kHz, mono. Recommended frame size: 100 ms.
stop→ client{"type":"stop"}: finalize the last phrase and close the session.
WebSocket
← from server→ from client
wss://api.uzasr.uz/v1/realtime?model=uzasr-large ← { "type": "ready" }→ <binary PCM s16le 16 kHz, 100 ms>← { "type": "partial", "utterance": 0, "start": 0.0,    "text": "Assalomu alaykum qanday", "stable": "Assalomu alaykum" }← { "type": "final", "utterance": 0, "start": 0.0, "end": 2.4,    "text": "Assalomu alaykum, qanday yordam bera olaman?" }→ { "type": "stop" }← { "type": "done", "audio_seconds": 2.9 }

Browsers can't send headers over WebSocket: connect from your server and proxy the stream.

Models

An alias always points to the current version.

GET/v1/models

ModelParametersWERWhen to use
uzasr-large600M8.1%Default, maximum accuracy
uzasr-base220M9.4%High volumes, lower cost

Errors

A single OpenAI-compatible format.

HTTPcodeWhat happened
400unsupported_parameterUnknown form parameter.
400unsupported_languagelanguage is set to something other than uz.
400audio_unreadableCouldn't decode the audio.
400audio_too_longThe recording exceeds the endpoint limit. Use /v1/jobs.
401invalid_api_keyThe key is missing, invalid or revoked.
404model_not_foundNo such model. See GET /v1/models.
413file_too_largeThe file exceeds the size limit.
429concurrency_limit_exceededToo many concurrent requests. See Retry-After.
503model_unavailableThe model is starting up or under maintenance. Try again in a minute.
504timeoutTranscription timed out. For long files, use /v1/jobs.
JSON
{  "error": {    "type": "invalid_request_error",    "code": "unsupported_language",    "message": "Only 'uz' is supported"  }}

Limits

Default values. Configurable for enterprise customers.

LimitValue
Synchronous requestup to 10 minutes of audio
Async jobup to 3 hours of audio
Concurrent requests per key8
Realtime sessionup to 5 minutes
Job result retention7 days