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. 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. 2

    Get a key

    Create a free account for a live key with every country, provider, and 7 days of history.

  3. 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"
200 OK
{
  "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_xxxxxxxxxxxxxxxxxxxxxxxx

Plans and limits

PlanCountriesProvidersHistoryTrending listRequests / moAlerts
FreeAllAll7 daysTop 103,000None
ProAllAll30 daysTop 10050,0003 titles, email
IntelligenceAllAllFullTop 100200,000200 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.

GET/v1/charts?provider=netflix&country=US
curl "https://streamrank.io/v1/charts?provider=netflix&country=US"
Response
Run a request to see the response.

Breakouts

Breakout picks

GET/v1/trending/breakouts

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 why and, once it charts within 30 days, outcome.
  • track_record is 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 in meta.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. movie returns 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 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 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

      strong for a launch (a release inside 3 days or in the 14 days before the pick), watch for 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 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. outcome can 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 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 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

      tv and movie, each with the same fields and its own control. Movies are logged but not published; their record lives here.

    • by_strengthobject

      strong and watch: the published calls split by strength, with the same fields. Pool fields repeat the whole pool.

Show meta fields
  • countinteger

    Items returned.

  • limit_maxinteger

    Largest limit your 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"
200 OK
{
  "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

GET/v1/trending/breakouts/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.

  • from is clamped to your plan's history window.
  • Page with limit and offset against meta.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. movie returns 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 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 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

      strong for a launch (a release inside 3 days or in the 14 days before the pick), watch for 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 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. outcome can 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 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 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"
200 OK
{
  "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

GET/v1/charts

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 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 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"
200 OK
{
  "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

Get a title

GET/v1/titles/{id}

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 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 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"
200 OK
{
  "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

GET/v1/titles/{id}/rankings

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 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"
200 OK
{
  "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
  }
}

Catalog

Countries

GET/v1/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"
200 OK
{
  "data": [
    {
      "code": "US",
      "name": "United States",
      "providers": [
        "netflix",
        "prime",
        "disney",
        "max",
        "hulu",
        "apple",
        "paramount",
        "peacock",
        "starz"
      ],
      "included_in_plan": true
    }
  ]
}

Providers

GET/v1/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"
200 OK
{
  "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, each provider, 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

POSTyour endpoint URL

One POST per event with a JSON body. data is the payload for the event type.

Headers
X-StreamRank-Signature: t=<unix seconds>,v1=<hex>
X-StreamRank-Event: pick.created
X-StreamRank-Delivery: dlv_1842

Verify the signature

  • v1 is 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.
POST body
{
  "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"
    }
  }
}
Verify in Node
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.

403 Forbidden
{
  "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