# Switch from OpenAI text to speech and Whisper

OpenAI is removing tts-1 and whisper-1 from its API. Point the OpenAI SDK at Paxa, and your model and voice names keep working.

Switching from OpenAI? Change the base URL and the key, and your model and voice names keep working.

- `tts-1`, `tts-1-hd`, and `gpt-4o-mini-tts` leave OpenAI's API on January 6, 2027.
- `whisper-1`, `gpt-4o-transcribe`, and `gpt-4o-mini-transcribe` leave on February 26, 2027, along with `gpt-4o-transcribe-diarize`. Paxa does not take that name; speaker labels are served on [POST /v1/stt](https://paxalabs.com/docs/api/stt).

The details are on [OpenAI's deprecations page](https://developers.openai.com/api/docs/deprecations). For speech, OpenAI points to its Realtime API, which works differently from `/v1/audio/speech`.

The Paxa API serves [POST /v1/audio/speech](https://paxalabs.com/docs/api/speech) and [POST /v1/audio/transcriptions](https://paxalabs.com/docs/api/transcriptions) in OpenAI's shape and accepts OpenAI's model and voice names. Where your code or tool lets you set a base URL, two settings switch it.

| Setting | Value |
| --- | --- |
| Base URL | `https://api.paxalabs.com/v1` |
| API key | A Paxa key from the [dashboard](https://paxalabs.com/app/keys) |

Model names, voice names, and request bodies stay as they are. A new account starts with 100 free credits.

## Text to speech

Python:

```python
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.paxalabs.com/v1",
    api_key=os.environ["PAXA_API_KEY"],
)

with client.audio.speech.with_streaming_response.create(
    model="tts-1",
    voice="alloy",
    input="สวัสดีครับ ยินดีต้อนรับสู่ Paxa Labs",
) as response:
    response.stream_to_file("speech.mp3")
```

TypeScript:

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

const client = new OpenAI({
  baseURL: "https://api.paxalabs.com/v1",
  apiKey: process.env.PAXA_API_KEY,
});

const response = await client.audio.speech.create({
  model: "tts-1",
  voice: "alloy",
  input: "สวัสดีครับ ยินดีต้อนรับสู่ Paxa Labs",
});

await writeFile("speech.mp3", Buffer.from(await response.arrayBuffer()));
```

curl:

```bash
curl -X POST https://api.paxalabs.com/v1/audio/speech \
  -H "Authorization: Bearer $PAXA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "tts-1",
    "input": "สวัสดีครับ ยินดีต้อนรับสู่ Paxa Labs",
    "voice": "alloy"
  }' \
  --output speech.mp3
```

AI SDK:

```typescript
import { readFile, writeFile } from "node:fs/promises";
import { createOpenAI } from "@ai-sdk/openai";
import { generateSpeech, transcribe } from "ai";

const paxa = createOpenAI({
  baseURL: "https://api.paxalabs.com/v1",
  apiKey: process.env.PAXA_API_KEY,
});

const { audio } = await generateSpeech({
  model: paxa.speech("tts-1"),
  voice: "alloy",
  text: "สวัสดีครับ ยินดีต้อนรับสู่ Paxa Labs",
});
await writeFile("speech.mp3", audio.uint8Array);

const { text } = await transcribe({
  model: paxa.transcription("whisper-1"),
  audio: await readFile("meeting.m4a"),
});
```

## Speech to text

Python:

```python
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.paxalabs.com/v1",
    api_key=os.environ["PAXA_API_KEY"],
)

transcript = client.audio.transcriptions.create(
    model="whisper-1",
    file=open("meeting.m4a", "rb"),
)
print(transcript.text)
```

- `response_format` is `json` (the default), `verbose_json`, `text`, `srt`, or `vtt`.
- `language` passes a hint, and without one the model detects the language.
- A recording runs up to 60 minutes and 25 MiB.
- Paxa STT Lite is a Research preview.

## Which voice speaks

When a request names an OpenAI voice, one of our voices speaks it. Every one of them speaks English, Thai, and Mandarin, mixed sentences included. Each response names the voice that spoke in its `x-voice-id` header.

| You send | Paxa voice | Role |
| --- | --- | --- |
| alloy | Foi Thong (`foithong`) | Narrator |
| ash | Khanom Krok (`khanomkrok`) | Lead voice |
| ballad | Oliang (`oliang`) | Late-night radio |
| cedar | Khao Tom (`khaotom`) | Family man |
| coral | Cookie (`cookie`) | Support agent |
| echo | Massaman (`massaman`) | Leading man |
| fable | Espresso (`espresso`) | Long-form reader |
| marin | Salim (`salim`) | Girl next door |
| nova | Nom Yen (`nomyen`) | Lead voice |
| onyx | Thong Ek (`thongek`) | News anchor |
| sage | Bai Toey (`baitoey`) | Mentor |
| shimmer | Tako (`tako`) | Friendly reader |
| verse | Latte (`latte`) | Brand films |

To choose a voice yourself, send its id instead, for example `"khanomkrok"`. [GET /v1/voices](https://paxalabs.com/docs/api/voices) lists all 50, and the [voice library](https://paxalabs.com/voices) plays them.

Model names map the same way. `tts-1`, `tts-1-hd`, `gpt-4o-mini-tts`, `gpt-4o-mini-tts-2025-03-20`, `gpt-4o-mini-tts-2025-12-15` run on `paxa-tts-flash-v2`, and `whisper-1`, `gpt-4o-transcribe`, `gpt-4o-mini-transcribe`, `gpt-4o-mini-transcribe-2025-03-20`, `gpt-4o-mini-transcribe-2025-12-15` run on `paxa-stt-lite-v1-preview`.

## In tools you already use

Most tools with an OpenAI speech option let you change the base URL. Menu names vary by version.

- In Open WebUI, open Admin Panel, Settings, Audio. Choose the OpenAI engine for text to speech and for speech to text, set the base URL to `https://api.paxalabs.com/v1`, and paste your Paxa key.
- In n8n, create an OpenAI credential for audio alone, with Base URL `https://api.paxalabs.com/v1` and your Paxa key, and use it in the OpenAI node's audio actions. Keep your existing credential for chat, because Paxa serves speech and transcription only.
- In Home Assistant's OpenAI TTS custom integration, choose the custom option, set the URL to `https://api.paxalabs.com/v1/audio/speech`, and keep your model and voice.
- In LibreChat, set the `url` of the speech and transcription settings in `librechat.yaml` to `https://api.paxalabs.com/v1/audio/speech` and `https://api.paxalabs.com/v1/audio/transcriptions`. LibreChat posts to the URL as written.
- In SillyTavern, choose the OpenAI Compatible TTS provider and set the endpoint to `https://api.paxalabs.com/v1/audio/speech`.

The [integration guides](https://paxalabs.com/docs/integrations) walk through Open WebUI, LibreChat, Home Assistant, and SillyTavern step by step, along with AnythingLLM, LiveKit Agents, and Strands Agents.

A tool that reads `OPENAI_BASE_URL` moves all of its OpenAI calls to Paxa, chat included, and Paxa does not serve chat. Set it only for a tool that uses OpenAI for audio alone.

## What differs from OpenAI

- The formats are mp3 (the default), opus, wav, pcm, mulaw, and alaw. pcm is 24 kHz 16-bit mono. aac and flac answer 400.
- Speed runs from 0.5 to 1.5, and a value outside that range answers 400.
- `instructions` is ignored. To steer the delivery, write [direction tags](https://paxalabs.com/docs/directions) into the text, such as `[whispering] see you tomorrow` or `[cheerful] welcome back!`.
- Streaming is on by default, and `"stream": false` returns a complete file.
- Streaming sends raw audio bytes under an audio content type, also when a request sets `"stream_format": "sse"`. A client that parses events reads the content type first.
- A request the schema refuses answers [400 validation](https://paxalabs.com/docs/errors#validation) with `path`, the field at fault, and `reason`, a stable code for what is wrong with it.
- An unknown model or voice answers [400 unknown_model](https://paxalabs.com/docs/errors#unknown_model) or [400 unknown_voice](https://paxalabs.com/docs/errors#unknown_voice).
- A speech request carries up to 5,000 characters.
- Speech costs 10 credits per 1,000 characters, and transcription 8.33 credits per minute. See [pricing](https://paxalabs.com/pricing).

## More than a drop-in

- Every voice speaks English, Thai, and Mandarin, mixed sentences included.
- [Direction tags](https://paxalabs.com/docs/directions) steer the delivery and add sounds such as `[laughs]` and `[sighs]`, and `<emph>` marks a span.
- The native API adds [word timestamps](https://paxalabs.com/docs/timestamps) and a [live socket](https://paxalabs.com/docs/live-streaming) that takes text as it is written.

## Questions

### Does alloy sound the same?

No. Our voices answer to OpenAI's names, and the table above shows which voice speaks each one. Listen before you switch, or pick any voice by id.

### What if my tool has no base URL setting?

Then it needs a native Paxa integration. [Tell us which tool](https://paxalabs.com/contact).

### Can I keep OpenAI for chat?

Yes. Point only your audio calls at Paxa.

### What happens with a name you do not map?

An unknown voice or model answers 400 `unknown_voice` or `unknown_model`. Nothing switches silently.
