API за сезони и епизоди на сериали

Един сезон с всичките му епизоди се чете на GET /3/tv/{series_id}/season/{season_number}, а отделен епизод е едно ниво по-дълбоко. JSON съвпада с TMDB v3 с air_date, episode_number, runtime и still_path. Всеки епизод носи crew и guest_stars, сезон 0 съдържа специалните епизоди, а append_to_response добавя credits, images и videos.

Обновено Отвори като Markdown

Вземане на сезон

GET /3/tv/{series_id}/season/{season_number} връща един сезон и пълния му масив episodes в един отговор. Номерата на сезоните започват от 1, а 0 е запазен за специални епизоди. Вземете id на сериала и номерата на сезоните от записа сериали.

Примерът чете сезон 1 на Breaking Bad. Кодът отпечатва по един ред за епизод.

bashjspyphpgo
curl -sSf "https://api.amodb.dev/3/tv/1396/season/1?language=en-US" \
  -H "Authorization: Bearer $AMODB_KEY"
const url = 'https://api.amodb.dev/3/tv/1396/season/1?language=en-US';
const res = await fetch(url, { headers: { Authorization: `Bearer ${process.env.AMODB_KEY}` } });
if (!res.ok) throw new Error(`amodb returned ${res.status}`);
const season = await res.json();
for (const ep of season.episodes) {
  console.log(String(ep.episode_number).padStart(2, '0'), ep.name, ep.air_date, `${ep.runtime ?? '?'} min`);
}
import os
import requests

r = requests.get(
    "https://api.amodb.dev/3/tv/1396/season/1",
    params={"language": "en-US"},
    headers={"Authorization": f"Bearer {os.environ['AMODB_KEY']}"},
    timeout=10,
)
r.raise_for_status()
season = r.json()
for ep in season["episodes"]:
    print(f"{ep['episode_number']:02d}", ep["name"], ep["air_date"], ep["runtime"] or "?")
<?php
$url = 'https://api.amodb.dev/3/tv/1396/season/1?language=en-US';
$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");
}
$season = json_decode($body, true);
foreach ($season['episodes'] as $ep) {
    printf("%02d %s %s\n", $ep['episode_number'], $ep['name'], $ep['air_date']);
}
package main

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

type Season struct {
	Name     string `json:"name"`
	Episodes []struct {
		EpisodeNumber int    `json:"episode_number"`
		Name          string `json:"name"`
		AirDate       string `json:"air_date"`
		Runtime       int    `json:"runtime"`
	} `json:"episodes"`
}

func main() {
	req, _ := http.NewRequest("GET", "https://api.amodb.dev/3/tv/1396/season/1?language=en-US", 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 Season
	if err := json.NewDecoder(res.Body).Decode(&s); err != nil {
		panic(err)
	}
	for _, e := range s.Episodes {
		fmt.Printf("%02d %s %s %d min\n", e.EpisodeNumber, e.Name, e.AirDate, e.Runtime)
	}
}

Параметри

  • series_idпътзадължителен
    Числов id на сериала, например 1396.
  • season_numberпътзадължителен
    Цял номер на сезона. 0 връща специалните епизоди.
  • api_keyзаявкаедин от двата
    Вашият ключ. Ползвайте него или заглавката Authorization: Bearer.
  • languageзаявка
    Таг на TMDB, например en-US или fr-FR. Поддържат се 14 основни езика. По подразбиране en-US.
  • append_to_responseзаявка
    Стойности на ниво сезон: credits, external_ids, images, videos. Другите имена се игнорират.

Полета на отговора

ПолеТипБележки
id, season_numberцяло числоId на сезона и номерът му в сериала.
name, overviewнизЛокализиран текст, празен, когато няма превод.
air_dateниз или nullДата на първия епизод, YYYY-MM-DD.
poster_pathниз или nullДобавя се към https://img.amodb.dev/t/p/{size}.
vote_averageчислоОбобщена потребителска оценка за сезона.
episodesмасивВсеки епизод, с полетата, изброени в следващия раздел.

Примерен отговор

GET /3/tv/1396/season/1?language=en-US. Сезонът има 7 епизода, затова episodes е съкратен до един запис, а масивите crew и guest_stars на този запис са пропуснати:

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 of lung cancer, he decides to...",
      "production_code": "",
      "runtime": 59,
      "season_number": 1,
      "show_id": 1396,
      "still_path": "/ydlY3iPfeOAvu8gVqrxPoMvzNCn.jpg",
      "vote_average": 0,
      "vote_count": 0
    }
  ],
  "name": "Season 1",
  "overview": "High school chemistry teacher Walter White's life is suddenly transformed by a dire medical diagnosis. Stre...",
  "id": 3572,
  "poster_path": "/91EIXdWxmp2mHNRsSuDW3WyDJLj.jpg",
  "season_number": 1,
  "vote_average": 0
}

Всеки епизод в отговора за сезон носи и масиви crew и guest_stars с формата на записа, описана на страницата участници. runtime може да е null за неизлъчен епизод.

Вземане на епизод

GET /3/tv/{series_id}/season/{season_number}/episode/{episode_number} връща един епизод. Отговорът за сезон вече съдържа всеки епизод с crew и guest_stars, затова ползвайте този ендпойнт, за да обновите един запис, без да зареждате отново сезона. Приема language и append_to_response със credits, external_ids, images, translations и videos. Заявка като /3/tv/1396/season/1/episode/1?append_to_response=credits струва една заявка.

ПолеТипБележки
idцяло числоId на епизода.
show_idцяло числоId на сериала. Присъства в отговора за сезон и в указателите на сериала, но не и в отговора за единичен епизод.
season_number, episode_numberцяло числоПозиция в сериала. Ползвайте ги, за да построите пътя на заявката.
name, overviewнизЛокализиран текст.
air_dateниз или nullСамо дата, без час и часова зона. Null, когато е ненасрочен.
episode_typeнизstandard за обикновени епизоди. За да познаете финал, сравнете episode_number с episode_count на този сезон в записа на сериала.
runtimeцяло число или nullМинути.
production_codeнизКод на студиото, често празен.
still_pathниз или nullКадър от епизода. Ползвайте w300 или original от https://img.amodb.dev/t/p/{size}.
vote_average, vote_countчисло, цяло числоОбобщена потребителска оценка.
crew, guest_starsмасивУчастниците в този епизод, вижте участници.

Следващ и последен епизод в записа на сериала

Ендпойнтът за сериал връща next_episode_to_air и last_episode_to_air. Всеки от тях е кратко описание на епизод с полетата по-горе, плюс show_id и без crew и guest_stars. Следващият е null за приключили сериали и за продължаващи сериали без потвърдена дата. Примерът чете South Park, продължаващ сериал.

JavaScript
const headers = { Authorization: `Bearer ${process.env.AMODB_KEY}` };
const res = await fetch('https://api.amodb.dev/3/tv/2190', { headers });
if (!res.ok) throw new Error(`amodb returned ${res.status}`);
const next = (await res.json()).next_episode_to_air;
console.log(next ? `Next: S${next.season_number}E${next.episode_number} on ${next.air_date}` : 'No upcoming episode');

За обратно броене сравнете air_date с местната дата на зрителя. Стойността не носи час от денонощието, затова показвайте дата, а не часовник.

Подресурси на сезон и епизод

Пътищата за сезон и епизод имат собствени подресурси. Няколко от тях днес връщат празни данни.

Метод и пътКакво връща
GET /tv/{series_id}/season/{season_number}/creditsid, cast и crew за сезона
GET /tv/{series_id}/season/{season_number}/imagesid и празен масив posters
GET /tv/{series_id}/season/{season_number}/videosid и празен масив results
GET /tv/{series_id}/season/{season_number}/external_idsid плюс tvdb_id, wikidata_id и други id, всички null
GET /tv/{series_id}/season/{season_number}/translationsid и празен масив translations
GET .../episode/{episode_number}/creditsid, празен cast, crew и guest_stars
GET .../episode/{episode_number}/imagesid и масив stills с кадъра на епизода
GET .../episode/{episode_number}/videosid и празен масив results
GET .../episode/{episode_number}/external_idsid плюс imdb_id, tvdb_id и други id, всички null
GET .../episode/{episode_number}/translationsid и масив translations със заглавие и описание за всеки език

Участниците в сезон и епизод са описани на страницата участници, а кадрите на страницата изображения. amodb не предлага пътищата changes на TMDB и ендпойнт за епизодите на една група епизоди.

Грешки

HTTPstatus_codeКога
4017Ключът липсва или е грешен.
40236Периодът на плана е изтекъл.
40434Сериалът, сезонът или епизодът не съществува, например сезон 0 при сериал без специални епизоди, или пътят не се предлага.
40537Извикали сте метод за запис.
42925Надхвърлен е лимитът на заявки в минута. Изчакайте Retry-After секунди.

Вижте грешки за пълния формат на тялото и лимити на заявките за прозорците.

Практически бележки

  • Сезоните и епизодите се кешират за 6 часа. Докато сериалът се излъчва, четете текущия сезон отново веднъж-два пъти на ден.
  • Сериал с 10 сезона изисква 10 извиквания за сезони. При плана с 20 заявки в минута това е половината от лимита за една минута, а повторно изпълнение в рамките на 6 часа се обслужва от edge кеша.
  • Неизлъчен епизод може да има air_date със стойност null, runtime със стойност null и празен overview. Показвайте заместител вместо да се чупите.
  • Кадрите са широки изображения, а не постери. Искайте w300 за списъци и original само когато ви трябва изглед в пълен размер.