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-Keyheader onPOST.
Create transcription
Returns 202 Accepted with a job. Provide exactly one of audio_url or upload_id.
| Field | Type | Description |
|---|---|---|
| audio_url* | string | Fetchable recording URL (or use upload_id) |
| upload_id* | string | From POST /v1/uploads |
| audio_auth | object | Optional Basic Auth for protected URLs (Bandwidth) |
| audio_auth.type | string | basic or bandwidth |
| audio_auth.username | string | API username |
| audio_auth.password | string | API password |
| model | string | standard (default) or pro |
| features.diarization | bool | Speaker labels |
| features.redaction | bool | PII / PCI redaction |
| features.multichannel | bool | Dual-channel calls |
| callback_url | string | Signed webhook destination when complete |
| metadata | object | Optional 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 bevoice.bandwidth.com) - Or
type: "basic"for any HTTPS URL that needs Basic Auth - Set
features.multichannel: truefor 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
Fetch a single job by id. Status values include queued, processing, completed, and failed.
List transcriptions
| Query | Type | Description |
|---|---|---|
| status | string | Filter by job status |
| limit | int | Max 200 (default 50) |
| offset | int | Pagination offset |
Purge transcript
Removes stored transcript text for the job (metadata is retained). Returns 204 No Content.
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
| Status | Meaning |
|---|---|
| 400 | Invalid request (e.g. unsafe URL, missing source, bad Bandwidth host) |
| 401 | Missing or invalid API key |
| 402 | Insufficient credits / spend guardrail |
| 404 | Job not found for this project |
Job-level fetch failures (after accept) set error_code on the job:
| error_code | Meaning |
|---|---|
| auth_failed | Bandwidth/Basic Auth rejected (401/403) |
| fetch_failed | Could not download the recording URL |
| rehost_failed | Upload to transcription pipeline failed |
| empty_audio | Recording URL returned an empty body |
| audio_too_large | Recording exceeded size limit |
Need help integrating? See Support.