Voice prompts
Voice prompts are the phone system's audio files: welcome, menu, closed and announcement messages, and music on hold tracks. They can be uploaded as files or generated from text with a synthetic voice. Scopes media:read / media:write.
Uploading a file
Accepted formats: MP3, WAV, OGG, M4A, up to 20 MB. Audio is normalized and automatically converted to telephony formats; in the meantime the prompt is shown as processing.
curl -s -X POST https://centralino.exovoip.it/api/v1/prompts/upload \
-H "X-API-Key: $EXOPBX_API_KEY" \
-F name="Benvenuto" -F kind="prompt" -F file=@benvenuto.wavimport { readFile } from 'node:fs/promises';
const audio = new Blob([await readFile('benvenuto.wav')], { type: 'audio/wav' });
const uploaded = await pbx.prompts.upload({
name: 'Benvenuto',
kind: 'prompt',
file: audio,
filename: 'benvenuto.wav',
});$prompt = $pbx->prompts->upload('benvenuto.wav', ['name' => 'Benvenuto', 'kind' => 'prompt']);prompt = pbx.prompts.upload("benvenuto.wav", {"name": "Benvenuto", "kind": "prompt"})| Field | Values |
|---|---|
kind | prompt (message), announcement (announcement), moh (music track), whisper (announcement to the agent) |
lang | it, en, de, fr, es |
Generating from text
curl -s -X POST https://centralino.exovoip.it/api/v1/prompts \
-H "X-API-Key: $EXOPBX_API_KEY" -H "Content-Type: application/json" \
-d '{"name":"Chiusura","kind":"announcement","lang":"it",
"text":"Grazie per aver chiamato. I nostri uffici sono chiusi, richiamare dalle 9 alle 18."}'
curl -s -X POST https://centralino.exovoip.it/api/v1/prompts/31/generate -H "X-API-Key: $EXOPBX_API_KEY"
curl -s https://centralino.exovoip.it/api/v1/jobs/88 -H "X-API-Key: $EXOPBX_API_KEY"const { prompt } = await pbx.prompts.createTts({
name: 'Chiusura',
kind: 'announcement',
lang: 'it',
text: 'Grazie per aver chiamato. I nostri uffici sono chiusi, richiamare dalle 9 alle 18.',
});
const { job } = await pbx.prompts.generate(prompt.id); // elaborazione in background
const state = await pbx.jobs.get(job.id); // pending → running → done$prompt = $pbx->prompts->createTts(['name' => 'Chiusura', 'kind' => 'announcement', 'lang' => 'it', 'text' => 'Grazie per aver chiamato.'])['prompt'];
$job = $pbx->prompts->generate($prompt['id'])['job'];
$state = $pbx->jobs->get($job['id']);prompt = pbx.prompts.create_tts({"name": "Chiusura", "kind": "announcement", "lang": "it", "text": "Grazie per aver chiamato."})["prompt"]
job = pbx.prompts.generate(prompt["id"])["job"]
state = pbx.jobs.get(job["id"])Generation runs in the background: POST /v1/prompts/:id/generate returns a job whose status can be read with GET /v1/jobs/:id (pending, running, done, failed). Editing the text with PATCH returns the prompt to draft until it is generated again.
GET /v1/prompts/:id/audio returns the audio for playback; usedBy in the details shows where the prompt is used (a prompt in use cannot be deleted: 409 IN_USE).
Choosing the voice
GET /v1/voices lists the voices available for text prompts, default voice first. Filters: lang (it, en, de, fr, es) and gender (female, male, neutral). Each voice has a name, gender, age, tone, suggested use and languages; isDefault marks the voice used when a prompt does not specify one. The catalog updates automatically once a day.
- Preview:
GET /v1/voices/:voiceId/previewreturns a short MP3 sample (withETagand 24-hour caching). - Try your own text:
POST /v1/voices/:voiceId/samplewith{ "text": "...", "lang": "en" }(up to 200 characters) returns WAV audio. Tries are limited to 20 per day per company (429 RATE_LIMITEDbeyond the limit); a sentence already played does not count. TheX-Samples-Remainingheader shows the tries left. - Company default voice:
PUT /v1/voices/defaultwith{ "voiceId": "..." };nullgoes back to the platform's recommended voice.
To use a voice in a prompt, pass voiceId in POST /v1/prompts or PATCH /v1/prompts/:id (an unavailable voice returns 400 VALIDATION_ERROR). Without voiceId the prompt uses the company default voice.
Endpoints
| Request | Scope | SDK method |
|---|---|---|
GET /v1/jobs/:id | media:read | jobs.get() |
GET /v1/prompts | media:read | prompts.list() |
POST /v1/prompts | media:write | prompts.createTts() · py: prompts.create_tts() |
POST /v1/prompts/upload | media:write | prompts.upload() |
GET /v1/prompts/:id | media:read | prompts.get() |
PATCH /v1/prompts/:id | media:write | prompts.update() |
DELETE /v1/prompts/:id | media:write | prompts.delete() |
POST /v1/prompts/:id/generate | media:write | prompts.generate() |
GET /v1/prompts/:id/audio | media:read | prompts.audio() |
GET /v1/voices | media:read | voices.list() |
POST /v1/voices/sync | system:write | voices.sync() |
PUT /v1/voices/default | media:write | voices.setTenantDefault() · py: voices.set_tenant_default() |
PUT /v1/voices/platform-default | system:write | voices.setPlatformDefault() · py: voices.set_platform_default() |
GET /v1/voices/:voiceId/preview | media:read | voices.preview() |
POST /v1/voices/:voiceId/sample | media:write | voices.sample() |
