Production API uses async jobs.
External API keys use recoverable uploads, job creation, status polling, and webhook callbacks. The short-audio fast path is an internal product lane, not a public token API.
Quickstart
Create an API key in the console (keys start with ahk_). External integrations use the three-step async flow: upload, complete upload, create job.
Three-step async workflow
1. POST /v1/audio/uploads
curl https://audio.niumedia-ai.com/v1/audio/uploads \
-H "Authorization: Bearer $ORPHEUS_KEY" \
-H "Content-Type: application/json" \
-d '{"file_name":"meeting.mp3","mime_type":"audio/mpeg","size_bytes":52428800}'2. PUT $UPLOAD_URL
curl $UPLOAD_URL \
-X PUT \
-H "Content-Type: audio/mpeg" \
--data-binary @meeting.mp33. POST /v1/audio/jobs
# Complete the upload session, then create the job.
curl https://audio.niumedia-ai.com/v1/audio/uploads/$UPLOAD_ID/complete \
-H "Authorization: Bearer $ORPHEUS_KEY" \
-X POST
curl https://audio.niumedia-ai.com/v1/audio/jobs \
-H "Authorization: Bearer $ORPHEUS_KEY" \
-H "Content-Type: application/json" \
-d '{"upload_id":"$UPLOAD_ID","task":"transcribe","callback_url":"https://your-app.com/webhook"}'Endpoint overview
The public API exposes the durable async contract only. Console workbench handles short-audio fast paths inside the product surface.
| Endpoint | Purpose | Limit |
|---|---|---|
POST /v1/audio/ingest | Create an async upload session | Best effort |
POST /v1/audio/uploads | Create upload session | Up to 2 GB |
GET /v1/audio/uploads/:id | Recover or inspect upload state | — |
POST /v1/audio/uploads/:id/complete | Finalize upload session | Idempotent |
POST /v1/audio/jobs | Create async transcription job | Completed upload required |
GET /v1/audio/jobs/:id | Poll job status or fetch result | — |
Webhook callbacks
Pass callback_url when creating the job. Orpheus sends one signed POST when the job reaches a terminal state; non-2xx responses are retried up to 3 times.
- Header:
X-Orpheus-Signature - Format:
t=<unix_seconds>,v1=<hmac_sha256_hex> - Signed payload:
<timestamp>.<raw_body> - Replay window: reject timestamps older than 5 minutes
import crypto from 'node:crypto'
export function verify(rawBody: string, sigHeader: string, secret: string) {
const parts = Object.fromEntries(sigHeader.split(',').map((p) => p.split('=', 2)))
const timestamp = parseInt(parts.t, 10)
if (Math.abs(Date.now() / 1000 - timestamp) > 300) throw new Error('timestamp too old')
const expected = crypto.createHmac('sha256', secret).update(`${timestamp}.${rawBody}`).digest('hex')
if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1))) throw new Error('bad signature')
}Error codes
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | Missing or invalid request field |
| 401 | unauthorized | API key missing or invalid |
| 402 | insufficient_credits | Workspace has no available quota |
| 403 | plan_required | Plan does not include API access |
| 413 | file_too_large | Upload exceeds the supported object limit |
| 415 | unsupported_media_type | Audio/video format is not supported |
| 429 | rate_limit_exceeded | Retry after the returned Retry-After value |
| 500 / 502 | internal_error | Include x-orpheus-request-id when contacting support |
Rate limits
Each API key has its own requests-per-minute ceiling. Over-limit requests return 429 with a Retry-After header.
Get an API key
Open the console, upgrade to an API-enabled plan, and create a key starting with ahk_.
API-toegang