Audio

Create Speech

Turn text into speech. Returns a durable WAV URL you can pass straight to video generation as `audio_url`.

Synchronous. The request follows the OpenAI speech shape (model, input, voice, instructions, response_format), but the response is JSON with a url, not raw audio bytes. The clip is stored on the CDN as a WAV (24 kHz, 16-bit mono) and registered as one of your audio clips, so it shows up in GET /v1/audio with source: "speech".

Three models. spicy-voice-1 speaks 45 preset voices. spicy-voice-1-expressive speaks 21 of them and also takes instructions describing emotion, pace, pitch and delivery. spicy-voice-1-custom speaks only your own voices, the vc_... ids from POST /v1/voices. A custom voice on a preset model, a preset voice on the custom model, or instructions on a model without them is a 400 that names the right model. GET /v1/voices lists every voice with the models that speak it.

Billed per 10,000 characters of input: $0.20 on spicy-voice-1, $0.23 on spicy-voice-1-expressive, $0.23 on spicy-voice-1-custom. CJK ideographs count as 2 characters. instructions are included in the debit; when the billed count comes back lower the difference is refunded, and cost_usd is the settled amount. Failed generations are refunded.

The input and the instructions are screened like a prompt before anything is charged; a blocked request returns the same 422 as a blocked prompt. dry_run: true validates, screens and returns the price without generating. Sandbox keys get a fixture clip flagged sandbox: true with the cost_usd a live key would pay; nothing is billed.

Make a character speak: pass the returned url byte-for-byte as audio_url on POST /v1/videos/generations. On spicy-motion-2, spicy-video-1 and the spicy-pov-* fine-tunes it is driving audio: the clip becomes the soundtrack and the mouth follows the words, alongside a first frame where the model takes one. On spicy-motion-3 and spicy-motion-3-fast it is reference audio: the model uses it for voice, tone and beat while the words come from the prompt, with a text prompt or references and never with a first frame (up to 5 clips, 15 seconds in total). Audio for video must be 2 to 30 seconds long, so split long text across requests.

POST/v1/audio/speechTry it
Create Speech
cURL
curl --request POST \
  --url https://api.spicyapi.com/v1/audio/speech \
  --header 'Authorization: Bearer $SPICYAPI_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "model": "spicy-voice-1",
    "input": "Come here. I have been waiting all evening.",
    "voice": "Cherry"
  }'
200
JSON
{
  "id": "au_7d2e9c1a4b6f8d0e2a",
  "object": "audio.speech",
  "model": "spicy-voice-1",
  "url": "https://cdn.spicyapi.com/audio/a1b2c3d4e5f6a7b8/au_7d2e9c1a4b6f8d0e2a.wav",
  "duration_s": 3.4,
  "voice": "Cherry",
  "cost_usd": 0.00086
}

Authorizations

Authorizationstringheaderrequired

Bearer authentication header of the form Bearer <token>, where <token> is your SpicyAPI key (sk-spicy-…). Create one in the dashboard under API Keys.

Body

application/json
modelstringrequired

spicy-voice-1, spicy-voice-1-expressive or spicy-voice-1-custom.

inputstringrequired

The text to speak, at most 600 characters. Longer text is a 400: split it into several requests.

voicestringrequired

A preset voice name the model speaks (case-insensitive, e.g. Cherry), or on spicy-voice-1-custom one of your vc_... voice ids. See GET /v1/voices.

instructionsstring

spicy-voice-1-expressive only: how to say it, in plain English or Chinese (emotion, pace, pitch, delivery), at most 1,600 characters. Counted in the debit, settled to the billed count.

languagestring

One of Auto, English, Chinese, German, Italian, Portuguese, Spanish, Japanese, Korean, French, Russian (case-insensitive). Defaults to Auto, which detects the language as it goes.

response_formatstring

wav, the default and only format. mp3 is a 400.

dry_runboolean

When true, validates and screens the request and returns { object: "dry_run", cost_usd, moderation } without generating or charging. A blocked prompt still returns the normal 422.

userstring

Your own id for the end user making this request (up to 128 characters, hashed at rest). Send it if your product serves many people: declined-prompt history, strikes and suspensions are then kept per end user, so one person's behaviour never affects another's requests or your account. After 10 severe violations that user gets 403 end_user_suspended; the id is echoed back as user in every screening error so you can act on it.

Response

200 · application/json

Speech

idstringrequired

Clip id, au_...; the same id appears in GET /v1/audio.

objectstringrequired

Always audio.speech.

modelstringrequired

The model that spoke.

urlstringrequired

CDN URL of the WAV. Pass it byte-for-byte as audio_url (or in audio_urls) on POST /v1/videos/generations.

duration_snumberrequired

Length in seconds, to one decimal.

voicestringrequired

The preset name or vc_... id that was used.

cost_usdnumberrequired

What this request cost in US dollars, settled to the billed character count.

Was this page helpful?