API documentation
Daily breakout picks and the streaming Top 10s we score them against. Plain JSON over HTTPS.
Base URL
https://streamrank.io/v1
Format
JSON over HTTPS
Auth
Bearer API key
Quickstart
- 1
Make a request
No key needed in the sample scope. You get today's US breakout picks, the reasons for each, and the track record.
- 2
Get a key
Create a free account for a live key with every country, provider, and 7 days of history.
- 3
Cache responses
Picks and charts update once a day. Top 10s are at
GET /v1/charts.
curl "https://streamrank.io/v1/trending/breakouts?country=US"{
"data": {
"scope": "US",
"date": "2026-09-15",
"items": [
{
"position": 1,
"score": 45.4,
"score_change": 5.2,
"status": "rising",
"signals": {
"chart_momentum": 0,
"demand": 83.1,
"attention": 45.2
},
"why": [
"Lands Sep 19 on Netflix.",
"Demand 83 of 100.",
"Score up 5.2 today.",
"On no Top 10 in United States."
],
"strength": "strong",
"premiere": "2026-09-19",
"providers": ["netflix"],
"outcome": {
"first_chart_date": "2026-09-20",
"first_chart_provider": "netflix",
"first_chart_country": "US",
"first_chart_rank": 4,
"days_to_chart": 5,
"peak_rank": 2,
"days_on_chart": 6
},
"missed": false,
"title": {
"id": "ttl_9q2h7v3zkm1d",
"slug": "obsession-2026",
"name": "Obsession",
"type": "movie",
"year": 2026,
"tmdb_id": 1364532,
"imdb_id": "tt31520893",
"poster_url": "https://image.tmdb.org/t/p/w500/obsession.jpg"
}
}
],
"track_record": {
"scope": "US",
"from": "2026-08-02",
"to": "2026-08-31",
"window_days": 14,
"long_window_days": 30,
"types": ["tv"],
"picks": 96,
"charted_7d": 29,
"charted_14d": 41,
"hit_rate_14d": 42.7,
"median_days_to_chart": 4,
"median_peak_rank": 3,
"median_days_on_chart": 7,
"picks_30d": 45,
"charted_30d": 21,
"hit_rate_30d": 46.7,
"pool": 640,
"pool_charted_14d": 122,
"pool_hit_rate_14d": 19.1,
"pool_30d": 300,
"pool_charted_30d": 66,
"pool_hit_rate_30d": 22,
"by_type": {
"tv": {
"picks": 96,
"charted_7d": 29,
"charted_14d": 41,
"hit_rate_14d": 42.7,
"median_days_to_chart": 4,
"median_peak_rank": 3,
"median_days_on_chart": 7,
"picks_30d": 45,
"charted_30d": 21,
"hit_rate_30d": 46.7,
"pool": 640,
"pool_charted_14d": 122,
"pool_hit_rate_14d": 19.1,
"pool_30d": 300,
"pool_charted_30d": 66,
"pool_hit_rate_30d": 22,
"control": {
"picks": 150,
"charted_7d": 9,
"charted_14d": 16,
"hit_rate_14d": 10.7,
"median_days_to_chart": 7,
"median_peak_rank": 7,
"median_days_on_chart": 2,
"picks_30d": 70,
"charted_30d": 11,
"hit_rate_30d": 15.7,
"pool": 640,
"pool_charted_14d": 122,
"pool_hit_rate_14d": 19.1,
"pool_30d": 300,
"pool_charted_30d": 66,
"pool_hit_rate_30d": 22
}
},
"movie": {
"picks": 104,
"charted_7d": 6,
"charted_14d": 9,
"hit_rate_14d": 8.7,
"median_days_to_chart": 9,
"median_peak_rank": 6,
"median_days_on_chart": 3,
"picks_30d": 50,
"charted_30d": 8,
"hit_rate_30d": 16,
"pool": 1570,
"pool_charted_14d": 76,
"pool_hit_rate_14d": 4.8,
"pool_30d": 730,
"pool_charted_30d": 88,
"pool_hit_rate_30d": 12.1,
"control": {
"picks": 150,
"charted_7d": 6,
"charted_14d": 11,
"hit_rate_14d": 7.3,
"median_days_to_chart": 8,
"median_peak_rank": 8,
"median_days_on_chart": 2,
"picks_30d": 70,
"charted_30d": 9,
"hit_rate_30d": 12.9,
"pool": 1570,
"pool_charted_14d": 76,
"pool_hit_rate_14d": 4.8,
"pool_30d": 730,
"pool_charted_30d": 88,
"pool_hit_rate_30d": 12.1
}
}
},
"by_strength": {
"strong": {
"picks": 30,
"charted_7d": 12,
"charted_14d": 16,
"hit_rate_14d": 53.3,
"median_days_to_chart": 3,
"median_peak_rank": 2,
"median_days_on_chart": 9,
"picks_30d": 14,
"charted_30d": 8,
"hit_rate_30d": 57.1,
"pool": 640,
"pool_charted_14d": 122,
"pool_hit_rate_14d": 19.1,
"pool_30d": 300,
"pool_charted_30d": 66,
"pool_hit_rate_30d": 22
},
"watch": {
"picks": 66,
"charted_7d": 17,
"charted_14d": 25,
"hit_rate_14d": 37.9,
"median_days_to_chart": 5,
"median_peak_rank": 4,
"median_days_on_chart": 6,
"picks_30d": 31,
"charted_30d": 13,
"hit_rate_30d": 41.9,
"pool": 640,
"pool_charted_14d": 122,
"pool_hit_rate_14d": 19.1,
"pool_30d": 300,
"pool_charted_30d": 66,
"pool_hit_rate_30d": 22
}
},
"control": {
"picks": 150,
"charted_7d": 9,
"charted_14d": 16,
"hit_rate_14d": 10.7,
"median_days_to_chart": 7,
"median_peak_rank": 7,
"median_days_on_chart": 2,
"picks_30d": 70,
"charted_30d": 11,
"hit_rate_30d": 15.7,
"pool": 640,
"pool_charted_14d": 122,
"pool_hit_rate_14d": 19.1,
"pool_30d": 300,
"pool_charted_30d": 66,
"pool_hit_rate_30d": 22
}
}
},
"meta": {
"count": 1,
"locked": 0,
"limit_max": 10,
"history_days": 30
}
}Authentication
Send your key in the Authorization header.
sk_live_keys count toward your plan, Free included.sk_test_keys return real data in the sample scope and never count toward quota.- No key: the sample scope (United States; Netflix; current charts) at 10 requests per minute and 200 per calendar month per IP.
Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxxPlans and limits
| Plan | Countries | Providers | History | Trending list | Requests / mo | Alerts |
|---|---|---|---|---|---|---|
| Free | All | All | 7 days | Top 10 | 3,000 | None |
| Pro | All | All | 30 days | Top 100 | 50,000 | 3 titles, email |
| Intelligence | All | All | Full | Top 100 | 200,000 | 200 titles + markets, email, webhook, slack |
Free keys must credit StreamRank with a visible link to streamrank.io wherever the data is shown.
Playground
Real requests against the live API. Runs in the sample scope until you add a key.
Without a key, requests use the sample scope: United States; Netflix; current charts.
/v1/charts?provider=netflix&country=UScurl "https://streamrank.io/v1/charts?provider=netflix&country=US"Run a request to see the response.Breakouts
Breakout picks
Titles heating up on zero Top 10 charts in the scope: today's picks, why each was picked, and how past picks did.
How a title qualifies
- On no Top 10 chart in the scope, and off the charts for 30 days.
- Demand of 40 or more from two feeds.
How the list is ordered
- Launches first, then originals on their own service, then titles landing within 3 days, then demand level.
- Inside each group, fading titles go last.
- Movies publish only as launches. Ask for them with
type=movie.
What comes back
- Each item has
whyand, once it charts within 30 days,outcome. track_recordis the 14-day and 30-day hit rate of past calls next to the rate for every eligible title. A title picked on consecutive days is one call.
Plan limits
On a list younger than 14 days, Free, test keys, and calls without a key get the top pick; the rest is counted inmeta.locked. Older lists return in full for everyone.More examples
- /v1/trending/breakouts?country=US&type=tv
- /v1/trending/breakouts?country=GB&date=2026-09-10
Query parameters
- countrystring
ISO 3166-1 alpha-2. Omit it for the global list. A country scope means zero Top 10 charts in that country.
- typemovie | tv
Default
tv, the published list.moviereturns the movie picks, which are logged every day but not published while they chart at the control rate. - limitinteger
1–50, default 10, capped by your plan's trending limit. On a list younger than 14 days, Free, test keys, and calls without a key get the top pick and the rest is reported in
meta.locked; paid plans get all of them. Lists 14 days old or older return in full for everyone. - dateYYYY-MM-DD
The newest pick list on or before this date, inside your plan's history window.
Response
Fields of data:
- scopestring
Country code, or
global. - datedate
The pick list day.
- itemsarray
The day's picks, in list order.
Show 12 child fieldsHide child fields
- positioninteger
Place on the day's list, 1 first.
- scorenumber
Trend score, 0–100, in this scope.
- score_changenumber | null
Change since yesterday.
- statusnew | rising | steady | peaking | fading
new: on this list today and not in the 7 days before.rising: the signals are growing against their own 7-day average and the title has already reached a meaningful level (a single new chart entry does not qualify).steady: little day-over-day change.peaking: near the top of the scale and no longer growing.fading: the signals are shrinking. - signalsobject
Category levels, each 0–100, or null when that category had no data that day.
Show 3 child fieldsHide child fields
- chart_momentumnumber | null
Position, breadth, and movement across Top 10 charts inside the scope.
- demandnumber | null
Consumption and discovery intent. First-party activity is worldwide and counted over the last complete day; discovery rankings follow the country scope and are summed on the global list.
- attentionnumber | null
Broad web attention, from one worldwide feed and from reading per language that follows the country (summed across languages on the global list). Discounted when flat: a title that draws the same attention every day keeps half its level, a spike keeps all of it. Attention alone never carries a title above titles with chart or demand presence unless it is spiking.
- whyarray
Plain-language reasons, built from the categories and release data.
- strengthstrong | watch
strongfor a launch (a release inside 3 days or in the 14 days before the pick),watchfor the rest. - premieredate | null
Next digital release, premiere, or season start inside the scope, known on pick day.
- providersarray
Tracked services carrying the title inside the scope, known on pick day.
- outcomeobject | null
Set once the title enters a Top 10 inside the scope within 30 days. Null while the window is open or after it closed without a chart.
Show 7 child fieldsHide child fields
- first_chart_datedate
First day on a Top 10 inside the scope.
- first_chart_providerstring
Provider of that first chart.
- first_chart_countrystring
Country of that first chart.
- first_chart_rankinteger
Rank on that first chart.
- days_to_chartinteger
Days from pick to first chart.
- peak_rankinteger
Best rank inside the scope, updated until day 30.
- days_on_chartinteger
Distinct chart days inside the scope, updated until day 30.
- missedboolean
True once 14 days pass without a chart.
outcomecan still fill in later, up to day 30. - titleobject
Canonical title: id, slug, name, type, year, tmdb_id, imdb_id, poster_url.
Show 8 child fieldsHide child fields
- idstring
Title id,
ttl_…. - slugstring
URL slug, e.g.
the-whisper-man-2026. - namestring
Display name.
- typemovie | tv
Movie or show.
- yearinteger | null
Release year.
- tmdb_idinteger | null
TMDB id.
- imdb_idstring | null
IMDb id.
- poster_urlstring | null
Poster image.
- track_recordobject
Hit rate of past calls next to the rate for every eligible title.
Show 25 child fieldsHide child fields
- scopestring
Country code, or
global. - fromdate
First pick day counted.
- todate
Last pick day counted.
- window_daysinteger
The main window, 14 days.
- long_window_daysinteger
The long window, 30 days.
- typesarray
Content types the top-level numbers cover: the published types.
- picksinteger
Calls whose 14-day window has closed. A title picked on consecutive days (gaps up to 7 days) is one call, dated from its first day.
- charted_7dinteger
Calls that entered a Top 10 inside the scope within 7 days.
- charted_14dinteger
Calls that entered a Top 10 inside the scope within 14 days.
- hit_rate_14dnumber | null
charted_14d as a percentage of picks.
- median_days_to_chartnumber | null
Median days from pick to first chart, over the calls that charted within 14 days.
- median_peak_ranknumber | null
Median best rank inside the scope, over 14-day hits whose 30-day window has closed.
- median_days_on_chartnumber | null
Median chart days inside the scope, over the same hits.
- picks_30dinteger
Calls whose 30-day window has closed.
- charted_30dinteger
Of those, the calls that charted within 30 days.
- hit_rate_30dnumber | null
charted_30d as a percentage of picks_30d.
- poolinteger
Every uncharted title that met the rules on the same days.
- pool_charted_14dinteger
Pool titles that charted within 14 days.
- pool_hit_rate_14dnumber | null
The pool's 14-day rate. The list has to beat it to mean anything.
- pool_30dinteger
Pool titles on the days whose 30-day window has closed.
- pool_charted_30dinteger
Of those, the titles that charted within 30 days.
- pool_hit_rate_30dnumber | null
The pool's 30-day rate.
- controlobject
Ten random titles a day from the same eligible pool, checked the same way as picks. The same fields as the top level. The fairest baseline.
- by_typeobject
tvandmovie, each with the same fields and its owncontrol. Movies are logged but not published; their record lives here. - by_strengthobject
strongandwatch: the published calls split by strength, with the same fields. Pool fields repeat the whole pool.
Show meta fieldsHide meta fields
- countinteger
Items returned.
- limit_maxinteger
Largest
limityour plan allows. - history_daysinteger
Days of history your plan includes.
- lockedinteger
Picks your plan holds back on a list younger than 14 days.
curl "https://streamrank.io/v1/trending/breakouts" \
-H "Authorization: Bearer $STREAMRANK_API_KEY"{
"data": {
"scope": "US",
"date": "2026-09-15",
"items": [
{
"position": 1,
"score": 45.4,
"score_change": 5.2,
"status": "rising",
"signals": {
"chart_momentum": 0,
"demand": 83.1,
"attention": 45.2
},
"why": [
"Lands Sep 19 on Netflix.",
"Demand 83 of 100.",
"Score up 5.2 today.",
"On no Top 10 in United States."
],
"strength": "strong",
"premiere": "2026-09-19",
"providers": ["netflix"],
"outcome": {
"first_chart_date": "2026-09-20",
"first_chart_provider": "netflix",
"first_chart_country": "US",
"first_chart_rank": 4,
"days_to_chart": 5,
"peak_rank": 2,
"days_on_chart": 6
},
"missed": false,
"title": {
"id": "ttl_9q2h7v3zkm1d",
"slug": "obsession-2026",
"name": "Obsession",
"type": "movie",
"year": 2026,
"tmdb_id": 1364532,
"imdb_id": "tt31520893",
"poster_url": "https://image.tmdb.org/t/p/w500/obsession.jpg"
}
}
],
"track_record": {
"scope": "US",
"from": "2026-08-02",
"to": "2026-08-31",
"window_days": 14,
"long_window_days": 30,
"types": ["tv"],
"picks": 96,
"charted_7d": 29,
"charted_14d": 41,
"hit_rate_14d": 42.7,
"median_days_to_chart": 4,
"median_peak_rank": 3,
"median_days_on_chart": 7,
"picks_30d": 45,
"charted_30d": 21,
"hit_rate_30d": 46.7,
"pool": 640,
"pool_charted_14d": 122,
"pool_hit_rate_14d": 19.1,
"pool_30d": 300,
"pool_charted_30d": 66,
"pool_hit_rate_30d": 22,
"by_type": {
"tv": {
"picks": 96,
"charted_7d": 29,
"charted_14d": 41,
"hit_rate_14d": 42.7,
"median_days_to_chart": 4,
"median_peak_rank": 3,
"median_days_on_chart": 7,
"picks_30d": 45,
"charted_30d": 21,
"hit_rate_30d": 46.7,
"pool": 640,
"pool_charted_14d": 122,
"pool_hit_rate_14d": 19.1,
"pool_30d": 300,
"pool_charted_30d": 66,
"pool_hit_rate_30d": 22,
"control": {
"picks": 150,
"charted_7d": 9,
"charted_14d": 16,
"hit_rate_14d": 10.7,
"median_days_to_chart": 7,
"median_peak_rank": 7,
"median_days_on_chart": 2,
"picks_30d": 70,
"charted_30d": 11,
"hit_rate_30d": 15.7,
"pool": 640,
"pool_charted_14d": 122,
"pool_hit_rate_14d": 19.1,
"pool_30d": 300,
"pool_charted_30d": 66,
"pool_hit_rate_30d": 22
}
},
"movie": {
"picks": 104,
"charted_7d": 6,
"charted_14d": 9,
"hit_rate_14d": 8.7,
"median_days_to_chart": 9,
"median_peak_rank": 6,
"median_days_on_chart": 3,
"picks_30d": 50,
"charted_30d": 8,
"hit_rate_30d": 16,
"pool": 1570,
"pool_charted_14d": 76,
"pool_hit_rate_14d": 4.8,
"pool_30d": 730,
"pool_charted_30d": 88,
"pool_hit_rate_30d": 12.1,
"control": {
"picks": 150,
"charted_7d": 6,
"charted_14d": 11,
"hit_rate_14d": 7.3,
"median_days_to_chart": 8,
"median_peak_rank": 8,
"median_days_on_chart": 2,
"picks_30d": 70,
"charted_30d": 9,
"hit_rate_30d": 12.9,
"pool": 1570,
"pool_charted_14d": 76,
"pool_hit_rate_14d": 4.8,
"pool_30d": 730,
"pool_charted_30d": 88,
"pool_hit_rate_30d": 12.1
}
}
},
"by_strength": {
"strong": {
"picks": 30,
"charted_7d": 12,
"charted_14d": 16,
"hit_rate_14d": 53.3,
"median_days_to_chart": 3,
"median_peak_rank": 2,
"median_days_on_chart": 9,
"picks_30d": 14,
"charted_30d": 8,
"hit_rate_30d": 57.1,
"pool": 640,
"pool_charted_14d": 122,
"pool_hit_rate_14d": 19.1,
"pool_30d": 300,
"pool_charted_30d": 66,
"pool_hit_rate_30d": 22
},
"watch": {
"picks": 66,
"charted_7d": 17,
"charted_14d": 25,
"hit_rate_14d": 37.9,
"median_days_to_chart": 5,
"median_peak_rank": 4,
"median_days_on_chart": 6,
"picks_30d": 31,
"charted_30d": 13,
"hit_rate_30d": 41.9,
"pool": 640,
"pool_charted_14d": 122,
"pool_hit_rate_14d": 19.1,
"pool_30d": 300,
"pool_charted_30d": 66,
"pool_hit_rate_30d": 22
}
},
"control": {
"picks": 150,
"charted_7d": 9,
"charted_14d": 16,
"hit_rate_14d": 10.7,
"median_days_to_chart": 7,
"median_peak_rank": 7,
"median_days_on_chart": 2,
"picks_30d": 70,
"charted_30d": 11,
"hit_rate_30d": 15.7,
"pool": 640,
"pool_charted_14d": 122,
"pool_hit_rate_14d": 19.1,
"pool_30d": 300,
"pool_charted_30d": 66,
"pool_hit_rate_30d": 22
}
}
},
"meta": {
"count": 1,
"locked": 0,
"limit_max": 10,
"history_days": 30
}
}Pick history
Every pick we have made in the scope, newest day first and in list order inside a day, each with the outcome we recorded.
fromis clamped to your plan's history window.- Page with
limitandoffsetagainstmeta.total.
Plan limits
On a list younger than 14 days, Free, test keys, and calls without a key get the top pick only.More examples
- /v1/trending/breakouts/history?country=US&type=tv&from=2026-08-01&to=2026-08-31
- /v1/trending/breakouts/history?limit=50&offset=50
Query parameters
- countrystring
ISO 3166-1 alpha-2. Omit it for the global list.
- typemovie | tv
Default
tv, the published list.moviereturns the movie picks, which are logged every day but not published while they chart at the control rate. - fromYYYY-MM-DD
Optional start date. Clamped to your plan's history window.
- toYYYY-MM-DD
Optional end date.
- limit1–500
Picks per page, default 100.
- offsetinteger
Picks to skip, default 0. Page with
meta.total.
Response
Fields of data:
- scopestring
Country code, or
global. - fromdate
First pick day, after clamping to your plan's history window.
- todate
Last pick day.
- itemsarray
Picks, newest day first and in list order inside a day.
Show 13 child fieldsHide child fields
- datedate
Day the pick was made.
- positioninteger
Place on the day's list, 1 first.
- scorenumber
Trend score, 0–100, in this scope.
- score_changenumber | null
Change since yesterday.
- statusnew | rising | steady | peaking | fading
new: on this list today and not in the 7 days before.rising: the signals are growing against their own 7-day average and the title has already reached a meaningful level (a single new chart entry does not qualify).steady: little day-over-day change.peaking: near the top of the scale and no longer growing.fading: the signals are shrinking. - signalsobject
Category levels, each 0–100, or null when that category had no data that day.
Show 3 child fieldsHide child fields
- chart_momentumnumber | null
Position, breadth, and movement across Top 10 charts inside the scope.
- demandnumber | null
Consumption and discovery intent. First-party activity is worldwide and counted over the last complete day; discovery rankings follow the country scope and are summed on the global list.
- attentionnumber | null
Broad web attention, from one worldwide feed and from reading per language that follows the country (summed across languages on the global list). Discounted when flat: a title that draws the same attention every day keeps half its level, a spike keeps all of it. Attention alone never carries a title above titles with chart or demand presence unless it is spiking.
- whyarray
Plain-language reasons, built from the categories and release data.
- strengthstrong | watch
strongfor a launch (a release inside 3 days or in the 14 days before the pick),watchfor the rest. - premieredate | null
Next digital release, premiere, or season start inside the scope, known on pick day.
- providersarray
Tracked services carrying the title inside the scope, known on pick day.
- outcomeobject | null
Set once the title enters a Top 10 inside the scope within 30 days. Null while the window is open or after it closed without a chart.
Show 7 child fieldsHide child fields
- first_chart_datedate
First day on a Top 10 inside the scope.
- first_chart_providerstring
Provider of that first chart.
- first_chart_countrystring
Country of that first chart.
- first_chart_rankinteger
Rank on that first chart.
- days_to_chartinteger
Days from pick to first chart.
- peak_rankinteger
Best rank inside the scope, updated until day 30.
- days_on_chartinteger
Distinct chart days inside the scope, updated until day 30.
- missedboolean
True once 14 days pass without a chart.
outcomecan still fill in later, up to day 30. - titleobject
Canonical title: id, slug, name, type, year, tmdb_id, imdb_id, poster_url.
Show 8 child fieldsHide child fields
- idstring
Title id,
ttl_…. - slugstring
URL slug, e.g.
the-whisper-man-2026. - namestring
Display name.
- typemovie | tv
Movie or show.
- yearinteger | null
Release year.
- tmdb_idinteger | null
TMDB id.
- imdb_idstring | null
IMDb id.
- poster_urlstring | null
Poster image.
Show meta fieldsHide meta fields
- countinteger
Items returned.
- totalinteger
Every pick that matches the query. Page against it.
- limitinteger
Page size.
- offsetinteger
Picks skipped.
- history_daysinteger
Days of history your plan includes.
curl "https://streamrank.io/v1/trending/breakouts/history?country=US" \
-H "Authorization: Bearer $STREAMRANK_API_KEY"{
"data": {
"scope": "US",
"from": "2026-08-16",
"to": "2026-09-15",
"items": [
{
"date": "2026-09-15",
"position": 1,
"score": 45.4,
"score_change": 5.2,
"status": "rising",
"signals": {
"chart_momentum": 0,
"demand": 83.1,
"attention": 45.2
},
"why": [
"Lands Sep 19 on Netflix.",
"Demand 83 of 100.",
"Score up 5.2 today.",
"On no Top 10 in United States."
],
"strength": "strong",
"premiere": "2026-09-19",
"providers": ["netflix"],
"outcome": {
"first_chart_date": "2026-09-20",
"first_chart_provider": "netflix",
"first_chart_country": "US",
"first_chart_rank": 4,
"days_to_chart": 5,
"peak_rank": 2,
"days_on_chart": 6
},
"missed": false,
"title": {
"id": "ttl_9q2h7v3zkm1d",
"slug": "obsession-2026",
"name": "Obsession",
"type": "movie",
"year": 2026,
"tmdb_id": 1364532,
"imdb_id": "tt31520893",
"poster_url": "https://image.tmdb.org/t/p/w500/obsession.jpg"
}
}
]
},
"meta": {
"count": 1,
"total": 310,
"limit": 100,
"offset": 0,
"history_days": 30
}
}Charts
Top 10 chart
The Top 10 for one provider in one country. Omit type to receive both the movie and TV charts in one response.
We compute the derived metrics from our own stored history, so they cover the days we have collected.
More examples
- /v1/charts?provider=netflix&country=JP&type=tv
- /v1/charts?provider=disney&country=GB
- /v1/charts?provider=max&country=US&type=tv&date=2026-09-01
Query parameters
- providerstringrequired
netflix, prime, disney, max, hulu, apple, paramount, peacock, starz.
- countrystringrequired
ISO 3166-1 alpha-2, e.g. US, GB, JP.
- typemovie | tv
Return one chart instead of both.
- dateYYYY-MM-DD
A past chart. Resolves to the newest chart on or before the date. Requires history on your plan.
- limit1–10
Return only the top N.
Response
Fields of data:
- providerstring
Provider id.
- countrystring
ISO 3166-1 alpha-2.
- typemovie | tv
Which chart. Present when you pass
type. - datedate
Chart day.
- updated_atdatetime
When we last stored this chart.
- rankingsarray
The Top 10, best first.
Show 8 child fieldsHide child fields
- rankinteger
Position on the chart, 1–10.
- previous_rankinteger | null
Rank the day before, or null if the title was not on yesterday's chart.
- rank_changeinteger | null
previous_rank − rank. Positive means it moved up.
- is_newboolean
True on the first day a title appears on this chart.
- days_in_top_10integer
Total days on this chart, including today.
- peak_rankinteger
Best rank so far on this chart.
- first_charted_atdate
First day on this chart.
- titleobject
Canonical title: id, slug, name, type, year, tmdb_id, imdb_id, poster_url.
Show 8 child fieldsHide child fields
- idstring
Title id,
ttl_…. - slugstring
URL slug, e.g.
the-whisper-man-2026. - namestring
Display name.
- typemovie | tv
Movie or show.
- yearinteger | null
Release year.
- tmdb_idinteger | null
TMDB id.
- imdb_idstring | null
IMDb id.
- poster_urlstring | null
Poster image.
- chartsarray
Without
type: one chart per type, each with provider, country, type, date, updated_at, and rankings.
curl "https://streamrank.io/v1/charts?provider=netflix&country=US&type=movie" \
-H "Authorization: Bearer $STREAMRANK_API_KEY"{
"data": {
"provider": "netflix",
"country": "US",
"type": "movie",
"date": "2026-09-10",
"updated_at": "2026-09-10T22:49:43.000Z",
"rankings": [
{
"rank": 1,
"previous_rank": 3,
"rank_change": 2,
"is_new": false,
"days_in_top_10": 8,
"peak_rank": 1,
"first_charted_at": "2026-09-03",
"title": {
"id": "ttl_5k2m9x1qzc7v",
"slug": "the-whisper-man-2026",
"name": "The Whisper Man",
"type": "movie",
"year": 2026,
"tmdb_id": 860508,
"imdb_id": "tt11561116",
"poster_url": "https://image.tmdb.org/t/p/w500/….jpg"
}
}
]
}
}Titles
Search titles
Look up a title by name, IMDb id, or TMDB id. Returns a ranked list, so an ambiguous name is not a 404. Then call /v1/titles/{id} for current positions.
More examples
- /v1/titles?imdb_id=tt4574334
- /v1/titles?tmdb_id=1396&type=tv
- /v1/titles?q=Ready+or+Not&year=2019
Query parameters
- qstring
Name, slug, ttl_ id, IMDb id, or TMDB id. Required unless imdb_id or tmdb_id is set.
- imdb_idstring
Exact IMDb id, e.g. tt4574334.
- tmdb_idinteger
Exact TMDB id. Pass type when a movie and a show share the number.
- typemovie | tv
Restrict results to one kind.
- yearinteger
Prefer titles released this year when matching by name.
- limit1–20
Default 10.
Response
Each item in data:
- idstring
Title id,
ttl_…. - slugstring
URL slug, e.g.
the-whisper-man-2026. - namestring
Display name.
- typemovie | tv
Movie or show.
- yearinteger | null
Release year.
- tmdb_idinteger | null
TMDB id.
- imdb_idstring | null
IMDb id.
- poster_urlstring | null
Poster image.
- matchname | slug | id | imdb_id | tmdb_id
What the query matched.
Show meta fieldsHide meta fields
- countinteger
Results returned.
curl "https://streamrank.io/v1/titles?q=The+Pitt" \
-H "Authorization: Bearer $STREAMRANK_API_KEY"{
"data": [
{
"id": "ttl_5k2m9x1qzc7v",
"slug": "the-whisper-man-2026",
"name": "The Whisper Man",
"type": "movie",
"year": 2026,
"tmdb_id": 860508,
"imdb_id": "tt11561116",
"poster_url": "https://image.tmdb.org/t/p/w500/….jpg",
"match": "name"
}
],
"meta": { "count": 1 }
}Get a title
A canonical title with where it currently ranks, plus stats over the history your plan includes. Countries and providers follow the same entitlements as /v1/charts.
More examples
- /v1/titles/the-whisper-man-2026
- /v1/titles/tt11561116
Path parameters
- idstringrequired
Title id (
ttl_…), slug, IMDb id, or numeric TMDB id.
Response
Fields of data:
- idstring
Title id,
ttl_…. - slugstring
URL slug, e.g.
the-whisper-man-2026. - namestring
Display name.
- typemovie | tv
Movie or show.
- yearinteger | null
Release year.
- tmdb_idinteger | null
TMDB id.
- imdb_idstring | null
IMDb id.
- poster_urlstring | null
Poster image.
- overviewstring | null
Synopsis.
- backdrop_urlstring | null
Backdrop image.
- current_rankingsarray
Every current chart the title is on, inside your plan.
Show 9 child fieldsHide child fields
- datedate
Chart day.
- providerstring
Provider id.
- countrystring
ISO 3166-1 alpha-2.
- typemovie | tv
Which chart.
- rankinteger
Position on that chart, 1–10.
- previous_rankinteger | null
Rank the day before.
- rank_changeinteger | null
previous_rank − rank. Positive means it moved up.
- days_in_top_10integer
Total days on this chart.
- peak_rankinteger
Best rank so far on this chart.
- statsobject
Lifetime stats over the countries, providers, and history your plan includes.
Show 6 child fieldsHide child fields
- total_top_10_daysinteger
Chart days across every chart.
- peak_rankinteger | null
Best rank on any chart.
- days_at_number_oneinteger
Chart days at #1.
- countries_chartedinteger
Countries where it has charted.
- first_charted_atdate | null
First chart day.
- last_charted_atdate | null
Most recent chart day.
curl "https://streamrank.io/v1/titles/ttl_5k2m9x1qzc7v" \
-H "Authorization: Bearer $STREAMRANK_API_KEY"{
"data": {
"id": "ttl_5k2m9x1qzc7v",
"slug": "the-whisper-man-2026",
"name": "The Whisper Man",
"type": "movie",
"year": 2026,
"tmdb_id": 860508,
"imdb_id": "tt11561116",
"poster_url": "https://image.tmdb.org/t/p/w500/….jpg",
"overview": "…",
"backdrop_url": "https://image.tmdb.org/t/p/original/….jpg",
"current_rankings": [
{
"date": "2026-09-10",
"provider": "netflix",
"country": "US",
"type": "movie",
"rank": 1,
"previous_rank": 3,
"rank_change": 2,
"days_in_top_10": 8,
"peak_rank": 1
}
],
"stats": {
"total_top_10_days": 8,
"peak_rank": 1,
"days_at_number_one": 3,
"countries_charted": 1,
"first_charted_at": "2026-09-03",
"last_charted_at": "2026-09-10"
}
}
}Ranking history
Day-by-day ranking history for a title, newest first, clamped to your plan's history window.
Path parameters
- idstringrequired
Title id (
ttl_…) or slug.
Query parameters
- providerstring
Optional filter.
- countrystring
Optional filter.
- fromYYYY-MM-DD
Optional start date.
- toYYYY-MM-DD
Optional end date.
- limit1–5000
Default 1000.
Response
Each item in data:
- datedate
Chart day.
- providerstring
Provider id.
- countrystring
ISO 3166-1 alpha-2.
- typemovie | tv
Which chart.
- rankinteger
Position on that chart, 1–10.
- previous_rankinteger | null
Rank the day before.
- rank_changeinteger | null
previous_rank − rank. Positive means it moved up.
- days_in_top_10integer
Total days on this chart.
- peak_rankinteger
Best rank so far on this chart.
Show meta fieldsHide meta fields
- title_idstring
Title id.
- fromdate
First day returned, after clamping to your plan's history window.
- todate
Last day returned.
- history_daysinteger
Days of history your plan includes.
curl "https://streamrank.io/v1/titles/ttl_5k2m9x1qzc7v/rankings?country=US&provider=netflix" \
-H "Authorization: Bearer $STREAMRANK_API_KEY"{
"data": [
{
"date": "2026-09-10",
"provider": "netflix",
"country": "US",
"type": "movie",
"rank": 3,
"previous_rank": 1,
"rank_change": -2,
"days_in_top_10": 13,
"peak_rank": 1
}
],
"meta": {
"title_id": "ttl_5k2m9x1qzc7v",
"from": "2026-08-11",
"to": "2026-09-10",
"history_days": 30
}
}Trending
Chart movers
Movement inside one provider's charts in one country: biggest_risers, new_entries, and longest_streaks.
No cross-provider ranking
A #1 on Apple TV and a #5 on Netflix are not comparable. For one list across every service, use trending titles.Query parameters
- providerstringrequired
- countrystringrequired
ISO 3166-1 alpha-2.
- limit1–20
Items per bucket, default 5.
Response
Fields of data:
- providerstring
Provider id.
- countrystring
ISO 3166-1 alpha-2.
- datedate
Chart day.
- biggest_risersarray
Ranking items from both the movie and TV charts, each with
type.Show 9 child fieldsHide child fields
- rankinteger
Position on the chart, 1–10.
- previous_rankinteger | null
Rank the day before, or null if the title was not on yesterday's chart.
- rank_changeinteger | null
previous_rank − rank. Positive means it moved up.
- is_newboolean
True on the first day a title appears on this chart.
- days_in_top_10integer
Total days on this chart, including today.
- peak_rankinteger
Best rank so far on this chart.
- first_charted_atdate
First day on this chart.
- titleobject
Canonical title: id, slug, name, type, year, tmdb_id, imdb_id, poster_url.
Show 8 child fieldsHide child fields
- idstring
Title id,
ttl_…. - slugstring
URL slug, e.g.
the-whisper-man-2026. - namestring
Display name.
- typemovie | tv
Movie or show.
- yearinteger | null
Release year.
- tmdb_idinteger | null
TMDB id.
- imdb_idstring | null
IMDb id.
- poster_urlstring | null
Poster image.
- typemovie | tv
Which chart.
- new_entriesarray
Ranking items from both the movie and TV charts, each with
type.Show 9 child fieldsHide child fields
- rankinteger
Position on the chart, 1–10.
- previous_rankinteger | null
Rank the day before, or null if the title was not on yesterday's chart.
- rank_changeinteger | null
previous_rank − rank. Positive means it moved up.
- is_newboolean
True on the first day a title appears on this chart.
- days_in_top_10integer
Total days on this chart, including today.
- peak_rankinteger
Best rank so far on this chart.
- first_charted_atdate
First day on this chart.
- titleobject
Canonical title: id, slug, name, type, year, tmdb_id, imdb_id, poster_url.
Show 8 child fieldsHide child fields
- idstring
Title id,
ttl_…. - slugstring
URL slug, e.g.
the-whisper-man-2026. - namestring
Display name.
- typemovie | tv
Movie or show.
- yearinteger | null
Release year.
- tmdb_idinteger | null
TMDB id.
- imdb_idstring | null
IMDb id.
- poster_urlstring | null
Poster image.
- typemovie | tv
Which chart.
- longest_streaksarray
Ranking items from both the movie and TV charts, each with
type.Show 9 child fieldsHide child fields
- rankinteger
Position on the chart, 1–10.
- previous_rankinteger | null
Rank the day before, or null if the title was not on yesterday's chart.
- rank_changeinteger | null
previous_rank − rank. Positive means it moved up.
- is_newboolean
True on the first day a title appears on this chart.
- days_in_top_10integer
Total days on this chart, including today.
- peak_rankinteger
Best rank so far on this chart.
- first_charted_atdate
First day on this chart.
- titleobject
Canonical title: id, slug, name, type, year, tmdb_id, imdb_id, poster_url.
Show 8 child fieldsHide child fields
- idstring
Title id,
ttl_…. - slugstring
URL slug, e.g.
the-whisper-man-2026. - namestring
Display name.
- typemovie | tv
Movie or show.
- yearinteger | null
Release year.
- tmdb_idinteger | null
TMDB id.
- imdb_idstring | null
IMDb id.
- poster_urlstring | null
Poster image.
- typemovie | tv
Which chart.
curl "https://streamrank.io/v1/trending?provider=netflix&country=US" \
-H "Authorization: Bearer $STREAMRANK_API_KEY"Trending titles
One list that ranks titles across every service by a single trend score, 0–100.
Three categories feed the score
chart_momentum: position, breadth, and movement across Top 10 charts inside the scope.demand: consumption and discovery intent. First-party activity is worldwide; discovery rankings follow the country.attention: broad web attention, from one worldwide feed and from reading per language that follows the country.
Scope and timing
- Omit
countryfor the global list. A country scope weights that country's Top 10 charts, discovery rankings, and reading in its language; first-party demand stays worldwide. - The score is daily. First-party demand counts cover the last complete day.
- Attention is discounted when it is flat. Titles seen only by attention rank after titles with chart or demand presence.
More examples
- /v1/trending/titles?country=US&type=tv
- /v1/trending/titles?status=rising&limit=25
- /v1/trending/titles?country=GB&date=2026-09-10
Query parameters
- countrystring
ISO 3166-1 alpha-2. Omit it for the global list. A country scope weights that country's Top 10 charts, that country's discovery rankings, and reading in its language; first-party demand stays worldwide.
- typemovie | tv
Restrict the list to movies or to shows.
- statusnew | rising | steady | peaking | fading
Keep only titles with this status.
- limit1–100
Default 10. Capped by your plan: 10 on Free, without a key, or with a test key; 100 on paid plans.
- dateYYYY-MM-DD
A past list. Resolves to the newest list on or before the date. Requires history on your plan.
Response
Fields of data:
- scopestring
Country code, or
global. - datedate
The list day.
- itemsarray
Titles by trend score, best first.
Show 11 child fieldsHide child fields
- rankinteger
Position on the trending list for this scope and day.
- previous_rankinteger | null
Trending rank the day before, or null if the title was not on yesterday's list.
- rank_changeinteger | null
previous_rank − rank. Positive means it moved up.
- scorenumber
Trend score, 0–100. Relative to every other title scored in the same scope on the same day.
- previous_scorenumber | null
Yesterday's score in this scope, or null.
- score_changenumber | null
score − previous_score, one decimal place.
- statusnew | rising | steady | peaking | fading
new: on this list today and not in the 7 days before.rising: the signals are growing against their own 7-day average and the title has already reached a meaningful level (a single new chart entry does not qualify).steady: little day-over-day change.peaking: near the top of the scale and no longer growing.fading: the signals are shrinking. - chart_countinteger
How many Top 10 charts the title sits on today inside the scope. Counts every chart, not only the ones your plan can read.
- on_chartsarray
Today's chart positions, filtered to the countries and providers your plan includes, so it can be shorter than chart_count.
Show 4 child fieldsHide child fields
- providerstring
Provider id.
- countrystring
ISO 3166-1 alpha-2.
- typemovie | tv
Which chart.
- rankinteger
Position on that chart, 1–10.
- signalsobject
Category levels, each 0–100, or null when that category had no data that day.
Show 3 child fieldsHide child fields
- chart_momentumnumber | null
Position, breadth, and movement across Top 10 charts inside the scope.
- demandnumber | null
Consumption and discovery intent. First-party activity is worldwide and counted over the last complete day; discovery rankings follow the country scope and are summed on the global list.
- attentionnumber | null
Broad web attention, from one worldwide feed and from reading per language that follows the country (summed across languages on the global list). Discounted when flat: a title that draws the same attention every day keeps half its level, a spike keeps all of it. Attention alone never carries a title above titles with chart or demand presence unless it is spiking.
- titleobject
Canonical title: id, slug, name, type, year, tmdb_id, imdb_id, poster_url.
Show 8 child fieldsHide child fields
- idstring
Title id,
ttl_…. - slugstring
URL slug, e.g.
the-whisper-man-2026. - namestring
Display name.
- typemovie | tv
Movie or show.
- yearinteger | null
Release year.
- tmdb_idinteger | null
TMDB id.
- imdb_idstring | null
IMDb id.
- poster_urlstring | null
Poster image.
Show meta fieldsHide meta fields
- countinteger
Items returned.
- limit_maxinteger
Largest
limityour plan allows. - history_daysinteger
Days of history your plan includes.
curl "https://streamrank.io/v1/trending/titles" \
-H "Authorization: Bearer $STREAMRANK_API_KEY"{
"data": {
"scope": "global",
"date": "2026-09-10",
"items": [
{
"rank": 1,
"previous_rank": 4,
"rank_change": 3,
"score": 92.6,
"previous_score": 81.4,
"score_change": 11.2,
"status": "rising",
"chart_count": 9,
"on_charts": [
{
"provider": "netflix",
"country": "US",
"type": "movie",
"rank": 1
},
{
"provider": "netflix",
"country": "GB",
"type": "movie",
"rank": 2
}
],
"signals": {
"chart_momentum": 96.1,
"demand": 88.3,
"attention": 90.7
},
"title": {
"id": "ttl_5k2m9x1qzc7v",
"slug": "the-whisper-man-2026",
"name": "The Whisper Man",
"type": "movie",
"year": 2026,
"tmdb_id": 860508,
"imdb_id": "tt11561116",
"poster_url": "https://image.tmdb.org/t/p/w500/….jpg"
}
}
]
},
"meta": {
"count": 1,
"limit_max": 10,
"history_days": 0
}
}Title trend
The title's row on today's list plus its score history, newest first, clamped to your plan's history window. current is null when the title is not trending in that scope today.
More examples
- /v1/titles/the-whisper-man-2026/trend?country=US&limit=30
Path parameters
- idstringrequired
Title id (
ttl_…), slug, IMDb id, or numeric TMDB id.
Query parameters
- countrystring
ISO 3166-1 alpha-2. Omit it for the global scope.
- fromYYYY-MM-DD
Optional start date. Clamped to your plan's history window.
- toYYYY-MM-DD
Optional end date.
- limit1–365
Days of history, default 90.
Response
Fields of data:
- title_idstring
Title id.
- scopestring
Country code, or
global. - currentobject | null
Today's row on the trending list, or null when the title is not trending in that scope today.
Show 11 child fieldsHide child fields
- scopestring
Country code, or
global. - datedate
List day.
- rankinteger
Position on the trending list for this scope and day.
- previous_rankinteger | null
Trending rank the day before, or null if the title was not on yesterday's list.
- rank_changeinteger | null
previous_rank − rank. Positive means it moved up.
- scorenumber
Trend score, 0–100. Relative to every other title scored in the same scope on the same day.
- previous_scorenumber | null
Yesterday's score in this scope, or null.
- score_changenumber | null
score − previous_score, one decimal place.
- statusnew | rising | steady | peaking | fading
new: on this list today and not in the 7 days before.rising: the signals are growing against their own 7-day average and the title has already reached a meaningful level (a single new chart entry does not qualify).steady: little day-over-day change.peaking: near the top of the scale and no longer growing.fading: the signals are shrinking. - chart_countinteger
How many Top 10 charts the title sits on today inside the scope. Counts every chart, not only the ones your plan can read.
- signalsobject
Category levels, each 0–100, or null when that category had no data that day.
Show 3 child fieldsHide child fields
- chart_momentumnumber | null
Position, breadth, and movement across Top 10 charts inside the scope.
- demandnumber | null
Consumption and discovery intent. First-party activity is worldwide and counted over the last complete day; discovery rankings follow the country scope and are summed on the global list.
- attentionnumber | null
Broad web attention, from one worldwide feed and from reading per language that follows the country (summed across languages on the global list). Discounted when flat: a title that draws the same attention every day keeps half its level, a spike keeps all of it. Attention alone never carries a title above titles with chart or demand presence unless it is spiking.
- historyarray
One row per day, newest first.
Show 6 child fieldsHide child fields
- datedate
List day.
- rankinteger
Trending rank that day.
- scorenumber
Trend score, 0–100.
- statusnew | rising | steady | peaking | fading
new: on this list today and not in the 7 days before.rising: the signals are growing against their own 7-day average and the title has already reached a meaningful level (a single new chart entry does not qualify).steady: little day-over-day change.peaking: near the top of the scale and no longer growing.fading: the signals are shrinking. - chart_countinteger
Top 10 charts inside the scope that day.
- signalsobject
Category levels, each 0–100, or null when that category had no data that day.
Show 3 child fieldsHide child fields
- chart_momentumnumber | null
Position, breadth, and movement across Top 10 charts inside the scope.
- demandnumber | null
Consumption and discovery intent. First-party activity is worldwide and counted over the last complete day; discovery rankings follow the country scope and are summed on the global list.
- attentionnumber | null
Broad web attention, from one worldwide feed and from reading per language that follows the country (summed across languages on the global list). Discounted when flat: a title that draws the same attention every day keeps half its level, a spike keeps all of it. Attention alone never carries a title above titles with chart or demand presence unless it is spiking.
Show meta fieldsHide meta fields
- fromdate
First day returned, after clamping to your plan's history window.
- todate
Last day returned.
- history_daysinteger
Days of history your plan includes.
curl "https://streamrank.io/v1/titles/ttl_5k2m9x1qzc7v/trend" \
-H "Authorization: Bearer $STREAMRANK_API_KEY"{
"data": {
"title_id": "ttl_5k2m9x1qzc7v",
"scope": "US",
"current": {
"scope": "US",
"date": "2026-09-10",
"rank": 2,
"previous_rank": 5,
"rank_change": 3,
"score": 90.1,
"previous_score": 78.9,
"score_change": 11.2,
"status": "rising",
"chart_count": 3,
"signals": {
"chart_momentum": 94,
"demand": 86.2,
"attention": 88.5
}
},
"history": [
{
"date": "2026-09-10",
"rank": 2,
"score": 90.1,
"status": "rising",
"chart_count": 3,
"signals": {
"chart_momentum": 94,
"demand": 86.2,
"attention": 88.5
}
},
{
"date": "2026-09-09",
"rank": 5,
"score": 78.9,
"status": "new",
"chart_count": 2,
"signals": {
"chart_momentum": 81.3,
"demand": 74,
"attention": null
}
}
]
},
"meta": {
"from": "2026-08-11",
"to": "2026-09-10",
"history_days": 30
}
}Title signals
What moved the score, one day per row. Each category carries its 0–100 level, the number of independent feeds that saw the title that day, and its growth against its own 7-day baseline.
thresholdis the demand level a title must reach to be a pick, so you can read off the day it crossed.- Feeds are counted, never named.
More examples
- /v1/titles/the-whisper-man-2026/signals?country=US&limit=30
Path parameters
- idstringrequired
Title id (
ttl_…), slug, IMDb id, or numeric TMDB id.
Query parameters
- countrystring
ISO 3166-1 alpha-2. Omit it for the global scope.
- fromYYYY-MM-DD
Optional start date. Clamped to your plan's history window.
- toYYYY-MM-DD
Optional end date.
- limit1–365
Days of history, default 90.
Response
Fields of data:
- title_idstring
Title id.
- scopestring
Country code, or
global. - thresholdnumber
Demand level a title must reach to be a pick.
- historyarray
One row per day, newest first.
Show 4 child fieldsHide child fields
- datedate
Day.
- chart_momentumobject
Chart level and breadth.
Show 2 child fieldsHide child fields
- valuenumber | null
Category level, 0–100.
- chartsinteger
Top 10 charts the title sat on inside the scope that day.
- demandobject
Consumption and discovery intent.
Show 3 child fieldsHide child fields
- valuenumber | null
Category level, 0–100, or null when it had no data that day.
- feedsinteger | null
Independent feeds that saw the title that day. Feeds are counted, never named.
- growthnumber | null
Clipped log growth against the category's own 7-day baseline, −1 to 1.
- attentionobject
Broad web attention.
Show 3 child fieldsHide child fields
- valuenumber | null
Category level, 0–100, or null when it had no data that day.
- feedsinteger | null
Independent feeds that saw the title that day. Feeds are counted, never named.
- growthnumber | null
Clipped log growth against the category's own 7-day baseline, −1 to 1.
Show meta fieldsHide meta fields
- fromdate
First day returned, after clamping to your plan's history window.
- todate
Last day returned.
- history_daysinteger
Days of history your plan includes.
curl "https://streamrank.io/v1/titles/ttl_5k2m9x1qzc7v/signals" \
-H "Authorization: Bearer $STREAMRANK_API_KEY"{
"data": {
"title_id": "ttl_5k2m9x1qzc7v",
"scope": "US",
"threshold": 40,
"history": [
{
"date": "2026-09-10",
"chart_momentum": { "value": 94, "charts": 3 },
"demand": {
"value": 86.2,
"feeds": 2,
"growth": 0.31
},
"attention": {
"value": 88.5,
"feeds": 1,
"growth": 0.12
}
},
{
"date": "2026-09-09",
"chart_momentum": { "value": null, "charts": 0 },
"demand": {
"value": 38.4,
"feeds": 1,
"growth": 0.44
},
"attention": {
"value": null,
"feeds": null,
"growth": null
}
}
]
},
"meta": {
"from": "2026-08-11",
"to": "2026-09-10",
"history_days": 30
}
}Catalog
Countries
Every country with chart data and the providers available in each, plus whether your plan includes it.
Response
Each item in data:
- codestring
ISO 3166-1 alpha-2.
- namestring
Country name.
- providersarray
Provider ids with chart data in this country.
- included_in_planboolean
Whether your plan can read this country.
curl "https://streamrank.io/v1/countries" \
-H "Authorization: Bearer $STREAMRANK_API_KEY"{
"data": [
{
"code": "US",
"name": "United States",
"providers": [
"netflix",
"prime",
"disney",
"max",
"hulu",
"apple",
"paramount",
"peacock",
"starz"
],
"included_in_plan": true
}
]
}Providers
Every provider we cover, the countries that have data, and whether your plan includes it.
Response
Each item in data:
- idstring
Provider id, used in
provider=. - namestring
Display name.
- countriesarray
Countries with chart data for this provider.
- included_in_planboolean
Whether your plan can read this provider.
curl "https://streamrank.io/v1/providers" \
-H "Authorization: Bearer $STREAMRANK_API_KEY"{
"data": [
{
"id": "netflix",
"name": "Netflix",
"countries": [
"AU",
"CA",
"DE",
"FR",
"GB",
"JP",
"US"
],
"included_in_plan": true
},
{
"id": "prime",
"name": "Prime Video",
"countries": ["…"],
"included_in_plan": true
}
]
}Alerts
Alerts tell you when a title or a market moves, so you don't have to poll. Set them up in the dashboard at /dashboard/alerts. Watch one title in one scope, or watch a market and receive every pick it produces.
Channels
Email to your account address on every plan with alerts. Signed webhooks and Slack digests are on the Intelligence plan, $99 a month.Event types
- title.threshold_crossed
A watched title's demand reached 40 with zero Top 10s in the scope. Yesterday it was below. Payload adds
threshold,demand,previous_demand,signals,status. - title.charted
A watched title entered a Top 10 inside the scope. Payload adds
charts: one entry per chart it entered, eachprovider,country,type,rank. - pick.created
A title became one of the day's ten picks. A market watch gets all ten, dated on the list day. Payload adds
position,score,score_change,status,signals,why,strength,premiere,providers. - pick.charted
A pick landed on a Top 10 inside 30 days. Dated on the first chart date. Payload adds
pick_date,position,first_chart_date,first_chart_provider,first_chart_country,first_chart_rank,days_to_chart.
Every payload also carries scope, date (the chart or list day the event is about), and title (the canonical title object).
Webhooks
One POST per event with a JSON body. data is the payload for the event type.
X-StreamRank-Signature: t=<unix seconds>,v1=<hex>
X-StreamRank-Event: pick.created
X-StreamRank-Delivery: dlv_1842Verify the signature
v1is HMAC-SHA256 over${t}.${rawBody}with your endpoint secret.- Compare it in constant time against the exact bytes you received, not a re-serialized body.
Delivery
- Respond 2xx within 10 seconds.
- A failed delivery is retried on the next run, up to 3 attempts.
- After 10 consecutive failures the endpoint is paused; re-enable it in the dashboard.
{
"id": "evt_1842",
"type": "pick.created",
"created_at": "2026-09-15T11:05:12.431Z",
"data": {
"type": "pick.created",
"scope": "US",
"date": "2026-09-15",
"position": 1,
"score": 45.4,
"score_change": 5.2,
"status": "rising",
"signals": {
"chart_momentum": 0,
"demand": 83.1,
"attention": 45.2
},
"why": [
"Lands Sep 19 on Netflix.",
"Demand 83 of 100.",
"On no Top 10 in United States."
],
"strength": "strong",
"premiere": "2026-09-19",
"providers": ["netflix"],
"title": {
"id": "ttl_9q2h7v3zkm1d",
"slug": "obsession-2026",
"name": "Obsession",
"type": "movie",
"year": 2026,
"tmdb_id": 1364532,
"imdb_id": "tt31520893",
"poster_url": "https://image.tmdb.org/t/p/w500/obsession.jpg"
}
}
}import crypto from "node:crypto";
// rawBody must be the exact bytes you received, before JSON.parse.
function verify(rawBody, header, secret) {
const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
const expected = crypto.createHmac("sha256", secret).update(`${parts.t}.${rawBody}`).digest("hex");
const a = Buffer.from(expected, "hex");
const b = Buffer.from(parts.v1 ?? "", "hex");
if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) return false;
// Reject anything older than five minutes.
return Math.abs(Date.now() / 1000 - Number(parts.t)) < 300;
}Slack
One digest post per day per endpoint, with every event since the last post.
Errors
Errors are JSON with a stable code and a human-readable message. They include details.docs_url and, when useful, details.hint with the next legal call.
- invalid_request400
Missing or malformed parameter. details.hint says how to fix it.
- unauthorized401
Malformed or revoked API key. Omit the header for the sample scope.
- plan_required403
The country, provider, or date is outside your plan. details lists allowed values and upgrade_url.
- not_found404
No chart or title for that request. For titles, search GET /v1/titles?q=.
- rate_limited429
Per-minute limit hit. Honor Retry-After. Check X-RateLimit-Reset.
- quota_exceeded429
Monthly request quota hit. Honor Retry-After or upgrade.
- internal_error500
Our fault. Retry with backoff.
Every response carries X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset. 429 responses also send Retry-After.
{
"error": {
"code": "plan_required",
"message": "Country \"JP\" is not included in the sample scope without an API key.",
"details": {
"param": "country",
"requested": "JP",
"allowed_countries": ["US"],
"hint": "Use country=US, or send a key for a plan that includes JP.",
"upgrade_url": "https://streamrank.io/pricing",
"docs_url": "https://streamrank.io/docs.md#authentication"
}
}
}MCP server
Assistants can use StreamRank as a remote MCP server (Streamable HTTP) at https://streamrank.io/mcp. Each tool calls the matching endpoint above.
Clients that support MCP sign-in (Claude, ChatGPT, Claude Code, Cursor, VS Code) ask you to sign in with your StreamRank account the first time. A free account works; tools then use your plan. Clients without sign-in can send Authorization: Bearer sk_live_… or connect to https://streamrank.io/mcp?key=sk_live_…. Treat that URL like the key. Tool calls count toward the same monthly quota as direct API calls.
Tools
- list_coverage
Streaming services StreamRank tracks and the countries each one has a daily Top 10 in.
- get_chart
The daily Top 10 for one streaming service in one country, with rank change, days in the Top 10, and peak rank for each title.
- get_chart_movers
Biggest risers, new entries, and longest streaks on one service's Top 10 in one country.
- get_trending_titles
Titles ranked by demand across services (charts, search, social, and catalog signals), with a status of new, rising, steady, peaking, or fading.
- get_breakouts
StreamRank's daily picks: titles with demand behind them that are not on a streaming Top 10 yet, plus the public hit rate of past picks.
- search_titles
Find a movie or show by name, IMDb id, or TMDB id. Returns ids to pass to get_title.
- get_title
One movie or show: where it is on the Top 10s right now and its chart stats.
- get_title_rankings
Day-by-day Top 10 positions for one title, optionally for one service and country. History depth depends on the plan.
claude mcp add --transport http streamrank https://streamrank.io/mcp