NewWe just added 1,500 new sounds to the library
Building an Audio Pipeline with Lotsofsounds
|2 min read|lotsofsounds team

Building an Audio Pipeline with Lotsofsounds

Manual asset management doesn't scale. Here's how to build an automated audio pipeline using the Lotsofsounds API.

The problem

Most teams manage sound effects by downloading files manually and committing them to version control. This works until:

  • Your sound library grows past 100 files
  • Multiple team members need to update assets
  • You want to A/B test different sound variants

A better approach

Use the Lotsofsounds API to fetch sounds at build time instead of storing them in your repo.

Create a manifest file

Define the sounds your app needs in a JSON manifest:

sounds.json
{
  "sounds": {
    "button_click": { "query": "ui click soft", "index": 0 },
    "notification": { "query": "notification chime", "index": 0 },
    "error": { "query": "error buzz short", "index": 0 }
  }
}

Write a build script

Create a script that reads the manifest and downloads sounds:

scripts/fetch-sounds.js
const manifest = require("./sounds.json");

const API_KEY = process.env.LOS_API_KEY;
const BASE_URL = "https://api.lotsofsounds.com/api/v1";

for (const [name, config] of Object.entries(manifest.sounds)) {
  // Search for sounds matching the query
  const searchRes = await fetch(
    `${BASE_URL}/sounds?q=${encodeURIComponent(config.query)}`,
    { headers: { "x-api-key": API_KEY } }
  );
  const { data } = await searchRes.json();
  const sound = data[config.index];

  // Get a signed download URL
  const dlRes = await fetch(`${BASE_URL}/sounds/${sound.id}/download`, {
    headers: { "x-api-key": API_KEY },
  });
  const { data: dl } = await dlRes.json();

  // Download the file
  const audio = await fetch(dl.download_url);
  // Save to your assets directory...
}
scripts/fetch_sounds.py
import json, os, requests

with open("sounds.json") as f:
    manifest = json.load(f)

API_KEY = os.environ["LOS_API_KEY"]
BASE_URL = "https://api.lotsofsounds.com/api/v1"

for name, config in manifest["sounds"].items():
    # Search for sounds matching the query
    search = requests.get(
        f"{BASE_URL}/sounds",
        params={"q": config["query"]},
        headers={"x-api-key": API_KEY},
    ).json()
    sound = search["data"][config["index"]]

    # Get a signed download URL
    dl = requests.get(
        f"{BASE_URL}/sounds/{sound['id']}/download",
        headers={"x-api-key": API_KEY},
    ).json()

    # Download the file
    audio = requests.get(dl["data"]["download_url"])
    with open(f"assets/sounds/{name}.mp3", "wb") as f:
        f.write(audio.content)

Add to your CI pipeline

Run the script as a build step. Cache the downloads to avoid hitting rate limits:

.github/workflows/build.yml
- name: Fetch sounds
  env:
    LOS_API_KEY: ${{ secrets.LOS_API_KEY }}
  run: node scripts/fetch-sounds.js
  cache:
    paths: [assets/sounds]

Benefits

  • Version control: Your manifest tracks intent, not binary blobs
  • Easy updates: Change a search query to swap a sound
  • Team-friendly: No merge conflicts on audio files
  • CI-compatible: Sounds are always fresh and consistent

Rate limit tips

Cache in CI

Downloads are unlimited on all paid plans, but cache aggressively in CI to keep builds fast and reduce unnecessary API calls.

Check out the endpoint docs and authentication guide for more details.