Audio

Create Voice

Design a voice from a description, or clone one from one of your clips with the speaker's consent. Custom voices are spoken by `spicy-voice-1-custom`.

Send exactly one of description (design a voice) or audio_url with consent: true (clone a voice). Either way you get a voice id, vc_..., to pass as voice on POST /v1/audio/speech with model: "spicy-voice-1-custom".

Design: description says what the voice sounds like (gender, age range, pitch, pace, tone, accent). It must describe vocal qualities, not a person: a name or description that names, references or imitates a real person ("sounds like" someone, "the voice of" someone, impressions, celebrities) is a 400 with code: "real_person", and the name, description and preview line are screened like a prompt as well (422 when blocked). A designed voice comes with preview_url, a WAV of preview_text in the new voice.

Clone: audio_url must be one of your own clips from POST /v1/audio (browse them with GET /v1/audio), at most 10 MB; the clip was transcribed and screened when it was uploaded, and the voice name is screened here. consent: true is required: it is your attestation that the voice is your own, or that you hold the speaker's written consent to clone it and to generate speech with it. The attestation is stored with the voice, together with the time, the key and the user you send, and returned as consent_attested_at. Cloning someone's voice without that consent breaks the acceptable use policy. A noisy sample, or one that does not match its transcript, still makes a voice but returns a warning; a clean 10 to 20 second sample gives the closest match.

Price: $0.40 per designed voice and $0.02 per cloned voice, debited once when the voice is created and refunded if creation fails. Speaking with it is billed like any other speech request. dry_run: true validates, screens and prices without creating. Sandbox keys get a fixture voice (vc_sbx_...) that sandbox speech accepts; nothing is billed.

POST/v1/voicesTry it
Create Voice
cURL
# design a voice
curl --request POST \
  --url https://api.spicyapi.com/v1/voices \
  --header 'Authorization: Bearer $SPICYAPI_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "name": "Mara",
    "description": "Woman in her thirties, low and warm, slightly husky, unhurried, a playful smile in the voice, neutral American accent."
  }'

# clone your own voice from one of your clips
curl --request POST \
  --url https://api.spicyapi.com/v1/voices \
  --header 'Authorization: Bearer $SPICYAPI_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "name": "My voice",
    "audio_url": "https://cdn.spicyapi.com/audio/a1b2c3d4e5f6a7b8/au_3c9f1e7a2b4d6f80a1c2.wav",
    "consent": true
  }'
200
JSON
{
  "id": "vc_4e1b7c9a2d5f8e0b3c",
  "object": "voice",
  "kind": "designed",
  "name": "Mara",
  "models": ["spicy-voice-1-custom"],
  "description": "Woman in her thirties, low and warm, slightly husky, unhurried, a playful smile in the voice, neutral American accent.",
  "source_audio_id": null,
  "preview_url": "https://cdn.spicyapi.com/audio/a1b2c3d4e5f6a7b8/vc_4e1b7c9a2d5f8e0b3c-preview.wav",
  "consent_attested_at": null,
  "created": 1758553200,
  "cost_usd": 0.4
}

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
namestringrequired

A label for the voice, at most 60 characters.

descriptionstring

Design: the voice's qualities, at most 2,048 characters. Omit when cloning.

preview_textstring

Design: the line spoken in the preview clip, 1 to 1,024 characters. Defaults to a short neutral line.

audio_urlstring

Clone: the url of one of your clips from POST /v1/audio, at most 10 MB. Omit when designing.

consentboolean

Clone: must be true, your attestation that the voice is your own or that the speaker gave written consent. Anything else is a 400.

languagestring

The voice's language: English (default), Chinese, German, Italian, Portuguese, Spanish, Japanese, Korean, French or Russian.

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

Voice

idstringrequired

What you pass as voice: the preset name, or vc_... for your own voices.

objectstringrequired

Always voice.

kindstringrequired

preset, designed or cloned.

namestringrequired

Display name.

modelsstring[]required

The speech models that speak this voice; spicy-voice-1-custom for your own.

descriptionstring | null

Designed voices: the description they were made from.

source_audio_idstring | null

Cloned voices: the clip (au_...) they were cloned from.

preview_urlstring | null

Designed voices: a WAV of the preview line in the new voice.

consent_attested_atinteger | null

Cloned voices: Unix timestamp of your consent attestation.

createdinteger | null

Unix timestamp. Custom voices only.

warningstring

Clones only, when the sample was noisy or off-transcript and the clone may sound less like the speaker.

cost_usdnumberrequired

The creation fee, already debited.

Was this page helpful?