InsightSocial API
Recipes

Music trend detection

Score how fast a sound is spreading on TikTok with a log-weighted heat score you can track day over day. 20 credits per song.

You will build an early-warning detector for sounds that are taking off. A song moves on the creation side first: creators pick it up on TikTok, and only later does it reach the charts. Measuring how many videos use a sound, and how far those videos travel, catches the move while it is still early.

Cost per run

20 credits per song: the sound itself with its usage count (10) and one page of TikTok videos using it (10). Finding each track's id is a one-off at 10 credits. Scanning 100 tracks daily costs at least 60,000 credits a month. Scan a shortlist daily and a wider list weekly to keep that down.

How can you catch a rising sound before it charts?

Combine two signals. GET /v1/tiktok/song returns the sound with how many videos use it. GET /v1/tiktok/song/videos returns videos that use it, with their view counts. A log-weighted mix of the two, stored per day, shows which songs are accelerating.

What you need

EndpointSignalParameterCredits
GET /v1/tiktok/songThe sound, with its usage count in post.ext.use_countclipId10
GET /v1/tiktok/song/videosVideos that use the soundclipId10

Resolving the id

TikTok keys sounds by id, not by name, and the id is stable per track. Look it up once and store it.

  • TikTok clipId: GET /v1/tiktok/search/music (10 credits) searches sounds by keyword. Each sound comes back as a post: post.id is the clipId, post.content.text the title, and post.ext.video_count how many videos use it. sort_by=most-used puts the biggest first.

The code

Python
# music_heat.py
# A heat score for one track. Store it per day and watch the delta.
# Run with: INSIGHTSOCIAL_API_KEY=isk_live_... python music_heat.py
import math
import os
from concurrent.futures import ThreadPoolExecutor

import requests

KEY = os.environ["INSIGHTSOCIAL_API_KEY"]
BASE = "https://api.insightsocial.app/v1"

# Resolve the id once (see above), then keep it.
TIKTOK_CLIP_ID = "7364498342501435408"   # "Espresso", Sabrina Carpenter

def get(path, **params):
    res = requests.get(f"{BASE}/{path}", params=params,
                       headers={"x-api-key": KEY}, timeout=120)
    return res.json()

def views_on_page(body):
    """Sum of views on the page, and how many rows showed a view count."""
    if not body["success"]:
        return 0, 0
    views = [i["post"]["engagement"]["views"] for i in body["data"]["items"]]
    known = [v for v in views if v is not None]  # null means hidden, not zero
    return sum(known), len(known)

with ThreadPoolExecutor(max_workers=2) as pool:
    sg = pool.submit(get, "tiktok/song", clipId=TIKTOK_CLIP_ID)
    vd = pool.submit(get, "tiktok/song/videos", clipId=TIKTOK_CLIP_ID)
    song, videos = sg.result(), vd.result()

use_count = (song["data"]["post"]["ext"] or {}).get("use_count") or 0 if song["success"] else 0
sample_views, on_page = views_on_page(videos)

# One page is a sample, not a census. Weight it with the usage count, then track the trend.
heat = 0.5 * math.log10(use_count + 1) + 0.5 * math.log10(sample_views + 1)

print({
    "use_count": use_count,
    "sample_views": sample_views, "videos_on_page": on_page,
    "heat_score": round(heat, 2),
    "credits_used": song.get("credits_used", 0) + videos.get("credits_used", 0),
})

What you get back

Example output
{'use_count': 2140000, 'sample_views': 52700000, 'videos_on_page': 30,
 'heat_score': 7.03, 'credits_used': 20}

The figures are illustrative. The video list returns one page, not every video that uses the sound, so the view sum is a reach sample. A row whose view count is hidden (null) adds nothing to the sum and is not counted in videos_on_page. Compare a track's score with its own history, not with an absolute bar.

What to change

  • The id. Swap in the track you are watching. Budget 10 credits once per new track if you still need to look it up.
  • Weight the usage count's change. post.ext.use_count is the cleanest creation-velocity number TikTok publishes; its day-over-day change is worth a term of its own in the score.
  • See how the sound is being used. Read the captions yourself: post.content.text on each row of tiktok/song/videos. Counting rows by post.published_at day gives you a date histogram of the page.
  • Find candidates to score. GET /v1/tiktok/search/music with sort_by=most-used (10) surfaces the most-used sounds for a keyword.
  • Deepen the sample. Send pagination.next_cursor back as cursor, with the same id, to read more pages at 10 credits each, and adjust the weights to match.
  • Track the delta, not the level. Store heat_score per track per day. A rising score is the signal. A high, flat score is a song that already broke.

On this page