TV show API for series, seasons and episodes

The TV show API returns a series at GET /3/tv/{series_id} with its status, networks, season list and next_episode_to_air. Season and episode endpoints add air dates, runtimes and stills. The JSON matches TMDB v3, in 14 languages, on prepaid plans of 20, 40 or 120 requests per minute.

A TV show API with status, seasons and next episode

GET /3/tv/{series_id} returns a series with its status, networks, seasons list, last_episode_to_air and next_episode_to_air. Season and episode endpoints add air dates, runtimes and stills. amodb is an independent API that speaks the TMDB v3 protocol, so a client written for TMDB works after you change the base URL to https://api.amodb.dev/3.

What you get:

  • Series records with the number of seasons and episodes, plus first and last air dates.
  • A status string and an in_production flag.
  • Networks with ids, logos and origin country.
  • One call per season, returning every episode of that season.
  • Lists of series that air today or within the next 7 days.

What data you get

You needCallKey fields
Series recordGET /3/tv/{series_id}name, original_name, status, in_production, number_of_seasons, number_of_episodes
Next and last episodesame callnext_episode_to_air, last_episode_to_air
One seasonGET /3/tv/{series_id}/season/{season_number}episodes, air_date, poster_path
One episodeGET /3/tv/{series_id}/season/{season_number}/episode/{episode_number}name, overview, runtime, still_path, air_date
A networkGET /3/network/{network_id}name, headquarters, origin_country

The full field lists are on TV series and seasons and episodes.

Start in 3 steps

  1. Open pricing and choose the plan with the request rate you need: 20, 40 or 120 per minute.
  2. Create an API key in your account dashboard.
  3. Send GET /3/tv/{series_id} with Authorization: Bearer YOUR_API_KEY, or add api_key as a query parameter.

Example request

The script reads Breaking Bad (series id 1396), prints its status and next episode, then lists season 1. Save it as check.mjs and run it with Node 18 or newer.

curl -s "https://api.amodb.dev/3/tv/1396?language=en-US&append_to_response=ratings" \
  -H "Authorization: Bearer $AMODB_KEY"

curl -s "https://api.amodb.dev/3/tv/1396/season/1?language=en-US" \
  -H "Authorization: Bearer $AMODB_KEY"
const base = 'https://api.amodb.dev/3';
const headers = { Authorization: `Bearer ${process.env.AMODB_KEY}` };

async function get(path) {
  const res = await fetch(`${base}${path}`, { headers });
  if (!res.ok) throw new Error(`amodb returned ${res.status} for ${path}`);
  return res.json();
}

const show = await get('/tv/1396?language=en-US');
const next = show.next_episode_to_air;
console.log(`${show.name}: ${show.status}, ${show.number_of_seasons} seasons`);
console.log(next
  ? `Next: S${next.season_number}E${next.episode_number} on ${next.air_date}`
  : 'No upcoming episode is scheduled');

const season = await get('/tv/1396/season/1?language=en-US');
for (const ep of season.episodes) {
  console.log(`E${ep.episode_number} ${ep.air_date} ${ep.name}`);
}

A trimmed series reply for language=en-US. Only some fields are kept, and seasons shows its first 2 of 6 entries. Some names do not follow language in this data: the season 0 name is Chinese and the name inside last_episode_to_air is Hebrew.

JSON
{
  "first_air_date": "2008-01-20",
  "id": 1396,
  "in_production": false,
  "last_air_date": "2013-09-29",
  "last_episode_to_air": {
    "air_date": "2013-09-29",
    "episode_number": 16,
    "episode_type": "standard",
    "id": 62161,
    "name": "פלינה",
    "overview": "הסדרה זוכת הפרסים מגיעה לסיום דרמתי בפרק החותם אותה.",
    "production_code": "",
    "runtime": 56,
    "season_number": 5,
    "show_id": 1396,
    "still_path": "/pA0YwyhvdDXP3BEGL2grrIhq8aM.jpg",
    "vote_average": 0,
    "vote_count": 0
  },
  "name": "Breaking Bad",
  "next_episode_to_air": null,
  "number_of_episodes": 62,
  "number_of_seasons": 5,
  "original_name": "Breaking Bad",
  "seasons": [
    {
      "air_date": "2009-02-17",
      "episode_count": 9,
      "id": 3577,
      "name": "特别篇",
      "overview": "",
      "poster_path": "/ikBSCmgG5Z4jequUUAjKpf1QG3T.jpg",
      "season_number": 0,
      "vote_average": 0
    },
    {
      "air_date": "2008-01-20",
      "episode_count": 7,
      "id": 3572,
      "name": "Season 1",
      "overview": "High school chemistry teacher Walter White's life is suddenly transformed by a dire medical diagn...",
      "poster_path": "/91EIXdWxmp2mHNRsSuDW3WyDJLj.jpg",
      "season_number": 1,
      "vote_average": 0
    }
  ],
  "status": "Ended"
}

Reading status and the next episode

The status string tells you how to label a series. next_episode_to_air is an object only while an episode is scheduled, so it is null between seasons as well as after the end. Test status before you show "ended".

statusMeaningWhat to show
Returning SeriesMore episodes are expectedNext air date if the object exists, otherwise "returning"
In ProductionBeing made, not on air yet"In production"
PlannedAnnounced only"Planned"
PilotOnly a pilot exists"Pilot"
EndedThe run is finished"Ended" and last_air_date
CanceledStopped before the planned end"Canceled"

Fields inside next_episode_to_air and last_episode_to_air: air_date, season_number, episode_number, episode_type, id, show_id, name, overview, runtime and still_path. The status string can also be empty on a few titles, so keep a neutral label ready.

Details are cached at the edge for 6 hours, so asking for the same series more than four times a day returns the same body. Poll your followed shows once or twice a day and refresh the one a user opens.

Seasons, episodes and what is on air

Season 0, when a series has one, holds specials. Regular seasons start at 1.

CallReturnsParameters
GET /3/tv/{series_id}/season/{season_number}Season record with an episodes arraylanguage, append_to_response
GET /3/tv/airing_todaySeries with an episode airing todaypage, language
GET /3/tv/on_the_airSeries airing in the coming weekpage, language
GET /3/discover/tvSeries filtered by network, status and morewith_networks, with_status, sort_by, page

Lists and discover results are cached for 30 minutes, so one request per half hour is enough for an "airing soon" badge. Match the returned ids against the series your users follow. Season and episode details are covered on the episode guide page.

Building a follow list with countdowns

A "shows I follow" screen needs one stored id per show and a small daily job.

  1. Save the series id when a user follows a show.
  2. Once a day, call /3/tv/{series_id} for each followed id and store status, next_episode_to_air and last_air_date.
  3. When next_episode_to_air is an object, show air_date as a date. It carries no time of day and no time zone, so do not count down to the minute.
  4. When it is null and status is Returning Series, show "new season not scheduled".
  5. Fetch the season call only when a user opens the show, because it is the largest reply.

A 404 with status_code 34 means the id is unknown, and a 429 means you went over your requests per minute: wait for Retry-After seconds. With 200 followed shows, one daily pass is 200 requests, about ten minutes at 20 requests per minute. See rate limits and errors.

How it compares

CapabilityScrape pages yourselfFree-tier metadata APIamodb
Season and episode structureRebuilt from page layoutsVaries, check the docsSeason call with an episodes array
Next air dateParsed from a schedule pageVaries, check the docsnext_episode_to_air, null when none is scheduled
Show statusFree text on a pageVaries, check the docsstatus string and in_production flag
Airing this weekScrape a scheduleVaries, check the docs/3/tv/on_the_air and /3/tv/airing_today
LanguagesWhatever the page offersVaries14, chosen with language
Access termsThe site's terms applyFree tier with usage termsPaid, prepaid, no free tier

Pricing

Pay once for 1, 3, 6, 12 or 24 months. Longer periods take 10, 20, 30 or 40 percent off, and nothing renews automatically. Every plan gets all TV data, with 20, 40 or 120 requests per minute as the only difference. See pricing, create a key, and your first series call takes one request.

Questions and answers

How do I know if a TV show is still airing?

Read status on /3/tv/{id}. Returning Series means more episodes are expected, while Ended and Canceled mean none. The field next_episode_to_air holds the next scheduled episode and is null when nothing is scheduled.

Can I fetch every episode of a series in one request?

One season per call. GET /3/tv/{id}/season/{n} returns all episodes of that season in an episodes array, so a five season show takes five season calls plus one series call.

What do I get for a network?

The networks array on a series lists id, name, logo_path and origin_country. GET /3/network/{id} adds details, and with_networks in /3/discover/tv lists the series of one network.

Can I list the shows that air today?

Yes. /3/tv/airing_today lists series with an episode airing today and /3/tv/on_the_air covers the next 7 days. Both are paged, take language, and sit in the edge cache for 30 minutes.

Is there a free tier for the TV show API?

No free tier and no trial. You prepay for 1, 3, 6, 12 or 24 months and nothing renews by itself. Every plan returns all data, and plans differ only in requests per minute.