API de series de TV

El endpoint de series de TV devuelve una serie por id en GET /3/tv/{series_id}: nombres, sinopsis, estado, temporadas, cadenas, géneros y punteros al último y al próximo episodio. El JSON coincide con TMDB v3, así que los clientes existentes solo necesitan una nueva URL base. Añade append_to_response para incorporar clasificaciones por edad, créditos y puntuaciones en una sola solicitud.

Actualizado el Ver en Markdown

Obtén los detalles de una serie de TV

GET /3/tv/{series_id} devuelve el registro principal de una serie: nombres, sinopsis, estado, géneros, cadenas, la lista de temporadas y punteros al último y al próximo episodio. El id es el id numérico de TV de TMDB, así que una serie que guardas como 1396 conserva ese id aquí. Los ids de películas y de TV son espacios separados, así que guarda siempre el tipo de medio junto al número.

El ejemplo pide Breaking Bad en inglés y añade sus clasificaciones por edad y puntuaciones externas en la misma llamada.

bashjspyphpgo
curl -sSf "https://api.amodb.dev/3/tv/1396?language=en-US&append_to_response=content_ratings,ratings" \
  -H "Authorization: Bearer $AMODB_KEY"
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);
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
$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;
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)
}

Parámetros

  • series_idrutaobligatorio
    ID numérico de TV, por ejemplo 1396.
  • api_keyconsultauno de los dos
    Tu clave. Usa esta o el encabezado Authorization: Bearer.
  • languageconsulta
    Etiqueta TMDB como en-US, uk-UA o es-ES. Se sirven 14 idiomas base. Por defecto en-US.
  • append_to_responseconsulta
    Lista separada por comas de subrecursos que se incorporan a la respuesta, hasta 20 valores.

Campos de la respuesta

CampoTipoNotas
identeroID de TV.
name, original_nametextoTítulo localizado y original. Los nombres originales en japonés o coreano se quedan en original_name.
overview, taglinetextoTexto localizado, vacío cuando no existe traducción.
first_air_date, last_air_datetexto o nullYYYY-MM-DD.
statustextoCiclo de vida, ver la tabla siguiente.
in_productionbooleanotrue mientras la serie sigue en producción.
number_of_seasons, number_of_episodesenteroTotales, tal como están guardados para la serie.
episode_run_timearrayDuraciones típicas de episodio en minutos, puede estar vacío.
seasonsarrayUn resumen por temporada con id, season_number, name, overview, episode_count, air_date, poster_path, vote_average.
last_episode_to_air, next_episode_to_airobjeto o nullResúmenes de episodio, con la forma de los objetos de temporadas y episodios.
networks, production_companiesarrayid, name, logo_path, origin_country.
production_countries, spoken_languagesarrayPaíses con iso_3166_1 y name. Idiomas con english_name, iso_639_1 y name.
created_byarrayCreadores con id, name, profile_path y credit_id. Vacío en la mayoría de las series.
genresarrayObjetos con id y name. Los ids de género de TV son distintos de los de películas.
origin_country, original_language, languagesarray, textoCódigos de país y de idioma.
homepagetextoSitio oficial, vacío cuando no se conoce.
poster_path, backdrop_pathtexto o nullSe añaden a https://img.amodb.dev/t/p/{size}. Ver imágenes.
popularitynúmeroPuntuación relativa que usa la lista de populares.
vote_average, vote_countnúmero, enteroPuntuación agregada de los usuarios.
adultbooleanoSiempre false. Los títulos para adultos nunca se sirven.

Ejemplo de respuesta

GET /3/tv/1396?language=en-US&append_to_response=content_ratings,ratings, con arrays y textos largos acortados:

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

Los bloques content_ratings y ratings vienen de append_to_response. Los nombres y las sinopsis dentro de seasons, last_episode_to_air y next_episode_to_air se guardan por registro y pueden no seguir language, como muestra el nombre de episodio en hebreo de arriba. Lee el texto localizado de temporadas y episodios desde el endpoint de temporada.

Estado y punteros de episodio

status te dice en qué punto de su vida está una serie, y next_episode_to_air te dice cuándo volver a mirar.

Valor de statusSignificadonext_episode_to_air
Returning SeriesEn emisión o entre temporadas.Definido cuando se conoce una fecha, si no es null.
Planned, In ProductionTodavía no es una serie regular.Normalmente null.
EndedTerminó su emisión.Null.
CanceledSe detuvo antes del final previsto.Null.

Una serie en curso entre temporadas tiene un next_episode_to_air null, así que interpreta null como «fecha desconocida» y no como «terminada».

El array seasons lista un resumen por temporada, y la temporada 0 reúne los especiales. Para leer los episodios de una temporada, llama al endpoint descrito en temporadas y episodios.

Endpoints relacionados de series

Todas las rutas comparten la base https://api.amodb.dev/3, y los endpoints con texto localizado también aceptan language.

Método y rutaDevuelveParámetros adicionales
GET /tv/{series_id}/alternative_titles{id, results} con iso_3166_1, title, type, a menudo vacíoninguno
GET /tv/{series_id}/content_ratingsClasificación por edad por paísninguno
GET /tv/{series_id}/episode_groupsLista de órdenes alternativos de episodios, como DVD o arco argumentalninguno
GET /tv/{series_id}/recommendationsUna lista de 20 series recomendadasninguno
GET /tv/{series_id}/similarUna lista de 20 series similaresninguno
GET /tv/{series_id}/reviewsresults está vacío en la mayoría de las seriesninguno
GET /tv/{series_id}/listsListas públicas que contienen la seriepage
GET /tv/{series_id}/watch/providersProveedores de streaming, alquiler y compra por paísninguno
GET /tv/latestEl registro de serie más reciente añadidoninguno

Las listas de recomendaciones y de similares siempre devuelven la página 1 con 20 elementos. La respuesta de lists está paginada con page, 20 listas por página. Las demás listas paginadas de la API aceptan page de 1 a 500.

Las clasificaciones por edad llegan como entradas de results con iso_3166_1, rating y descriptors, así que elige la entrada que coincide con el país del espectador. Los proveedores de visionado se organizan por código de país, y cada país contiene un link más listas flatrate, rent y buy con provider_id, provider_name, logo_path y display_priority. Los ids de proveedor para filtrar salen de las listas de consulta de géneros y listas de consulta.

La lista de grupos de episodios devuelve id (un texto), name, description, type, episode_count, group_count y network. amodb lista los grupos, pero no ofrece un endpoint que devuelva los episodios de un grupo. Tampoco ofrece las rutas changes de TMDB.

Combina más datos en una sola llamada

Lista los subrecursos en append_to_response y cada uno llega bajo su propia clave. Toda la llamada cuenta una sola vez contra tus 20, 40 o 120 solicitudes por minuto. Funcionan hasta 20 valores, y los nombres desconocidos se ignoran sin error. Estos valores funcionan en una serie:

ValorAñadeDetalles
creditsReparto y equipo técnicoCréditos
external_idsIds como imdb_id, tvdb_id y wikidata_idBuscar por ID externo
images, videosPósters, imágenes de fondo (backdrop) y tráilersImágenes, Vídeos
keywords, translationsEtiquetas y textos traducidosPalabras clave, Traducciones
content_ratings, alternative_titles, episode_groups, lists, watch/providers, similar, recommendations, reviewsLos subrecursos de la tabla anteriorEsta página
ratings, moods, soundtracks, wikidata, showtimesExtras de amodbPuntuaciones, Moods, Bandas sonoras, Horarios de cine

Errores

Una llamada fallida devuelve el cuerpo de error de TMDB. Un id incorrecto da status_code 34 con el mensaje «The resource you requested could not be found.»

HTTPstatus_codeCuándo
4017Falta la clave o es incorrecta.
40236El periodo del plan ha terminado.
40434No hay ninguna serie con ese id, es un título para adultos, o la ruta no se ofrece.
40537Llamaste a un método de escritura, como puntuar una serie.
42925Superaste tus solicitudes por minuto. Espera los segundos indicados en Retry-After.

La lista completa está en errores, y los límites por plan están en límites de solicitudes.

Notas prácticas

  • Los detalles de la serie y todos los subrecursos anteriores se guardan en caché 6 horas. Consulta last_episode_to_air como máximo unas pocas veces al día.
  • Solicita el idioma que muestras. Un overview vacío significa que no existe traducción, así que vuelve a solicitar con en-US como respaldo.
  • Usa number_of_seasons como límite del bucle cuando obtengas todas las temporadas, una llamada por cada una.
  • Para listar series en lugar de leer una, consulta búsqueda, discover y tendencias y listas.