API di stagioni ed episodi delle serie TV

Leggi una stagione con ogni episodio su GET /3/tv/{series_id}/season/{season_number}, o un singolo episodio un livello più sotto. Il JSON segue TMDB v3 con air_date, episode_number, runtime e still_path. Ogni episodio porta crew e guest_stars, la stagione 0 contiene gli speciali, e append_to_response aggiunge crediti, immagini e video.

Aggiornato il Vedi in Markdown

Ottenere una stagione

GET /3/tv/{series_id}/season/{season_number} restituisce una stagione e il suo array episodes completo in una sola risposta. I numeri di stagione partono da 1, e 0 è riservato agli speciali. Prendi l'ID della serie e i numeri di stagione dalla scheda serie TV.

L'esempio legge la stagione 1 di Breaking Bad. Il codice stampa una riga per episodio.

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)
	}
}

Parametri

  • series_idpercorsoobbligatorio
    ID numerico della serie TV, per esempio 1396.
  • season_numberpercorsoobbligatorio
    Numero di stagione intero. 0 restituisce gli speciali.
  • api_keyqueryuno dei due
    La tua chiave. Usa questa o l'header Authorization: Bearer.
  • languagequery
    Tag TMDB come en-US o fr-FR. Sono servite 14 lingue di base. Predefinito en-US.
  • append_to_responsequery
    Valori a livello di stagione: credits, external_ids, images, videos. Gli altri nomi vengono ignorati.

Campi della risposta

CampoTipoNote
id, season_numberinteroID della stagione e il suo numero nella serie.
name, overviewstringaTesto localizzato, vuoto quando non esiste una traduzione.
air_datestringa o nullData del primo episodio, YYYY-MM-DD.
poster_pathstringa o nullDa accodare a https://img.amodb.dev/t/p/{size}.
vote_averagenumeroPunteggio aggregato degli utenti per la stagione.
episodesarrayOgni episodio, con i campi elencati nella sezione successiva.

Risposta di esempio

GET /3/tv/1396/season/1?language=en-US. La stagione ha 7 episodi, quindi episodes è tagliato a una voce, e gli array crew e guest_stars di quella voce sono omessi:

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
}

Ogni episodio nella risposta della stagione porta anche gli array crew e guest_stars, con la struttura delle voci descritta nella pagina crediti. runtime può essere null per un episodio non ancora andato in onda.

Ottenere un episodio

GET /3/tv/{series_id}/season/{season_number}/episode/{episode_number} restituisce un episodio. La risposta della stagione contiene già ogni episodio con crew e guest_stars, quindi usa questo endpoint per aggiornare un record senza ricaricare la stagione. Accetta language e append_to_response con credits, external_ids, images, translations e videos. Una richiesta come /3/tv/1396/season/1/episode/1?append_to_response=credits costa una richiesta.

CampoTipoNote
idinteroID dell'episodio.
show_idinteroID della serie. Presente nella risposta della stagione e nei puntatori della serie, non nella risposta di un singolo episodio.
season_number, episode_numberinteroPosizione nella serie. Usali per costruire il percorso della richiesta.
name, overviewstringaTesto localizzato.
air_datestringa o nullSolo la data, senza ora né fuso orario. Null quando non programmato.
episode_typestringastandard per gli episodi normali. Per individuare un finale, confronta episode_number con l'episode_count di quella stagione nella scheda della serie.
runtimeintero o nullMinuti.
production_codestringaCodice dello studio, spesso vuoto.
still_pathstringa o nullImmagine dell'episodio. Usa w300 o original da https://img.amodb.dev/t/p/{size}.
vote_average, vote_countnumero, interoPunteggio aggregato degli utenti.
crew, guest_starsarrayCrediti di questo episodio, vedi crediti.

Prossimo e ultimo episodio nella scheda della serie

L'endpoint della serie restituisce next_episode_to_air e last_episode_to_air. Ognuno è un riepilogo di episodio con i campi qui sopra, più show_id e senza crew e guest_stars. Il prossimo è null per le serie concluse e per le serie in corso senza una data confermata. L'esempio legge South Park, una serie in corso.

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');

Per un conto alla rovescia, confronta air_date con la data locale dello spettatore. Il valore non porta l'ora del giorno, quindi mostra una data e non un orario.

Sottorisorse di stagioni ed episodi

I percorsi di stagioni ed episodi hanno le proprie sottorisorse. Diverse oggi restituiscono dati vuoti.

Metodo e percorsoRestituisce
GET /tv/{series_id}/season/{season_number}/creditsid, cast e crew della stagione
GET /tv/{series_id}/season/{season_number}/imagesid e un array posters vuoto
GET /tv/{series_id}/season/{season_number}/videosid e un array results vuoto
GET /tv/{series_id}/season/{season_number}/external_idsid più tvdb_id, wikidata_id e altri ID, tutti nulli
GET /tv/{series_id}/season/{season_number}/translationsid e un array translations vuoto
GET .../episode/{episode_number}/creditsid, un cast vuoto, crew e guest_stars
GET .../episode/{episode_number}/imagesid e un array stills con l'immagine dell'episodio
GET .../episode/{episode_number}/videosid e un array results vuoto
GET .../episode/{episode_number}/external_idsid più imdb_id, tvdb_id e altri ID, tutti nulli
GET .../episode/{episode_number}/translationsid e un array translations con nome e trama per lingua

I crediti di stagioni ed episodi sono trattati nella pagina crediti, e le immagini nella pagina immagini. amodb non offre i percorsi changes di TMDB né un endpoint per gli episodi di un gruppo di episodi.

Errori

HTTPstatus_codeQuando
4017La chiave manca o è sbagliata.
40236Il periodo del piano è terminato.
40434La serie, la stagione o l'episodio non esiste, per esempio la stagione 0 di una serie senza speciali, oppure il percorso non è offerto.
40537Hai chiamato un metodo di scrittura.
42925Oltre le tue richieste al minuto. Attendi i secondi di Retry-After.

Vedi errori per il formato completo del corpo e limiti di richieste per le finestre.

Note pratiche

  • Stagioni ed episodi restano in cache per 6 ore. Rileggi la stagione corrente una o due volte al giorno mentre una serie va in onda.
  • Una serie di 10 stagioni richiede 10 chiamate di stagione. Con il piano da 20 richieste al minuto consuma metà della disponibilità di un minuto, e una seconda esecuzione entro 6 ore viene servita dalla cache edge.
  • Un episodio non ancora andato in onda può avere air_date null, runtime null e overview vuoto. Mostra un segnaposto invece di fallire.
  • Le immagini degli episodi sono inquadrature larghe, non locandine. Chiedi w300 per gli elenchi e original solo quando ti serve una vista a dimensione piena.