HTTP API · v1
Voices & audio API
From your first request to a complete integration. Create voices, generate audio and use the characters in your plan.
The API is disabled in this environment. The reference is public; live requests are not available yet.
Quickstart
1. Sign in and open Account → Developers → API. Create a key with voices:read, speech:generate, jobs:read and audio:read. Store the secret in VOCLONER_API_KEY on your server.
2. Call GET /voices and choose an authorized identifier. Send POST /speech with voice_id, text, format and your own stable Idempotency-Key.
3. Save the job id and poll GET /jobs/{id}. Once completed, download GET /assets/{asset_id}/content with the same Authorization header. The downloadable examples include the complete flow.
POST /speech
curl --request POST 'https://api.vocloner.org/v1/speech' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Idempotency-Key: REUSE_THIS_KEY_FOR_RETRIES' \
--header 'Content-Type: application/json' \
--data '{"voice_id":"c816ce5b-22f5-4ed2-91a9-90e79b874a24","text":"Hola, esta es mi primera generación con Vocloner.","format":"mp3"}'Authentication and permissions
Send Authorization: Bearer vcl_api_... with every request. REST and MCP keys are different credentials. Never place secrets in URLs, repositories or distributed applications.
Every key has explicit permissions, expiration and an optional budget. Keys cannot administer accounts or issue additional keys. Revoke a compromised key from the dashboard.
To rotate, create a successor, update your servers and revoke the old key. Rotation does not automatically revoke the existing key.
Reading a job requires jobs:read and its original operation permission. Canceling also requires jobs:cancel. Working with files requires files:write. Select these permissions when creating your key.
Cloning, design and consent
To clone, prepare a file with purpose: clone, upload it and confirm it. POST /voices requires consent_ownership: true. When a challenge is required, obtain its phrase from /consent-challenges, record it and upload the audio with purpose: consent.
New voices are private. Confirm consent_public_use: true to request publication. A voice becomes public only after required review and moderation. Report unauthorized use with /reports.
Design returns temporary candidates. Retrieve the batch and save a candidate using candidate_id before it expires. Saving requires an available voice slot and does not charge the design again.
Text, emotions and dialogues
POST /speech accepts MP3 or WAV and up to 12,000 text characters; your plan determines the effective per-request limit. Compatible expressive tags such as [excited] and [whispering] follow the web billing rules.
Dialogues support two to ten lines, authorized voices and gaps from 0 to 3,000 ms. Your plan must enable this feature. Current limits apply to each line.
Generated audio is processed and verified before it becomes available. Bytes without the forensic watermark are not delivered. A processing failure can prevent delivery even after the provider responds.
Files, tools and downloads
POST /files returns temporary upload instructions for private Storage. Upload the file following those instructions and confirm it with /files/{id}/complete. Pending files cannot be used.
The server validates format, actual size, duration and hash. Limits depend on purpose and operation; check /capabilities. Temporary files expire.
Tools accept exactly one file_id or generation_id. Check enabled operations and options before calling /audio-tools/{operation}. Derivatives of generated audio retain their provenance.
GET /assets/{id}/content requires authorization on every download. Retrieve /generations for history. Resources owned by someone else return 404; active jobs may prevent file deletion.
Upload limits: cloning 20 MiB and 5–270 seconds; remote tools 20 MiB and up to 20 minutes; local tools 25 MiB and up to 15 minutes; consent 5 MiB. Duration must be verifiable. The capabilities response is the reference for your environment.
Jobs, retries and idempotency
Long operations return 202 with id, status, status_url, result and usage. States are queued, running, reconciling, completed, failed and canceled. Reconciliation resolves an external effect whose outcome is not yet confirmed.
Use Idempotency-Key for creation and update operations. Reuse the same key and content after a timeout. Different content with the same key returns 409. Idempotency records are retained for thirty days.
Respect Retry-After when polling jobs or receiving 429/503. A POST with Prefer: wait=20 may return 200 or 202; both use the job resource. Never create another job just because the first one is slow.
Queued cancellation is immediate. Once work starts, cancellation is a request: wait for its final state and check usage before assuming no charge occurred.
The Postman collection keeps a different Idempotency-Key for each operation. Do not clear its variable when retrying. To begin a new operation, clear the corresponding idempotency_<operationId> collection variable.
Characters, limits and settlement
The API, web and MCP share the same plan. TTS charges billable text; a dialogue adds its lines. Cloning and designing a batch each cost 1,000 characters. Saving a candidate does not add a second design charge.
Reads and downloads do not consume characters. Tools retain their operation cost, which may depend on duration. /capabilities describes availability and limits; there is no account or balance endpoint.
Characters are reserved before execution, committed once on completion and released after definitive failure according to the operation policy. A dialogue may incur partial usage.
A key’s UTC monthly budget adds a limit to the shared balance and counts all active reservations, including those from a previous month. Creating more keys does not increase quota or concurrency. Results report reserved_characters, billed_characters and remaining_characters when applicable.
Signed notifications
Register HTTPS destinations in the developer dashboard for job.completed and job.failed. Save the signing secret when shown; polling is available without a destination.
Verify the signature against the original bytes before processing an event. Validate the timestamp and deduplicate by event identifier. Retries may deliver the same event more than once. Return 2xx after persisting it.
Events contain id, type, created_at and data: {job_id, status}. Destinations are managed in the dashboard. Use the verification example and project deployment guide when integrating your receiver.
Vocloner-Signature uses t=<unix>,v1=<hexadecimal HMAC-SHA256>. Sign the timestamp, a dot and the original body using the secret. Reject timestamps more than five minutes away. Vocloner-Event-Id identifies deliveries for deduplication.
Verify a notification on your server
import { createHmac, timingSafeEqual } from 'node:crypto';
function verify(rawBody: Buffer, header: string, secret: string) {
const match = /^t=(\d{1,12}),v1=([a-f0-9]{64})$/.exec(header);
if (!match) return false;
const timestamp = Number(match[1]);
if (Math.abs(Date.now() / 1000 - timestamp) > 300) return false;
const expected = createHmac('sha256', secret)
.update(String(timestamp) + '.').update(rawBody).digest();
return timingSafeEqual(expected, Buffer.from(match[2]!, 'hex'));
}
// Read the ORIGINAL request bytes, before parsing JSON.
export async function handleWebhook(request: Request,
persistEventOnce: (event: { id: string; type: string;
data: { job_id: string; status: string } }) => Promise<void>) {
const rawBody = Buffer.from(await request.arrayBuffer());
const secret = process.env.VOCLONER_WEBHOOK_SECRET!;
if (!secret || !verify(rawBody,
request.headers.get('Vocloner-Signature') ?? '', secret)) {
return new Response('Invalid signature', { status: 401 });
}
const event = JSON.parse(rawBody.toString('utf8'));
if (event.id !== request.headers.get('Vocloner-Event-Id')) {
return new Response('Invalid event ID', { status: 400 });
}
// Required: atomically insert event.id into a UNIQUE column and
// persist the job notification in your database. A duplicate ID
// returns 200 without applying the event again. On DB failure,
// return 500 so Vocloner can retry. Query /jobs/{job_id} with
// your API key when you need the authoritative result.
await persistEventOnce(event);
return new Response(null, { status: 200 });
}Errors, retention and support
All errors use error.code, error.message, error.request_id and error.retryable. Keep X-Request-Id to diagnose a request without storing keys or audio in logs.
Pagination returns items and next_cursor. Treat cursors as opaque and pass them unchanged. Resource identifiers are UUIDs, not provider identifiers.
Results and files follow current retention policies. Download anything you need to keep before it expires. The first version does not offer early streaming, real-time conversation or a delivery SLA.
| HTTP | What to do |
|---|---|
400 / 422 | Review fields, formats and limits in the contract. |
401 | Replace an invalid, expired or revoked key. |
403 | Review permissions, consent and plan capabilities. |
404 | Check the resource ID and owner. |
409 | Reuse the original content or choose a new key for a new operation. |
413 | Reduce file size to match its purpose limits. |
429 | Check quotas and concurrency; respect Retry-After. |
500 / 503 | Keep request_id and retry only when appropriate, using the same Idempotency-Key. |
Endpoint reference
Example identifiers and responses are illustrative. Replace them with authorized resources from your account.
26 / 26
GET/voicesList voices
Owned voices and authorized public voices. Paginate with cursor and limit.
- Required permission
voices:read- Usage
- No character charge
Request examples
curl --request GET 'https://api.vocloner.org/v1/voices' \
--header 'Authorization: Bearer YOUR_API_KEY'Response
200 · application/json
{
"items": [
{
"id": "c816ce5b-22f5-4ed2-91a9-90e79b874a24",
"name": "Example voice",
"visibility": "private",
"language": "es",
"category": "narrator",
"status": "ready",
"avatar_url": null,
"review_state": "approved",
"created_at": "2026-10-29T12:00:00.000Z"
}
],
"next_cursor": null
}Long operations return a job. Poll status_url until a terminal state. All errors include request_id.
Errors and recoveryGET/voices/{id}Get a voice
Retrieve metadata for a voice you are allowed to use.
- Required permission
voices:read- Usage
- No character charge
Request examples
curl --request GET 'https://api.vocloner.org/v1/voices/c816ce5b-22f5-4ed2-91a9-90e79b874a24' \
--header 'Authorization: Bearer YOUR_API_KEY'Response
200 · application/json
{
"id": "c816ce5b-22f5-4ed2-91a9-90e79b874a24",
"name": "Example voice",
"visibility": "private",
"language": "es",
"category": "narrator",
"status": "ready",
"avatar_url": null,
"review_state": "approved",
"created_at": "2026-10-29T12:00:00.000Z"
}Long operations return a job. Poll status_url until a terminal state. All errors include request_id.
Errors and recoveryPOST/voicesClone a voice
Upload and confirm a recording before cloning. Include a recorded challenge when required. New voices are private.
- Required permission
voices:clone- Usage
- 1,000 characters
Request body
| Field | Type and limits | Required |
|---|---|---|
file_id | string · uuid | Required |
name | string · length 1–120 | Required |
consent_ownership | boolean | Required |
language | string · length 2–40 · default: "es" | Optional |
category | string · length 2–40 · default: "narrator" | Optional |
locale | string · es | en · default: "es" | Optional |
consent_challenge_id | string · uuid | Optional |
consent_file_id | string · uuid | Optional |
Request examples
curl --request POST 'https://api.vocloner.org/v1/voices' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Idempotency-Key: REUSE_THIS_KEY_FOR_RETRIES' \
--header 'Content-Type: application/json' \
--data '{"file_id":"ab198ae5-9225-40f3-b176-56ed83861080","name":"Mi voz","consent_ownership":true,"language":"es","category":"narrator","locale":"es"}'Response
202 Accepted · application/json
{
"id": "f261e35c-420f-4c82-bd88-a0e370c936ab",
"operation": "clone",
"status": "queued",
"status_url": "https://api.vocloner.org/v1/jobs/f261e35c-420f-4c82-bd88-a0e370c936ab",
"created_at": "2026-10-29T12:00:00.000Z",
"started_at": null,
"completed_at": null,
"cancel_requested": false,
"result": null,
"error": null,
"usage": {
"reserved_characters": 1000,
"billed_characters": 0,
"remaining_characters": 9000
}
}Long operations return a job. Poll status_url until a terminal state. All errors include request_id.
Errors and recoveryPATCH/voices/{id}Update a voice
Update the name, language or category of an owned voice.
- Required permission
voices:write- Usage
- No character charge
Request body
| Field | Type and limits | Required |
|---|---|---|
name | string · length 1–120 | Optional |
language | string · length 2–40 · default: "es" | Optional |
category | string · length 2–40 · default: "narrator" | Optional |
Request examples
curl --request PATCH 'https://api.vocloner.org/v1/voices/c816ce5b-22f5-4ed2-91a9-90e79b874a24' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Idempotency-Key: REUSE_THIS_KEY_FOR_RETRIES' \
--header 'Content-Type: application/json' \
--data '{"name":"Narración"}'Response
200 · application/json
{
"id": "c816ce5b-22f5-4ed2-91a9-90e79b874a24",
"name": "Example voice",
"visibility": "private",
"language": "es",
"category": "narrator",
"status": "ready",
"avatar_url": null,
"review_state": "approved",
"created_at": "2026-10-29T12:00:00.000Z"
}Long operations return a job. Poll status_url until a terminal state. All errors include request_id.
Errors and recoveryDELETE/voices/{id}Delete a voice
Delete an owned voice. Existing generations keep their retention rules.
- Required permission
voices:delete- Usage
- No character charge
Request examples
curl --request DELETE 'https://api.vocloner.org/v1/voices/c816ce5b-22f5-4ed2-91a9-90e79b874a24' \
--header 'Authorization: Bearer YOUR_API_KEY'Response
200 · application/json
{
"deleted": true
}Long operations return a job. Poll status_url until a terminal state. All errors include request_id.
Errors and recoveryPOST/voices/{id}/publication-requestsRequest publication
Confirm public use permission and request review. A request does not automatically publish the voice.
- Required permission
voices:publish- Usage
- No character charge
Request body
| Field | Type and limits | Required |
|---|---|---|
consent_public_use | boolean | Required |
Request examples
curl --request POST 'https://api.vocloner.org/v1/voices/c816ce5b-22f5-4ed2-91a9-90e79b874a24/publication-requests' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Idempotency-Key: REUSE_THIS_KEY_FOR_RETRIES' \
--header 'Content-Type: application/json' \
--data '{"consent_public_use":true}'Response
201 · application/json
{
"voice_id": "c816ce5b-22f5-4ed2-91a9-90e79b874a24",
"review_state": "pending"
}Long operations return a job. Poll status_url until a terminal state. All errors include request_id.
Errors and recoveryPOST/voices/{id}/reportsReport a voice
Report impersonation, missing consent or other abuse for review.
- Required permission
voices:report- Usage
- No character charge
Request body
| Field | Type and limits | Required |
|---|---|---|
reason | string · impersonation | no_consent | offensive | spam | other | Required |
detail | string · length 0–1000 | Optional |
Request examples
curl --request POST 'https://api.vocloner.org/v1/voices/c816ce5b-22f5-4ed2-91a9-90e79b874a24/reports' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Idempotency-Key: REUSE_THIS_KEY_FOR_RETRIES' \
--header 'Content-Type: application/json' \
--data '{"reason":"no_consent","detail":"Información para la revisión."}'Response
200 · application/json
{
"reported": true
}Long operations return a job. Poll status_url until a terminal state. All errors include request_id.
Errors and recoveryPOST/voice-designsDesign voice candidates
Describe a voice to obtain temporary candidates. Save a candidate before using it for speech.
- Required permission
voices:design- Usage
- 1,000 characters
Request body
| Field | Type and limits | Required |
|---|---|---|
prompt | string · length 8–1000 | Required |
Request examples
curl --request POST 'https://api.vocloner.org/v1/voice-designs' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Idempotency-Key: REUSE_THIS_KEY_FOR_RETRIES' \
--header 'Content-Type: application/json' \
--data '{"prompt":"Una voz cálida, clara y pausada para narración en español."}'Response
202 Accepted · application/json
{
"id": "f261e35c-420f-4c82-bd88-a0e370c936ab",
"operation": "voice_design",
"status": "queued",
"status_url": "https://api.vocloner.org/v1/jobs/f261e35c-420f-4c82-bd88-a0e370c936ab",
"created_at": "2026-10-29T12:00:00.000Z",
"started_at": null,
"completed_at": null,
"cancel_requested": false,
"result": null,
"error": null,
"usage": {
"reserved_characters": 1000,
"billed_characters": 0,
"remaining_characters": 9000
}
}Long operations return a job. Poll status_url until a terminal state. All errors include request_id.
Errors and recoveryGET/voice-designs/{id}Get a voice design
Retrieve candidates and expiration for an owned design batch.
- Required permission
voices:design- Usage
- No character charge
Request examples
curl --request GET 'https://api.vocloner.org/v1/voice-designs/c816ce5b-22f5-4ed2-91a9-90e79b874a24' \
--header 'Authorization: Bearer YOUR_API_KEY'Response
200 · application/json
{
"id": "f261e35c-420f-4c82-bd88-a0e370c936ab",
"operation": "voice_design",
"status": "completed",
"status_url": "https://api.vocloner.org/v1/jobs/f261e35c-420f-4c82-bd88-a0e370c936ab",
"created_at": "2026-10-29T12:00:00.000Z",
"started_at": "2026-10-29T12:00:00.000Z",
"completed_at": "2026-10-29T12:00:00.000Z",
"cancel_requested": false,
"result": {
"design_id": "f261e35c-420f-4c82-bd88-a0e370c936ab",
"candidates": [
{
"id": "6e657fb6-cf58-46d8-9311-7f3828b203c7",
"index": 0,
"duration_ms": 3500,
"audio_url": "https://api.vocloner.org/v1/assets/6e657fb6-cf58-46d8-9311-7f3828b203c7/content"
}
]
},
"error": null,
"usage": {
"reserved_characters": 46,
"billed_characters": 46,
"remaining_characters": 9000
}
}Long operations return a job. Poll status_url until a terminal state. All errors include request_id.
Errors and recoveryPOST/voice-designs/{id}/voicesSave a candidate
Create a reusable private voice without charging the design again. Requires an available voice slot.
- Required permission
voices:design- Usage
- No character charge
Request body
| Field | Type and limits | Required |
|---|---|---|
candidate_id | string · uuid | Required |
name | string · length 1–120 | Required |
language | string · length 2–40 · default: "es" | Optional |
category | string · length 2–40 · default: "narrator" | Optional |
Request examples
curl --request POST 'https://api.vocloner.org/v1/voice-designs/c816ce5b-22f5-4ed2-91a9-90e79b874a24/voices' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Idempotency-Key: REUSE_THIS_KEY_FOR_RETRIES' \
--header 'Content-Type: application/json' \
--data '{"candidate_id":"c816ce5b-22f5-4ed2-91a9-90e79b874a24","name":"Narradora","language":"es","category":"narrator"}'Response
202 Accepted · application/json
{
"id": "f261e35c-420f-4c82-bd88-a0e370c936ab",
"operation": "voice_design_select",
"status": "queued",
"status_url": "https://api.vocloner.org/v1/jobs/f261e35c-420f-4c82-bd88-a0e370c936ab",
"created_at": "2026-10-29T12:00:00.000Z",
"started_at": null,
"completed_at": null,
"cancel_requested": false,
"result": null,
"error": null,
"usage": {
"reserved_characters": 46,
"billed_characters": 0,
"remaining_characters": 9000
}
}Long operations return a job. Poll status_url until a terminal state. All errors include request_id.
Errors and recoveryPOST/speechGenerate speech
Convert text to MP3 or WAV. Supports compatible expressive tags. Prefer: wait=20 waits up to twenty seconds; the response may still be 202.
- Required permission
speech:generate- Usage
- Billable text characters
Request body
| Field | Type and limits | Required |
|---|---|---|
voice_id | string · uuid | Required |
text | string · length 1–12000 | Required |
format | string · mp3 | wav · default: "mp3" | Optional |
Request examples
curl --request POST 'https://api.vocloner.org/v1/speech' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Idempotency-Key: REUSE_THIS_KEY_FOR_RETRIES' \
--header 'Content-Type: application/json' \
--data '{"voice_id":"c816ce5b-22f5-4ed2-91a9-90e79b874a24","text":"Hola, esta es mi primera generación con Vocloner.","format":"mp3"}'Response
202 Accepted · application/json
{
"id": "f261e35c-420f-4c82-bd88-a0e370c936ab",
"operation": "speech",
"status": "queued",
"status_url": "https://api.vocloner.org/v1/jobs/f261e35c-420f-4c82-bd88-a0e370c936ab",
"created_at": "2026-10-29T12:00:00.000Z",
"started_at": null,
"completed_at": null,
"cancel_requested": false,
"result": null,
"error": null,
"usage": {
"reserved_characters": 46,
"billed_characters": 0,
"remaining_characters": 9000
}
}Long operations return a job. Poll status_url until a terminal state. All errors include request_id.
Errors and recoveryPOST/dialoguesGenerate a dialogue
Between two and ten lines. Every voice must be authorized and the plan must enable dialogues.
- Required permission
speech:generate- Usage
- Billable text characters
Request body
| Field | Type and limits | Required |
|---|---|---|
lines | array · items 2–10 | Required |
lines[].voice_id | string · uuid | Required |
lines[].text | string · length 1–12000 | Required |
gap_ms | integer · 0–3000 · default: 400 | Optional |
Request examples
curl --request POST 'https://api.vocloner.org/v1/dialogues' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Idempotency-Key: REUSE_THIS_KEY_FOR_RETRIES' \
--header 'Content-Type: application/json' \
--data '{"lines":[{"voice_id":"c816ce5b-22f5-4ed2-91a9-90e79b874a24","text":"Hola."},{"voice_id":"c816ce5b-22f5-4ed2-91a9-90e79b874a24","text":"Bienvenido."}],"gap_ms":400}'Response
202 Accepted · application/json
{
"id": "f261e35c-420f-4c82-bd88-a0e370c936ab",
"operation": "dialogue",
"status": "queued",
"status_url": "https://api.vocloner.org/v1/jobs/f261e35c-420f-4c82-bd88-a0e370c936ab",
"created_at": "2026-10-29T12:00:00.000Z",
"started_at": null,
"completed_at": null,
"cancel_requested": false,
"result": null,
"error": null,
"usage": {
"reserved_characters": 46,
"billed_characters": 0,
"remaining_characters": 9000
}
}Long operations return a job. Poll status_url until a terminal state. All errors include request_id.
Errors and recoveryPOST/filesPrepare an upload
Obtain a temporary authorization for a direct upload to private Storage. Confirm the upload using /complete afterwards.
- Required permission
files:write- Usage
- No character charge
Request body
| Field | Type and limits | Required |
|---|---|---|
file_name | string · length 1–180 | Required |
content_type | string · audio/mpeg | audio/mp3 | audio/wav | audio/x-wav | audio/wave | audio/ogg | audio/flac | audio/x-flac | audio/mp4 | audio/m4a | audio/x-m4a | audio/webm | Required |
size_bytes | integer · …–26214400 | Required |
purpose | string · clone | audio_tool | local_tool | consent | Required |
Request examples
curl --request POST 'https://api.vocloner.org/v1/files' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Idempotency-Key: REUSE_THIS_KEY_FOR_RETRIES' \
--header 'Content-Type: application/json' \
--data '{"file_name":"voz.wav","content_type":"audio/wav","size_bytes":1048576,"purpose":"clone"}'Response
201 · application/json
{
"id": "ab198ae5-9225-40f3-b176-56ed83861080",
"file_name": "voz.wav",
"content_type": "audio/wav",
"size_bytes": 1048576,
"duration_ms": null,
"sha256": null,
"purpose": "clone",
"status": "pending",
"created_at": "2026-10-29T12:00:00.000Z",
"expires_at": "2026-10-30T12:00:00.000Z",
"upload_url": "https://storage.example.com/signed-upload/illustrative-only",
"upload_token": "ILLUSTRATIVE_UPLOAD_TOKEN",
"upload_expires_at": "2026-10-29T12:00:00.000Z",
"upload_method": "PUT",
"upload_headers": {
"Content-Type": "audio/wav"
}
}Long operations return a job. Poll status_url until a terminal state. All errors include request_id.
Errors and recoveryPOST/files/{id}/completeComplete an upload
Validate actual content, size, duration and hash before allowing use.
- Required permission
files:write- Usage
- No character charge
Request examples
curl --request POST 'https://api.vocloner.org/v1/files/c816ce5b-22f5-4ed2-91a9-90e79b874a24/complete' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Idempotency-Key: REUSE_THIS_KEY_FOR_RETRIES'Response
200 · application/json
{
"id": "ab198ae5-9225-40f3-b176-56ed83861080",
"file_name": "voz.wav",
"content_type": "audio/wav",
"size_bytes": 1048576,
"duration_ms": 12000,
"sha256": null,
"purpose": "clone",
"status": "ready",
"created_at": "2026-10-29T12:00:00.000Z",
"expires_at": "2026-10-30T12:00:00.000Z"
}Long operations return a job. Poll status_url until a terminal state. All errors include request_id.
Errors and recoveryGET/files/{id}Get a file
Retrieve status, duration and expiration of an owned file.
- Required permission
files:write- Usage
- No character charge
Request examples
curl --request GET 'https://api.vocloner.org/v1/files/c816ce5b-22f5-4ed2-91a9-90e79b874a24' \
--header 'Authorization: Bearer YOUR_API_KEY'Response
200 · application/json
{
"id": "ab198ae5-9225-40f3-b176-56ed83861080",
"file_name": "voz.wav",
"content_type": "audio/wav",
"size_bytes": 1048576,
"duration_ms": 12000,
"sha256": null,
"purpose": "clone",
"status": "ready",
"created_at": "2026-10-29T12:00:00.000Z",
"expires_at": "2026-10-30T12:00:00.000Z"
}Long operations return a job. Poll status_url until a terminal state. All errors include request_id.
Errors and recoveryDELETE/files/{id}Delete a file
Delete an owned file when no active job needs it.
- Required permission
files:write- Usage
- No character charge
Request examples
curl --request DELETE 'https://api.vocloner.org/v1/files/c816ce5b-22f5-4ed2-91a9-90e79b874a24' \
--header 'Authorization: Bearer YOUR_API_KEY'Response
200 · application/json
{
"id": "ab198ae5-9225-40f3-b176-56ed83861080",
"deleted": true
}Long operations return a job. Poll status_url until a terminal state. All errors include request_id.
Errors and recoveryPOST/consent-challengesCreate a consent challenge
Obtain a temporary phrase, record it and upload the audio with purpose: consent. Include both identifiers when cloning.
- Required permission
voices:clone- Usage
- No character charge
Request body
| Field | Type and limits | Required |
|---|---|---|
locale | string · es | en · default: "es" | Optional |
Request examples
curl --request POST 'https://api.vocloner.org/v1/consent-challenges' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Idempotency-Key: REUSE_THIS_KEY_FOR_RETRIES' \
--header 'Content-Type: application/json' \
--data '{"locale":"es"}'Response
201 · application/json
{
"id": "ab198ae5-9225-40f3-b176-56ed83861080",
"phrase": "Read the challenge returned by your live request.",
"expires_at": "2026-10-29T12:00:00.000Z",
"consent_version": "example-version",
"consent_text": "The live response provides the applicable consent text.",
"recording_required": true
}Long operations return a job. Poll status_url until a terminal state. All errors include request_id.
Errors and recoveryPOST/audio-tools/{operation}Process audio
Check /capabilities for available operations and options. Supply exactly one owned file or generation.
- Required permission
audio:process- Usage
- Per operation; check capabilities
Request body
| Field | Type and limits | Required |
|---|---|---|
file_id | string · uuid | Optional |
generation_id | string · uuid | Optional |
options | object · default: {} | Optional |
options.start_ms | integer · 0–9007199254740991 | Optional |
options.end_ms | integer · …–9007199254740991 | Optional |
options.volume | number · 0–4 | Optional |
options.fade_in_ms | integer · 0–30000 | Optional |
options.fade_out_ms | integer · 0–30000 | Optional |
options.target_peak_db | number · -24–-0.1 | Optional |
Request examples
curl --request POST 'https://api.vocloner.org/v1/audio-tools/trim' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Idempotency-Key: REUSE_THIS_KEY_FOR_RETRIES' \
--header 'Content-Type: application/json' \
--data '{"file_id":"ab198ae5-9225-40f3-b176-56ed83861080","options":{"start_ms":0,"end_ms":5000}}'Response
202 Accepted · application/json
{
"id": "f261e35c-420f-4c82-bd88-a0e370c936ab",
"operation": "audio_tool",
"status": "queued",
"status_url": "https://api.vocloner.org/v1/jobs/f261e35c-420f-4c82-bd88-a0e370c936ab",
"created_at": "2026-10-29T12:00:00.000Z",
"started_at": null,
"completed_at": null,
"cancel_requested": false,
"result": null,
"error": null,
"usage": {
"reserved_characters": 46,
"billed_characters": 0,
"remaining_characters": 9000
}
}Long operations return a job. Poll status_url until a terminal state. All errors include request_id.
Errors and recoveryGET/jobsList jobs
Paginated owned jobs ordered by creation.
- Required permission
jobs:read- Usage
- No character charge
Request examples
curl --request GET 'https://api.vocloner.org/v1/jobs' \
--header 'Authorization: Bearer YOUR_API_KEY'Response
200 · application/json
{
"items": [
{
"id": "f261e35c-420f-4c82-bd88-a0e370c936ab",
"operation": "speech",
"status": "completed",
"status_url": "https://api.vocloner.org/v1/jobs/f261e35c-420f-4c82-bd88-a0e370c936ab",
"created_at": "2026-10-29T12:00:00.000Z",
"started_at": "2026-10-29T12:00:00.000Z",
"completed_at": "2026-10-29T12:00:00.000Z",
"cancel_requested": false,
"result": {
"generation_id": "f261e35c-420f-4c82-bd88-a0e370c936ab",
"asset_id": "6e657fb6-cf58-46d8-9311-7f3828b203c7",
"audio_url": "https://api.vocloner.org/v1/assets/6e657fb6-cf58-46d8-9311-7f3828b203c7/content",
"format": "mp3",
"duration_ms": 3500
},
"error": null,
"usage": {
"reserved_characters": 46,
"billed_characters": 46,
"remaining_characters": 9000
}
}
],
"next_cursor": null
}Long operations return a job. Poll status_url until a terminal state. All errors include request_id.
Errors and recoveryGET/jobs/{id}Get a job
Retrieve status, result and billed characters. Respect Retry-After before polling again.
- Required permission
jobs:read- Usage
- No character charge
Request examples
curl --request GET 'https://api.vocloner.org/v1/jobs/c816ce5b-22f5-4ed2-91a9-90e79b874a24' \
--header 'Authorization: Bearer YOUR_API_KEY'Response
200 · application/json
{
"id": "f261e35c-420f-4c82-bd88-a0e370c936ab",
"operation": "speech",
"status": "completed",
"status_url": "https://api.vocloner.org/v1/jobs/f261e35c-420f-4c82-bd88-a0e370c936ab",
"created_at": "2026-10-29T12:00:00.000Z",
"started_at": "2026-10-29T12:00:00.000Z",
"completed_at": "2026-10-29T12:00:00.000Z",
"cancel_requested": false,
"result": {
"generation_id": "f261e35c-420f-4c82-bd88-a0e370c936ab",
"asset_id": "6e657fb6-cf58-46d8-9311-7f3828b203c7",
"audio_url": "https://api.vocloner.org/v1/assets/6e657fb6-cf58-46d8-9311-7f3828b203c7/content",
"format": "mp3",
"duration_ms": 3500
},
"error": null,
"usage": {
"reserved_characters": 46,
"billed_characters": 46,
"remaining_characters": 9000
}
}Long operations return a job. Poll status_url until a terminal state. All errors include request_id.
Errors and recoveryPOST/jobs/{id}/cancelCancel a job
Cancel queued work immediately. For running work, request cancellation and check the final status and usage.
- Required permission
jobs:cancel- Usage
- No character charge
Request examples
curl --request POST 'https://api.vocloner.org/v1/jobs/c816ce5b-22f5-4ed2-91a9-90e79b874a24/cancel' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Idempotency-Key: REUSE_THIS_KEY_FOR_RETRIES'Response
200 · application/json
{
"id": "f261e35c-420f-4c82-bd88-a0e370c936ab",
"operation": "speech",
"status": "canceled",
"status_url": "https://api.vocloner.org/v1/jobs/f261e35c-420f-4c82-bd88-a0e370c936ab",
"created_at": "2026-10-29T12:00:00.000Z",
"started_at": "2026-10-29T12:00:00.000Z",
"completed_at": "2026-10-29T12:00:00.000Z",
"cancel_requested": true,
"result": null,
"error": null,
"usage": {
"reserved_characters": 46,
"billed_characters": 0,
"remaining_characters": 9000
}
}Long operations return a job. Poll status_url until a terminal state. All errors include request_id.
Errors and recoveryGET/generationsList generations
List owned generations from the web, MCP and API using a stable cursor.
- Required permission
generations:read- Usage
- No character charge
Request examples
curl --request GET 'https://api.vocloner.org/v1/generations' \
--header 'Authorization: Bearer YOUR_API_KEY'Response
200 · application/json
{
"items": [
{
"id": "f261e35c-420f-4c82-bd88-a0e370c936ab",
"kind": "tts",
"voice_id": "c816ce5b-22f5-4ed2-91a9-90e79b874a24",
"status": "completed",
"char_count": 46,
"duration_ms": 3500,
"format": "mp3",
"audio_asset_id": "6e657fb6-cf58-46d8-9311-7f3828b203c7",
"audio_url": "https://api.vocloner.org/v1/assets/6e657fb6-cf58-46d8-9311-7f3828b203c7/content",
"created_at": "2026-10-29T12:00:00.000Z",
"completed_at": "2026-10-29T12:00:00.000Z",
"error_code": null
}
],
"next_cursor": null
}Long operations return a job. Poll status_url until a terminal state. All errors include request_id.
Errors and recoveryGET/generations/{id}Get a generation
Retrieve metadata and the audio reference of an owned generation.
- Required permission
generations:read- Usage
- No character charge
Request examples
curl --request GET 'https://api.vocloner.org/v1/generations/c816ce5b-22f5-4ed2-91a9-90e79b874a24' \
--header 'Authorization: Bearer YOUR_API_KEY'Response
200 · application/json
{
"id": "f261e35c-420f-4c82-bd88-a0e370c936ab",
"kind": "tts",
"voice_id": "c816ce5b-22f5-4ed2-91a9-90e79b874a24",
"status": "completed",
"char_count": 46,
"duration_ms": 3500,
"format": "mp3",
"audio_asset_id": "6e657fb6-cf58-46d8-9311-7f3828b203c7",
"audio_url": "https://api.vocloner.org/v1/assets/6e657fb6-cf58-46d8-9311-7f3828b203c7/content",
"created_at": "2026-10-29T12:00:00.000Z",
"completed_at": "2026-10-29T12:00:00.000Z",
"error_code": null
}Long operations return a job. Poll status_url until a terminal state. All errors include request_id.
Errors and recoveryDELETE/generations/{id}Delete a generation
Delete an owned generation according to retention rules.
- Required permission
generations:delete- Usage
- No character charge
Request examples
curl --request DELETE 'https://api.vocloner.org/v1/generations/c816ce5b-22f5-4ed2-91a9-90e79b874a24' \
--header 'Authorization: Bearer YOUR_API_KEY'Response
200 · application/json
{
"deleted": true
}Long operations return a job. Poll status_url until a terminal state. All errors include request_id.
Errors and recoveryGET/assets/{id}/contentDownload audio
Return authorized audio bytes. Send Bearer on every download; never put the key in the URL.
- Required permission
audio:read- Usage
- No character charge
Request examples
curl --request GET 'https://api.vocloner.org/v1/assets/c816ce5b-22f5-4ed2-91a9-90e79b874a24/content' \
--header 'Authorization: Bearer YOUR_API_KEY'Response
200 OK · audio/mpeg / audio/wav
Long operations return a job. Poll status_url until a terminal state. All errors include request_id.
Errors and recoveryGET/capabilitiesGet capabilities
Check formats, operations and limits supported in this environment before integrating.
- Required permission
Valid API key- Usage
- No character charge
Request examples
curl --request GET 'https://api.vocloner.org/v1/capabilities' \
--header 'Authorization: Bearer YOUR_API_KEY'Response
200 · application/json
{
"api_version": "v1",
"formats": {
"speech": [
"mp3",
"wav"
],
"dialogue": [
"mp3"
]
},
"operations": [
"speech",
"dialogue",
"clone",
"voice_design",
"voice_design_select",
"audio_tool"
],
"audio_tools": {
"trim": true,
"volume": true,
"fade": true,
"reverse": true,
"normalize": true,
"denoise": false,
"separate": false
},
"files": {
"clone": {
"max_bytes": 20971520,
"min_seconds": 5,
"max_seconds": 270
},
"consent": {
"max_bytes": 5242880
},
"audio_tool": {
"max_bytes": 20971520,
"max_seconds": 1200
},
"local_tool": {
"max_bytes": 26214400,
"max_seconds": 900
}
},
"consent": {
"version": "example-version",
"recording_required": true
},
"jobs": {
"default_mode": "async",
"max_wait_seconds": 20
},
"idempotency": {
"retention_days": 30
}
}Long operations return a job. Poll status_url until a terminal state. All errors include request_id.
Errors and recoveryTry a generation
Your key stays in memory and is cleared when you leave. Audio downloads require authorization. Never ship production keys in browser code.
The API is disabled in this environment. The reference is public; live requests are not available yet.
Changelog
v1 · Voices, audio and jobs with shared quotas. Actual availability depends on the environment and is reported by capabilities.