Skip to content

Migrate from the OpenAI speech endpoint.

Two changes in your client code: a new base URL and a new key. The rest of the OpenAI SDK call shape stays the same. This page covers the exact substitutions and the small differences.

Ask Claude CodeAsk ChatGPT

The two-line change

The OpenAI Python SDK accepts a custom base_url. Point it at the Gandr endpoint and swap the key. The rest of your code is unchanged.

Recipe
# Python, OpenAI SDK
  
  # Before
  from openai import OpenAI
  client = OpenAI(api_key="sk-...")
  
  # After
  from openai import OpenAI
  client = OpenAI(
      api_key="gnd_...",
      base_url="https://tts.gandr.ai/v1",
  )
  
  # Your existing call works as-is:
  response = client.audio.speech.create(
      model="tts-1",
      voice="gandr-mia",   # see voice mapping below
      input="The quick brown fox jumps over the lazy dog.",
  )
  response.stream_to_file("output.mp3")
  
  # ---
  # Node (OpenAI SDK)
  # const client = new OpenAI({ apiKey: "gnd_...", baseURL: "https://tts.gandr.ai/v1" })
  # const response = await client.audio.speech.create({ model: "tts-1", voice: "gandr-mia", input: "..." })
  
  # ---
  # Raw HTTP (works identically to the OpenAI endpoint)
  # curl -X POST https://tts.gandr.ai/v1/audio/speech \
  #   -H "Authorization: Bearer gnd_..." \
  #   -H "Content-Type: application/json" \
  #   -d '{"model":"tts-1","input":"Hello world.","voice":"gandr-mia","response_format":"mp3"}' \
  #   -o output.mp3

The API key comes from your Gandr account. Free tier includes 50,000 tokens. One token is one character.

What changes

What it takes

base_urlhttps://tts.gandr.ai/v1
api_keygnd_... from your Gandr account
voicesee voice mapping table in the section below
modeltts-1 works as-is

Voice mapping

Gandr ships six voices. The table below maps the six OpenAI voice names to Gandr voices by character. These are suggestions: listen to all six and pick the ones that fit your use case.

  • alloy -> gandr-mia (clear, neutral female)
  • echo -> gandr-leo (measured male)
  • fable -> gandr-lewis (warmer male, storytelling)
  • onyx -> gandr-dane (deep, authoritative male)
  • nova -> gandr-jenny (bright female)
  • shimmer -> gandr-ava (soft female)

Differences from the OpenAI endpoint

Most call shapes are identical. These are the points where the two endpoints behave differently.

  • Character cap: 2000 characters per request. Split longer text at sentence boundaries and send multiple requests.
  • Formats: mp3 (default), wav, pcm. mp3 and wav behave the same as on the OpenAI endpoint. pcm is headerless s16le mono 24000 Hz, no WAV container.
  • Unit: one token is one character. Usage and billing are in tokens.
  • Voices: six Gandr voices (see table above). Passing an OpenAI voice name returns an error; update the voice parameter.
  • Languages: 23 languages across all voices.
  • Watermarking: every render is watermarked.
  • Speed parameter: pass speed in the request body (0.25 to 4.0) as with the OpenAI endpoint.

PCM format detail

If you use response_format pcm, note that Gandr PCM is headerless signed 16-bit little-endian mono at 24000 Hz, streaming as a plain chunked HTTP body. There is no WAV header and no container. If your pipeline expects a different sample rate, resample after receiving the bytes.

Free tier

The free tier is 50,000 tokens. One token is one character. There is no time limit on the free tier.

Notes

Do I need to change the model name?

No. tts-1 is accepted as-is.

What happens if I pass an OpenAI voice name?

The API returns an error. Update the voice parameter to one of the six Gandr voice names: gandr-mia, gandr-ava, gandr-jenny, gandr-dane, gandr-leo, gandr-lewis.

Is the response streaming?

Yes. The response body streams over plain HTTP the same way the OpenAI endpoint does. SDK methods like stream_to_file and iter_bytes work without changes.

What is the per-request character limit?

2000 characters. If your existing code sends longer strings, add a split step before calling the API.

How do I get an API key?

Keys are available from your Gandr account. The free tier includes 50,000 tokens with no expiry.

Is the response_format parameter the same?

Supported formats are mp3, wav, and pcm. The default is mp3. The tts-1-hd model variant is not available; tts-1 is the model to use.

Two lines changed and your existing code works against the Gandr endpoint.

Get a key

Full API reference , gandr.ai/docs