Audio models
Text to speech, speech to text and realtime voice through one OpenAI-compatible API: requests, voices, formats and the exact price of every audio model.
Text to speech, speech to text and realtime voice through one API: the requests, the voices, the formats, and the prices.
All models, capabilities, and prices Documentation index for AI agents:https://oneprovider.dev/docs/llms.txt Available audio models
grok-tts Runnable - characters of input text
- $15.00 / 1M characters
grok-stt Runnable - audio file transcription (batch)
- $0.10 / hour
grok-voice-3.0 Runnable - audio in and out, per minute of session
- $0.08 / minute
grok-voice-latest Runnable - audio in and out, per minute of session
- $0.08 / minute
gemini-2.5-flash-tts Runnable - text input
- $0.50 / 1M tokens
- generated audio output
- $10.00 / 1M tokens
gemini-2.5-pro-tts Runnable - text input
- $1.00 / 1M tokens
- generated audio output
- $20.00 / 1M tokens
gemini-3.1-flash-tts Runnable - text input
- $1.00 / 1M tokens
- generated audio output
- $20.00 / 1M tokens
gemini-3.1-tts Runnable - text input
- $1.00 / 1M tokens
- generated audio output
- $20.00 / 1M tokens
gemini-3.8-flash-tts Runnable - text input
- $0.50 / 1M tokens
- generated audio output
- $9.00 / 1M tokens
gemini-3.8-flash-lite-tts Runnable - text input
- $0.50 / 1M tokens
- generated audio output
- $6.00 / 1M tokens
gemini-3.5-transcribe Runnable - audio input
- $2.00 / 1M tokens
- transcript output
- $12.00 / 1M tokens
gemini-3.5-stt Runnable - audio input
- $0.30 / 1M tokens
- cached audio input
- $0.03 / 1M tokens
- transcript output
- $2.50 / 1M tokens
gemini-3-stt Runnable - audio input
- $1.00 / 1M tokens
- cached audio input
- $0.10 / 1M tokens
- transcript output
- $3.00 / 1M tokens
| Task | Path | Models |
|---|---|---|
| Text to speech (TTS) | POST /v1/audio/speech | grok-tts, gemini-2.5-flash-tts, gemini-2.5-pro-tts, gemini-3.1-flash-tts, gemini-3.1-tts, gemini-3.8-flash-tts, gemini-3.8-flash-lite-tts |
| Speech to text (STT) | POST /v1/audio/transcriptions | grok-stt, gemini-3-stt, gemini-3.5-stt, gemini-3.5-transcribe |
| Realtime voice | GET /v1/realtime?model= (WebSocket) | grok-voice-3.0, grok-voice-latest |
Text to speech
bashcurl -sS https://api.oneprovider.dev/v1/audio/speech \
-H "Authorization: Bearer sk-..." \
-H "Content-Type: application/json" \
-d '{
"model": "grok-tts",
"input": "Hello from OneProvider.",
"voice": "eve",
"response_format": "mp3"
}' \
--output hello.mp3 python from openai import OpenAI
client = OpenAI(base_url="https://api.oneprovider.dev/v1", api_key="sk-...")
with client.audio.speech.with_streaming_response.create(
model="gemini-3.8-flash-tts",
voice="Kore",
input="Hello from OneProvider.",
response_format="wav",
) as response:
response.stream_to_file("hello.wav") | Field | Value |
|---|---|
model | Required. A text-to-speech model ID. |
input | Required. The text to speak. |
voice | The voice: for Grok a lowercase name from the list below or your own custom voice ID, for Gemini a name from the second list. |
response_format | mp3 (default), wav or pcm. |
The reply is the audio file in the chosen format. For long text, send one request per paragraph and join the files.
Grok voices
altairaraatlasauroracarinacastorcelestecosmoevehelioshelixiriskeplerleolioralumenlunaluxnakshorionperseusrexrigelsalsiriusursazaganzenith Gemini voices
ZephyrPuckCharonKoreFenrirLedaOrusAoedeCallirrhoeAutonoeEnceladusIapetusUmbrielAlgiebaDespinaErinomeAlgenibRasalgethiLaomedeiaAchernarAlnilamSchedarGacruxPulcherrimaAchirdZubenelgenubiVindemiatrixSadachbiaSadaltagerSulafat Speech to text
bashcurl -sS https://api.oneprovider.dev/v1/audio/transcriptions \
-H "Authorization: Bearer sk-..." \
-F model=grok-stt \
-F file=@meeting.mp3
# {"text":"..."} python from openai import OpenAI
client = OpenAI(base_url="https://api.oneprovider.dev/v1", api_key="sk-...")
with open("meeting.mp3", "rb") as audio:
result = client.audio.transcriptions.create(model="gemini-3.5-transcribe", file=audio)
print(result.text) The request is multipart/form-data with the fields file (the audio file) and model. The reply is JSON with a text field.
Realtime voice
Open a WebSocket to wss://api.oneprovider.dev/v1/realtime?model=grok-voice-3.0 with the same key in the Authorization header. The events follow the OpenAI Realtime API.
import asyncio, base64, json
import websockets
async def main():
url = "wss://api.oneprovider.dev/v1/realtime?model=grok-voice-3.0"
async with websockets.connect(url, additional_headers={"Authorization": "Bearer sk-..."}) as ws:
await ws.send(json.dumps({"type": "session.update", "session": {"instructions": "Answer briefly."}}))
await ws.send(json.dumps({"type": "conversation.item.create", "item": {
"type": "message", "role": "user",
"content": [{"type": "input_text", "text": "Say hello in one sentence."}],
}}))
await ws.send(json.dumps({"type": "response.create"}))
audio = bytearray()
async for message in ws:
event = json.loads(message)
if event["type"] == "response.output_audio.delta":
audio += base64.b64decode(event["delta"])
elif event["type"] == "response.output_audio_transcript.delta":
print(event["delta"], end="")
elif event["type"] == "response.done":
break
asyncio.run(main()) | Event | Purpose |
|---|---|
session.update | Client: sets the instructions and session options. |
conversation.item.create | Client: adds a message to the conversation, text or audio. |
response.create | Client: asks the model to reply. |
response.output_audio.delta | Server: the next chunk of the reply audio, base64. |
response.output_audio_transcript.delta | Server: the next piece of text of what the model says. |
response.done | Server: the reply is complete. |
Pricing
- Grok TTS is billed per character of input text.
- Grok STT is billed per hour of audio.
- Grok Voice is billed per minute of conversation, plus a small fee for every text message you send.
- Gemini is billed in tokens: input text or audio, and output audio or text; one second of audio is 25 tokens.
Example: grok-tts, 1,000 characters = $15.00 / 1M × 1 000 = $0.015.
The exact price of every model is in the table above and on the pricing page .
Errors
| HTTP | Cause |
|---|---|
| 400 | An invalid field, an unknown voice or format. |
| 401 | The key is invalid or revoked. |
| 402 / 403 / 429 | Insufficient balance or the key limit was reached. Top up and retry. |
| 5xx | The service is temporarily unavailable. Retry later. |
Quick answers
Which base URL do I use?
Claude Code and Anthropic SDKs use https://api.oneprovider.dev. OpenAI SDKs and OpenAI-compatible clients use https://api.oneprovider.dev/v1. One key works behind both; the model list is on the models page ; rates are on the pricing page .
How do I authenticate?
Send the raw sk-… key in x-api-key or Authorization: Bearer: one of them, never both. Keep the key in an environment variable, not in a file that gets committed. More on authentication .
Where do I get a key?
Open your cabinet in the Telegram bot @oneprovider_robot or at app.oneprovider.dev, top up the balance and press “Issue a key”. Each key can carry its own spend limit. Cabinet & API keys .
What do 401, 404 and 429 mean?
401: the key is missing, mistyped or sent in the wrong header; paste the whole key without quotes or spaces. 404: usually a wrong base URL, for example a missing or doubled /v1. 429 with “Insufficient balance”: the cabinet balance or the key’s spend limit is used up, so top up instead of retrying; any other 429 is a rate limit, so wait for Retry-After. Details: error codes and troubleshooting .
Why do streams cut off or reset?
VPN and VLESS proxies often buffer SSE or break HTTP/2 negotiation. OneProvider has no regional restrictions and does not buffer streams, so turn the proxy off and retry.
Where do I ask if this is not enough?
Message @Oneproviderhelpbot on Telegram or open “Support” in the web cabinet, with the HTTP status code and the exact error message. How support works .
Last updated: 2026-10-21 Found a bug? @Oneproviderhelpbot