Find sound effects by describing the moment you’re scoring — “whoosh for a scene change”, “cash register cha-ching”, “soft notification chime” — and get back ranked SFX, each with a pre-signed download URL. It’s the same semantic search behind background music: set type=sound_effects on GET /v3/audio/sounds and describe what you want in plain language.
Search the Catalog
Send a GET request to /v3/audio/sounds with a natural-language query and type=sound_effects:
curl -X GET "https://api.heygen.com/v3/audio/sounds?query=whoosh%20for%20a%20scene%20change&type=sound_effects&limit=3" \
-H "x-api-key: YOUR_API_KEY"
{
"data": [
{
"id": "7f2e91ac5b3d4e8f9a1c6d0b2e4f8a3c",
"name": "Cinematic Whoosh: 7f2e91ac",
"description": "Fast airy whoosh transition, ideal for scene changes and reveals.",
"audio_url": "https://heygen-product.s3-accelerate.amazonaws.com/sound_effects/7f2e91ac...wav?X-Amz-Algorithm=...",
"duration": 1.4,
"score": 0.941,
"type": "sound_effects"
},
{
"id": "c4a8d2f1e6b9470a8d3e5f7c1a9b2d6e",
"name": "Swipe Transition: c4a8d2f1",
"description": "Quick swish swipe, light and modern, suited to UI motion and cuts.",
"audio_url": "https://heygen-product.s3-accelerate.amazonaws.com/sound_effects/c4a8d2f1...wav?X-Amz-Algorithm=...",
"duration": 0.9,
"score": 0.902,
"type": "sound_effects"
}
],
"has_more": true,
"next_token": "eyJvZmZzZXQiOiAzLCAiX3R5cGUiOiAic291bmRfZWZmZWN0cyJ9"
}
Query Parameters
| Parameter | Type | Default | Description |
|---|
query | string | — | Required. Natural-language description of the sound you want, e.g. cash register cha-ching. Results are ranked by semantic similarity to this text. |
type | string | music | Audio content type. Set to sound_effects to search the SFX catalog; music (the default) searches background music. |
limit | integer | 10 | Maximum number of results to return (1–50). |
min_score | number | 0.7 | Minimum semantic similarity score (0–1). Effects scoring below this are omitted. Raise it for tighter matches; lower it to widen the net. |
token | string | — | Opaque pagination cursor. Pass the next_token from a prior response to fetch the next page. |
Response Fields
| Field | Type | Description |
|---|
data[].id | string | Stable identifier for the sound effect. |
data[].name | string | Display name of the sound effect. |
data[].description | string | Human-readable description of the sound and where it fits. |
data[].audio_url | string | Pre-signed download URL for the audio file (WAV). |
data[].duration | number | Length in seconds. Most effects are short — under a few seconds. |
data[].score | number | Semantic similarity score (0–1) against your query. Results are returned highest-first. |
data[].type | string | sound_effects for results from the SFX catalog. |
has_more | boolean | true if more results are available beyond this page. |
next_token | string | Cursor for the next page. Pass it as token on your next request. Absent when has_more is false. |
Each audio_url is a pre-signed link with a limited lifetime. Download the file (or hand the URL to a downstream step) soon after searching rather than caching it for later.
Paginate Through Results
When has_more is true, pass the returned next_token as the token parameter to fetch the next page:
curl -X GET "https://api.heygen.com/v3/audio/sounds?query=whoosh%20for%20a%20scene%20change&type=sound_effects&limit=3&token=eyJvZmZzZXQiOiAzLCAiX3R5cGUiOiAic291bmRfZWZmZWN0cyJ9" \
-H "x-api-key: YOUR_API_KEY"
Full Example
import requests
from urllib.parse import urlencode
API_KEY = "YOUR_API_KEY"
BASE = "https://api.heygen.com"
HEADERS = {"x-api-key": API_KEY}
def search_sound_effects(query, limit=10, min_score=0.7):
"""Yield every matching sound effect, following pagination."""
token = None
while True:
params = {
"query": query,
"type": "sound_effects",
"limit": limit,
"min_score": min_score,
}
if token:
params["token"] = token
resp = requests.get(
f"{BASE}/v3/audio/sounds?{urlencode(params)}",
headers=HEADERS,
)
page = resp.json()
for effect in page["data"]:
yield effect
if not page.get("has_more"):
break
token = page["next_token"]
# Grab the single best-matching effect
best = next(search_sound_effects("cash register cha-ching", limit=1))
print(f"{best['name']} ({best['duration']}s, score {best['score']:.2f})")
print(f"Download: {best['audio_url']}")
If your integration validates the type field in responses against an enum, add sound_effects to it — the changelog entry for this release has the full migration note.