Catalogue search

Structured catalogue search with POST /v1/search/tracks.

Use catalogue search to find tracks across accessible Workspace catalogues and, when entitled, MusiMap Atlas. The public endpoint is POST /v1/search/tracks. Criteria are explicit: title and artist text, taxonomy tags, identifiers, and audio-feature ranges.

Search vs inventory

POST /v1/search/tracks searches analysed catalogue content with explicit text and structured filters. GET /v1/workspace/tracks and GET /v1/atlas/tracks list technical inventory. Use inventory for browse, exact IDs, and delivery metadata. Use catalogue search to select tracks by title, artist, tag IDs, and audio attributes, then retrieve a selected entity from its plane inventory endpoint when you need the full record.

Literal text, not natural language

Use Catalogue Search when you have explicit criteria: lexical title and artist terms, taxonomy tags, identifiers, or supported audio-feature filters. query is lexical, not natural language. After Unicode case-folding and collapsed whitespace, every term must appear as a whole token in the track title or the primary artist credit. Terms may be split across those fields and do not need to be adjacent. If any query term is missing from both fields, the track does not match. Catalogue Search does not interpret moods, styles, context, intent, or prose.

Looking for natural-language discovery?

MusiSearch is MusiMap's natural-language music discovery capability. It is intended for descriptions that involve moods, styles, context, intent, or prose. See Discovery (POST /v1/discovery). Catalogue Search remains the public API for explicit, structured criteria.

OAuth scopes

  • search.read: run structured catalogue search.
  • atlas.read: required when include_atlas is true or targets includes atlas (plus matching organisation entitlement).

Tag IDs

Tag filters use stable tag IDs from GET /v1/tagging/taxonomy (categories[].tags[].id). Pass those values as tag_id in filters. Tag labels are display metadata only.

Workspace and Atlas inclusion

  • include_workspace: include organisation Workspace catalogues.
  • include_atlas: include MusiMap Atlas (requires atlas.read).
  • targets: alternative array of workspace and/or atlas.
  • catalog_id / catalog_ids: optional Workspace catalogue overrides.

Each hit includes source.layer: workspace or atlas. When you need the full inventory record, retrieve it from GET /v1/workspace/tracks/{id} or GET /v1/atlas/tracks/{id} accordingly. Atlas and Workspace inventory are also browsable directly without searching first. See Atlas.

Search request

Provide at least one of query, filters or an explicit sort other than score. A sort on its own orders every accessible track: for example {"sort": "bpm", "sort_direction": "asc"} returns the slowest tracks first.

curl -X POST "https://api.musimap.com/v1/search/tracks" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "Fever Dua Lipa",
    "catalog_id": "0190…",
    "include_workspace": true,
    "include_atlas": true,
    "filters": {
      "tags": {
        "required": [
          { "tag_id": "0190…", "score_min": 70, "score_max": 100 }
        ],
        "optional": [
          { "tag_id": "0190…", "score_min": 50 }
        ],
        "excluded": [
          { "tag_id": "0190…", "score_min": 60 }
        ]
      },
      "bpm_min": 100,
      "bpm_max": 140
    },
    "sort": "score",
    "sort_direction": "desc",
    "page": 1,
    "page_size": 20
  }'

Text matching

query is required eligibility when present. After Unicode case-folding and collapsed whitespace, every term must appear as a whole token in the track title, the primary artist credit, or both. Terms do not need to sit in the same field or next to one another, so Fever Dua Lipa matches title Fever and artist Dua Lipa. Combine it with BPM, tags, or identifiers using AND: every required condition must hold. Additional title/artist filters (title_contains, title_exact, artist_contains, artist_exact) are also AND constraints.

Tag filter modes

  • required: eligibility. The track must match every required condition.
  • optional: preference. Eligible tracks remain in the result; optional matches change search.score.
  • excluded: exclude tracks where the tag score falls within the range.

Other supported filters

  • isrc, outer_id.
  • bpm_min, bpm_max, energy_min, energy_max.
  • title_contains, title_exact, artist_contains, artist_exact.

artist_exact matches a primary artist name exactly as returned in artists[].name on search hits (case-sensitive as stored). On multi-artist tracks, any credited primary artist name may match. Do not treat joined credit strings as a separator protocol for artist names. artist_contains is a case-insensitive substring match on the stored primary artist credit text used for lexical search.

Use taxonomy tag id values (as tag_id in filters) rather than label lists such as genres or moods. Unknown filter names are rejected.

Preference score

search.score is a value from 0 to 100. Required criteria decide whether a track is returned at all. When there are no optional tag or numeric preferences, every eligible result scores 100. With optional preferences, the score is the share of the available optional weight that the track actually earned (clamped to 0–100). A score of 0 with optional preferences means none of those preferences matched; the track is still eligible.

Sort and pagination

Default order is score descending; among equal scores, Workspace hits come before Atlas hits, then immutable track_id ascending. track_id ascending compares identifiers in their canonical text form; these identifiers are time-ordered, so this approximates creation order, but it is not an ingestion timestamp. The same tie-breaks follow every other sort or sorts key, and sort=track_id uses the same canonical order. The same request over unchanged data returns the same order on every page; tracks ingested or reanalysed between two requests can shift later pages. Supported sort values: score, track_id, title, artist, bpm, updated_at. relevance is a compatibility alias for score. Optional sort_direction is asc or desc. updated_at is the analysis projection timestamp and can move while ingest is active. Pagination is over logical tracks after collapsing multiple analyses per track, not an unordered sample.

Sorting by several keys

sorts is an ordered list of up to five keys, applied lexicographically over every eligible track: the first key orders all results, each further key only orders the tracks tied on the previous keys. Each key is {"field", "direction"}; field accepts the sort values above, the audio features energy, danceability, loudness_lufs, instrumental_probability and release_year, and tag_score, which orders by one tag's score and requires its tag_id. Tracks without a value for a key come last for that key. Sorting never changes which tracks are eligible or their preference score. Use either sorts or sort/sort_direction, not both; an unsupported field or key is rejected with 400 validation_error.

{
  "include_atlas": true,
  "sorts": [
    { "field": "tag_score", "tag_id": "<Happy tag_id>", "direction": "desc" },
    { "field": "bpm", "direction": "asc" }
  ]
}

This lists the happiest tracks first; among tracks with the same Happy score, the slowest come first.

Response shape

{
  "status": 200,
  "message": "OK",
  "data": {
    "count": 1,
    "page": 1,
    "page_size": 20,
    "total_pages": 1,
    "has_next": false,
    "has_previous": false,
    "results": [
      {
        "track": {
          "id": "0190…",
          "title": "Fever",
          "outer_id": "client-track-42"
        },
        "artists": [{ "id": "0190…", "name": "Dua Lipa" }],
        "release": { "id": "0190…", "title": "Future Nostalgia" },
        "source": { "layer": "workspace", "catalog_id": "0190…" },
        "audio_tagging": {
          "taxonomy_version": "v1",
          "tags": {
            "moods": [{ "uid": "mood_happy", "name": "Happy", "score": 82 }]
          }
        },
        "search": { "score": 100 }
      }
    ]
  }
}

Need natural-language discovery?

For moods, styles, context, and prose queries, use Discovery (MusiSearch).