brauo

API

From a key to audio.

The same API that powers the extension and the apps. Base URL https://api.brauo.com. Your account dashboard is at /account; your key is at /account/key.

01

Authentication

Every request needs Authorization: Bearer brauo_sk_…. Keys are created on signup, shown once, and rotatable at /account/key. The server stores only a hash, so a lost key means rotating. Without a valid key the API returns 401 with code invalid_key.

02

Credits

1 credit = 1,000 characters with a Brauo Original voice (1x). Extra voices bill at 20x - each voice’s credit_multiplier is in the catalog. Replaying audio the platform already cached does not re-charge. Free accounts get a small daily allowance; paid plans are sold as listening hours at /pricing. Out of credits returns 402 quota_exceeded.

03

POST /v1/speak

Read a passage aloud as mp3. Request body: { "text": "…", "voice": "brauo-elena-es" }. Text up to 2,000 characters per request. Response is audio/mpeg (chunked), with headers X-Brauo-Request-Id and X-Brauo-Cache: hit|miss.

POST /v1/speakcurl
curl -X POST https://api.brauo.com/v1/speak \
  -H "Authorization: Bearer brauo_sk_…" \
  -d '{ "text": "Any page, read aloud…",
       "voice": "brauo-elena-es" }'
04

POST /v1/speak/realtime

For voice agents: raw PCM16 mono little-endian at 24 kHz, streamed while it synthesizes - first bytes before the sentence is done. Request { "text", "voice" }, text up to 500 characters (one conversational turn). Response audio/pcm with X-Brauo-Sample-Rate: 24000 and X-Brauo-Request-Id. Never cached. Hanging up mid-stream is normal (barge-in): synthesis stops and the turn is billed as delivered.

POST /v1/speak/realtimeaudio/pcm · 24 kHz
curl -N -X POST https://api.brauo.com/v1/speak/realtime \
  -H "Authorization: Bearer brauo_sk_…" \
  -d '{ "text": "One short turn at a time.",
       "voice": "brauo-elena-es" }' \
  | ffplay -f s16le -ar 24000 -ch_layout mono -
05

GET /v1/voices

Public, no auth. Response shape (excerpt):

GET /v1/voicesjson
{
  "voices": [
    {
      "id": "brauo-elena-es",
      "language": "es",
      "tier": "…",
      "credit_multiplier": 1,
      "badge": "Brauo Original"
    }
  ]
}

Live catalog (grouped by language):

Loading catalog…

06

GET /v1/account

Your balance: { "plan", "credits", "credit_chars", "key_prefix", "usage": { "allowance_chars", "used_chars", "period_end" } }. The usage object is present on paid plans. Also available: GET /v1/usage/history - recent requests with request_id, chars, and outcome (success | partial | failed).

07

POST /v1/translate

Document translation, free within daily caps: free accounts 3 jobs/day up to 30k characters each; paid 20/day up to 600k. Request { "text", "target_language" } returns 202 with a job id; poll GET /v1/translate/{id} until done. Listening to the result is priced like any speak.

08

Errors

Envelope: { "error": { "code": "…", "message": "…" } }.

codestatus
invalid_request400
invalid_key401
quota_exceeded402
paid_voice_required403
voice_not_found404
provider_unavailable502
09

Status