Quak

docs

Build with Quak

One REST API for everything Quak does: text-to-speech, sounds, your own clips and push-to-talk on your Sonos speakers. JSON in, JSON out, one API key.

Quickstart

  1. Sign up and connect your Sonos account in the app.
  2. Get an API key (see Authentication).
  3. Look up the slugs of your speakers and groups.
  4. Play something.
POST /v1/play/text
curl https://api.quak.party/v1/play/text \
  -H "Authorization: Bearer $QUAK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text": "Dinner is ready!", "targets": ["kitchen", "living-room"]}'

That's a short text with your default voice on two speakers, 6 credits. The response is the play with its id and status, and the header X-Quak-User-Credits carries your balance afterwards.

Authentication

Send your API key as a bearer token: Authorization: Bearer <API_KEY>. The query parameter ?apikey=<API_KEY> works too, for tools that can't set headers. Keep the key secret, it can play on your speakers and spend your credits.

You get a key by logging in with your email, no password involved. The app does this for you, from a script it takes three steps:

login with a magic link
# 1. start the login, Quak sends you an email
curl https://api.quak.party/v1/user/login \
  -H "Content-Type: application/json" \
  -d '{"email": "you@example.com"}'
# → {"verifyToken": "…", "loginPhrase": "…", "expiresAt": "…"}

# 2. click "Confirm login" in the email (check the phrase matches)

# 3. exchange the token for an API key, waits up to 180 s for your click
curl https://api.quak.party/v1/user/login/key \
  -H "Content-Type: application/json" \
  -d '{"verifyToken": "…", "waitForConfirmation": true}'
# → {"apiKey": "…"}

With that key you can create more keys with a name, one per integration, so you can revoke them one by one. GET /v1/keys lists them with their request and play counts.

POST /v1/keys
curl https://api.quak.party/v1/keys \
  -H "Authorization: Bearer $QUAK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "home-assistant"}'

Speakers and targets

A target is anything Quak can play on: a single speaker, a Sonos group, a household or all your speakers. Each has a slug like kitchen that you pass in targets. Without targets, Quak uses your default targets.

GET /v1/user/targets
curl https://api.quak.party/v1/user/targets \
  -H "Authorization: Bearer $QUAK_API_KEY"

Kinds of plays

All play routes answer 201 with the play. During quiet hours the answer is 200 with status: "SKIPPED", nothing plays and nothing is charged. Every play lands in the history (GET /v1/plays) and can be stopped while it runs (POST /v1/plays/:id/stop).

RouteWhatCredits
POST /v1/play/textSpeak a text with a voice from /v1/voices2 + voice rate per started 100 characters
POST /v1/play/soundA built-in sound from /v1/sounds1
POST /v1/play/clipOne of your own clips from /v1/clips1
POST /v1/play/urlAudio from a URL, with or without processing1, processed 2
POST /v1/play/fileAn uploaded file (multipart)2
POST /v1/play/talkA recording from the mic, plays when you let go (multipart)2 + 1 per started 10 s
POST /v1/play/sound
curl https://api.quak.party/v1/play/sound \
  -H "Authorization: Bearer $QUAK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"sound": "gong", "volume": 40}'

Announcements are short, at most about a minute: texts up to 1,000 characters, files and clips up to 60 seconds and 10 MB.

Common parameters

Missing parameters come from your defaults (PATCH /v1/user/defaults), so most calls only need the content.

ParameterMeaning
targetsTarget slugs from /v1/user/targets, as an array or comma-separated. Default: your default targets.
volume1 to 100.
intro, outroA sound slug, clip:<slug> for your own clip, or none.
effect, intensityA voice effect or backdrop, intensity 0 to 100.
quietHoursOverrides your quiet hours for this play, none lifts them.
prioritytrue interrupts other clips on the speaker.
previewtrue only renders the audio and returns its audioUrl, nothing plays on Sonos.

Credits

A play costs 1 credit when Sonos fetches the audio directly (sounds, clips, URLs without processing) and 2 when it goes through Quak (text, processed URLs, files, talk). Text adds the voice rate per started 100 characters, talk 1 per started 10 seconds. A text from the cache costs 2. One announcement to many speakers costs the same as to one.

Plans and packs are on the pricing page.

Responses and errors

Successful responses wrap their payload in data, errors in error with a stable code and a readable message. 4xx means you need to change something, 5xx means the request was fine and you can send it again later.

error response
{
  "error": {
    "code": "ERROR_INSUFFICIENT_CREDITS",
    "message": "…"
  }
}
StatusCodeWhen
400ERROR_MISSING_PARAMS, ERROR_INVALID_PARAMSA parameter is missing or invalid, field names it.
401ERROR_MISSING_API_KEY, ERROR_INVALID_API_KEYNo API key, or an invalid one.
402ERROR_INSUFFICIENT_CREDITSNot enough credits for this announcement.
404ERROR_NOT_FOUNDThe play or clip doesn't exist.
409ERROR_SONOS_RECONNECT_REQUIREDSonos rejected the login, reconnect your Sonos account. Nothing is charged.
424ERROR_SONOS_FAILEDNo speaker accepted the announcement. Nothing is charged, the play is in the history as FAILED.
503ERROR_TTS_FAILEDSpeech synthesis is down. Nothing is charged, try again later.

CLIcoming soon

quak (or just q) brings the API to your terminal: q text "Build is green" --to office, q sound clapping-crowd, fuzzy search for sounds and voices. It's in the works, install instructions follow here.

MCP servercoming soon

Let Claude, ChatGPT and other assistants make announcements and pick fitting sounds for you. The MCP server is in the works. Until then, hand your assistant the OpenAPI schema, it knows what to do with it.