Music trend detection
Detect songs gaining traction across TikTok, Instagram, and Spotify with a cross-platform heat score. 3 credits per song.
You will build an A&R trend detector that scores songs gaining traction across TikTok, Instagram, and Spotify before they reach the mainstream charts.
Cost per run: 3 credits per song (3 platforms x 1 credit). All three endpoints are standard tier, so scanning a hundred tracks costs 300 credits.
How do you spot a song trending on TikTok before the charts?
Combine three signals. GET /v1/tiktok/song/videos counts how many videos use the sound, GET /v1/instagram/audio/reels shows whether the same audio is spreading on Reels, and GET /v1/spotify/search returns the canonical track stats. A log-weighted composite of the three catches breakouts while chart positions still lag.
By the time a song appears on a chart, the trend is priced in. The early signal lives on the creation side before it shows up on the consumption side: TikTok creation velocity spikes first, Instagram Reels tells you whether the sound crossed platforms or stayed a single-app meme, and Spotify streams confirm the move afterwards.
What you need
Three standard-tier endpoints (1 credit each), one composite score:
| Endpoint | Signal | Param |
|---|---|---|
GET /v1/tiktok/song/videos | Videos using a specific TikTok sound | clipId |
GET /v1/instagram/audio/reels | Reels using a specific Instagram audio track | audio_id |
GET /v1/spotify/search | Spotify track / artist / podcast search | query |
Resolving the two ids
TikTok and Instagram key off ids, not track names, and both are stable per track. Resolve once, then cache them:
- TikTok
clipId:GET /v1/tiktok/song(1 credit) takes aclipIdand returns the sound's metadata, so use it to confirm an id you already scraped from atiktok.com/music/...URL. - Instagram
audio_id: the numeric id in aninstagram.com/reels/audio/{audio_id}/URL.GET /v1/instagram/search/music(5 credits, advanced tier) searches Instagram's audio library by keyword and returns matching tracks with their ids.
Because both ids are stable, the 5-credit Instagram lookup is a one-off per track, not a per-run cost. The 3-credit figure above is the steady-state scan.
The code
// recipe-music-heat.ts
// Calculates a cross-platform "heat score" for one track.
// Run with: SOCIALCRAWL_KEY=sc_... npx tsx recipe-music-heat.ts
const KEY = process.env.SOCIALCRAWL_KEY;
if (!KEY) throw new Error("Set SOCIALCRAWL_KEY");
const BASE = "https://www.socialcrawl.dev/v1";
// Both ids are stable per track, resolve them once and store them.
const tiktokClipId = "7349589214432069122";
const instagramAudioId = "1392969992841787";
const spotifyQuery = "Espresso Sabrina Carpenter";
async function get(path: string, params: Record<string, string>) {
const url = new URL(`${BASE}/${path}`);
for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v);
const res = await fetch(url, { headers: { "x-api-key": KEY! } });
return (await res.json()) as {
success: boolean;
data?: Record<string, unknown>;
};
}
const [tiktok, instagram, spotify] = await Promise.all([
get("tiktok/song/videos", { clipId: tiktokClipId }),
get("instagram/audio/reels", { audio_id: instagramAudioId }),
get("spotify/search", { query: spotifyQuery }),
]);
type PostItem = { post?: { engagement?: { views?: number | null } } };
// TikTok reports a total usage count for the sound.
const tiktokVideos = (tiktok.data?.total as number | undefined) ?? 0;
// Instagram returns ONE PAGE of reels, there is no total. Summing views on
// the first page is a reach sample, not a catalogue count. Page with `cursor`
// if you want more depth; the weight below assumes one page.
const instagramReelViews = (
(instagram.data?.items as PostItem[] | undefined) ?? []
).reduce((sum, item) => sum + (item.post?.engagement?.views ?? 0), 0);
const spotifyPlays =
(spotify.data?.items as PostItem[] | undefined)?.[0]?.post?.engagement
?.views ?? 0;
// Weighted composite. Tune the weights for your use case.
const heat =
Math.log10(tiktokVideos + 1) * 0.5 +
Math.log10(instagramReelViews + 1) * 0.2 +
Math.log10(spotifyPlays + 1) * 0.3;
console.log({
tiktok_videos: tiktokVideos,
instagram_reel_views: instagramReelViews,
spotify_plays: spotifyPlays,
heat_score: heat.toFixed(2),
});What you get back
// Aggregated, post-composite:
{
"tiktok_videos": 2400000, // <-- `data.total` from TikTok song/videos
"instagram_reel_views": 41800000, // <-- summed over ONE page of audio/reels
"spotify_plays": 1180000000, // <-- top track from Spotify search
"heat_score": "7.44", // <-- log-weighted composite of the three above
}What to change
- The three ids: swap
tiktokClipId,instagramAudioId, andspotifyQueryfor the track you are watching. Add 5 credits once per track if you still need the/v1/instagram/search/musicid lookup. - The weights:
0.5 / 0.2 / 0.3favours TikTok creation velocity. Shift weight to Spotify if you care about confirmed listening rather than early creation. - Find candidates to score:
GET /v1/instagram/music/trending(5 credits) andGET /v1/instagram/reels/trending(5 credits) surface what is already moving. - Deepen the Instagram sample: page
audio/reelswithcursorso the view sum covers more than the first page, and adjust its weight accordingly. - Track the delta, not the level: store
heat_scoreper day. A rising score is the signal; a high static score is a song that already broke.
Related
Creator engagement scoring
The same parallel-fetch and composite-score pattern, on creators.
Hybrid search-then-enrich
Universal search feeding per-platform deep fetches.
Endpoint pricing
The full standard / advanced / premium tier breakdown.
Spotify API
Every Spotify endpoint, including track and artist search.
Quickstart
New here? Get a key and make your first request.
