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
- Sign up and connect your Sonos account in the app.
- Get an API key (see Authentication).
- Look up the slugs of your speakers and groups.
- Play something.
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:
# 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.
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.
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).
| Route | What | Credits |
|---|---|---|
POST /v1/play/text | Speak a text with a voice from /v1/voices | 2 + voice rate per started 100 characters |
POST /v1/play/sound | A built-in sound from /v1/sounds | 1 |
POST /v1/play/clip | One of your own clips from /v1/clips | 1 |
POST /v1/play/url | Audio from a URL, with or without processing | 1, processed 2 |
POST /v1/play/file | An uploaded file (multipart) | 2 |
POST /v1/play/talk | A recording from the mic, plays when you let go (multipart) | 2 + 1 per started 10 s |
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.
| Parameter | Meaning |
|---|---|
targets | Target slugs from /v1/user/targets, as an array or comma-separated. Default: your default targets. |
volume | 1 to 100. |
intro, outro | A sound slug, clip:<slug> for your own clip, or none. |
effect, intensity | A voice effect or backdrop, intensity 0 to 100. |
quietHours | Overrides your quiet hours for this play, none lifts them. |
priority | true interrupts other clips on the speaker. |
preview | true 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": {
"code": "ERROR_INSUFFICIENT_CREDITS",
"message": "…"
}
}| Status | Code | When |
|---|---|---|
| 400 | ERROR_MISSING_PARAMS, ERROR_INVALID_PARAMS | A parameter is missing or invalid, field names it. |
| 401 | ERROR_MISSING_API_KEY, ERROR_INVALID_API_KEY | No API key, or an invalid one. |
| 402 | ERROR_INSUFFICIENT_CREDITS | Not enough credits for this announcement. |
| 404 | ERROR_NOT_FOUND | The play or clip doesn't exist. |
| 409 | ERROR_SONOS_RECONNECT_REQUIRED | Sonos rejected the login, reconnect your Sonos account. Nothing is charged. |
| 424 | ERROR_SONOS_FAILED | No speaker accepted the announcement. Nothing is charged, the play is in the history as FAILED. |
| 503 | ERROR_TTS_FAILED | Speech 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.