API Reference

Submit call recordings, get durable job delivery, and receive signed webhooks when transcripts are ready. Base URL: https://api-production-254f.up.railway.app

Authentication

All API requests use a project API key in the Authorization header. Create keys in the dashboard (test or live mode).

Authorization: sk_live_...
  • Test keys return synthetic completed jobs and never hit the vendor.
  • Live keys bill against prepaid credits and run the full pipeline.
  • Create and list jobs require an Idempotency-Key header on POST.

Create transcription

POST /v1/transcriptions

Returns 202 Accepted with a job. Provide exactly one of audio_url or upload_id.

FieldTypeDescription
audio_url*stringFetchable recording URL (or use upload_id)
upload_id*stringFrom POST /v1/uploads
audio_authobjectOptional Basic Auth for protected URLs (Bandwidth)
audio_auth.typestringbasic or bandwidth
audio_auth.usernamestringAPI username
audio_auth.passwordstringAPI password
modelstringstandard (default) or pro
features.diarizationboolSpeaker labels
features.redactionboolPII / PCI redaction
features.multichannelboolDual-channel calls
callback_urlstringSigned webhook destination when complete
metadataobjectOptional client metadata
POST https://api-production-254f.up.railway.app/v1/transcriptions
Authorization: sk_live_...
Idempotency-Key: call-42891
Content-Type: application/json

{
  "audio_url": "https://.../call-42891.wav",
  "model": "standard",
  "features": { "diarization": true, "redaction": true },
  "callback_url": "https://your.app/webhooks/diodeo"
}

Bandwidth recordings

Bandwidth recordingAvailable webhooks include a mediaUrl that requires HTTP Basic Auth. Pass that URL as audio_url with audio_auth. diodeo downloads the recording with your credentials, rehosts it for transcription, then clears the credentials from the job.

  • Use audio_auth.type: "bandwidth" (host must be voice.bandwidth.com)
  • Or type: "basic" for any HTTPS URL that needs Basic Auth
  • Set features.multichannel: true for dual-channel Bandwidth recordings
  • Credentials are never written into Temporal workflow history
// From Bandwidth recordingAvailable.mediaUrl
POST https://api-production-254f.up.railway.app/v1/transcriptions
Authorization: sk_live_...
Idempotency-Key: bw-r-115da407
Content-Type: application/json

{
  "audio_url": "https://voice.bandwidth.com/api/v2/accounts/.../media",
  "audio_auth": {
    "type": "bandwidth",
    "username": "YOUR_BANDWIDTH_USERNAME",
    "password": "YOUR_BANDWIDTH_PASSWORD"
  },
  "model": "standard",
  "features": { "diarization": true, "multichannel": true },
  "callback_url": "https://your.app/webhooks/diodeo"
}

Get transcription

GET /v1/transcriptions/{job_id}

Fetch a single job by id. Status values include queued, processing, completed, and failed.

List transcriptions

GET /v1/transcriptions
QueryTypeDescription
statusstringFilter by job status
limitintMax 200 (default 50)
offsetintPagination offset

Purge transcript

DELETE /v1/transcriptions/{job_id}

Removes stored transcript text for the job (metadata is retained). Returns 204 No Content.

Uploads

POST /v1/uploads

Issues a presigned PUT URL. Upload bytes directly to storage, then create a transcription with the returned upload_id.

POST https://api-production-254f.up.railway.app/v1/uploads?content_type=audio/wav
Authorization: sk_live_...

// -> { upload_id, upload_url, ... }

Webhooks

When you set callback_url, diodeo POSTs a signed payload when the job finishes. Verify the HMAC signature before trusting the body. Failed deliveries are retried automatically.

  • Prefer webhooks over polling for production volume.
  • You can still GET /v1/transcriptions/{id} as a fallback.
  • Transcripts are held briefly for retry, then purged per your retention settings.

Errors

StatusMeaning
400Invalid request (e.g. unsafe URL, missing source, bad Bandwidth host)
401Missing or invalid API key
402Insufficient credits / spend guardrail
404Job not found for this project

Job-level fetch failures (after accept) set error_code on the job:

error_codeMeaning
auth_failedBandwidth/Basic Auth rejected (401/403)
fetch_failedCould not download the recording URL
rehost_failedUpload to transcription pipeline failed
empty_audioRecording URL returned an empty body
audio_too_largeRecording exceeded size limit

Need help integrating? See Support.