Find Similar Tracks
The Cyanite.ai API offers the functionality to find similar tracks based on a input track.
You can search for similar tracks for any library or spotify track and retreive results from either your Library (LibraryTrack
), a Crate (LibraryTrack
) or Spotify (SpotifyTrack
).
Additionally, it is possible to specify a search criteria, e.g. only return tracks whose BPM is the range of the input track or tracks whose genre matches a specified genre.
The functionalilty is exposed via the Track.similarTracks
field.
We assume that you already have a basic understanding GraphQL interfaces and unions. If you are new with GraphQL in general we recommend starting with the official learning resource.
Example Query
query SimilarTracksQuery($trackId: ID!) {
libraryTrack(id: $trackId) {
__typename
... on Error {
message
}
... on Track {
id
similarTracks(target: { spotify: {} }) {
__typename
... on SimilarTracksError {
code
message
}
... on SimilarTracksConnection {
edges {
node {
id
}
}
}
}
}
}
}
{
"data": {
"libraryTrack": {
"__typename": "LibraryTrack",
"id": "test-id-1",
"similarTracks": {
"__typename": "SimilarTracksConnection",
"edges": [
{
"node": {
"id": "5P8KKoAiwhzZkwcBuyhdUi"
}
},
{
"node": {
"id": "6tnnuZ3pgO83D65xIRgEaG"
}
},
{
"node": {
"id": "6q64fAbMqCU92HOJcDKm34"
}
}
]
}
}
}
}
Specifying a Target
The Track.similarTracks
field has one required parameter which is the Track.similarTracks(target:)
argument of the SimilarTracksTarget!
input type.
This argument specifies what kind of search results we want. Currently, it is possible to get results from the library, a crate or spotify.
Target | Track.similarTracks(target:) value |
---|---|
library | { library: {} } |
crate | { crate: { crateId: "$crateId" } } |
spotify | { spotify: {} } |
It is only possible to specify one target. Mixing options e.g. { library: {}, spotify: {} }
might result in an error.
Specifying the Search Mode
There different methods available for finding similar tracks. By default the segment of the track that is categorized as the most-representative one of the track will be used.
In addition it is possible to choose two additional modes via the Track.similarTracks(searchMode:)
argument of the SimilarTracksSearchMode
type.
Example Document: Specifying a Search Mode
fragment TrackSimilarTracksFragment on Track {
similarTracks(target: { library: {} }, searchMode: { complete: {} }) {
__typename
... on SimilarTracksError {
code
message
}
... on SimilarTracksConnection {
edges {
node {
id
}
}
}
}
}
Input | Description | Track.similarTracks(searchMode:) value |
---|---|---|
mostRepresentative | Use most representative part of the track. | { mostRepresentative: {} } |
complete | Use the complete track. | { complete: {} } |
interval | Use a custom part of the track. | { interval: { start: 10, end: 20 } } |
Applying Search Filters
The search filter API is subjected to change and is not fully stable yet.
By default no additional filters will be applied and all similar sounding tracks will be returned. Additionally, it is possible to apply filters for narrowing down the selection of returned tracks.
The filters are applied via the Track.similarTracks(experimental_filter:)
argument of the experimental_SimilarTracksFilter
input type.
Example filters:
Filter | Description | Example Track.similarTracks(experimental_filter:) value |
---|---|---|
BPM | Filter track by BPM (in range of track) | { bpm: { input: {} } } |
Genre | Filter track by genre | { genre: { input: {} } } |
Key | Filter track by key | { key: { input: {} } } |
The above filters would result only returning tracks which match the BPM, genre and key of the input track. But, it is also possible to specify custom ranges.
All the filters can be mixed, so it is possible to filter by bpm and additionally also filter by genre or key.
Example Document: BPM and Key Filter
fragment TrackSimilarTracksFragment on Track {
similarTracks(
target: { library: {} }
experimental_filter: {
bpm: { range: { start: 160, end: 200 } }
key: { input: {} }
}
) {
__typename
... on SimilarTracksError {
code
message
}
... on SimilarTracksConnection {
edges {
node {
id
}
}
}
}
}
BPM filter
The experimental_SimilarTracksFilter.bpm
field of the input type experimental_SimilarTracksFilterBpm
describes a bpm filter.
It is possible to either filter for the bpm of the input track or a custom range:
Filter | Example Track.similarTracks(experimental_filter:) value |
---|---|
BPM (input track) | { bpm: { input: {} } } |
BPM (custom range) | { bpm: { range: { start: 60, end: 140 } } } |
Genre filter
The experimental_SimilarTracksFilter.genre
field of the input type experimental_SimilarTracksFilterGenre
describes a genre filter.
It is possible to either filter for the genre of the input track or a list of specified genres.
Filter | Example Track.similarTracks(experimental_filter:) value |
---|---|
Genre (input track) | { genre: { input: {} } } |
Genre (custom list) | { genre: { list: ["country", "folk"] } |
The possible genres are described by the MusicalGenre
enum type.
Key filter
The experimental_SimilarTracksFilter.key
field of the input type experimental_SimilarTracksFilterKey
describes a key filter.
It is possible to either filter for a specific key (input track or list of keys) or via the camelot method.
Filter | Example Track.similarTracks(experimental_filter:) value |
---|---|
Key (input track) | { key: { matching: { input: {} } } } |
Key (custom list) | { key: { matching: { list: ["cMajor"] } } |
Camelot (input track) | { key: { camelot: { input: {} } } } |
Camelot (custom list) | { key: { camelot: { key: "cMajor" } } } |
The possible keys are described by the MusicalKey
enum type.
Specify the amount of edges to fetch
By default the Track.similarTracks
field will return up to 10 tracks, given they match all the specified filters and there are enough available. It is possible to fetch up to 100 songs by specifying the Track.similarTracks(first:)
argument of the Int
type.
Example Document: Fetch 100 items
fragment TrackSimilarTracksFragment on Track {
similarTracks(target: { library: {} }, first: 100) {
__typename
... on SimilarTracksError {
code
message
}
... on SimilarTracksConnection {
edges {
node {
id
}
}
}
}
}