Pagination
All list endpoints in the Epidemic Sound API use offset-based pagination. Results are divided into pages controlled by two query parameters: limit and offset.
Query parameters
| Parameter | Description |
|---|---|
limit | Number of items to return per page (default and max vary per endpoint — see table below) |
offset | Number of items to skip (default: 0). Must be 0 or a multiple of limit |
offset must divide evenly by limitAny other value returns 400 "Invalid offset. Offset must be 0 or divisible by {limit}", so validity depends on the pair: ?limit=30&offset=500 fails, while ?limit=30&offset=600 and ?limit=100&offset=500 both work.
Per-endpoint limits
| Endpoint | Default limit | Max limit |
|---|---|---|
GET /v0/tracks/search | 50 | 60 |
GET /v0/tracks | 50 | 100 |
GET /v0/collections | 10 | 20 |
GET /v0/collections/{collectionId} | 50 | 100 |
GET /v0/moods, GET /v0/genres | 20 | 20 |
GET /v0/sound-effects/collections | 10 | 20 |
GET /v0/sound-effects/collections/{collectionId} | 50 | 100 |
GET /v0/sound-effects/categories | 50 | no cap |
GET /v0/sound-effects/categories/{id}/tracks | 50 | 100 |
GET /v0/tracks/matching-image/{imageId} | 50 | 100 |
GET /v0/users/me/liked/tracks | 25 (fixed) | 25 |
limit on /v0/collections counts collections, not tracksGET /v0/collections embeds a maximum of 20 tracks per collection regardless of limit — that parameter controls how many collections are returned. To get all tracks in a collection, call GET /v0/collections/{collectionId}, where limit accepts up to 100.
GET /v0/moods and GET /v0/genres both accept a limit above 20 but return 20 with pagination.limit: 20. The full catalogs contain 46 moods and roughly 500 genres, so pagination is the only way to retrieve complete lists. The type parameter already defaults to all.
GET /v0/users/me/liked/tracks does not accept a limit parameter — it always returns 25 results per page, so offset must be a multiple of 25.
The maximum offset is 3000 when browsing, but only 500 for text search (GET /v0/tracks/search with a term), regardless of limit.
At offset 500 text search returns 200 with an empty tracks array rather than an error, so a paging loop stops there even when more matches exist. Narrow with filters instead of paging deep.
Pagination response
Every list response includes a pagination object and a links object:
{
"tracks": [...],
"pagination": {
"page": 2,
"limit": 25,
"offset": 25
},
"links": {
"next": "/v0/tracks/search?limit=25&offset=50",
"prev": "/v0/tracks/search?limit=25&offset=0"
}
}
| Field | Description |
|---|---|
pagination.page | Current page number (1-based) |
pagination.limit | Number of items returned in this response |
pagination.offset | Number of items skipped |
links.next | Relative path for the next page, or null |
links.prev | Relative path for the previous page, or null |
When links.next is null, you have reached the last page.
Fetching the first page
curl "https://partner-content-api.epidemicsound.com/v0/tracks/search?term=happy&limit=25&offset=0" \
-H "Authorization: Bearer your-api-key"
Fetching all pages
Use links.next to determine whether more pages exist. Append the offset from the next link to the same base request, or construct it yourself by incrementing offset by limit each iteration.
async function fetchAllTracks(apiKey, searchTerm) {
const baseUrl = 'https://partner-content-api.epidemicsound.com'
const limit = 50
let offset = 0
let allTracks = []
while (true) {
const response = await fetch(
`${baseUrl}/v0/tracks/search?term=${encodeURIComponent(
searchTerm
)}&limit=${limit}&offset=${offset}`,
{ headers: { Authorization: `Bearer ${apiKey}` } }
)
const data = await response.json()
allTracks = allTracks.concat(data.tracks)
if (!data.links.next) {
break
}
offset += limit
}
return allTracks
}
Best practices
- Request only what you need. Fetch a single page at a time rather than loading all results upfront. For a search results UI, 20–30 results per page is usually sufficient.
- Use
links.nextas your stop condition. Whenlinks.nextisnull(or absent), you have reached the last page. - Avoid high offsets on large catalogs. Performance degrades with very large offsets. Use filters (
mood,genre,term) to narrow results before paginating. - Cache the current page offset. If users navigate between pages in your UI, store the current
offsetso you can resume without re-fetching earlier pages.