Concepts
Trackers
Standing watches on a creator: how a cycle runs, when it reports a change, and how to pause one.
A Tracker is a standing interest in one creator. You name them once; we look every day, keep the history, and tell you only about the days something moved. Creating one runs its first cycle straight away, so you have a baseline at once, and that first cycle is charged like every cycle after it.
Creators only, for now
A creator Tracker watches the creator’s profile and their recent videos, and is the kind that also refreshes the follower history and the baseline every other score is measured against. It is the only kind available today: video, hashtag and sound are refused with 422 unsupported_kind, and Facebook with 400 unsupported_platform. Neither creates or charges anything.
One cycle costs $0.05, because it fetches a profile and a video page. Ask for analysis on the Tracker and each new video it finds adds $0.02 on the cycle that finds it, and nothing on the cycles that do not. A Balance that cannot pay for the first cycle is a 402 and no Tracker is created.
POST /v1/trackers·The first cycle is charged on create: $0.05, plus $0.02 per new video when `intelligence` is on. Each later daily cycle costs the same.
curl -X POST "https://www.shortsintel.com/v1/trackers" \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"kind":"creator","platform":"tiktok","target":"someone","intelligence":true}'const response = await fetch(
"https://www.shortsintel.com/v1/trackers",
{
method: "POST",
headers: {
"Authorization": "Bearer sk_live_YOUR_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
"kind": "creator",
"platform": "tiktok",
"target": "someone",
"intelligence": true
}),
},
);
if (!response.ok) {
throw new Error(`ShortsIntel ${response.status}`);
}
const data = await response.json();import requests
response = requests.post(
"https://www.shortsintel.com/v1/trackers",
headers={
"Authorization": "Bearer sk_live_YOUR_KEY",
"Content-Type": "application/json",
},
json={
"kind": "creator",
"platform": "tiktok",
"target": "someone",
"intelligence": True,
},
)
response.raise_for_status()
data = response.json()200 · `{ tracker, created: false }` — you were already tracking that target. Not charged.
{
"tracker": {
"id": "trk_4b1e90c7aa",
"kind": "creator",
"platform": "tiktok",
"target": "someone",
"intelligence": true,
"state": "active",
"last_cycle_at": "2026-09-08T04:00:11.402Z",
"last_run_id": "run_c07a41bb92",
"created_at": "2026-09-01T11:20:03.118Z",
"updated_at": "2026-09-08T04:00:11.402Z"
},
"created": false
}Creating the same target twice is not a conflict: the second call answers 200 with the Tracker you already have and created: false, and is not charged. Targets are normalised before they are compared, so @Example and example are one Tracker, not two.
A cycle is a Run
Once a day each active Tracker runs a cycle, and every cycle creates a Run of its own with its own charge — the same Run you would get from any other operation, listed by GET /v1/runs and readable for free forever. A cycle writes a Snapshot whether or not anything interesting happened; that unbroken series is what later makes change measurable at all.
Several Customers tracking one target still cost one fetch between them, but each gets their own Run, their own charge and their own reports, evaluated against their own Tracker’s history. Nobody sees anybody else’s Tracker.
GET /v1/trackers/{id}/snapshots pages the history. It is free, and it reaches back past the day you started tracking, because Snapshots of a target are shared rather than owned by your Tracker.
Refreshing now
Waiting for tomorrow is not always an option. $0.05, plus $0.02 per new video when the Tracker opted into analysis. Same price as a scheduled cycle.
POST /v1/trackers/{id}/refresh·$0.05, plus $0.02 per new video when the Tracker opted into analysis. Same price as a scheduled cycle.
curl -X POST "https://www.shortsintel.com/v1/trackers/trk_4b1e90c7aa/refresh" \
-H "Authorization: Bearer sk_live_YOUR_KEY"const response = await fetch(
"https://www.shortsintel.com/v1/trackers/trk_4b1e90c7aa/refresh",
{
method: "POST",
headers: {
"Authorization": "Bearer sk_live_YOUR_KEY",
},
},
);
if (!response.ok) {
throw new Error(`ShortsIntel ${response.status}`);
}
const data = await response.json();import requests
response = requests.post(
"https://www.shortsintel.com/v1/trackers/trk_4b1e90c7aa/refresh",
headers={
"Authorization": "Bearer sk_live_YOUR_KEY",
},
)
response.raise_for_status()
data = response.json()A refresh is the same cycle the schedule would have run, forced to call the vendor rather than answer from a fresh Snapshot — which is exactly why it costs the same as a scheduled one. It answers with { run, tracker, change_report }, and change_report is null on a quiet cycle.
Change Reports
A Change Report is written only when a cycle trips a threshold. Four things count:
- new_videos
- The target posted something you have not been told about since your last cycle.
- outlier
- A video crossed 3x its creator's median views.
- followers
- The creator's follower count moved by 10% or more, up or down.
- velocity
- A video is running at 2x the creator's usual views per hour.
Outlier and velocity describe states, not events. A video sitting at 4.2x median is still at 4.2x tomorrow, so it is reported on the cycle it crosses the line and stays quiet afterwards. That is the difference between a feed you keep reading and one you turn off in a week.
Quiet cycles produce no report at all. A day missing from GET /v1/trackers/{id}/changes means nothing tripped that day, not that a report was lost.
200 · `{ items, next_cursor }`.
{
"items": [
{
"id": "chg_2ac910f4d8",
"tracker_id": "trk_4b1e90c7aa",
"run_id": "run_c07a41bb92",
"cycle_key": "tiktok:creator:someone:2026-09-08",
"triggers": [
"new_videos",
"outlier"
],
"changes": {
"new_videos": {
"before": 61,
"after": 62,
"count": 1,
"videos": [
{
"id": "7300000000000000000",
"url": "https://www.tiktok.com/@someone/video/7300000000000000000",
"posted_at": "2026-09-05T06:32:11.000Z",
"views": 1284000
}
]
},
"outliers": [
{
"id": "7300000000000000000",
"url": "https://www.tiktok.com/@someone/video/7300000000000000000",
"views": 1284000,
"outlier": 4.21,
"threshold": 3
}
]
},
"summary": "1 new video, 1 outlier at 4.2x median",
"created_at": "2026-09-08T04:00:11.402Z"
}
],
"next_cursor": null
}triggers says which thresholds fired and changes carries the numbers behind each — the videos that are new, the before and after of a follower move, the multiple an outlier reached and the threshold it passed. summary is one line for a human. Subscribe to the tracker.changed webhook and you are told the moment one is written instead of polling for it.
Active, paused, deleted
- active
- Cycles run daily. The only state that is charged.
- paused
- No cycles, no charges. Everything already collected stays readable, and resuming picks up from the day you resume.
- deleted
- The watch is over. Nothing further is fetched and nothing further is charged, and the Tracker drops out of the list, but the Snapshots and the Change Reports stay exactly where they were.
PATCH /v1/trackers/{id} pauses and resumes; DELETE /v1/trackers/{id} stops the watch for good. Both are free. Deleting is not erasing: the history a Tracker gathered, its Change Reports included, stays readable afterwards, so stopping a watch never costs you the series you paid to build.
200 · the tracker after deletion
{
"tracker": {
"id": "trk_4b1e90c7aa",
"kind": "creator",
"platform": "tiktok",
"target": "someone",
"intelligence": true,
"state": "deleted",
"last_cycle_at": "2026-09-08T04:00:11.402Z",
"last_run_id": "run_c07a41bb92",
"created_at": "2026-09-01T11:20:03.118Z",
"updated_at": "2026-09-08T04:00:11.402Z"
}
}How many you can have
100 active Trackers per Customer. Past that, POST /v1/trackers answers 409 with tracker_limit_exceeded, and so does resuming a paused one when resuming would take you over.
409 · `tracker_limit_exceeded` at 100 active Trackers.
{
"type": "https://docs.shortsintel.com/errors/tracker_limit_exceeded",
"title": "Tracker limit exceeded",
"status": 409,
"code": "tracker_limit_exceeded",
"detail": "You already have 100 active Trackers. Pause one before starting another.",
"limit": 100,
"active": 100
}Paused and deleted Trackers do not count. If you are at the cap, pause the watches you are not reading — they cost nothing while paused and keep everything they have collected.
The first cycle is charged on create: $0.05, plus $0.02 per new video when `intelligence` is on. Each later daily cycle costs the same. See Runs for what a cycle’s Run looks like when it goes wrong, and pricing and estimates for how the charges land on your balance.