English
English
Appearance
English
English
Appearance
Two shared resource groups used in AutoCall:
voice_id when creating a script..wav/.mp3/...) used as target_audio_url for the DTMF actions playback / playback_then_hangup.GET /api/autocall/voicesPurpose: returns only available voices. These voices are guaranteed to render preview/dial successfully — they will NOT throw Voice not available as can happen with arbitrary voices from a provider.
Response 200 (only the 5 fields the client needs):
{
"data": [
{
"id": "voice_id_premium_02",
"name": "vi-VN-female-01",
"preview_url": "https://app.zorio.vn/api/autocall/voices/preview",
"gender": "female",
"language": "vi"
}
]
}Response fields:
| Field | Type | Description |
|---|---|---|
id | string | Voice ID — used as voice_id when calling POST /api/autocall/scripts |
name | string | Friendly display name |
preview_url | string | null | MP3 sample URL for preview playback |
gender | string | null | male / female |
language | string | null | vi / en / ... |
Fallback when a provider fails
If a provider integration is temporarily unreachable (network/API key), the endpoint still returns the voice with only the id + name=id fields so the client does NOT error out — the UI can fall back to displaying the raw ID.
Tier A vs Tier B
tts_tier is configured at the script level (see Scripts). The system auto-routes by voice_id → matching provider.
The standard Zorio Media Files module — upload audio files (.wav/.mp3/.m4a/...) and they are auto-converted to WAV 16-bit PCM 8 kHz mono. Inside AutoCall, use the file_path of a media file as target_audio_url for the DTMF actions playback / playback_then_hangup.
Category enum:
announcement — announcement for DTMF actions (e.g. "Thank you", "Transferring you to an agent...")ivr — IVR prompts (greeting, menu...)moh — music on holdlibrary — generalPermission
manage_recordings or admin is required to upload/edit/delete; viewers may list and fetch audio.
GET /api/media-files?category=announcementQuery:
| Param | Type | Description |
|---|---|---|
category | string, optional | Filter by the enum ivr / moh / announcement / library. Omit → return all |
Response 200:
{
"data": [
{
"id": 20,
"tenant_id": 1,
"name": "VNT v2",
"file_path": "/media/ivr/studio-1776477792_1776477798_d939.wav",
"file_size": 176718,
"duration": 11,
"format": "wav",
"category": "ivr",
"tts_text": null,
"tts_voice": null,
"tts_provider": null,
"created_at": "2026-04-18 02:03:19"
}
]
}Response fields:
| Field | Type | Description | Valid values |
|---|---|---|---|
data[].id | integer | Media file ID | Positive integer |
data[].tenant_id | integer | ID of the owning account | — |
data[].name | string | Display name | Up to 255 characters |
data[].file_path | string | File identifier (use as target_audio_url) for DTMF action playback | Internal identifier |
data[].file_size | integer | File size (bytes) | > 0 |
data[].duration | integer | Audio duration (seconds) | >= 0 |
data[].format | string | Audio format (always wav after conversion) | wav |
data[].category | string | File category | ivr / moh / announcement / library |
data[].tts_text | string | null | Source text (only != null if the file was synthesized via TTS) | — |
data[].tts_voice | string | null | Voice ID (only for TTS files) | — |
data[].tts_provider | string | null | TTS provider used | tts_provider_01 / local / null |
data[].created_at | datetime | Upload time (UTC, format YYYY-MM-DD HH:mm:ss) | — |
TTS metadata fields
tts_text, tts_voice, tts_provider are only != null when the file was synthesized via TTS (not relevant for manually uploaded files). Informational; integrators do not need to handle them.
POST /api/media-files
Content-Type: multipart/form-dataBody (multipart):
| Field | Required | Type | Description |
|---|---|---|---|
file | Yes | binary | Audio file (.wav, .mp3, .m4a, .ogg, .aac, .flac). Max 50 MB |
name | Yes | string | Display name (e.g. "Thank you message") |
category | No | enum | ivr / moh / announcement / library. Default library |
Sample request (curl):
curl -X POST https://app.zorio.vn/api/media-files \
-H "Authorization: Bearer $TOKEN" \
-H "Accept: application/json" \
-F "file=@thank-you.mp3" \
-F "name=Thank you message" \
-F "category=announcement"Response 201:
{
"data": {
"tenant_id": 1,
"name": "Test",
"file_path": "/media/library/test_1782374777.wav",
"file_size": 43704,
"duration": 3,
"format": "wav",
"category": "library",
"id": 21
},
"message": "File uploaded and converted successfully."
}Response fields:
| Field | Type | Description | Valid values |
|---|---|---|---|
data.id | integer | Newly created media file ID | Positive integer |
data.tenant_id | integer | ID of the owning account | — |
data.name | string | Display name | — |
data.file_path | string | File identifier after conversion (WAV 16-bit PCM 8 kHz mono) | Internal identifier |
data.file_size | integer | Converted file size (bytes) | > 0 |
data.duration | integer | Audio duration (seconds) | >= 0 |
data.format | string | Format after conversion | Always wav |
data.category | string | File category | ivr / moh / announcement / library |
message | string | Success confirmation message | — |
Error 422 (wrong file format / too large):
{
"message": "The file must be a file of type: wav, mp3, m4a, ogg, aac, flac.",
"errors": { "file": ["The file must be a file of type: wav, mp3, m4a, ogg, aac, flac."] }
}Error 500 (server missing audio conversion engine):
{ "error": "audio conversion engine is not installed on the server" }PATCH /api/media-files/{id}Changes name / category only — the physical file is not touched.
Path params:
| Field | Type | Required | Description | Valid values |
|---|---|---|---|---|
id | integer | Yes | ID of the media file to update | Positive integer |
Body:
{
"name": "Thank you — version 2",
"category": "announcement"
}Body fields:
| Field | Type | Required | Description | Valid values |
|---|---|---|---|---|
name | string | No | Change display name | Up to 255 characters |
category | string | No | Change category | ivr / moh / announcement / library |
Response 200:
{
"data": {
"id": 21,
"tenant_id": 1,
"name": "Thank you — version 2",
"file_path": "/media/library/test_1782374777.wav",
"file_size": 43704,
"duration": 3,
"format": "wav",
"category": "announcement",
"tts_text": null,
"tts_voice": null,
"tts_provider": null,
"created_at": "2026-06-25 08:06:17"
},
"message": "Audio file updated."
}Response fields: same shape as a GET /api/media-files item (see the table in List media files) plus a message next to data.
POST /api/media-files/{id}/replace
Content-Type: multipart/form-dataThe old file is backed up as <path>.bak-<timestamp> and the new content is written to the same file_path — IVR/DTMF actions referencing target_audio_url do not need to be updated because the path is unchanged.
Path params:
| Field | Type | Required | Description | Valid values |
|---|---|---|---|---|
id | integer | Yes | ID of the media file to replace | Positive integer |
Body (multipart):
| Field | Type | Required | Description | Valid values |
|---|---|---|---|---|
file | binary | Yes | New audio file | .wav, .mp3, .m4a, .ogg, .aac, .flac, max 50 MB |
Response 200:
{
"data": {
"id": 21,
"tenant_id": 1,
"name": "Thank you — version 2",
"file_path": "/media/library/test_1782374777.wav",
"file_size": 43704,
"duration": 3,
"format": "wav",
"category": "announcement",
"tts_text": null,
"tts_voice": null,
"tts_provider": null,
"created_at": "2026-06-25 08:06:17"
},
"backup": "test_1782374777.wav.bak-20260625-080956",
"message": "File replaced successfully. The previous version has been backed up."
}Response fields:
| Field | Type | Description | Valid values |
|---|---|---|---|
data | object | Media file object (same shape as a GET /api/media-files item) | — |
backup | string | Name of the backup file for the previous version. Full path = dirname(file_path) + '/' + backup | <filename>.bak-<timestamp> |
message | string | Confirmation message | — |
backup field at top level
Not nested under data — it contains the backup file name. Full path = dirname(file_path) + '/' + backup.
DELETE /api/media-files/{id}Deletes the DB record + physical file.
Response 200:
{ "message": "Deleted." }Audit before deleting
If a DTMF action's target_audio_url still references the file, dialing will fail with "file not found". Audit usage before deleting.
GET /api/media-files/{id}/audioReturns a binary WAV stream with Content-Type: audio/wav. Use in an HTML5 <audio> tag or save via curl:
curl -s https://app.zorio.vn/api/media-files/5/audio \
-H "Authorization: Bearer $TOKEN" \
-o thank-you.wav