API documentation
One REST API for daily Top 10 rankings across every major streaming provider and country. Plain JSON, human-readable identifiers, cache-friendly responses.
Base URL
https://streamrank.io/v1
Format
JSON over HTTPS
Auth
Bearer API key
Quickstart
- Create an account. You receive a live key and a test key immediately.
- Make your first request:
curl "https://streamrank.io/v1/charts?provider=netflix&country=US&type=movie" \
-H "Authorization: Bearer sk_live_…"You get the current Netflix Top 10 movies in the United States:
{
"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"
}
}
]
}
}Charts update once a day. Cache responses as long as you like. We meter dataset access (countries, providers, history), not how often you fetch.
Authentication
Send your key in the Authorization header. Live keys start with sk_live_ and count toward your plan. Test keys start with sk_test_, return real data in the free scope, and never count toward quota.
Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxxRequests without a key work in the free scope (United States; Netflix; current charts) at 10 requests per minute and 200 per calendar month per IP, so you can try the API before signing up.
| Plan | Countries | Providers | History | Trending list | Requests / mo |
|---|---|---|---|---|---|
| Free | US | netflix | Current only | Top 10 | 1,000 |
| Developer | All | All | 30 days | Top 100 | 50,000 |
| Pro | All | All | Full | Top 100 | 500,000 |
| Business | All | All | Full | Top 100 | 5,000,000 |
Playground
Real requests against the live API. Runs in the free scope until you add a key.
Without a key, requests use the free scope: United States; Netflix; current charts.
/v1/charts?provider=prime&country=FRcurl "https://streamrank.io/v1/charts?provider=prime&country=FR"Run a request to see the response.Charts
The Top 10 for one provider in one country. Omit type to receive both the movie and TV charts in one response.
| provider | string | Required. netflix, prime, disney, max, hulu, apple, paramount, peacock. |
| country | string | Required. ISO 3166-1 alpha-2, e.g. US, GB, JP. |
| type | movie | tv | Optional. Return one chart instead of both. |
| date | YYYY-MM-DD | Optional. A past chart. Resolves to the newest chart on or before the date. Requires history on your plan. |
| limit | 1–10 | Optional. Return only the top N. |
GET /v1/charts?provider=netflix&country=US&type=movie
GET /v1/charts?provider=netflix&country=JP&type=tv
GET /v1/charts?provider=disney&country=GB
GET /v1/charts?provider=max&country=US&type=tv&date=2026-09-01Ranking fields
| rank | integer | Position on the chart, 1–10. |
| previous_rank | integer | null | Rank the day before, or null if the title was not on yesterday's chart. |
| rank_change | integer | null | previous_rank − rank. Positive means it moved up. |
| is_new | boolean | True on the first day a title appears on this chart. |
| days_in_top_10 | integer | Total days on this chart, including today. |
| peak_rank | integer | Best rank so far on this chart. |
| first_charted_at | date | First day on this chart. |
| title | object | Canonical title: id, slug, name, type, year, tmdb_id, imdb_id, poster_url. |
We compute the derived metrics from our own stored history, so they cover the days we have collected.
Titles
Look up a title by name, IMDb id, or TMDB id. Returns a ranked list; ambiguous names are not a 404. Then call /v1/titles/{id} for current positions.
| q | string | Name, slug, ttl_ id, IMDb id, or TMDB id. Required unless imdb_id or tmdb_id is set. |
| imdb_id | string | Exact IMDb id, e.g. tt4574334. |
| tmdb_id | integer | Exact TMDB id. Pass type when a movie and a show share the number. |
| type | movie | tv | Optional. Restrict results to one kind. |
| year | integer | Optional. Prefer titles released this year when matching by name. |
| limit | 1–20 | Optional. Default 10. |
GET /v1/titles?q=The+Pitt
GET /v1/titles?imdb_id=tt4574334
GET /v1/titles?tmdb_id=1396&type=tv
GET /v1/titles?q=Ready+or+Not&year=2019{
"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
}
}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. Accepts a title id (ttl_…), slug, IMDb id, or TMDB id.
GET /v1/titles/ttl_5k2m9x1qzc7v
GET /v1/titles/the-whisper-man-2026
GET /v1/titles/tt11561116Day-by-day ranking history for a title, newest first, clamped to your plan's history window.
| provider | string | Optional filter. |
| country | string | Optional filter. |
| from | YYYY-MM-DD | Optional start date. |
| to | YYYY-MM-DD | Optional end date. |
| limit | 1–5000 | Optional. Default 1000. |
{
"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
Provider-scoped signals from today's movie and TV charts: biggest_risers, new_entries, and longest_streaks. There is deliberately no cross-provider ranking: a #1 on Apple TV+ and a #5 on Netflix are not comparable.
| provider | string | Required. |
| country | string | Required. ISO 3166-1 alpha-2. |
| limit | 1–20 | Optional. Items per bucket, default 5. |
GET /v1/trending?provider=netflix&country=USTrending titles
One list that ranks titles across every service by a single trend score, 0–100. Three categories feed it: 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), and attention (broad web attention, worldwide). Omit country for the global list; a country scope weights that country's Top 10 charts and discovery rankings, while first-party demand and attention stay worldwide. The score is daily. First-party demand counts cover the last complete day, attention is discounted when it is flat, and titles seen only by attention rank after titles with chart or demand presence.
| country | string | Optional. ISO 3166-1 alpha-2. Omit it for the global list. A country scope weights that country's Top 10 charts and that country's discovery rankings; first-party demand and attention stay worldwide. |
| type | movie | tv | Optional. Restrict the list to movies or to shows. |
| status | new | rising | steady | peaking | fading | Optional. Keep only titles with this status. |
| limit | 1–100 | Optional. Default 10. Capped by your plan: 10 on Free, 100 on paid plans. |
| date | YYYY-MM-DD | Optional. A past list. Resolves to the newest list on or before the date. Requires history on your plan. |
GET /v1/trending/titles
GET /v1/trending/titles?country=US&type=tv
GET /v1/trending/titles?status=rising&limit=25
GET /v1/trending/titles?country=GB&date=2026-09-10{
"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
}
}Trend fields
| rank | integer | Position on the trending list for this scope and day. |
| previous_rank | integer | null | Trending rank the day before, or null if the title was not on yesterday's list. |
| rank_change | integer | null | previous_rank − rank. Positive means it moved up. |
| score | number | Trend score, 0–100. Relative to every other title scored in the same scope on the same day. |
| previous_score | number | null | Yesterday's score in this scope, or null. |
| score_change | number | null | score − previous_score, one decimal place. |
| status | new | rising | steady | peaking | fading | `new`: first day on this list. `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_count | integer | 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_charts | array | Today's chart positions: provider, country, type, rank. Filtered to the countries and providers your plan includes, so it can be shorter than chart_count. |
| signals | object | `chart_momentum`, `demand`, and `attention`, each 0–100 or null when that category had no data that day. chart_momentum is position, breadth, and movement across Top 10 charts inside the scope. demand is 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. attention is broad web attention, worldwide, discounted when it is 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. |
| title | object | Canonical title: id, slug, name, type, year, tmdb_id, imdb_id, poster_url. |
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.
| country | string | Optional. ISO 3166-1 alpha-2. Omit it for the global scope. |
| from | YYYY-MM-DD | Optional start date. Clamped to your plan's history window. |
| to | YYYY-MM-DD | Optional end date. |
| limit | 1–365 | Optional. Days of history, default 90. |
{
"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
}
}Countries
Every country with chart data and the providers available in each, plus whether your plan includes it.
{
"data": [
{
"code": "US",
"name": "United States",
"providers": [
"netflix",
"prime",
"disney",
"max",
"hulu",
"apple",
"paramount",
"peacock"
],
"included_in_plan": true
}
]
}Providers
{
"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
}
]
}Errors
Errors are JSON with a stable code and a human-readable message.
{
"error": {
"code": "plan_required",
"message": "Country \"JP\" is not included in the Free plan.",
"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"
}
}
}| 400 invalid_request | Missing or malformed parameter. details.hint says how to fix it. | |
| 401 unauthorized | Malformed or revoked API key. Omit the header for the free anonymous scope. | |
| 403 plan_required | The country, provider, or date is outside your plan. details lists allowed values and upgrade_url. | |
| 404 not_found | No chart or title for that request. For titles, search GET /v1/titles?q=. | |
| 429 rate_limited | Per-minute limit hit. Honor Retry-After. Check X-RateLimit-Reset. | |
| 429 quota_exceeded | Monthly request quota hit. Honor Retry-After or upgrade. | |
| 500 internal_error | Our fault. Retry with backoff. |
Every response carries X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset. 429 responses also send Retry-After. Errors include details.docs_url and, when useful, details.hint with the next legal call.
SDKs
The API is plain HTTP, so any client works. Official SDKs are coming; until then:
const res = await fetch(
"https://streamrank.io/v1/charts?provider=netflix&country=US&type=movie",
{ headers: { Authorization: `Bearer ${process.env.STREAMRANK_KEY}` } }
);
const { data } = await res.json();
console.log(data.rankings[0].title.name);import os, requests
r = requests.get(
"https://streamrank.io/v1/charts",
params={"provider": "netflix", "country": "US", "type": "movie"},
headers={"Authorization": f"Bearer {os.environ['STREAMRANK_KEY']}"},
)
for item in r.json()["data"]["rankings"]:
print(item["rank"], item["title"]["name"])