Senova API · Voice

Voice API

Put Senova's voices in your own app: text to speech with Aria and speech to text with Notation. The endpoints follow OpenAI's audio API, so the OpenAI SDKs work by changing the base URL and key, and OpenAI model and voice names (tts-1, whisper-1, alloy…) map to Senova's. Create a key with the Voice scope in the console; calls are paid from the same prepaid credit as chat (see API reference for keys, credit and webhooks).

POST /v1/audio/speech

Turns text into audio. Fields: model (aria-1, or tts-1), input (up to 4,096 characters), voice (default af_heart), speed (0.5–2, default 1), response_format (mp3 default, wav, or pcm: raw 16-bit mono at 24 kHz). The audio streams back as it's made, so playback can start before the end. The response headers X-Senova-Billed-Characters and X-Senova-Price-Usd say what the call cost.

curl https://senovasys.com/v1/audio/speech \
  -H "Authorization: Bearer $SENOVA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"aria-1","input":"Hello from Senova.","voice":"af_heart","response_format":"mp3"}' \
  --output hello.mp3
// JavaScript (npm install openai)
import fs from "node:fs"
import OpenAI from "openai"

const senova = new OpenAI({ baseURL: "https://senovasys.com/v1", apiKey: process.env.SENOVA_API_KEY })
const speech = await senova.audio.speech.create({ model: "aria-1", voice: "af_heart", input: "Hello from Senova." })
fs.writeFileSync("hello.mp3", Buffer.from(await speech.arrayBuffer()))
# Python (pip install openai)
import os
from openai import OpenAI

senova = OpenAI(base_url="https://senovasys.com/v1", api_key=os.environ["SENOVA_API_KEY"])
with senova.audio.speech.with_streaming_response.create(model="aria-1", voice="af_heart", input="Hello from Senova.") as r:
    r.stream_to_file("hello.mp3")

POST /v1/audio/transcriptions

Turns speech into text. Send multipart/form-data with file (flac, m4a, mp3, mp4, mpeg, mpga, ogg, wav or webm, up to 25 MB), model (notation-1, or whisper-1), and optionally language (ISO-639-1, such as en) and response_format: json (default, {"text","usage"}), text, or verbose_json (adds language, duration and timed segments).

curl https://senovasys.com/v1/audio/transcriptions \
  -H "Authorization: Bearer $SENOVA_API_KEY" \
  -F [email protected] -F model=notation-1 -F response_format=json
// JavaScript
const t = await senova.audio.transcriptions.create({ model: "notation-1", file: fs.createReadStream("meeting.mp3") })
console.log(t.text)
# Python
with open("meeting.mp3", "rb") as f:
    t = senova.audio.transcriptions.create(model="notation-1", file=f)
print(t.text)

GET /v1/audio/voices

Lists the voices, the audio models your key can call with their prices, and the limits. Aria 1 voices are English: ids starting a are American, b British; the second letter is f (female) or m (male). OpenAI voice names map like this: alloy → af_alloy, ash → am_adam, ballad → bm_george, coral → af_heart, echo → am_echo, fable → bm_fable, nova → af_nova, onyx → am_onyx, sage → af_sarah, shimmer → af_bella, verse → am_michael. Voice cloning (making a voice from a recording) isn't offered through the API.

af_alloy af_aoede af_bella af_heart af_jessica af_kore af_nicole af_nova af_river af_sarah af_sky am_adam am_echo am_eric am_fenrir am_liam am_michael am_onyx am_puck am_santa bf_alice bf_emma bf_isabella bf_lily bm_daniel bm_fable bm_george bm_lewis

Prices

idModelPriceStatus
aria-1Aria 1 (speech)$6 per 1M charactersAvailable
aria-2Aria 2 (speech)$10 per 1M charactersAvailable
notation-1Notation 1 (transcription)$0.003 per minuteAvailable
notation-2Notation 2 (transcription)$0.006 per minuteComing soon

Speech is billed by the characters in input; transcription by the seconds of audio, rounded up, at least one second per request. Calls the voice service couldn't complete aren't charged. Each call shows under Usage by model and key.

Limits

Up to 4,096 characters per speech request (split longer text) and 25 MB per audio file. Voice calls share each key's requests-per-minute and monthly spend limits, and the organization's limit, with chat. A speech request needs enough credit for its full price before it starts.

Errors

Errors use OpenAI's shape, {"error":{"message","type","code"}}:

  • 400 invalid request; code input_too_long, voice_not_found, unsupported_file or voice_cloning_unsupported
  • 401 missing or bad key; 403 key without the audio scope, or a suspended organization
  • 402 insufficient_quota: not enough credit
  • 404 model_not_found; 413 file_too_large
  • 429 rate_limit or key_limit (monthly spend); retry after a minute or raise the limit in the console
  • 502 the voice service didn't answer (not charged; retry); 503 at capacity (retry with backoff)

Data handling

The text or audio you send goes to the speech service that runs the model (Senova's own server first, a hosted provider as a fallback) and the result comes straight back. Senova doesn't store the text or the audio, and voice calls are never written to request logs, even when logging is on. Usage records (characters or seconds, model, time, key, price) are kept for billing. Generated speech is synthetic: tell your listeners when a voice is AI-generated where the law requires it. See the Privacy Policy.