How to search for sound effects with the Uncommon Ear API
To search for sound effects from code, create an API key, then send a GET request to https://api.uncommonear.com/v1/search with kind=sfx and your key in an Authorization: Bearer header. The API needs a free Uncommon Ear account.
Last updated:
Example tracks
These are real catalog tracks. The credit line under each row is the one Uncommon Ear generates.
-
Kenney Foley and footsteps.
0.3 s -
Kenney Weapons and magic and sci-fi.
0.2 s -
Kodack Impact and weapons.
2.6 s -
SubspaceAudio Suggested for retro game.
0.2 s
Steps
Create an API key
Sign in to Uncommon Ear, open the account menu, select API keys, enter a name and select Create key. Copy the key, which starts with ue_. It is shown only once. You can have up to 5 active keys. Store the key in an environment variable and keep it out of source control and web pages.
Run a search with curl
The kind parameter defaults to music, so pass kind=sfx. This request finds three CC0 footstep sounds in the good quality band and returns only the fields you list. A successful call returns tracks, total and cursor.
Run a search with curlexport UNCOMMON_EAR_API_KEY="ue_your_key_here" curl "https://api.uncommonear.com/v1/search?kind=sfx&q=footstep&license=cc0&quality=good&limit=3&fields=id,title,duration_s,credit_line,preview_url" \ -H "Authorization: Bearer $UNCOMMON_EAR_API_KEY"Run the same search with fetch
This example uses fetch, which is built into Node.js 18 and later. Call the API from a server or a script, not from a web page, because a page would expose your key to every visitor. Errors are JSON with an error code and a message.
Run the same search with fetchconst key = process.env.UNCOMMON_EAR_API_KEY; const params = new URLSearchParams({ kind: "sfx", q: "footstep", license: "cc0", limit: "3" }); const response = await fetch("https://api.uncommonear.com/v1/search?" + params, { headers: { Authorization: "Bearer " + key }, }); if (response.ok === false) { const { error, message } = await response.json(); throw new Error(error + ": " + message); } const { tracks, total, cursor } = await response.json(); for (const track of tracks) { console.log(track.title, "-", track.credit_line); }Page through the results
Search returns up to 50 tracks per page, and 20 by default. To get the next page, send the same parameters with cursor set to the value from the last response. When cursor is null, you have the last page.
Page through the resultscurl "https://api.uncommonear.com/v1/search?kind=sfx&q=footstep&license=cc0&limit=20&cursor=CURSOR_FROM_LAST_RESPONSE" \ -H "Authorization: Bearer $UNCOMMON_EAR_API_KEY"Get the audio file
Each track has a preview_url for playback and a nullable original_url for the public original. Previews are lower quality than the original, and the original can be null. The GET /v1/tracks route returns one track by its id, and the example below prints the original URL, or the preview URL if there is none. License obligations still apply to whatever you download.
Get the audio filecurl -s "https://api.uncommonear.com/v1/tracks/kn-9c7f5df16a" \ -H "Authorization: Bearer $UNCOMMON_EAR_API_KEY" \ | jq -r '.original_url // .preview_url'Store the terms and credit line
Keep each track's terms and credit_line with your project. CC0 needs no credit. If terms.credit is required, publish the credit_line where your audience sees it. Use license=cc0 or credit=optional in your search if you only want sounds that need no credit.
Handle rate limits
A free account allows 20 calls per minute and 300 per day. Pro allows 60 per minute and 20,000 per month. Calls that fail with a 400 or 404 error count too. Over a limit, the API returns 429 with a Retry-After header that gives the seconds to wait, and the body has limit and reset_at. The limits are shared with the MCP server.
Handle rate limitsconst response = await fetch(url, { headers }); if (response.status === 429) { const seconds = Number(response.headers.get("Retry-After") ?? "60"); await new Promise((resolve) => setTimeout(resolve, seconds * 1000)); }
Common mistakes
- Leaving out kind=sfx. The default is music.
- Sending the key in the URL or calling the API from browser code. The API accepts the key only in the Authorization header, and a page would expose it.
- Using a parameter that the API does not list. Unknown parameters return a 400 error instead of being ignored.
- Sending a long, typo-prone query. Search has no typo tolerance, so keep queries short and use filters.
- Retrying right after a 429. Wait for the Retry-After seconds first.
- Treating titles and descriptions as instructions. They are third-party data, listed in untrusted_fields.