API des saisons et épisodes de séries TV
Lisez une saison avec tous ses épisodes sur GET /3/tv/{series_id}/season/{season_number}, ou un seul épisode un niveau plus bas. Le JSON suit TMDB v3 avec air_date, episode_number, runtime et still_path. Chaque épisode porte crew et guest_stars, la saison 0 contient les épisodes spéciaux, et append_to_response ajoute crédits, images et vidéos.
Obtenir une saison
GET / renvoie une saison et son tableau episodes complet en une seule réponse. Les numéros de saison commencent à 1, et 0 est réservé aux épisodes spéciaux. Prenez l'identifiant de la série et les numéros de saison dans la fiche séries TV.
L'exemple lit la saison 1 de Breaking Bad. Le code affiche une ligne par épisode.
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)
}
}Paramètres
series_idcheminobligatoireIdentifiant numérique de la série, par exemple1396.season_numbercheminobligatoireNuméro de saison entier.0renvoie les épisodes spéciaux.api_keyrequêtel'un des deuxVotre clé. Utilisez-la ou l'en-têteAuthorization: Bearer.languagerequêteBalise TMDB commeen-USoufr-FR. 14 langues de base sont servies. Par défauten-US.append_to_responserequêteValeurs au niveau de la saison :credits,external_ids,images,videos. Les autres noms sont ignorés.
Champs de la réponse
| Champ | Type | Remarques |
|---|---|---|
id, season_number | entier | Identifiant de la saison et son numéro dans la série. |
name, overview | chaîne | Texte localisé, vide quand il n'existe pas de traduction. |
air_date | chaîne ou null | Date du premier épisode, YYYY-MM-DD. |
poster_path | chaîne ou null | À ajouter à https:/. |
vote_average | nombre | Note agrégée des utilisateurs pour la saison. |
episodes | tableau | Tous les épisodes, avec les champs listés dans la section suivante. |
Exemple de réponse
GET /. La saison compte 7 épisodes : episodes est donc réduit à une entrée, et les tableaux crew et guest_stars de cette entrée sont omis :
{
"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
}Chaque épisode de la réponse de saison porte aussi des tableaux crew et guest_stars, avec la forme d'entrée décrite sur crédits. runtime peut être null pour un épisode pas encore diffusé.
Obtenir un épisode
GET / renvoie un épisode. La réponse de saison contient déjà tous les épisodes avec crew et guest_stars : utilisez donc ce point de terminaison pour actualiser une fiche sans recharger la saison. Il accepte language et append_to_response avec credits, external_ids, images, translations et videos. Une requête comme / coûte une requête.
| Champ | Type | Remarques |
|---|---|---|
id | entier | Identifiant de l'épisode. |
show_id | entier | Identifiant de la série. Présent dans la réponse de saison et dans les pointeurs de série, pas dans la réponse d'un seul épisode. |
season_number, episode_number | entier | Position dans la série. Utilisez-les pour construire le chemin de la requête. |
name, overview | chaîne | Texte localisé. |
air_date | chaîne ou null | Date seule, sans heure ni fuseau horaire. Null quand non programmé. |
episode_type | chaîne | standard pour les épisodes normaux. Pour repérer un final, comparez episode_number avec l'episode_count de cette saison dans la fiche de la série. |
runtime | entier ou null | Minutes. |
production_code | chaîne | Code du studio, souvent vide. |
still_path | chaîne ou null | Image de l'épisode. Utilisez w300 ou original depuis https:/. |
vote_average, vote_count | nombre, entier | Note agrégée des utilisateurs. |
crew, guest_stars | tableau | Crédits de cet épisode, voir crédits. |
Prochain et dernier épisode dans la fiche de la série
Le point de terminaison de série renvoie next_episode_to_air et last_episode_to_air. Chacun est un résumé d'épisode avec les champs ci-dessus, plus show_id et sans crew ni guest_stars. Le prochain est null pour les séries terminées et pour les séries en cours sans date confirmée. L'exemple lit South Park, une série en cours.
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');Pour un compte à rebours, comparez air_date avec la date locale du spectateur. La valeur ne porte pas d'heure : affichez donc une date et non une heure d'horloge.
Sous-ressources des saisons et des épisodes
Les chemins de saisons et d'épisodes ont leurs propres sous-ressources. Plusieurs renvoient aujourd'hui des données vides.
| Méthode et chemin | Renvoie |
|---|---|
GET / | id, cast et crew de la saison |
GET / | id et un tableau posters vide |
GET / | id et un tableau results vide |
GET / | id plus tvdb_id, wikidata_id et d'autres identifiants, tous nuls |
GET / | id et un tableau translations vide |
GET .../ | id, un cast vide, crew et guest_stars |
GET .../ | id et un tableau stills avec l'image de l'épisode |
GET .../ | id et un tableau results vide |
GET .../ | id plus imdb_id, tvdb_id et d'autres identifiants, tous nuls |
GET .../ | id et un tableau translations avec nom et résumé par langue |
Les crédits de saisons et d'épisodes sont traités sur crédits, et les images sur images. amodb ne propose pas les chemins changes de TMDB ni de point de terminaison pour les épisodes d'un groupe d'épisodes.
Erreurs
| HTTP | status_code | Quand |
|---|---|---|
| 401 | 7 | La clé est absente ou fausse. |
| 402 | 36 | La période de l'offre est terminée. |
| 404 | 34 | La série, la saison ou l'épisode n'existe pas, par exemple la saison 0 d'une série sans épisodes spéciaux, ou le chemin n'est pas proposé. |
| 405 | 37 | Vous avez appelé une méthode d'écriture. |
| 429 | 25 | Au-dessus de vos requêtes par minute. Attendez les secondes de Retry-After. |
Voir erreurs pour le format complet du corps et limites de débit pour les fenêtres.
Remarques pratiques
- Les saisons et les épisodes sont mis en cache 6 heures. Relisez la saison en cours une ou deux fois par jour pendant la diffusion d'une série.
- Une série de 10 saisons demande 10 appels de saison. Avec l'offre à 20 requêtes par minute, cela utilise la moitié du quota d'une minute, et une seconde exécution dans les 6 heures est servie depuis le cache de périphérie.
- Un épisode non diffusé peut avoir un
air_datenull, unruntimenull et unoverviewvide. Affichez une image de remplacement au lieu d'échouer. - Les images d'épisodes sont des plans larges, pas des affiches. Demandez
w300pour les listes etoriginalseulement quand vous avez besoin d'une vue en taille réelle.