Skip to main content

Filtering Results using Metadata Filters

Overview

The metadataFilter of the advancedSearch allows you to filter search results flexibly by providing a MongoDB-style query structure. It replaces the older pre-defined static metadata fields, offering a more powerful and expressive way to search through your music data.

The metadataFilter follows a JSON format and supports logical operations like $and, $or, $in, $gt, and others.

tip

A detailed guide for the Advanced Search and how you can use it can be found (here).


Syntax and Format

The metadataFilter field expects a JSON object using MongoDB-like operators.

A single metadata filter can look like this. Each field name corresponds to metadata or tagging of a track.

{ "<fieldName>": { "<operator>": "<value>" } }
Metadata Filter Fields
Field NameTypeOperatorsValues
arousalNumber$gt, $gte, $lt, $lte, $eq, $ne, $existsAudioAnalysisV7Result.arousal
valenceNumber$gt, $gte, $lt, $lte, $eq, $ne, $existsAudioAnalysisV7Result.valence
bpmPredictionNumber$gt, $gte, $lt, $lte, $eq, $ne, $existsInteger for bpm.
bpmRangeAdjustedNumber$gt, $gte, $lt, $lte, $eq, $ne, $existsInteger between 60-180 bpm.
genreTagsArray$in, $nin, $existsAudioAnalysisV6GenreTags
moodTagsArray$in, $nin, $existsAudioAnalysisV6MoodTags
subgenreTagsArray$in, $nin, $existsAudioAnalysisV6SubgenreTags
moodAdvancedTagsArray$in, $nin, $existsAudioAnalysisV6MoodAdvancedTags
characterTagsArray$in, $nin, $existsAudioAnalysisV6CharacterTags
movementTagsArray$in, $nin, $existsAudioAnalysisV6MovementTags
advancedGenreTagsArray$in, $nin, $existsAudioAnalysisV7GenreTags
advancedSubgenreTagsArray$in, $nin, $existsAudioAnalysisV7SubgenreTags
keyPredictionArray$in, $nin, $existsMusicalKey
instrumentTagsArray$in, $nin, $existsAudioAnalysisV6InstrumentTags
advancedInstrumentTagsExtendedArray$in, $nin, $existsAudioAnalysisV7ExtendedInstrumentTags
voiceTagsArray$in, $nin, $existsAudioAnalysisV6VoiceTags
voicePresenceProfileArray$in, $nin, $existsAudioAnalysisV6VoicePresenceProfile
predominantVoiceGenderArray$in, $nin, $existsAudioAnalysisV6PredominantVoiceGender
freeGenreTagsArray$in, $nin, $existsList of free genre tags.
musicalEraTagArray$in, $nin, $existsList of musical era tags.
customTagsArray$in, $nin, $existsLibraryTrack.customTags
Metadata Filter Operators
OperatorDescriptionFormat
$andCombine a list of filters where all must match.{"$and": [filter1, filter2, ...]}
$orCombine a list of filters where at least one must match.{"$or": [filter1, filter2, ...]}
$eqCondition for results to exactly match a value.{"$eq": int/float/str/bool }
$neCondition for results to not match a value.{"$ne": int/float/str/bool }
$gtCondition for results to be greater than a value.{"$gt": int/float }
$gteCondition for results to be greater than or equal to a value.{"$gte": int/float }
$ltCondition for results to be less than a value.{"$lt": int/float }
$lteCondition for equal for results to be less than or equal to a value.{"$lte": int/float }
$inCondition for results to match any value in a list.{"$in": [int/float/str, ...]}
$ninCondition for results to not match any value in a list.{"$nin": [int/float/str, ...]}
$existsCondition for results to include or exclude a field.{"$exists": true/false}

Examples

1. Simple Numeric Filter

Filter tracks where valence > 0.5. (See Syntax and Format for other numeric metadata filter fields)

{ "valence": {"$gt": 0.5} } }

GraphiQL

Example query with metadata filters for the new advancedSearch endpoint:

GraphiQL
Query Variables
Please enter your integration access token

Curl

Example curl request with metadata filters for the new advancedSearch endpoint:

curl -X POST https://api.cyanite.ai/graphql \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{ "query": "query AdvancedSearchExample($trackID: ID $trackIDs: [ID!] $text: String $target: AdvancedSearchTarget! $filter: JSONObject $searchMode: SimilarTracksSearchMode $retrieveSegmentScores: Boolean $first: Int) { advancedSearch( trackID: $trackID trackIDs: $trackIDs text: $text target: $target metadataFilter: $filter searchMode: $searchMode retrieveSegmentScores: $retrieveSegmentScores first: $first ) { ... on AdvancedSearchError { code message } ... on AdvancedSearchConnection { edges { node { track { ... on AdvancedSearchNodeLibraryTrack { id } ... on AdvancedSearchNodeSpotifyTrack { id } } } } } } }", "variables": { "trackID": 1, "target": { "library": {} }, "filter": { "valence": { "$gt": 0.5 } } } }'

2. Filter by Tags

Find tracks where specific tags are given or exluded. (See Syntax and Format for other metadata filter tags/array fields.)

{ "genreTags": { "$in": ["rock"] } }

GraphiQL

Example query with metadata filters for the new advancedSearch endpoint:

GraphiQL
Query Variables
Please enter your integration access token

Curl

Example curl request with metadata filters for the new advancedSearch endpoint:

curl -X POST https://api.cyanite.ai/graphql \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{ "query": "query AdvancedSearchExample($trackID: ID $trackIDs: [ID!] $text: String $target: AdvancedSearchTarget! $filter: JSONObject $searchMode: SimilarTracksSearchMode $retrieveSegmentScores: Boolean $first: Int) { advancedSearch( trackID: $trackID trackIDs: $trackIDs text: $text target: $target metadataFilter: $filter searchMode: $searchMode retrieveSegmentScores: $retrieveSegmentScores first: $first ) { ... on AdvancedSearchError { code message } ... on AdvancedSearchConnection { edges { node { track { ... on AdvancedSearchNodeLibraryTrack { id } ... on AdvancedSearchNodeSpotifyTrack { id } } } } } } }", "variables": { "trackID": 1, "target": { "library": {} }, "filter": { "genreTags": { "$in": ["rock"] } } } }'

3. Combining Multiple Conditions

Find tracks where:

  • valence > 0.5
  • AND (genreTags contains "rock" and "pop" OR moodTags contains "energetic")

(See Syntax and Format for other available metadata filters)

{
"$and": [
{ "valence": { "$gt": 0.5 } },
{
"$or": [
{ "genreTags": { "$in": ["rock", "pop"] } },
{ "moodTags": { "$in": ["energetic"] } }
]
}
]
}

GraphiQL

Example query with metadata filters for the new advancedSearch endpoint:

GraphiQL
Query Variables
Please enter your integration access token

Curl

Example curl request with metadata filters for the new advancedSearch endpoint:

curl -X POST https://api.cyanite.ai/graphql \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{ "query": "query AdvancedSearchExample($trackID: ID $trackIDs: [ID!] $text: String $target: AdvancedSearchTarget! $filter: JSONObject $searchMode: SimilarTracksSearchMode $retrieveSegmentScores: Boolean $first: Int) { advancedSearch( trackID: $trackID trackIDs: $trackIDs text: $text target: $target metadataFilter: $filter searchMode: $searchMode retrieveSegmentScores: $retrieveSegmentScores first: $first ) { ... on AdvancedSearchError { code message } ... on AdvancedSearchConnection { edges { node { track { ... on AdvancedSearchNodeLibraryTrack { id } ... on AdvancedSearchNodeSpotifyTrack { id } } } } } } }", "variables": { "trackID": 1, "target": { "library": {} }, "filter": {"$and": [{"valence": {"$gt": 0.5}}, {"$or": [{"genreTags": {"$in": ["rock", "pop"]}}, {"moodTags": {"$in": ["energetic"]}}]}]}}}'

Validation Rules

If your metadataFilter is invalid, the API will return an error indicating what was wrong with your query.


Possible Errors when Using metadataFilter

If your metadataFilter is incorrectly structured or uses unsupported fields or operators, the advanced search endpoint will return an AdvancedSearchError with an error code invalidMetadataFilter.
This error is raised during server-side validation and provides helpful information to correct your query.


Error Scenarios

Error ScenarioCauseExampleError Message
Invalid Top-Level KeyUsing a field name that is not a known metadata field or a logical operator ($and, $or).{ "unknownField": { "$eq": "value" } }Invalid metadata filter error for unknownField: Expected a valid top level metadata field: '$and', '$or' or any of [...]
Unsupported Logical OperatorUsing an unrecognized operator.{ "valence": { "$contains": "value" } }Invalid metadata filter error for $contains: Expected one of ['$eq', '$ne', '$gt', '$gte', '$lt', '$lte', '$in', '$nin', '$exists', '$and', '$or'].
Malformed Logical Group$and or $or provided with a non-list or invalid structure.{ "$and": "invalidType" }Invalid metadata filter error for $and: Got value invalidType (type str). Expected a list or subquery dictionaries
Invalid Field ConditionProviding a raw value instead of a condition dictionary for a metadata field.{ "valence": 0.8 }Invalid metadata filter error for valence: Expected one of ['$eq', '$ne', '$gt', '$gte', '$lt','$lte', '$in', '$nin', '$exists', '$and', '$or'].
Validation Error in OperatorUsing wrong data types inside operator filters.{ "valence": { "$in": 5 } }Operator '$in' expects a list of values, but received an integer.
Unknown Metadata FieldTypo or unsupported metadata field.{ "vallence": { "$gt": 0.5 } }Invalid metadata filter error for vallence: Expected a valid top level metadata field: '$and', '$or' or any of [...]

Best Practices to Avoid Errors

  • Double-check your field names against the available metadata fields.
  • Ensure logical groups ($and, $or) contain lists or valid subqueries.
  • Ensure to only use supported MongoDB-style operators ($eq, $in, $gt, etc.).
  • Always provide filtering conditions inside {} brackets under fields.
  • Validate your JSON format before sending queries.