Yapper API
Api reference
POST
/audio/speech

Legacy synchronous text-to-speech compatibility endpoint for ElevenLabs and Cartesia. New integrations should use audio-generation via POST /processes plus GET /audio/voices so model capabilities, references, process polling, and output lineage match image/video generation. This endpoint still generates spoken audio from a script and stores it as a team audio asset (readable via GET /assets/{assetId} and listed by GET /assets). No polling — the response returns the finished asset. Pass a voiceId from a previous response to reuse a voice, or a voiceQuery (e.g. "warm female narrator") to pick one by description; omitting both uses a neutral narrator. The first 5,000 script characters per team per UTC day are free; characters beyond that bill team credits at 30 credits per 1,000 characters for ElevenLabs voices or 15 credits per 1,000 characters for Cartesia voices (403 insufficient_credits when the team balance cannot cover the request). The response reports creditsCharged and freeCharactersRemainingToday. Always send an Idempotency-Key: retries with the same key and body replay the original response (Idempotency-Replayed: true) instead of double-billing and double-generating; the same key with a different body returns idempotency_conflict.

Authorization

bearerAuth processes:write
AuthorizationBearer <token>

In: header

Scope: processes:write

Header Parameters

Idempotency-Key?string

Stable caller-provided key for retry-safe speech generation.

Length1 <= length <= 255

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

application/json

curl -X POST "https://example.com/audio/speech" \  -H "Content-Type: application/json" \  -d '{    "script": "string"  }'
{  "data": {    "assetId": "string",    "type": "audio",    "url": "http://example.com",    "duration": 0,    "script": "string",    "voice": {      "voiceId": "string",      "provider": "string",      "name": "string"    },    "creditsCharged": 0,    "freeCharactersRemainingToday": 0  }}
{  "error": {    "code": "string",    "message": "string",    "requestId": "string"  }}
{  "error": {    "code": "string",    "message": "string",    "requestId": "string"  }}
{  "error": {    "code": "string",    "message": "string",    "requestId": "string"  }}
{  "error": {    "code": "string",    "message": "string",    "requestId": "string"  }}
{  "error": {    "code": "string",    "message": "string",    "requestId": "string"  }}
{  "error": {    "code": "string",    "message": "string",    "requestId": "string"  }}

Create a media process POST

Starts a generation process and charges team credits. V1 types: image-generation, video-generation, audio-generation, image-upscale, video-upscale, video-lipsync. The model must match the type (see GET /models). For seedance-2.5-edit, the first referenceVideos item is the required base video; editOperation defaults to edit, while extend, sequel, and prequel allow an omitted prompt. video-lipsync takes sourceVideoAssetId and audioAssetId from the team asset library; the server-measured audio duration determines its quote and charge. Sync-Max is train-once: omit trainingId on the first run, then reuse the trainingId returned on the process for faster later runs against the same trained source. Sync-Pro and Sync-v3 are single-shot and require no training. Always send an Idempotency-Key: retries with the same key and body return the original process instead of double-charging; the same key with a different body returns idempotency_conflict. input is validated per process type AND against the model's published capabilities (aspectRatios, resolutions, videoLengths from GET /models) — unsupported values are rejected with invalid_request, never silently coerced. Internal fields (batchId, filteringId, agent context) are ignored. metadata (flat string/number/boolean/null values, max 16 keys) is echoed back on reads. webhookSecret is optional for legacy unsigned webhook delivery; when supplied with webhookUrl, notifications are HMAC-signed and may be attempted twice with a stable delivery id.

Get an asset GET

Returns one normalized asset. Deleted or cross-team assets return not_found.