Audio Generation
Generate speech audio from text with ElevenLabs v3.
Generate audio
POST /api/v1/audio/generate
Scope: audio:generate
Turn text into an MP3. The request returns immediately with an id. Poll Get generation until the job is completed or failed.
Audio generation requires at least one credit purchase on the account. Signup credits are not enough. See Purchase required.
Request body
Generic fields stay at the top level. Settings unique to ElevenLabs go in provider_options.
| Field | Type | Required | Description |
|---|---|---|---|
text | string | Yes | Text to speak, 1–5,000 characters. Eleven v3 audio tags may be included inline. |
provider | string | Yes | Currently elevenlabs |
output_format | string | No | Currently mp3; defaults to mp3 |
provider_options | object | Yes | Provider-specific settings (see below) |
provider_options (ElevenLabs)
| Field | Type | Required | Description |
|---|---|---|---|
voice_id | string | Yes | ElevenLabs voice ID |
model | string | No | Currently eleven_v3 |
stability | string | No | creative, natural, or robust (default: natural) |
language_code | string | No | Two-letter ISO 639-1 code (en, he, …) |
seed | integer | No | Best-effort deterministic seed. Identical output is not guaranteed. |
text_normalization | string | No | auto, on, or off (default: auto) |
Credits
Cost is based on text length: 1 credit per 400 characters, rounded up, minimum 1. Charged when the job starts. Failed jobs are refunded. The start response includes credits_used and remaining_credits.
Examples: 1 character costs 1 credit. 400 characters cost 1. 401 characters cost 2.
Eleven v3 text
Put delivery direction in text:
- Audio tags such as
[whispers],[excited], or[sighs] - Ellipses, punctuation, capitalization, and line breaks for pauses, rhythm, and emphasis
- Do not use SSML
<break>tags; Eleven v3 does not support them - Pick a voice whose natural character matches the delivery. Tag behavior varies by voice
One voice per request. For more than one speaker, generate a separate job per voice.
Example
curl -X POST https://powerpost.ai/api/v1/audio/generate \
-H "x-api-key: pp_live_sk_YOUR_KEY" \
-H "X-Workspace-Id: YOUR_WORKSPACE_ID" \
-H "Content-Type: application/json" \
-d '{
"text": "[warmly] Welcome to PowerPost.",
"provider": "elevenlabs",
"output_format": "mp3",
"provider_options": {
"model": "eleven_v3",
"voice_id": "YOUR_VOICE_ID",
"stability": "natural",
"language_code": "en"
}
}'Response
{
"audio_generation_id": "22222222-2222-4222-8222-222222222222",
"status": "processing",
"status_url": "/api/v1/audio/generations/22222222-2222-4222-8222-222222222222",
"created_at": "2026-09-04T18:30:00Z",
"credits_used": 1,
"remaining_credits": 46
}| Field | Type | Description |
|---|---|---|
audio_generation_id | string | Id to poll for this job |
status | string | Always processing on a successful start |
status_url | string | Relative URL to poll for results |
created_at | string | ISO 8601 timestamp |
credits_used | number | Credits deducted |
remaining_credits | number | Balance after deduction |
Errors
| Code | Description |
|---|---|
| 400 | Invalid request body |
| 401 | Invalid API key |
| 402 | Insufficient credits (INSUFFICIENT_CREDITS) |
| 402 | Purchase required (MEDIA_REQUIRES_PURCHASE) |
| 403 | API key is missing the audio:generate scope |
| 429 | Rate limit exceeded |
Get generation
GET /api/v1/audio/generations/{id}
Scope: audio:read
Poll every 2–5 seconds until status is completed or failed.
Path parameters
| Parameter | Type | Description |
|---|---|---|
id | string | The audio generation id |
Example
curl https://powerpost.ai/api/v1/audio/generations/22222222-2222-4222-8222-222222222222 \
-H "x-api-key: pp_live_sk_YOUR_KEY" \
-H "X-Workspace-Id: YOUR_WORKSPACE_ID"Response (processing)
{
"audio_generation_id": "22222222-2222-4222-8222-222222222222",
"status": "processing",
"provider": "elevenlabs",
"model": "eleven_v3",
"error": null,
"created_at": "2026-09-04T18:30:00Z",
"updated_at": "2026-09-04T18:30:01Z",
"audio": null
}Response (completed)
{
"audio_generation_id": "22222222-2222-4222-8222-222222222222",
"status": "completed",
"provider": "elevenlabs",
"model": "eleven_v3",
"error": null,
"created_at": "2026-09-04T18:30:00Z",
"updated_at": "2026-09-04T18:30:08Z",
"audio": {
"audio_id": "33333333-3333-4333-8333-333333333333",
"media_id": "33333333-3333-4333-8333-333333333333",
"url": "https://temporary-signed-url.example/audio.mp3",
"file_name": "33333333-3333-4333-8333-333333333333.mp3",
"file_size": 123456,
"mime_type": "audio/mpeg",
"duration": 4.2
}
}Response (failed)
{
"audio_generation_id": "22222222-2222-4222-8222-222222222222",
"status": "failed",
"provider": "elevenlabs",
"model": "eleven_v3",
"error": {
"code": "AUDIO_GENERATION_FAILED",
"message": "Audio generation failed"
},
"created_at": "2026-09-04T18:30:00Z",
"updated_at": "2026-09-04T18:30:08Z",
"audio": null
}Response fields
| Field | Type | Description |
|---|---|---|
audio_generation_id | string | Audio generation id |
status | string | processing, completed, or failed |
provider | string | Speech provider |
model | string | Model used for this job |
error | object | null | Present when status is failed |
created_at | string | ISO 8601 timestamp |
updated_at | string | ISO 8601 timestamp |
audio | object | null | Output file when status is completed |
Audio object
| Field | Type | Description |
|---|---|---|
audio_id | string | Generated audio asset id. Same value as media_id. |
media_id | string | Workspace media library id. |
url | string | null | Signed MP3 URL, valid for 1 hour |
file_name | string | Stored file name |
file_size | number | Size in bytes |
mime_type | string | audio/mpeg |
duration | number | null | Length in seconds, when known |
Status values
| Status | Description |
|---|---|
processing | Speech is being generated |
completed | MP3 is ready |
failed | Generation failed; credits are refunded |
audio.url is signed and expires after 1 hour. Keep audio_generation_id and call this endpoint
again for a fresh URL. Completed audio is also stored in the workspace media library as
media_type: audio. You cannot pass media_id on posts yet; no publish destination accepts a
raw MP3. Use Video audio to mix it into a publishable MP4. If the media item is deleted, the generation remains in history and audio becomes
null, matching image and video generations.
Errors
| Code | Description |
|---|---|
| 401 | Invalid API key |
| 403 | API key is missing the audio:read scope |
| 404 | Audio generation not found |
| 429 | Rate limit exceeded |