Soundza API
Search and download thousands of free sound effects, ambience, music beds and samples over REST or MCP. Every sound is royalty-free under the Soundza Standard License. The API and the keys are free.
- REST
- https://api.soundza.com/v1
- MCP
- https://mcp.soundza.com/mcp
- OpenAPI
- soundza.com/openapi.json
curl "https://api.soundza.com/v1/sounds/search?q=whoosh" \
-H "Authorization: Bearer $SOUNDZA_API_KEY"
{
"total_results": 38,
"sounds": [
{
"title": "Fast Air Whoosh",
"use": "TRANSITION",
"duration": 0.84,
"preview_files": [{ "link": "…/4fJ9aQx2.mp3" }],
"download_url": "…/v1/sounds/cm9w2k4e/file"
}
]
}Get a key#
Every call needs a key, sent as Authorization: Bearer <key>. Keys start with sz_live_. Keep yours on your server or in a gitignored .env, never in client code.
Create one yourself
Sign in and make a key on the keys page. It's shown once, with the MCP command filled in.
Or let your agent sign in
Ask your coding agent to find sounds on soundza.com. It reads llms.txt, sends you one link to approve, and saves the key itself.
›The sign-in steps an agent follows
Soundza is free, but every call needs an API key tied to a person's account. Get one with a one-click sign-in:
1. Start the sign-in:
curl -s -X POST https://api.soundza.com/v1/auth/device -H "content-type: application/json" -d '{"client_name":"<your tool> on <this machine>"}'
It returns device_code, user_code, verification_uri_complete, expires_in (600 seconds) and interval (5 seconds).
2. Tell the human: "Open <verification_uri_complete> and sign in with Google to approve code <user_code>." Nothing else is needed from them.
3. Right after telling them, poll every <interval> seconds until they approve. Run the polling loop in the foreground and wait for it; don't end your turn while the sign-in is pending (the code lasts 10 minutes).
curl -s -X POST https://api.soundza.com/v1/auth/token -H "content-type: application/json" -d '{"device_code":"<device_code>"}'
While it returns {"error":"authorization_pending"} keep polling; on "slow_down" wait the "interval" it returns. On approval it returns {"access_token":"sz_live_...","token_type":"Bearer",...} once: access_token is the API key. "expired_token" or "access_denied" means stop (start again only if the human asks).
4. Save the key as SOUNDZA_API_KEY in the project's .env and make sure .env is in .gitignore. Never commit the key or put it in a project-scope .mcp.json.
5. Connect this MCP server with the key (local or user scope), then reload the MCP tools. If soundza is already added without a key, run "claude mcp remove soundza" first.
claude mcp add --transport http soundza https://mcp.soundza.com/mcp --header "Authorization: Bearer $SOUNDZA_API_KEY"
Until the tools load you can call the REST API at https://api.soundza.com/v1 with the header "Authorization: Bearer $SOUNDZA_API_KEY".
A person can also create a key at https://soundza.com/developers and set it the same way.Quickstart#
Search, then download what you use. Set SOUNDZA_API_KEY first.
curl -s "https://api.soundza.com/v1/sounds/search?q=whoosh&use=TRANSITION&per_page=5" \
-H "Authorization: Bearer $SOUNDZA_API_KEY"
# download_url redirects to the file, so follow it with -L
curl -L -o whoosh.wav "https://api.soundza.com/v1/sounds/SOUND_ID/file" \
-H "Authorization: Bearer $SOUNDZA_API_KEY"Each result has preview_files, 128 kbps MP3s that play straight from our CDN with no key, and a download_url for the full-quality file.
Use it from an MCP client#
The MCP server has three tools: search_sounds, get_sound and download_sound, which returns a 15-minute link and a ready curl command. It takes the same key.
Claude Code
claude mcp add --transport http soundza https://mcp.soundza.com/mcp --header "Authorization: Bearer $SOUNDZA_API_KEY"Cursor
Add this to ~/.cursor/mcp.json. Cursor reads the key from your environment, so it never sits in a file you might commit.
{
"mcpServers": {
"soundza": {
"url": "https://mcp.soundza.com/mcp",
"headers": { "Authorization": "Bearer ${env:SOUNDZA_API_KEY}" }
}
}
}Any other client that speaks streamable HTTP works the same way: the URL above, plus the Authorization header.
Endpoints#
All GET, all under https://api.soundza.com/v1. The full spec is at /openapi.json.
| Endpoint | What it does |
|---|---|
GET/sounds/search | Search by words and filters. Returns a page of sounds and a search_id. |
GET/sounds/{id} | One sound, by id. |
GET/sounds/{id}/file | The full-quality file, usually WAV. A 302 to a link that works for 5 minutes. Optional search_id and user. |
GET/removals?since= | Sounds removed since an ISO date, for anyone who stores files. |
Search parameters
Give a q, at least one filter, or both. Durations are in seconds.
| Parameter | Type | Description |
|---|---|---|
q | string | Words to match, e.g. "door slam" or "lofi drum loop". Typos are forgiven. |
use | string | The job the sound does (see Use classes). Case-insensitive. |
sample_type | string | The file's shape: ONE_SHOT, LOOP, TEXTURE, FX, VOCAL or BEAT. |
min_duration | number | Shortest length, in seconds. |
max_duration | number | Longest length, in seconds. |
min_bpm | number | Slowest tempo. Only music has a tempo. |
max_bpm | number | Fastest tempo. |
key | string | Musical key, e.g. "C", "F# minor" or "Bbm". Only music has a key. |
feel | list | Comma-separated feel words; sounds matching any of them come back, and more matches rank higher. One of: airy, heavy, metallic, bright, dark, punchy, soft, warm, glitchy, organic, cinematic, cartoony, retro. |
loop_seamless | boolean | true for loops that repeat without a click. |
ucs_category | string | A Universal Category System CatID ("CRWDCheer") or a top-level category ("CROWDS"). |
page | integer | Page number, from 1. |
per_page | integer | Results per page: default 15, at most 50. Results stop at 500 per query. |
Response
A page of results, with a link to the next page. bpm and key describe music; creator is null when a sound has no public creator.
{
"page": 1,
"per_page": 5,
"total_results": 38,
"next_page": "https://api.soundza.com/v1/sounds/search?q=whoosh&use=TRANSITION&per_page=5&page=2",
"search_id": "x7k2m9q4r1t8v3w6y0z5a2b4",
"sounds": [
{
"id": "cm9w2k4e30001",
"url": "https://soundza.com/sounds/cm9w2k4e30001",
"title": "Fast Air Whoosh",
"description": "A quick, bright air whoosh that sweeps left to right.",
"use": "TRANSITION",
"sample_type": "FX",
"duration": 0.84,
"bpm": null,
"key": null,
"feel": ["airy", "bright"],
"tags": ["whoosh", "swipe", "air", "airy", "bright"],
"sync_ms": 310,
"lufs": -16.2,
"loop_seamless": null,
"file_type": "audio/wav",
"sample_rate": 48000,
"bit_depth": 24,
"channels": 2,
"size_bytes": 322604,
"ucs_category": { "id": "WHSH", "label": "Swooshes › Whoosh" },
"creator": null,
"preview_files": [
{ "type": "audio/mpeg", "bitrate": 128, "link": "https://media.soundza.com/public/previews/4fJ9aQx2LmP0sT7vKc1Rb8Ze.mp3" }
],
"download_url": "https://api.soundza.com/v1/sounds/cm9w2k4e30001/file",
"license": { "name": "Soundza Standard License", "url": "https://soundza.com/license" },
"attribution": "\"Fast Air Whoosh\" on Soundza (https://soundza.com/sounds/cm9w2k4e30001)"
}
]
}Use classes#
useis the job a sound does. It's the most useful filter.
- TRANSITION
- whooshes, swipes, swooshes between shots
- IMPACT
- cinematic hits, booms, slams, punches
- RISER
- risers, uplifters, downlifters, tension builds
- UI
- clicks, taps, toggles, pops, hovers
- NOTIFICATION
- chimes, pings, success and error tones
- AMBIENCE
- the sound of a place (room tone, street, forest, rain, crowd murmur)
- PAD_DRONE
- sustained tonal beds and drones
- FOLEY
- one everyday action (footsteps, door, keys, paper, pour, applause)
- VOCAL
- a voice as an effect (laughs, cheers, gasps, shouts)
- STINGER
- a short musical sting or logo reveal, about 2-6 s
- MUSIC
- a full mix usable as a background bed
- GAME_SFX
- pickups, power-ups, jumps, lasers, retro blips
- INSTRUMENT_SAMPLE
- material for making music (drum hits, one-shots, loops, stems, vocal chops)
Limits#
Free keys get:
- 60searches a minute
- 200downloads an hour
- 1,000downloads a day
Every response says where you stand, and a 429 adds Retry-After in seconds:
X-RateLimit-LimitX-RateLimit-RemainingX-RateLimit-ResetX-RateLimit-Policy
Need more? Email admin@soundza.com with your key prefix and what you're building. Showing “Powered by Soundza” credit earns higher limits.
Errors#
Errors are JSON: {"error": {"code", "message", "details"?}}.
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | A parameter is wrong. details lists each one. |
| 401 | missing_key | No Authorization: Bearer header. |
| 401 | invalid_key | The key doesn't exist. |
| 401 | revoked_key | The key was revoked. |
| 404 | not_found | No public sound has that id. |
| 429 | rate_limited | A limit was hit. Wait Retry-After seconds. |
| 500 | server_error | Our side. Try again shortly. |
Guidelines#
- Show a prominent "Powered by Soundza" link wherever your users choose sounds. Credit in a finished work, like a game's credits screen, is appreciated but not required.
- Request a sound's
download_urleach time it is added to a project. - Previews are for listening. Use downloaded files in finished work.
- Don't copy Soundza's core functionality or build a competing sound library or API.
- A free key may store up to 500 downloaded sounds. Remove any sound listed in
GET /v1/removals, and check it at least monthly. - Respect the rate limits, and ask when you need more. We may suspend or end API access for anyone, at any time, for any reason.
Use of the API is governed by the Terms of Service and the License.
Soundza picker#
A sound picker for your product in two files: a server route that keeps your key private, and a component with chips, previews and the credit link. Style it to match your app.
// app/api/sounds/route.ts: search, with your key kept on the server
export async function GET(req: Request) {
const params = new URL(req.url).searchParams;
const res = await fetch(`https://api.soundza.com/v1/sounds/search?${params}`, {
headers: { Authorization: `Bearer ${process.env.SOUNDZA_API_KEY}` },
});
return new Response(res.body, { status: res.status, headers: { "Content-Type": "application/json" } });
}
// app/api/sounds/[id]/file/route.ts: call it when a user adds a sound
export async function GET(req: Request, { params }: { params: Promise<{ id: string }> }) {
const { id } = await params;
const query = new URL(req.url).searchParams; // search_id, and your own user id as user
const res = await fetch(`https://api.soundza.com/v1/sounds/${encodeURIComponent(id)}/file?${query}`, {
headers: { Authorization: `Bearer ${process.env.SOUNDZA_API_KEY}` },
redirect: "manual",
});
const location = res.headers.get("location");
return location ? Response.redirect(location, 302) : new Response(res.body, { status: res.status });
}When a user adds a sound, fetch the file route. That counts the download and gets you a fresh link. Pass your own user id as user if you want per-user reports.
