Music (catalogue search)
Search a music catalogue by artist, title, genre or mood and get back normalized tracks — artist, public URL, duration and play count — ranked by…
Search a music catalogue by artist, title, genre or mood and get back normalized tracks — artist, public URL, duration and play count — ranked by popularity, or read one track URL you already have back to its full detail (artwork, description, genre, likes, release date, label). Direct API, no browser.
Also known as: track, song, audio, artist, playlist, tune, music track
Call it
bowmark.music.search(query: string, limit?: number, options?: CallOptions): Promise<MusicSearchResult>
bowmark.music.getTrack(track: string | Track, options?: CallOptions): Promise<MusicTrackResult>Functions
| Function | What it does |
|---|---|
search | Searches the catalogue for tracks matching free text ("aphex twin", "lofi hip hop", "80s synthwave") and returns up to limit normalized tracks (default 20, max 200), most-played first. |
getTrack | Reads ONE track you already have a URL for — a public track link, or a Track that search returned — and returns the full detail a search row never carried: artwork, the publisher's… |
Types
type Track = {
source: "soundcloud" // which catalogue this came from
id: string // that catalogue's id for the track
title: string // track title as published
artist: string // publishing artist or account
url: string // public track page
durationMs: number // length in milliseconds
playCount: number | null // plays; null when not reported (never 0)
}
type MusicSearchResult = {
tracks: Track[] // most-played first
warnings: string[] // always present; empty when nothing was dropped. A
// catalogue named here returned NOTHING, which is a
// different fact from a query with no matches
}
type CallOptions = {
timeoutMs?: number // per-provider budget in ms, default 30000, clamped to 1000-55000.
// A provider slower than this is DROPPED from the results and
// NAMED in warnings — never silently absent
}
// What getTrack adds: the fields only a detail view carries. Every one is
// nullable because catalogues genuinely omit them — null means "this catalogue
// does not report it", never "we failed to read it".
type TrackDetail = Track & {
artworkUrl: string | null // cover art; null when published without any
description: string | null // publisher's notes — a mix's tracklist lives here
genre: string | null
likeCount: number | null // null when not reported (never 0)
releaseDate: string | null // for a reissue, the ORIGINAL release date
publisherArtist: string | null // label credit ("Aphex Twin") vs account ("aphextwin")
labelName: string | null
}
type MusicTrackResult = {
track: TrackDetail
warnings: string[] // always present; names the fields left unreported
}Examples
// Build a listening shortlist: search several moods at once, keep the most
// played track per mood, and total the runtime.
const moods = ["lofi hip hop", "ambient techno", "80s synthwave", "bossa nova"];
const picks = await Promise.all(moods.map(async (mood) => {
const { tracks, warnings } = await bowmark.music.search(mood, 25);
for (const w of warnings) log(`${mood}: ${w}`);
const top = tracks[0] || null;
log(`${mood}: ${top ? top.artist + " — " + top.title : "no matches"}`);
return top ? { mood, artist: top.artist, title: top.title, url: top.url, durationMs: top.durationMs, plays: top.playCount } : { mood, artist: null, durationMs: 0 };
}));
const found = picks.filter(p => p.artist);
return { totalMinutes: Math.round(found.reduce((s, p) => s + p.durationMs, 0) / 60000), picks: found };// Credit a set properly: search finds the upload, getTrack says who actually
// published it and when — the account that uploaded a reissue is not the artist,
// and the release date is the ORIGINAL one, not the upload day.
const { tracks } = await bowmark.music.search("selected ambient works", 10);
const detailed = [];
for (const t of tracks.slice(0, 3)) {
const { track, warnings } = await bowmark.music.getTrack(t);
for (const w of warnings) log(w);
detailed.push({
title: track.title,
uploadedBy: track.artist,
credited: track.publisherArtist ?? "(the catalogue names no publisher)",
label: track.labelName,
released: track.releaseDate,
artwork: track.artworkUrl,
});
}
return detailed;Providers behind it
| Provider | |
|---|---|
soundcloud | SoundCloud |