# 剧集指南 API

> 剧集指南 API 通过 GET /3/tv/{tv_id}/season/{season_number} 列出全部剧集，含名称、简介、播出日期、时长和剧照。episode_groups 列出 DVD 等其他排序。路径和 JSON 与 TMDB v3 一致。

## 获取一季的所有剧集

`GET /3/tv/{tv_id}/season/{season_number}` 返回一季及其完整的 `episodes` 数组。每一集都有 `episode_number`、`name`、`overview`、`air_date`、`runtime` 和 `still_path`。ID 是 TMDB 使用的数字 ID，例如 `1396` 对应《绝命毒师》。

你会得到季、带日期和时长的剧集、剧照、一部剧最近和下一次播出的剧集，以及其他剧集排序的列表。文本字段遵循 `language` 参数，没有译文时简介保持为空。

## 可获取的数据

| 接口                                                                  | 返回内容                                                                                  |
| ------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| `GET /3/tv/{tv_id}`                                                 | `seasons` 摘要、`number_of_seasons`、`status`、`next_episode_to_air`、`last_episode_to_air` |
| `GET /3/tv/{tv_id}/season/{season_number}`                          | 一季及其全部 `episodes`                                                                     |
| `GET /3/tv/{tv_id}/season/{season_number}/episode/{episode_number}` | 一集，含 `crew` 和 `guest_stars`                                                           |
| `GET /3/tv/{tv_id}/episode_groups`                                  | 该剧定义的每种其他排序的名称、`type` 和集数                                                             |

剧集的字段：

| 字段                               | 类型             | 说明                                                              |
| -------------------------------- | -------------- | --------------------------------------------------------------- |
| `id`、`show_id`                   | integer        | 剧集 ID 和电视剧 ID。`show_id` 出现在季列表和 `next_episode_to_air` 中，不在单集路径上 |
| `episode_number`、`season_number` | integer        | 在季中的位置                                                          |
| `episode_type`                   | string         | 例如 `standard`                                                   |
| `name`、`overview`                | string         | 随 `language` 本地化                                                |
| `air_date`                       | string 或 null  | `YYYY-MM-DD`，未公布时为空或 null                                       |
| `runtime`                        | integer 或 null | 分钟                                                              |
| `still_path`                     | string 或 null  | 拼接到 `https://img.amodb.dev/t/p/{size}`                          |
| `vote_average`、`vote_count`      | number、integer | 目前在剧集上为 `0`                                                     |
| `production_code`                | string         | 制作公司的代码，常为空                                                     |
| `crew`、`guest_stars`             | array          | 该集署名的人员，字段与演员条目相同                                               |

## 三步开始

1. 在[定价](https://amodb.dev/zh/pricing/)页选择套餐。所有套餐返回相同的剧集数据，区别只在于请求速率。
2. 在账户后台创建密钥，并保存到环境变量中。
3. 请求 `/3/tv/{tv_id}/season/1`，密钥通过 Bearer 请求头或 `api_key` 传递。

## 请求示例

示例以英语获取《绝命毒师》（剧集 ID `1396`）的第 1 季。Go 程序把它解码为带类型的结构体，并为每一集打印一行，包含播出日期、时长和剧照 URL。

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

```go
package main

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

type Episode struct {
	EpisodeNumber int     `json:"episode_number"`
	Name          string  `json:"name"`
	AirDate       string  `json:"air_date"`
	Runtime       int     `json:"runtime"`
	StillPath     *string `json:"still_path"`
}

type Season struct {
	Name         string    `json:"name"`
	SeasonNumber int       `json:"season_number"`
	Episodes     []Episode `json:"episodes"`
}

func main() {
	client := &http.Client{Timeout: 10 * time.Second}
	url := "https://api.amodb.dev/3/tv/1396/season/1?language=en-US"
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("AMODB_KEY"))
	res, err := client.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	if res.StatusCode != http.StatusOK {
		panic(fmt.Sprintf("amodb returned %s", res.Status))
	}
	var season Season
	if err := json.NewDecoder(res.Body).Decode(&season); err != nil {
		panic(err)
	}
	fmt.Println(season.Name)
	for _, e := range season.Episodes {
		still := "no still"
		if e.StillPath != nil {
			still = "https://img.amodb.dev/t/p/w300" + *e.StillPath
		}
		fmt.Printf("S%02dE%02d  %s  %3d min  %s  %s\n",
			season.SeasonNumber, e.EpisodeNumber, e.AirDate, e.Runtime, e.Name, still)
	}
}
```

精简响应：7 集中的 2 集，每集各带一名幕后人员和一名客串演员。

```json
{
  "air_date": "2008-01-20",
  "episodes": [
    {
      "air_date": "2008-01-20",
      "episode_number": 1,
      "episode_type": "standard",
      "id": 62085,
      "name": "Pilot",
      "overview": "When an unassuming high school chemistry teacher discovers he has a rare form...",
      "production_code": "",
      "runtime": 59,
      "season_number": 1,
      "show_id": 1396,
      "still_path": "/ydlY3iPfeOAvu8gVqrxPoMvzNCn.jpg",
      "vote_average": 0,
      "vote_count": 0,
      "crew": [
        {
          "department": "Camera",
          "job": "Director of Photography",
          "credit_id": "52b7029219c29533d00dd2c1",
          "adult": false,
          "gender": 2,
          "id": 2483,
          "known_for_department": "Camera",
          "name": "约翰·托尔",
          "original_name": "约翰·托尔",
          "popularity": 1.1957,
          "profile_path": "/cfL9A6tC7L5Ps5fq1o3WpVKGMb1.jpg"
        }
      ],
      "guest_stars": [
        {
          "character": "Steven Gomez",
          "credit_id": "5271b489760ee35b3e0881a7",
          "order": 8,
          "adult": false,
          "gender": 2,
          "id": 61535,
          "known_for_department": "Acting",
          "name": "史蒂文·迈克尔·奎扎达",
          "original_name": "史蒂文·迈克尔·奎扎达",
          "popularity": 1.7511,
          "profile_path": "/pVYrDkwI6GWvCNL2kJhpDJfBFyd.jpg"
        }
      ]
    },
    {
      "air_date": "2008-01-27",
      "episode_number": 2,
      "episode_type": "standard",
      "id": 62086,
      "name": "Cat's in the Bag...",
      "overview": "Walt and Jesse attempt to tie up loose ends. The desperate situation gets mor...",
      "production_code": "",
      "runtime": 49,
      "season_number": 1,
      "show_id": 1396,
      "still_path": "/AbMoecO0ZZio0LcgeLxlzdyGs6X.jpg",
      "vote_average": 0,
      "vote_count": 0,
      "crew": [
        {
          "department": "Camera",
          "job": "Director of Photography",
          "credit_id": "52b7049c19c2953b63015013",
          "adult": false,
          "gender": 2,
          "id": 17948,
          "known_for_department": "Camera",
          "name": "Reynaldo Villalobos",
          "original_name": "Reynaldo Villalobos",
          "popularity": 0.904,
          "profile_path": "/4YlfhHDRZWhbRgeqT2Bwl1u5p9j.jpg"
        }
      ],
      "guest_stars": [
        {
          "character": "Krazy-8",
          "credit_id": "52725845760ee3046b09426e",
          "order": 504,
          "adult": false,
          "gender": 2,
          "id": 1046460,
          "known_for_department": "Acting",
          "name": "Max Arciniega",
          "original_name": "Max Arciniega",
          "popularity": 1.4399,
          "profile_path": "/eqKAJKPpt41KpsLIkkBnAY4HMAL.jpg"
        }
      ]
    }
  ],
  "name": "Season 1",
  "overview": "High school chemistry teacher Walter White's life is suddenly transformed by...",
  "id": 3572,
  "poster_path": "/91EIXdWxmp2mHNRsSuDW3WyDJLj.jpg",
  "season_number": 1,
  "vote_average": 0
}
```

## 获取整部剧集

amodb 不接受 `append_to_response` 中 `season/1` 这类取值，所以各季调用需要分开。先从电视剧详情读取 `number_of_seasons` 和 `seasons` 列表，再循环请求每一季。

```js
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');
for (const { season_number } of show.seasons) {
  const season = await get(`/tv/1396/season/${season_number}`);
  console.log(season.name, season.episodes.length);
}
```

如果剧集有特别篇，`seasons` 会包含第 0 季，因此《绝命毒师》需要 1 次详情调用加 6 次季调用。有 10 季的剧集需要 11 个请求。详情在边缘缓存 6 小时，所以请保存结果并按计划刷新。

## 播出日期与接下来的内容

`GET /3/tv/{tv_id}` 包含 `next_episode_to_air` 和 `last_episode_to_air`，它们是完整的剧集对象，带有 `name`、`air_date`、`season_number`、`episode_number`、`runtime` 和 `still_path`。没有公布时 `next_episode_to_air` 为 `null`。把它与 `status`（例如 `Returning Series`、`Ended` 或 `Canceled`）结合起来，决定是否显示倒计时。

`air_date` 是不含具体时刻的日历日期。把它与今天的日期比较，即可标出新剧集。想了解正在播出的内容，[热门趋势与列表](https://amodb.dev/zh/trending-lists/)中的 `airing_today` 和 `on_the_air` 列表缓存 30 分钟。

## 剧照与时长

列表行用 `w185` 或 `w300`，完整尺寸用 `original`。剧照尺寸有 `w92`、`w185`、`w300` 和 `original`。一集可能没有剧照，因此当 `still_path` 为 `null` 时请渲染占位图。图片主机无需密钥，见[图片](https://amodb.dev/zh/images-api/)。

`runtime` 以分钟为单位，可能为 `null`。要显示一季的刷剧总时长，把 `episodes` 中的 `runtime` 相加，并把 `null` 当作 0。在单集路径上加上 `append_to_response=credits,images`，可得到 `credits` 对象和 `stills` 列表。单集的 `cast` 数组为空，人员位于 `crew` 和 `guest_stars` 中。详情见[季与集](https://amodb.dev/zh/tv-seasons-episodes/)和[演职员](https://amodb.dev/zh/credits/)。

## 用剧集分组查看其他排序

有些剧集的观看顺序与播出顺序不同。`GET /3/tv/{tv_id}/episode_groups` 列出为一部剧定义的排序。每一项包含 `id`、`name`、`description`、`type`、`episode_count`、`group_count` 和 `network`。没有定义时 `results` 数组为空。

| `type` | 排序     |
| ------ | ------ |
| 1      | 原始播出日期 |
| 2      | 绝对顺序   |
| 3      | DVD    |
| 4      | 数字发行   |
| 5      | 故事线    |
| 6      | 制作顺序   |
| 7      | 电视     |

amodb 只返回这个列表。它不提供 `GET /3/tv/episode_group/{id}`，因此分组内部的剧集无法获取。剧集数据请使用季接口。

## 对比

| 能力     | 抓取剧集页面     | 免费层元数据 API | amodb                              |
| ------ | ---------- | ---------- | ---------------------------------- |
| 完整的一季  | 每季抓取一个页面   | 请查阅其文档     | 一次调用，包含 `episodes` 数组              |
| 整部剧集   | 爬取每一季      | 请查阅其文档     | 每季一次调用，季列表在 `seasons` 中            |
| 播出日期   | 解析文本       | 请查阅其文档     | `air_date` 加 `next_episode_to_air` |
| 剧照     | 下载并缩放      | 请查阅其文档     | `img.amodb.dev` 上的固定尺寸，无需密钥        |
| 其他剧集排序 | 不提供        | 请查阅其文档     | `episode_groups` 列表，不提供分组内容        |
| 语言     | 每个网站一种区域设置 | 请查阅其文档     | 通过 `language` 支持 14 种语言            |

## 定价

套餐按 1、3、6、12 或 24 个月预付，较长的周期分别享受 0、10、20、30 或 40% 的折扣，也都不会自动续费。每分钟 20、40 和 120 个请求的套餐都能使用本页的所有接口。刷新一部剧集需要一次详情请求，外加每季一次请求。没有免费额度。请在[定价](https://amodb.dev/zh/pricing/)页选择套餐。

## 常见问题

### 如何列出一部电视剧的所有剧集？

先从 GET /3/tv/{tv_id} 读取 number_of_seasons，再对每一季调用 GET /3/tv/{tv_id}/season/{season_number}。每个季响应都包含完整的 episodes 数组，因此无需为每一集单独调用。如果没有剧集数据，少数季会返回空的 episodes 数组。

### 能在一次请求中获取多个季吗？

不能。amodb 会忽略 append_to_response 中 season/1 这类取值，因此每一季都是独立的请求。一部有 10 季的剧集需要 11 个请求：详情一个，每季一个。

### 什么是剧集分组？

剧集分组是同一批剧集的另一种排序，例如 DVD、绝对顺序或故事线顺序。GET /3/tv/{tv_id}/episode_groups 会列出它们的名称、类型和集数。amodb 不提供分组内部的剧集。

### 如何知道下一集何时播出？

GET /3/tv/{tv_id} 返回 next_episode_to_air，包含 air_date、season_number 和 episode_number。没有公布时该值为 null。last_episode_to_air 给出最近播出的一集。

### 剧集图片从哪里来？

每一集都有 still_path。把它拼接到 https://img.amodb.dev/t/p/{size}，例如列表行用 w300。图片无需密钥。still_path 可能为 null，请准备好占位图。

## 相关页面

- [电视剧季与单集 API](https://amodb.dev/zh/tv-seasons-episodes/): 路径和 JSON 与 TMDB v3 相同的电视剧季与单集 API。读取一季及其全部单集，或读取单集的播出日期、时长和剧照。
- [电视剧 API](https://amodb.dev/zh/tv-series/): 路径和 JSON 与 TMDB v3 相同的电视剧 API。按 ID 获取剧集的季、电视网和下一集，以及内容分级和观看平台。
- [图片 API 与图片主机](https://amodb.dev/zh/images-api/): 采用 TMDB v3 路径的电影图片 API：列出作品的海报、背景图、标志和剧照，再从 img.amodb.dev 以 10 种尺寸无密钥加载。
- [演职员 API](https://amodb.dev/zh/credits/): 与 TMDB v3 路径和 JSON 相同的演职员 API。获取电影、剧集、季和集的演员与幕后人员，含 order、department 和 job 字段。
- [用于剧集、季和集的电视剧 API](https://amodb.dev/zh/tv-show-api/): 电视剧 API：剧集状态、电视网、季、集和 next_episode_to_air。TMDB v3 兼容的 JSON，支持 14 种语言，每分钟 20 次起。
- [快速开始](https://amodb.dev/zh/quickstart/): 发出第一次 amodb 调用：获取密钥，用 curl、JavaScript、Python、PHP 或 Go 请求电影详情，再加载海报。

更新于: 2026-10-18. Source: https://amodb.dev/zh/episode-guide-api/
