> ## Documentation Index
> Fetch the complete documentation index at: https://docs.snapgen.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Voice changer

> Re-voice recorded speech with an ElevenLabs premade voice and receive the new audio in the response.

`POST /v1/audio/voice-changer` takes a speech recording and re-voices it with one of the premade voices (speech to speech). Send the recording as a multipart upload or a public `audio_url`; the response body is the new audio file.

| Model | Use it for | Input | Price |
| - | - | - | - |
| [`eleven-multilingual-sts-v2`](/api-manual/audio/eleven-multilingual-sts-v2) | Speech in any supported language | Up to 300 seconds and 50 MB | \$0.003 per second (\$0.18 per minute) |
| [`eleven-english-sts-v2`](/api-manual/audio/eleven-english-sts-v2) | English speech | Up to 300 seconds and 50 MB | \$0.003 per second (\$0.18 per minute) |

<ParamField body="model" type="string" required>
  `eleven-multilingual-sts-v2` or `eleven-english-sts-v2`.
</ParamField>

<ParamField body="file" type="file">
  The recording, in a multipart field named `file`, up to 50 MB. Send `file`
  or `audio_url`, not both.
</ParamField>

<ParamField body="audio_url" type="string">
  Public `http` or `https` URL of the recording. The gateway downloads it, up
  to 50 MB. Send `audio_url` or `file`, not both.
</ParamField>

<ParamField body="voice" type="string" required>
  The target voice: an ID or first name from the
  [voice list](/api-reference/audio-speech#voices), for example `Sarah`.
</ParamField>

<ParamField body="stability" type="number">
  From `0` to `1`. Lower values give a broader emotional range; higher values
  sound more consistent.
</ParamField>

<ParamField body="similarity_boost" type="number">
  From `0` to `1`. How closely the output follows the target voice.
</ParamField>

<ParamField body="style" type="number">
  From `0` to `1`. Exaggerates the voice's speaking style.
</ParamField>

<ParamField body="use_speaker_boost" type="boolean">
  Boosts similarity to the target speaker.
</ParamField>

<ParamField body="remove_background_noise" type="boolean">
  Removes background noise from the recording before changing the voice.
</ParamField>

<ParamField body="seed" type="integer">
  From `0` to `4294967295`. Makes repeated requests more repeatable, without
  guaranteeing identical audio.
</ParamField>

<ParamField body="response_format" type="string" default="mp3">
  `mp3`, `opus`, `pcm`, or `wav`. See
  [Output formats](/api-reference/audio-speech#output-formats).
</ParamField>

In a multipart upload, send one `model` field, one file in `file`, and the
other fields as text form fields. The gateway accepts WAV, AIFF, MP3, AAC, MP4,
M4A, MOV, FLAC, Ogg, and WebM files whose length can be read.

## Response

A successful request returns HTTP `200` with the audio as the body. The
`Content-Type` matches `response_format`, and the response carries
`x-gateway-execution-id`.

## Billing

The gateway bills the measured length of the input recording at \$0.003 per
second, rounded up to whole seconds after a 0.1-second allowance, with a
minimum of 1 second. A one-minute recording costs \$0.18; the 300-second
maximum costs \$0.90. Failed requests aren't charged. This endpoint rejects
`Idempotency-Key`; if a request times out, check your Console request logs
before you retry.

## Errors

| Status | `error.code` | Cause |
| - | - | - |
| 400 | `audio_input_required` | Neither `file` nor `audio_url` was sent. |
| 400 | `invalid_request` | `voice` is missing or not in the list, a field is invalid, or both `file` and `audio_url` were sent. |
| 400 | `invalid_multipart` | The form has no `model` field, more than one file, a repeated field, or the file isn't in the `file` field. |
| 400 | `unsupported_audio_format` | The format isn't supported, or its length can't be read. |
| 400 | `audio_too_long` | The recording is longer than 300 seconds. |
| 400 | `audio_download_failed` | The gateway couldn't download `audio_url`. |
| 400 | `provider_rejected_request` | The provider refused the recording or a parameter. |
| 402 | `insufficient_funds` | Your balance can't cover the request. |
| 413 | `audio_too_large`, `request_too_large` | The downloaded file or the upload is larger than 50 MB. |

See [Errors](/errors) for rate limits and provider failures.

<RequestExample>
  ```bash Upload a file theme={null}
  curl https://api.snapgen.org/v1/audio/voice-changer \
    -H "Authorization: Bearer $SNAPGEN_API_KEY" \
    -F model=eleven-multilingual-sts-v2 \
    -F file=@performance.mp3 \
    -F voice=EXAVITQu4vr4xnSDxMaL \
    --output changed.mp3
  ```

  ```bash Audio URL theme={null}
  curl https://api.snapgen.org/v1/audio/voice-changer \
    -H "Authorization: Bearer $SNAPGEN_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "eleven-multilingual-sts-v2",
      "audio_url": "https://example.com/performance.mp3",
      "voice": "EXAVITQu4vr4xnSDxMaL"
    }' \
    --output changed.mp3
  ```

  ```python Python theme={null}
  import os

  import requests

  with open("performance.mp3", "rb") as audio:
      response = requests.post(
          "https://api.snapgen.org/v1/audio/voice-changer",
          headers={"Authorization": f"Bearer {os.environ['SNAPGEN_API_KEY']}"},
          data={"model": "eleven-multilingual-sts-v2", "voice": "EXAVITQu4vr4xnSDxMaL"},
          files={"file": ("performance.mp3", audio, "audio/mpeg")},
          timeout=300,
      )
  response.raise_for_status()
  with open("changed.mp3", "wb") as output:
      output.write(response.content)
  ```

  ```javascript Node.js theme={null}
  import { openAsBlob } from "node:fs";
  import { writeFile } from "node:fs/promises";

  const form = new FormData();
  form.append("model", "eleven-multilingual-sts-v2");
  form.append("file", await openAsBlob("performance.mp3"), "performance.mp3");
  form.append("voice", "EXAVITQu4vr4xnSDxMaL");

  const response = await fetch("https://api.snapgen.org/v1/audio/voice-changer", {
    method: "POST",
    headers: { Authorization: `Bearer ${process.env.SNAPGEN_API_KEY}` },
    body: form,
  });
  if (!response.ok) throw new Error(await response.text());
  await writeFile("changed.mp3", Buffer.from(await response.arrayBuffer()));
  ```
</RequestExample>

<ResponseExample>
  ```text 200 theme={null}
  HTTP/1.1 200 OK
  content-type: audio/mpeg
  cache-control: no-store
  x-gateway-execution-id: 5b1e9f3a-2c4d-4e6f-8a7b-9c0d1e2f3a4b

  <binary MP3 audio>
  ```

  ```json 400 theme={null}
  {
    "error": {
      "message": "The audio must be at most 300 seconds long",
      "type": "invalid_request_error",
      "param": null,
      "code": "audio_too_long"
    }
  }
  ```
</ResponseExample>
