Use the OpenAI SDKs with ReadAloud text-to-speech

ReadAloud answers the same request that the OpenAI audio.speech.create call sends, at POST /v1/audio/speech, so the official OpenAI SDKs can use it by changing two constructor arguments: the API key and the base URL. There is no ReadAloud package to install for this integration. You keep the OpenAI client you already have, pass a ReadAloud key as the key, set the base URL to https://api.readaloudai.org/v1, and call client.audio.speech.create with voice readaloud-default. The model name you pass, such as tts-1, is accepted, and the ReadAloud documentation says the voice you choose decides how the audio is made. OpenAI voice names such as alloy are accepted and map to the same default voice. This approach suits code that already targets OpenAI's speech API, or tools that accept an OpenAI base URL, and it also covers streaming to a file with the Python SDK's with_streaming_response helper. Errors come back in OpenAI's error shape, so the SDK's own exception classes work. On 10 October 2026 we installed the current Python and JavaScript SDKs in clean environments and ran the calls below against the live API; limitations at the end note what was not run, including OpenAI-only features that have no equivalent.

Install

pip install openai        # Python
npm install openai        # JavaScript
export READALOUD_API_KEY=rtts_...   # placeholder: use your own key

No ReadAloud package is needed. Set base_url (Python) or baseURL (JavaScript) to https://api.readaloudai.org/v1. Create a ReadAloud API key at https://readaloudai.org/developers and export it as READALOUD_API_KEY; new accounts start with free credits.

Quickstart

Quickstart (python)
import os
from openai import OpenAI

client = OpenAI(api_key=os.environ["READALOUD_API_KEY"], base_url="https://api.readaloudai.org/v1")

with client.audio.speech.with_streaming_response.create(
    model="tts-1",
    voice="readaloud-default",
    input="Thanks for calling. How can I help you today?",
    response_format="mp3",
) as response:
    print(response.status_code, response.headers["content-type"])
    response.stream_to_file("openai_py.mp3")

What was tested

Checked with openai (Python, PyPI) 3.28.0 on Python 3.14.6, and openai (npm) 7.32.0 on Node 26.8.2. Version tested: Python 3.28.0, JavaScript 7.32.0. Date: October 10, 2026. This is one dated check against the live API. Other versions, and later releases, may behave differently.

What worked

  • The Python quickstart returned status 200 with content type audio/mpeg; the saved file was 39,597 bytes, began with an ID3 tag, and ffprobe read it as 24 kHz mono MP3 of 2.47 seconds.
  • The same call in the JavaScript SDK (client.audio.speech.create with baseURL set, then arrayBuffer()) returned 200, audio/mpeg and 38,829 bytes.
  • response_format mp3, opus, wav and pcm all returned audio, starting with ID3, OggS, RIFF and raw samples respectively. aac and flac returned 400 with a message listing the four supported formats.
  • The voice alloy returned audio, as documented, while an unknown voice returned 404 with a message pointing to GET /v1/voices.
  • A wrong key raised the SDK's AuthenticationError (401), and input of 5,001 characters raised BadRequestError (400, max_character_limit_exceeded).

Limits and what is not supported

  • Only the voice readaloud-default (ReadAloud Live) was used for the audio checks. We did not list or try Studio voices, and we did not test non-English text.
  • Every model name we tried (tts-1, tts-1-hd, gpt-4o-mini-tts, readaloud-live, readaloud-studio) returned 200. We did not check whether any of them changes the output, and the ReadAloud documentation says the voice decides.
  • OpenAI-specific features have no equivalent here: the instructions parameter, and the aac and flac formats. Each request is limited to 5,000 characters.
  • We ran the synchronous Python client and the JavaScript client for a single request each. We did not test the async client, the Azure client classes, or concurrent load.

Limits that apply to every integration

  • 5,000 characters per request. Split longer text and send it in order.
  • Output formats on the OpenAI-compatible route: mp3 (default, 24 kHz), opus (48 kHz, Ogg), wav (24 kHz) and pcm (24 kHz, 16-bit, mono); aac and flac return 400.
  • No SSML and no audio tags.
  • Beyond capacity the API returns 429 (HTTP) or an "at capacity" error with close code 1013 (WebSocket); retry with a short backoff.

What ReadAloud costs

  • ReadAloud Live: $4 per 1M characters ($0.004 per 1,000), the low-latency tier, built for live calls and voice agents.
  • ReadAloud Studio: $10 per 1M characters ($0.01 per 1,000), the higher-priced tier for read-aloud and narration, with several English voices.

Billing is per character of speech that finishes; cancelled requests are not billed, and there are no minimums. Every account gets a one-time grant of free credits (worth $0.10, about 10,000 characters of speech). It is one capped pool per account, shared across all of the account's keys and across speech, transcription, dubbing, voice conversion and voice design, and it is used first. When it runs out, requests return 402 until a payment method is added, then billing is pay as you go. Current prices are on the Voice API page (/developers).

Common questions

What do I change in existing OpenAI code?
The key and the base URL, and the voice. Use a ReadAloud key, base_url https://api.readaloudai.org/v1, and voice readaloud-default; the model argument can stay as it is.
What is the JavaScript version of the quickstart?
import OpenAI from 'openai'; const client = new OpenAI({ apiKey: process.env.READALOUD_API_KEY, baseURL: 'https://api.readaloudai.org/v1' }); const r = await client.audio.speech.create({ model: 'tts-1', voice: 'readaloud-default', input: 'Hello.', response_format: 'mp3' }); then Buffer.from(await r.arrayBuffer()). We ran this form on openai 7.32.0.
Do OpenAI voice names work?
alloy returned audio in our run and maps to the default voice, so existing code does not break. Unknown names return 404.
Can I use this with tools that take an OpenAI base URL?
The endpoint is the same one the SDK calls, so the tool's key and base URL fields are what to change. We tested the two official SDKs only, not other tools.

Something here does not match what you see? Tell us at support@readaloudai.org.