Reference
API reference
The public HTTP contract in one place. This reference lists customer-facing endpoints; internal and administrative endpoints are not part of the public contract.
Authentication
Use Authorization: Bearer <OMI_API_KEY> on every HTTP request. API keys are tenant credentials; keep them server-side and rotate them from the console.
Do not ship API keys in browser bundles
Public endpoints
/v1/audio/transcriptionsDirect upload: inline result or async job
/v1/jobsCreate a presigned large-upload slot
/v1/jobs/{job_id}/completeFreeze upload and enqueue
/v1/jobs/{job_id}Poll job and obtain result URL
/v1/jobs/{job_id}Reserved; cancellation is unsupported in v1
/v1/streamRealtime transcription on every plan; API key is sent in the start message
Synchronous multipart fields
| Field | Type | Default / limit | Availability |
|---|---|---|---|
file | binary | required · exactly ≤100,000,000 bytes | Inline up to 60.000 s; otherwise async |
model | string | required | omi-medical-1 |
response_format | enum | diarized_json | text, json, verbose_json, diarized_json |
language | BCP-47 / auto | dominant-language detection when omitted | Eight supported language families |
language_hints | JSON array string | 1–8 | Only with language=auto |
dictionary | boolean | true | Suppress stored terms with false; availability is model-specific |
vocabulary | JSON array string | ≤1,000 terms | omi-medical-1; lists above 50 select the 50 most relevant terms; ≤96 chars per term |
patterns | string | ≤32 expressions | Every plan; omi-medical-1 |
profile | enum | default | Omit or send default. standard and turbo are deprecated compatibility aliases with identical behavior. |
diarize | boolean | false | Attach speaker labels and word timestamps |
max_speakers | integer | 1–4 · default 4 | Upper speaker-count ceiling when diarize=true; excess identity is never folded into another person |
webhook_url | HTTPS URL | optional · port 443 | Forces async; requires signing secret |
Optional header Idempotency-Key applies only when this request creates an async job. Inline 200 requests accept and ignore it.
Verbose response
{
"text": "The patient takes metformin 500 mg twice daily.",
"language": "en",
"duration": 4.82,
"model": "omi-medical-1",
"request_id": "0b0e…",
"segments": [
{
"id": "seg_0001",
"speaker": "A",
"text": "The patient takes metformin 500 mg twice daily.",
"start": 0.22,
"end": 4.60,
"confidence": null,
"language": "en"
}
],
"words": [
{"word":"The","start":0.22,"end":0.36,"speaker":"A"}
],
"speakers": [{"speaker":"A"}],
"metadata": {
"api_version": "2026-07-01",
"runtime": "omi-runtime",
"processing_ms": {"asr": 640, "diarization": 0}
}
}| Field | Present when | Meaning |
|---|---|---|
text | always | Final normalized transcript. |
language | non-text JSON | Effective language; mixed for multilingual auto; und for silence. |
duration | verbose_json | Input duration in seconds. |
request_id | verbose_json | Also available as x-request-id; include it in support requests. |
profile | flagship JSON response or async job | Resolved processing profile: default. |
segments | verbose_json / diarized_json | Time-ordered transcript segments. |
words | alignment available | Acoustic word boundaries; speaker included when diarized. |
language_detection | verbose auto response | Candidates, selected languages, utterance count, and fallbacks. |
language_detection.mode | verbose detected-language response | dominant_probe for omission; per_utterance for explicit auto or a mixed probe. |
vocabulary | vocabulary used | Public context mode and safety audit. |
patterns | patterns used | Requested/applied counts and supporting transcript evidence. |
metadata | verbose_json | API version, public runtime label, and processing timing. |
Async job objects
{
"id": "job_…",
"object": "transcription.job",
"status": "accepted",
"created_at": "2026-07-26T01:02:03Z",
"model": "omi-medical-1",
"poll_url": "https://api.omi.health/v1/jobs/job_…",
"webhook": {"requested": false}
}Direct-upload jobs use accepted, running, succeeded, or failed. The presigned large-upload path also starts in awaiting_upload. A succeeded job contains result.download_url; a failed job contains a stable error.code and safe message.
Limits
| Surface | Duration | Upload / capacity | Notes |
|---|---|---|---|
| Direct upload | Up to 2 hours | 100,000,000 bytes | 200 up to 60.000 s without webhook; otherwise 202 through the asynchronous-optimized pipeline. |
| Presigned large upload | Up to 2 hours | 1 GiB | Result URL expires after 15 minutes. |
| Realtime | Up to 30 minutes per session | Builder: 2 live / 1 speaker room. Pay as you go: 10 live / 2 speaker rooms. Enterprise: custom or reserved. | wss://api.omi.health/v1/stream on every plan; 16 kHz mono PCM16; $0.45/audio-hour after the pooled allowance. |
| Vocabulary | per request | 1,000 terms | Lists of ≤50 are considered in full; larger lists select the 50 most relevant. Outcome fields report what was delivered. |
| Patterns | per request | 32 expressions | Never stored globally. |
| Auto hints | per request | 1–8 candidates | Supported families only. |
HTTP errors and retry behavior
Every error response uses exactly one envelope — {"error": {"code": "…", "message": "…"}} — on every route. No other top-level keys are returned and the message never reflects request content. Branch on error.code, never on message text.
| Status | Meaning | What your client should do |
|---|---|---|
400 | Malformed request, unsupported model option, or mismatched content type. | Fix the request; do not retry unchanged. |
401 | Missing or invalid API key. | Verify the bearer token and replace or rotate the credential if needed. |
402 | Usage is paused for billing: promotional credit and this month's included audio-hours are used up, a spend cap was reached, or a payment failed (billing_blocked). | Add a card on Billing to continue at $0.29/batch hour or $0.45/live hour, or wait for the UTC monthly reset. Results remain retrievable. |
403 | Your account is not entitled to a requested feature (entitlement_denied). | The key is valid; the feature is not enabled for it. Do not retry unchanged — remove the field or check the console for availability. |
404 | Unknown or non-owned job. | Check the job ID and the key that created it. |
408 | The upload timed out or remained below the minimum transfer rate. | Retry as a new request; preserve the idempotency key only when the request identity is unchanged. |
409 | The idempotency key is already in progress or was used for different request content. | Poll/retry the original request, or use a new key only for genuinely different content. |
413 | File or duration exceeds this route. | Move to async or split at a natural silence. |
415 | The multipart body or audio container is unsupported. | Send a supported audio file and multipart content type. |
422 | Unsupported/detected language, invalid vocabulary, pattern, hints, or speaker count. | Correct the field value or candidate set. |
429 | Rate, queue, or capacity limit. | Honor Retry-After with exponential backoff and jitter. |
503 | Temporary backend, detector, storage, or processing-capacity issue. | Honor Retry-After. Do not silently switch language or processing path. |
410 | An Omi-served result surface has expired. | The transcript must be regenerated; an expired signed storage URL uses the storage provider’s native response. |
Data handling
- Uploaded audio is deleted when processing completes or fails — inline and asynchronous alike.
- Async result artifacts are owner-scoped and retained until your configured expiry: default 24 hours, configurable 1–72 hours in the console. Job metadata and expiry tombstones may remain for up to 72 hours so expired jobs return a stable response. Webhook jobs have an effective 9-hour minimum.
- Operational telemetry stores non-content usage and safety counters, not transcript text.
- For protected health information (PHI), execute the self-serve Business Associate Agreement in the console before submitting audio. A GDPR Data Processing Agreement applies to all personal-data processing and is accepted at signup.
Availability and support
View independently hosted service probes on the Omi status page. For support, email hello@omi.health and include the request_id.