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.mp3

3. 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.

EndpointPurposeLimit
POST /v1/audio/ingestCreate an async upload sessionBest effort
POST /v1/audio/uploadsCreate upload sessionUp to 2 GB
GET /v1/audio/uploads/:idRecover or inspect upload state
POST /v1/audio/uploads/:id/completeFinalize upload sessionIdempotent
POST /v1/audio/jobsCreate async transcription jobCompleted upload required
GET /v1/audio/jobs/:idPoll 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

StatusCodeMeaning
400invalid_requestMissing or invalid request field
401unauthorizedAPI key missing or invalid
402insufficient_creditsWorkspace has no available quota
403plan_requiredPlan does not include API access
413file_too_largeUpload exceeds the supported object limit
415unsupported_media_typeAudio/video format is not supported
429rate_limit_exceededRetry after the returned Retry-After value
500 / 502internal_errorInclude 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_.

Obter chave API

See pricing

Plans control included minutes, concurrency, and API access.

Preços