Skip to main content

Metadata

This guide covers all metadata available through the Partner API: what fields are returned, how to fetch metadata efficiently, and what limitations exist.

Track metadata fields

All track-returning endpoints include a standard set of metadata fields:

FieldTypeDescription
idstringUUID identifier for the track
titlestringTrack title
mainArtistsarray of stringsPrimary artists (never null, but can be empty)
featuredArtistsarray of stringsFeatured/guest artists (nullable)
bpmnumberBeats per minute (integer, never null)
lengthnumberTrack duration in seconds
moodsarrayApplied mood tags (e.g. ["happy", "energetic"])
genresarrayApplied genre tags (e.g. ["pop", "indie-pop"])
imagesobjectCover art URLs in multiple sizes
waveformUrlstringURL to JSON waveform data
hasVocalsbooleanWhether the track contains any vocal content
vocalTypestringVocal classification: LEAD, PRESENCE, or NONE
isExplicitbooleanWhether the track contains explicit content
isPreviewOnlybooleanStream-only restriction (see content access)
tierOptionstringSubscription tier requirement
isrcstringInternational Standard Recording Code (nullable)
addedstringISO 8601 timestamp when track was added to catalog

A note on isPreviewOnly

When true, the track can only be streamed for preview and not downloaded. This depends on the user's subscription status and your partnership agreement.

Known issue: Partners with full catalogue access may see isPreviewOnly: true on tracks discovered outside their collections (e.g. via search, similar tracks, or mood/genre browsing), even though these tracks are actually downloadable. Do not rely on this flag alone to determine download eligibility — attempt the download regardless. See the Fundamentals on content access for details.

Filtering on vocals and explicit content

To narrow a result set on vocals or explicit content:

  • Vocals: use vocalType=NONE on browse or search for instrumental-only results. The filter runs server-side, so your page sizes and links.next stay correct.
  • Explicit content: music has no server-side filter, so use isExplicit to flag or hide tracks in your own UI and expect page sizes to vary. Sound effects do have one — see includeExplicit.

How to fetch metadata

Inline with content endpoints

Metadata comes automatically with every track-returning endpoint:

  • /v0/tracks (browse)
  • /v0/tracks/search
  • /v0/tracks/{id}/similar
  • /v0/collections/{id} (collection tracks)
  • /v0/genres/{id} (genre tracks)
  • /v0/moods/{id} (mood tracks)

ISRC lookup: These endpoints also accept ISRCs directly as track IDs (e.g., GET /v0/tracks/metadata?trackId=SE5Q52304763). An empty array response is a definitive "not in catalog" result.

Batch metadata lookup

Use /v0/tracks/metadata for efficient batch metadata retrieval:

GET /v0/tracks/metadata?trackId=uuid1&trackId=uuid2&trackId=uuid3

Batch size limit: The endpoint accepts multiple trackId parameters in the URL, but HTTP request line limits cap you at roughly 90 track IDs per request (4096-byte limit). For larger lists, split into batches and make parallel requests.

Single track metadata

Use /v0/tracks/{id} to get metadata for one specific track.

Taxonomies

Moods and genres

Moods (46 total): Emotional/atmospheric descriptors like happy, epic, relaxing. Full list retrieved via /v0/moods.

Genres (~500 total): Musical style tags with parent-child relationships. Parent genres (e.g. rock) match tracks tagged with any child genre (indie-rock, alternative-rock). Retrieved via /v0/genres.

Both endpoints:

  • Default to type=all (full catalog)
  • Support type=featured for curated subsets
  • Are capped at 20 results per page - paginate for complete lists
  • Include parent/child relationships in the response

Vocal types

  • NONE: Fully instrumental
  • PRESENCE: Vocal chops, samples, ad-libs, textures (no lead vocal)
  • LEAD: Sung lead vocals

Combined parameters endpoint

Use /v0/tracks/parameters to get moods and genres in one response - useful for building LLM enum schemas (providing AI models with valid option lists) or search UIs.

Facet counts (aggregations)

Search results include an aggregations object with facet counts:

{
"aggregations": {
"genres": [
{ "id": "pop", "name": "pop", "count": 45 },
{ "id": "indie-pop", "name": "indie-pop", "count": 23 }
],
"moods": [
{ "id": "happy", "name": "happy", "count": 67 },
{ "id": "energetic", "name": "energetic", "count": 34 }
]
}
}

Important caveats:

  1. Search-only: Only /v0/tracks/search populates aggregations. Browse and other endpoints return "aggregations": null. Since term is optional on search, you can still get facet counts for a filter-only request — see Browse vs. Search.
  2. Exact co-occurrence: Counts reflect how many tracks in the current result set have each tag, not catalog totals.
  3. Top 20 cap: Each dimension (moods, genres) returns only the 20 most common tags in the result set.
  4. name is a slug, not a label: Unlike everywhere else in the API, the name inside aggregations repeats the id instead of giving a display label — you get laid-back and hip-hop, where /v0/moods and /v0/genres return Laid Back and Hip Hop. Don't render it directly; resolve it instead, as below.

Labelling facets

Build an id-to-name map from /v0/moods and /v0/genres, which do return display labels. Every aggregation id resolves against them.

Fetch this once and cache it rather than per search: both endpoints cap limit at 20, so the full taxonomy is 3 requests for the 46 moods and around 28 for the ~540 genres. The lists change rarely.

// Built once at startup from the paginated /v0/genres response
const genreNames = new Map(allGenres.map((g) => [g.id, g.name]))

const facets = response.aggregations.genres.map((g) => ({
id: g.id,
label: genreNames.get(g.id) ?? g.id, // "hip-hop" -> "Hip Hop"
count: g.count,
}))

If you only need labels for a handful of featured values, type=featured returns 12 moods and 12 genres in a single call each.

Sound effect metadata

Sound effects include the following metadata fields:

FieldTypeDescription
idstringUUID identifier
titlestringEffect title — a comma-separated taxonomy path, general to specific, e.g. Footsteps, Human, Gravel, Walk. See how titles are structured
lengthnumberDuration in seconds
addedstringISO 8601 timestamp
imagesobjectURLs to cover art in multiple sizes (usually category artwork)

That is the complete set — sound effects carry no BPM, moods, genres or tags. Client-side filtering of results is therefore limited to title and length; everything else has to come from the search and category endpoints.

Unlike music, sound effects do have a server-side explicit filter: includeExplicit defaults to false on both search and category tracks.