Audio API
Speech synthesis, transcription, translation and music generation on one OpenAI-compatible surface. Pay per call in USDC — no per-vendor contracts.
Speech synthesis across the ElevenLabs, Google and OpenAI TTS models, Whisper transcription and translation, and music generation — on an OpenAI-compatible surface.
Coverage
Text-to-speech across the ElevenLabs range (flash-v2.5, turbo-v2.5, multilingual-v2, v3 and sound effects) plus Google and OpenAI TTS models, Whisper transcription and translation, and MiniMax music generation.
Speech is metered per input character and quoted per 1000. Music is metered per track. Generated files are served from CDN and stay available for a limited window, so download rather than hotlink.
7 endpoints
Text to speech
Natural speech from text, with voice aliases or a raw voice id. The model and voice are body fields, never path segments.
| Method | Endpoint | Description |
|---|---|---|
POST | /audio/speech | Synthesise speech; returns JSON carrying a CDN audio URL |
POST | /audio/sound-effects | Generate a sound effect from a description |
Transcription & translation
Whisper, over multipart form data. Transcription keeps the source language; translation returns English.
| Method | Endpoint | Description |
|---|---|---|
POST | /audio/transcriptions | Speech to text in the source language |
POST | /audio/translations | Spoken audio in any language to English text |
Music generation
Full-length tracks from a prompt, with lyrics or instrumental. Asynchronous: submit, then poll.
| Method | Endpoint | Description |
|---|---|---|
POST | /audio/generations | Start a music generation job |
GET | /audio/generations/{id} | Poll a job; the read reuses the original payment |
Voice roster
The voices available to /audio/speech, so a caller can list rather than guess.
| Method | Endpoint | Description |
|---|---|---|
GET | /marketplace/audio/voices | Available voices with their ids and aliases |
Pricing
Speech is billed per 1000 input characters and varies by model — the fast tiers cost roughly half the studio-grade ones. Music is billed per track. Polling a music job is free: the GET reuses the payment the POST made.
Quick start
cURL
# Text to speech — returns JSON with a CDN URL, not raw audio bytes
curl "https://api.jarvisclaw.ai/v1/audio/speech" \
-H "Authorization: Bearer sk-your-api-key" \
-H "Content-Type: application/json" \
-d '{"model":"elevenlabs/flash-v2.5","input":"Hello!","voice":"sarah"}'
# -> {"data":[{"url":"https://cdn.jarvisclaw.ai/.../audio.mp3","format":"mp3"}]}
# Then fetch the file
curl -o output.mp3 "https://cdn.jarvisclaw.ai/.../audio.mp3"
# Transcription is multipart, not JSON
curl "https://api.jarvisclaw.ai/v1/audio/transcriptions" \
-H "Authorization: Bearer sk-your-api-key" \
-F file="@recording.mp3" \
-F model="whisper-1"
# List the voices instead of guessing an id
curl "https://api.jarvisclaw.ai/v1/marketplace/audio/voices" \
-H "Authorization: Bearer sk-your-api-key"Python
import requests
BASE = "https://api.jarvisclaw.ai/v1"
headers = {"Authorization": "Bearer sk-your-api-key"}
# Speech: the response carries a URL, so download it
resp = requests.post(
f"{BASE}/audio/speech",
headers=headers,
json={
"model": "elevenlabs/flash-v2.5",
"input": "Hello, welcome to JarvisClaw!",
"voice": "sarah",
},
).json()
audio = requests.get(resp["data"][0]["url"])
open("output.mp3", "wb").write(audio.content)
# Transcription: multipart form data
with open("recording.mp3", "rb") as f:
text = requests.post(
f"{BASE}/audio/transcriptions",
headers=headers,
files={"file": f},
data={"model": "whisper-1", "language": "en"},
).json()["text"]
# Music: submit, then poll. The poll is free.
job = requests.post(
f"{BASE}/audio/generations",
headers=headers,
json={"model": "auto/music", "prompt": "calm piano jazz"},
).json()
status = requests.get(
f"{BASE}/audio/generations/{job['id']}", headers=headers
).json()JavaScript
const BASE = 'https://api.jarvisclaw.ai/v1'
const headers = {
Authorization: 'Bearer sk-your-api-key',
'Content-Type': 'application/json',
}
// Speech
const speech = await fetch(`${BASE}/audio/speech`, {
method: 'POST',
headers,
body: JSON.stringify({
model: 'elevenlabs/flash-v2.5',
input: 'Hello, welcome to JarvisClaw!',
voice: 'sarah',
}),
}).then((r) => r.json())
const mp3 = await fetch(speech.data[0].url).then((r) => r.arrayBuffer())
// Transcription — multipart, so no JSON content-type here
const form = new FormData()
form.append('file', fileBlob, 'recording.mp3')
form.append('model', 'whisper-1')
const { text } = await fetch(`${BASE}/audio/transcriptions`, {
method: 'POST',
headers: { Authorization: 'Bearer sk-your-api-key' },
body: form,
}).then((r) => r.json())Use cases
- Voice agents — The fast TTS tier answers in well under a second, which is what a conversational turn can absorb.
- Meeting and call transcription — Whisper over multipart upload, with an optional language hint for accuracy.
- Cross-language ingestion — Translate spoken audio in any language straight to English text in one call.
- Narration and audiobooks — Studio-grade voices for long-form reading, where quality outranks latency.
- Soundtracks — Generate a full-length track from a prompt, with lyrics or instrumental only.
- Sound design — Describe an effect and get it back — UI sounds, stings, ambience.
FAQ
Does /audio/speech return the audio file itself?
No. It returns JSON containing a CDN URL plus the format and character count. Fetch that URL to get the bytes — and download it, because the file is retained only for a limited window.
Is this OpenAI-compatible?
Yes for the shapes that matter: /audio/speech, /audio/transcriptions and /audio/translations accept the same fields, so the OpenAI SDK works by changing base_url.
How do I choose a voice?
Pass a voice alias such as sarah or george, or a raw provider voice id. GET /v1/marketplace/audio/voices lists what is available rather than leaving you to guess.
How is speech billed?
Per input character, quoted per 1000. Cost therefore scales with the text you send, and the model tier sets the rate — the fast tiers cost roughly half the studio ones.
Does polling a music job cost extra?
No. The GET reuses the payment made by the POST, so you can poll until the track is ready without being charged again.
What are the upload limits for transcription?
Files up to 25MB, in mp3, mp4, mpeg, mpga, m4a, wav or webm. Split longer recordings into segments under that size.
Documentation
- Audio & TTS reference — Models, parameters, voices and response shapes
- Music Generation reference — The asynchronous submit-and-poll flow
- Async & concurrent calls — Polling jobs without holding a request open
- SDK — AudioClient for Python and Go