TTS Swap › Guides

Using OPENAI_BASE_URL to move text-to-speech off tts-1 (and when not to)

From Swift Labs, makers of TTS Swap. Written with AI help and checked against the openai SDK source and our own service. Not affiliated with OpenAI.

Short answer: the openai Python and Node libraries send requests to whatever OPENAI_BASE_URL says, with the key in OPENAI_API_KEY. Set both to an OpenAI-compatible speech service and audio.speech.create calls go there without code changes. But it moves every OpenAI call in that process, chat included, so for apps that use OpenAI for more than speech, use a separate speech client instead (below).

Why this matters now

OpenAI's deprecations page lists tts-1, tts-1-hd and gpt-4o-mini-tts as shutting down on January 6, 2027, with gpt-realtime-2.1-mini as the recommended replacement. OpenAI's text-to-speech guide notes that this is a change of API workflow: gpt-realtime-2.1-mini isn't a supported model for /v1/audio/speech.

If you would rather keep your audio.speech.create code and send it to an OpenAI-compatible speech service instead, you change the base URL and API key. Many teams look for a way to do that from config, without touching code. That is what OPENAI_BASE_URL does.

How OPENAI_BASE_URL works

The openai Python library (checked on 3.46.0) and Node library (checked on 7.53.0) both read two environment variables when you create a client without arguments:

An explicit base_url / baseURL argument wins over the environment variable.

export OPENAI_BASE_URL="https://tts.deadlinkpatrol.com/v1"
export OPENAI_API_KEY="sk-tts-…"
from openai import OpenAI

client = OpenAI()  # picks up OPENAI_BASE_URL and OPENAI_API_KEY
client.audio.speech.create(model="tts-1", voice="alloy", input="Hello").write_to_file("hello.wav")

The catch: it moves every OpenAI call

OPENAI_BASE_URL applies to the whole client, not just speech. If the same process also calls chat, embeddings or transcription, those requests go to the new host too. TTS Swap serves speech only (/v1/audio/speech, plus /v1/models and /v1/usage), so chat calls sent there will fail.

Use these environment variables only when the process uses OpenAI for speech alone, such as a narration worker or a batch job, and set them only for that process (for example in its own service config), not in a shared shell profile or .env file.

Safer: a separate client for speech

If your app uses OpenAI for anything else, do not set OPENAI_BASE_URL or put the speech key in OPENAI_API_KEY. Configure each client explicitly: the chat client with OpenAI's URL and your OpenAI key, and a second client for speech with its own variables. Then neither client depends on what happens to be in the environment.

Python:

import os
from openai import OpenAI

chat_client = OpenAI(
    base_url="https://api.openai.com/v1",
    api_key=os.environ["OPENAI_CHAT_KEY"],  # your OpenAI key
)
tts_client = OpenAI(
    base_url=os.environ["TTS_BASE_URL"],  # https://tts.deadlinkpatrol.com/v1
    api_key=os.environ["TTS_API_KEY"],
)

tts_client.audio.speech.create(
    model="tts-1", voice="alloy", input="Hello", response_format="wav"
).write_to_file("hello.wav")

Node:

import OpenAI from "openai";
import { writeFile } from "node:fs/promises";

const chat = new OpenAI({
  baseURL: "https://api.openai.com/v1",
  apiKey: process.env.OPENAI_CHAT_KEY, // your OpenAI key
});

const tts = new OpenAI({
  baseURL: process.env.TTS_BASE_URL, // https://tts.deadlinkpatrol.com/v1
  apiKey: process.env.TTS_API_KEY,
});

const res = await tts.audio.speech.create({ model: "tts-1", voice: "alloy", input: "Hello", response_format: "wav" });
await writeFile("hello.wav", Buffer.from(await res.arrayBuffer()));

This also makes rollback easy. Change TTS_BASE_URL and TTS_API_KEY together: back to https://api.openai.com/v1 with your OpenAI key while OpenAI's models still run, or to another provider's URL with that provider's key. A URL without its matching key fails with a 401.

What to check before you switch

These apply to any OpenAI-compatible speech service. For TTS Swap:

Your options, fairly

  1. OpenAI's path: gpt-realtime-2.1-mini on the Realtime API. Keeps you on OpenAI voices, but it is a different workflow (sessions and streamed events instead of one HTTP POST). Best if you need OpenAI's voice quality.
  2. Another OpenAI-compatible provider or a self-hosted server (for example Kokoro-FastAPI or Speaches). Same OPENAI_BASE_URL approach. Compare voices, formats and data handling.
  3. TTS Swap. Change the base URL and API key and keep your calls. Free and paid keys are both available. Not a fit if you need OpenAI's voices, real MP3/Opus bytes, or adjustable speed today.

Try it

TTS Swap by Swift Labs. Written with AI help. Not affiliated with OpenAI. · Terms · Privacy · Manage or cancel subscription