# TV series API, the TV show endpoint

> This TV show API reference covers GET /3/tv/{series_id}, which returns one show by id: names, overview, status, seasons, networks, genres and pointers to the last and next episode. The JSON matches TMDB v3, so existing clients only need a new base URL. Add append_to_response to merge content ratings, credits and ratings into one request.

## Endpoint

`GET /3/tv/{series_id}`

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

Response:

```json
{
  "adult": false,
  "backdrop_path": "/ycFcYYnzVc8mWw41neszGPMyKc3.jpg",
  "created_by": [],
  "episode_run_time": [
    48,
    49
  ],
  "first_air_date": "2008-01-20",
  "genres": [
    {
      "id": 18,
      "name": "Drama"
    },
    {
      "id": 80,
      "name": "Crime"
    }
  ],
  "homepage": "",
  "id": 1396,
  "in_production": false,
  "languages": [
    "en"
  ],
  "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,
  "networks": [
    {
      "id": 174,
      "logo_path": "/pmvRmATOCaDykE6JrVoeYxlFHw3.png",
      "name": "AMC",
      "origin_country": "US"
    }
  ],
  "number_of_episodes": 62,
  "number_of_seasons": 5,
  "origin_country": [
    "US"
  ],
  "original_language": "en",
  "original_name": "Breaking Bad",
  "overview": "Walter White, a New Mexico chemistry teacher, is diagnosed with Stage III cancer and given a prognosis of only two years left to live. He becomes filled with a sense of fearlessness and an unrelenting desire to secure his family's financial...",
  "popularity": 268.4968,
  "poster_path": "/anFx9aTOOYqgS3v7x3R84Kz67ly.jpg",
  "production_companies": [
    {
      "id": 2605,
      "logo_path": null,
      "name": "Gran Via Productions",
      "origin_country": "US"
    },
    {
      "id": 11073,
      "logo_path": "/wHs44fktdoj6c378ZbSWfzKsM2Z.png",
      "name": "Sony Pictures Television",
      "origin_country": "US"
    },
    {
      "id": 33742,
      "logo_path": "/2jdh2sEa0R6y6uT0F7g0IgA2WO8.png",
      "name": "High Bridge Productions",
      "origin_country": "US"
    }
  ],
  "production_countries": [
    {
      "iso_3166_1": "US",
      "name": "United States of America"
    }
  ],
  "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 diagnosis. Street-savvy former student Jesse Pinkman \"teaches\" Walter a new trade.",
      "poster_path": "/91EIXdWxmp2mHNRsSuDW3WyDJLj.jpg",
      "season_number": 1,
      "vote_average": 0
    },
    {
      "air_date": "2009-03-08",
      "episode_count": 13,
      "id": 3573,
      "name": "第 2 季",
      "overview": "贩卖冰毒的沃尔特老师在毒品交易中越陷越深，这引起了竞争对手的注意并使他在缉毒局的小舅子陷入危险中。",
      "poster_path": "/zMO024gJxKhTJfWqM0XTYd3SgKj.jpg",
      "season_number": 2,
      "vote_average": 0
    }
  ],
  "spoken_languages": [
    {
      "english_name": "English",
      "iso_639_1": "en",
      "name": "English"
    },
    {
      "english_name": "Spanish",
      "iso_639_1": "es",
      "name": "Español"
    }
  ],
  "status": "Ended",
  "tagline": "Change the equation.",
  "vote_average": 8.955,
  "vote_count": 18871
}
```

## Get TV series details

The TV series API call `GET /3/tv/{series_id}` returns the core record for one show: names, overview, status, genres, networks, the list of seasons and pointers to the last and next episode. The id is the numeric TMDB tv id, so a show you store as `1396` keeps that id here. Movie ids and TV ids are separate spaces, so always store the media type next to the number.

The example asks for Breaking Bad in English and appends its content ratings and external scores in the same call.

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

```js
const params = new URLSearchParams({ language: 'en-US', append_to_response: 'content_ratings,ratings' });
const res = await fetch(`https://api.amodb.dev/3/tv/1396?${params}`, {
  headers: { Authorization: `Bearer ${process.env.AMODB_KEY}` },
});
if (!res.ok) throw new Error(`amodb returned ${res.status}`);
const show = await res.json();
const us = show.content_ratings.results.find((r) => r.iso_3166_1 === 'US');
console.log(show.name, show.status, show.number_of_seasons, us?.rating);
```

```python
import os
import requests

r = requests.get(
    "https://api.amodb.dev/3/tv/1396",
    params={"language": "en-US", "append_to_response": "content_ratings,ratings"},
    headers={"Authorization": f"Bearer {os.environ['AMODB_KEY']}"},
    timeout=10,
)
r.raise_for_status()
show = r.json()
us = next((x for x in show["content_ratings"]["results"] if x["iso_3166_1"] == "US"), None)
print(show["name"], show["status"], show["number_of_seasons"], us and us["rating"])
```

```php
<?php
$url = 'https://api.amodb.dev/3/tv/1396?' . http_build_query([
    'language' => 'en-US',
    'append_to_response' => 'content_ratings,ratings',
]);
$ch = curl_init($url);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 10,
    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('AMODB_KEY')],
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status !== 200) {
    throw new RuntimeException("amodb returned $status");
}
$show = json_decode($body, true);
echo $show['name'], ' ', $show['status'], ' ', $show['number_of_seasons'], PHP_EOL;
```

```go
package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"net/url"
	"os"
	"time"
)

type Show struct {
	Name             string `json:"name"`
	Status           string `json:"status"`
	NumberOfSeasons  int    `json:"number_of_seasons"`
	NumberOfEpisodes int    `json:"number_of_episodes"`
	Next             *struct {
		AirDate string `json:"air_date"`
	} `json:"next_episode_to_air"`
}

func main() {
	q := url.Values{"language": {"en-US"}}
	req, _ := http.NewRequest("GET", "https://api.amodb.dev/3/tv/1396?"+q.Encode(), nil)
	req.Header.Set("Authorization", "Bearer "+os.Getenv("AMODB_KEY"))
	client := &http.Client{Timeout: 10 * time.Second}
	res, err := client.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	if res.StatusCode != http.StatusOK {
		panic(res.Status)
	}
	var s Show
	if err := json.NewDecoder(res.Body).Decode(&s); err != nil {
		panic(err)
	}
	next := "none scheduled"
	if s.Next != nil {
		next = s.Next.AirDate
	}
	fmt.Println(s.Name, s.Status, s.NumberOfSeasons, s.NumberOfEpisodes, next)
}
```

### Parameters

| Parameter            | In    | Required   | Description                                                                                  |
| -------------------- | ----- | ---------- | -------------------------------------------------------------------------------------------- |
| `series_id`          | path  | yes        | Numeric TV id, for example `1396`.                                                           |
| `api_key`            | query | one of two | Your key. Use this or the `Authorization: Bearer` header.                                    |
| `language`           | query | no         | TMDB tag such as `en-US`, `uk-UA` or `es-ES`. 14 base languages are served. Default `en-US`. |
| `append_to_response` | query | no         | Comma separated list of sub-resources to merge into the reply, up to 20 values.              |

### Response fields

| Field                                              | Type            | Notes                                                                                                                              |
| -------------------------------------------------- | --------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `id`                                               | integer         | TV id.                                                                                                                             |
| `name`, `original_name`                            | string          | Localized and original title. Original names in Japanese or Korean stay in `original_name`.                                        |
| `overview`, `tagline`                              | string          | Localized text, empty when no translation exists.                                                                                  |
| `first_air_date`, `last_air_date`                  | string or null  | `YYYY-MM-DD`.                                                                                                                      |
| `status`                                           | string          | Lifecycle, see the table below.                                                                                                    |
| `in_production`                                    | boolean         | `true` while the show is still being made.                                                                                         |
| `number_of_seasons`, `number_of_episodes`          | integer         | Totals, as stored for the show.                                                                                                    |
| `episode_run_time`                                 | array           | Typical episode lengths in minutes, may be empty.                                                                                  |
| `seasons`                                          | array           | One summary per season with `id`, `season_number`, `name`, `overview`, `episode_count`, `air_date`, `poster_path`, `vote_average`. |
| `last_episode_to_air`, `next_episode_to_air`       | object or null  | Episode summaries, shaped like the objects on [seasons and episodes](https://amodb.dev/tv-seasons-episodes/).                      |
| `networks`, `production_companies`                 | array           | `id`, `name`, `logo_path`, `origin_country`.                                                                                       |
| `production_countries`, `spoken_languages`         | array           | Countries with `iso_3166_1` and `name`. Languages with `english_name`, `iso_639_1` and `name`.                                     |
| `created_by`                                       | array           | Creators with `id`, `name`, `profile_path` and `credit_id`. Empty for most series.                                                 |
| `genres`                                           | array           | Objects with `id` and `name`. TV genre ids differ from movie ids.                                                                  |
| `origin_country`, `original_language`, `languages` | array, string   | Country codes and language codes.                                                                                                  |
| `homepage`                                         | string          | Official site, empty when unknown.                                                                                                 |
| `poster_path`, `backdrop_path`                     | string or null  | Append to `https://img.amodb.dev/t/p/{size}`. See [images](https://amodb.dev/images-api/).                                         |
| `popularity`                                       | number          | Relative score used by the popular list.                                                                                           |
| `vote_average`, `vote_count`                       | number, integer | Aggregate user score.                                                                                                              |
| `adult`                                            | boolean         | Always `false`. Adult titles are never served.                                                                                     |

### Example response

`GET /3/tv/1396?language=en-US&append_to_response=content_ratings,ratings`, with long arrays and text shortened:

```json
{
  "adult": false,
  "backdrop_path": "/ycFcYYnzVc8mWw41neszGPMyKc3.jpg",
  "created_by": [],
  "episode_run_time": [
    48,
    49
  ],
  "first_air_date": "2008-01-20",
  "genres": [
    {
      "id": 18,
      "name": "Drama"
    },
    {
      "id": 80,
      "name": "Crime"
    }
  ],
  "homepage": "",
  "id": 1396,
  "in_production": false,
  "languages": [
    "en"
  ],
  "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,
  "networks": [
    {
      "id": 174,
      "logo_path": "/pmvRmATOCaDykE6JrVoeYxlFHw3.png",
      "name": "AMC",
      "origin_country": "US"
    }
  ],
  "number_of_episodes": 62,
  "number_of_seasons": 5,
  "origin_country": [
    "US"
  ],
  "original_language": "en",
  "original_name": "Breaking Bad",
  "overview": "Walter White, a New Mexico chemistry teacher, is diagnosed with Stage III cancer and given a prognosis of o...",
  "popularity": 268.4968,
  "poster_path": "/anFx9aTOOYqgS3v7x3R84Kz67ly.jpg",
  "production_companies": [
    {
      "id": 2605,
      "logo_path": null,
      "name": "Gran Via Productions",
      "origin_country": "US"
    },
    {
      "id": 11073,
      "logo_path": "/wHs44fktdoj6c378ZbSWfzKsM2Z.png",
      "name": "Sony Pictures Television",
      "origin_country": "US"
    }
  ],
  "production_countries": [
    {
      "iso_3166_1": "US",
      "name": "United States of America"
    }
  ],
  "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 diagnosis. Stre...",
      "poster_path": "/91EIXdWxmp2mHNRsSuDW3WyDJLj.jpg",
      "season_number": 1,
      "vote_average": 0
    }
  ],
  "spoken_languages": [
    {
      "english_name": "English",
      "iso_639_1": "en",
      "name": "English"
    },
    {
      "english_name": "Spanish",
      "iso_639_1": "es",
      "name": "Español"
    }
  ],
  "status": "Ended",
  "tagline": "Change the equation.",
  "vote_average": 9,
  "vote_count": 18863,
  "content_ratings": {
    "results": [
      {
        "descriptors": [],
        "iso_3166_1": "AT",
        "rating": "16"
      },
      {
        "descriptors": [],
        "iso_3166_1": "AU",
        "rating": "MA 15+"
      }
    ]
  },
  "ratings": {
    "imdb": {
      "value": 9.5,
      "votes": 2671962
    },
    "kinopoisk": {
      "value": 8.9,
      "votes": null
    },
    "metacritic": null,
    "rotten_tomatoes": {
      "value": 96,
      "votes": null
    },
    "tmdb": {
      "value": 9,
      "votes": 18863
    }
  }
}
```

The `content_ratings` and `ratings` blocks come from `append_to_response`. Names and overviews inside `seasons`, `last_episode_to_air` and `next_episode_to_air` are stored per record and may not follow `language`, as the Hebrew episode name above shows. Read localized season and episode text from the [season endpoint](https://amodb.dev/tv-seasons-episodes/).

## Status and episode pointers

`status` tells you where a show is in its life, and `next_episode_to_air` tells you when to look again.

| `status` value             | Meaning                        | `next_episode_to_air`                     |
| -------------------------- | ------------------------------ | ----------------------------------------- |
| `Returning Series`         | Airing now or between seasons. | Set when a date is known, otherwise null. |
| `Planned`, `In Production` | Not yet a regular series.      | Usually null.                             |
| `Ended`                    | Finished its run.              | Null.                                     |
| `Canceled`                 | Stopped before a planned end.  | Null.                                     |

A returning series between seasons has a null `next_episode_to_air`, so read null as "no date known" and not as "finished".

The `seasons` array lists one summary per season, and season `0` holds specials. To read the episodes of a season, call the endpoint on [seasons and episodes](https://amodb.dev/tv-seasons-episodes/). It works as the episode API: it lists the episodes of one season. For an overview of series, seasons and episodes together, see the [TV show API](https://amodb.dev/tv-show-api/) page.

## Related series endpoints

All paths share the base `https://api.amodb.dev/3`, and endpoints with localized text also take `language`.

| Method and path                          | Returns                                                         | Extra parameters |
| ---------------------------------------- | --------------------------------------------------------------- | ---------------- |
| `GET /tv/{series_id}/alternative_titles` | `{id, results}` with `iso_3166_1`, `title`, `type`, often empty | none             |
| `GET /tv/{series_id}/content_ratings`    | Age rating per country                                          | none             |
| `GET /tv/{series_id}/episode_groups`     | List of alternative episode orderings such as DVD or story arc  | none             |
| `GET /tv/{series_id}/recommendations`    | A list of 20 recommended shows                                  | none             |
| `GET /tv/{series_id}/similar`            | A list of 20 similar shows                                      | none             |
| `GET /tv/{series_id}/reviews`            | `results` is empty for most series                              | none             |
| `GET /tv/{series_id}/lists`              | Public lists that contain the show                              | `page`           |
| `GET /tv/{series_id}/watch/providers`    | Streaming, rental and purchase providers per country            | none             |
| `GET /tv/latest`                         | The newest series record added                                  | none             |

The recommendations and similar lists always return page 1 with 20 items. The `lists` reply is paged with `page`, 20 lists per page. Paged lists elsewhere on the API take `page` from 1 to 500.

Content ratings come back as `results` entries with `iso_3166_1`, `rating` and `descriptors`, so pick the entry that matches the viewer's country. Watch providers are keyed by country code, and each country holds a `link` plus `flatrate`, `rent` and `buy` lists with `provider_id`, `provider_name`, `logo_path` and `display_priority`. Provider ids for filtering come from the lookup lists on [genres and lookup lists](https://amodb.dev/genres/).

The episode groups list returns `id` (a string), `name`, `description`, `type`, `episode_count`, `group_count` and `network`. amodb lists the groups but does not offer an endpoint that returns the episodes of one group. It also does not offer the TMDB `changes` paths.

## Merge more data into one call

List sub-resources in `append_to_response` and each arrives under its own key. The whole call counts once against your 20, 40 or 120 requests per minute. Up to 20 values work, and unknown names are ignored without an error. These values work on a series:

| Value                                                                                                                          | Adds                                               | Details                                                                                                                                                            |
| ------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `credits`                                                                                                                      | Cast and crew                                      | [Credits](https://amodb.dev/credits/)                                                                                                                              |
| `external_ids`                                                                                                                 | Ids such as `imdb_id`, `tvdb_id` and `wikidata_id` | [Find by external id](https://amodb.dev/find-by-external-id/)                                                                                                      |
| `images`, `videos`                                                                                                             | Posters, backdrops, trailers                       | [Images](https://amodb.dev/images-api/), [Videos](https://amodb.dev/videos-trailers/)                                                                              |
| `keywords`, `translations`                                                                                                     | Tags and translated texts                          | [Keywords](https://amodb.dev/keywords/), [Translations](https://amodb.dev/translations/)                                                                           |
| `content_ratings`, `alternative_titles`, `episode_groups`, `lists`, `watch/providers`, `similar`, `recommendations`, `reviews` | The sub-resources in the table above               | This page                                                                                                                                                          |
| `ratings`, `moods`, `soundtracks`, `wikidata`, `showtimes`                                                                     | amodb extras                                       | [Ratings](https://amodb.dev/ratings/), [Moods](https://amodb.dev/moods/), [Soundtracks](https://amodb.dev/soundtracks/), [Showtimes](https://amodb.dev/showtimes/) |

## Errors

A failed call returns the TMDB error body. A wrong id gives `status_code` 34 with the message "The resource you requested could not be found."

| HTTP | status_code | When                                                                   |
| ---- | ----------- | ---------------------------------------------------------------------- |
| 401  | 7           | The key is missing or wrong.                                           |
| 402  | 36          | The plan period has ended.                                             |
| 404  | 34          | No series with that id, an adult title, or a path that is not offered. |
| 405  | 37          | You called a write method such as rating a show.                       |
| 429  | 25          | Over your requests per minute. Wait for the `Retry-After` seconds.     |

The full list is on [errors](https://amodb.dev/errors/), and limits per plan are on [rate limits](https://amodb.dev/rate-limits/).

## Practical notes

- Series details and every sub-resource above are cached for 6 hours. Poll `last_episode_to_air` no more than a few times a day.
- Request the language you display. An empty `overview` means no translation exists, so re-request with `en-US` for a fallback.
- Use `number_of_seasons` as the loop bound when you fetch every season, one call each.
- To list shows instead of reading one, see [search](https://amodb.dev/search/), [discover](https://amodb.dev/discover/) and [trending and lists](https://amodb.dev/trending-lists/).

## Questions and answers

### How do I know whether a series is still airing?

Read status together with next_episode_to_air. A returning series with a non-null next_episode_to_air has an episode scheduled. Ended and canceled series always return null there, and a show between seasons can too.

### Does the series record include an IMDb id?

Not in the base record, as in TMDB. Add append_to_response=external_ids to get imdb_id and tvdb_id, or call the find endpoint with an IMDb id to go from an external id to the series id.

### Can I get IMDb and Rotten Tomatoes scores for a show?

Yes. Call GET /3/tv/{series_id}/ratings or add append_to_response=ratings. You get IMDb, Kinopoisk, Metacritic, Rotten Tomatoes and TMDB scores, each as value and votes, or null when the score is not known.

### How long is TV data cached?

Series details and their sub-resources are cached at the edge for 6 hours, so a freshly aired episode can show up in last_episode_to_air with that delay. Lists such as on the air are cached for 30 minutes.

## Related pages

- [TV seasons and episodes API](https://amodb.dev/tv-seasons-episodes/): TV seasons and episodes API with the same paths and JSON as TMDB v3. Read a season with all its episodes, or one episode with air date, runtime and still.
- [Credits API](https://amodb.dev/credits/): Credits API with the same paths and JSON as TMDB v3. Get cast and crew for movies, series, seasons and episodes, with order, department and job fields.
- [Movie and TV ratings](https://amodb.dev/ratings/): Movie ratings API that returns IMDb, Kinopoisk, Metacritic, Rotten Tomatoes and TMDB scores for a title in one call, with null for any source not known.
- [TV show API for series, seasons and episodes](https://amodb.dev/tv-show-api/): TV show API with series status, networks, seasons, episodes and next_episode_to_air. TMDB v3 compatible JSON in 14 languages, from 20 requests per minute.
- [Errors](https://amodb.dev/errors/): Every amodb error with its HTTP status, TMDB status_code and message, plus the OMDb error shape. What each one means and what your client should do next.
- [Quickstart](https://amodb.dev/quickstart/): Make your first amodb call: get a key, request movie details in curl, JavaScript, Python, PHP or Go, then load the poster from img.amodb.dev. Under 2 minutes.

Updated: 2026-10-19. Source: https://amodb.dev/tv-series/
