# API de imágenes y host de imágenes

> Los endpoints de imágenes listan los pósters, fondos, logos, perfiles y fotogramas de un título como rutas de archivo. Luego cargas cada archivo desde img.amodb.dev en un tamaño fijo, sin clave y con 30 días de caché perimetral. Las rutas y el JSON coinciden con TMDB v3, así que tu código de imágenes funciona tras cambiar la URL base.

## Endpoint

`GET /3/movie/{movie_id}/images`

```bash
curl "https://api.amodb.dev/3/movie/550/images?include_image_language=en,null" \
  -H "Authorization: Bearer $AMODB_KEY"
```

Respuesta:

```json
{
  "id": 550,
  "backdrops": [
    {
      "aspect_ratio": 1.778,
      "height": 1440,
      "iso_639_1": null,
      "file_path": "/c6OLXfKAk5BKeR6broC8pYiCquX.jpg",
      "vote_average": 0,
      "vote_count": 0,
      "width": 2560
    },
    {
      "aspect_ratio": 1.778,
      "height": 1080,
      "iso_639_1": "en",
      "file_path": "/b9HyPoxwxjxkWEUL5ErZdhApQe2.jpg",
      "vote_average": 0,
      "vote_count": 0,
      "width": 1920
    },
    {
      "aspect_ratio": 1.778,
      "height": 2160,
      "iso_639_1": "en",
      "file_path": "/ewMhHVyXQKMAviVWM7InPjZqpSr.jpg",
      "vote_average": 0,
      "vote_count": 0,
      "width": 3840
    }
  ],
  "logos": [
    {
      "aspect_ratio": 4.638,
      "height": 389,
      "iso_639_1": "en",
      "file_path": "/7Uqhv24pGJs4Ns31NoOPWFJGWNG.png",
      "vote_average": 0,
      "vote_count": 0,
      "width": 1804
    },
    {
      "aspect_ratio": 0.848,
      "height": 1295,
      "iso_639_1": "en",
      "file_path": "/4XkF0Rf7gvSfea8fYLFbU5tmuJw.png",
      "vote_average": 0,
      "vote_count": 0,
      "width": 1098
    },
    {
      "aspect_ratio": 1.457,
      "height": 1299,
      "iso_639_1": "en",
      "file_path": "/lm0VCzO1ZFhyx81k5Fzkex4u6C8.png",
      "vote_average": 0,
      "vote_count": 0,
      "width": 1893
    }
  ],
  "posters": [
    {
      "aspect_ratio": 0.667,
      "height": 3000,
      "iso_639_1": "en",
      "file_path": "/jSziioSwPVrOy9Yow3XhWIBDjq1.jpg",
      "vote_average": 0,
      "vote_count": 0,
      "width": 2000
    },
    {
      "aspect_ratio": 0,
      "height": 0,
      "iso_639_1": null,
      "file_path": "/qkrH7rjYKU4KOwwIl6wF6H3ISvm.jpg",
      "vote_average": 0,
      "vote_count": 0,
      "width": 0
    },
    {
      "aspect_ratio": 0,
      "height": 0,
      "iso_639_1": null,
      "file_path": "/efBb4gjjKneUoBVgfFOUu2OwihS.jpg",
      "vote_average": 0,
      "vote_count": 0,
      "width": 0
    }
  ]
}
```

## Obtener las imágenes de una película

`GET /3/movie/{movie_id}/images` lista todas las imágenes conocidas de una película en tres arrays: `backdrops`, `logos` y `posters`. Cada entrada tiene un `file_path`, su tamaño en píxeles y una etiqueta de idioma. El archivo en sí no está en el JSON. Lo cargas desde el host de imágenes en un segundo paso.

El ejemplo pide imágenes en inglés y sin texto, elige el primer póster en inglés y luego obtiene ese archivo con 500 píxeles de ancho.

```bash
curl -s "https://api.amodb.dev/3/movie/550/images?include_image_language=en,null" \
  -H "Authorization: Bearer $AMODB_KEY"

curl -s -o poster.jpg -w "%{http_code}\n" \
  "https://img.amodb.dev/t/p/w500/jSziioSwPVrOy9Yow3XhWIBDjq1.jpg"
```

```js
const url = 'https://api.amodb.dev/3/movie/550/images?include_image_language=en,null';
const res = await fetch(url, { headers: { Authorization: `Bearer ${process.env.AMODB_KEY}` } });
if (!res.ok) throw new Error(`amodb returned ${res.status}`);
const { posters } = await res.json();
if (posters.length === 0) throw new Error('no posters');
const poster = posters.find((p) => p.iso_639_1 === 'en') ?? posters[0];
const posterUrl = `https://img.amodb.dev/t/p/w500${poster.file_path}`;
const img = await fetch(posterUrl);
console.log(img.status, img.headers.get('content-type'), posterUrl);
```

```python
import os
import requests

r = requests.get(
    "https://api.amodb.dev/3/movie/550/images",
    params={"include_image_language": "en,null"},
    headers={"Authorization": f"Bearer {os.environ['AMODB_KEY']}"},
    timeout=10,
)
r.raise_for_status()
posters = r.json()["posters"]
if not posters:
    raise SystemExit("no posters")
poster = next((p for p in posters if p["iso_639_1"] == "en"), posters[0])
poster_url = "https://img.amodb.dev/t/p/w500" + poster["file_path"]
img = requests.get(poster_url, timeout=10)
print(img.status_code, img.headers.get("content-type"), poster_url)
```

```php
<?php
$url = 'https://api.amodb.dev/3/movie/550/images?include_image_language=en,null';
$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");
}
$posters = json_decode($body, true)['posters'];
if (!$posters) {
    throw new RuntimeException('no posters');
}
$poster = $posters[0];
foreach ($posters as $p) {
    if ($p['iso_639_1'] === 'en') {
        $poster = $p;
        break;
    }
}
$posterUrl = 'https://img.amodb.dev/t/p/w500' . $poster['file_path'];
$img = curl_init($posterUrl);
curl_setopt_array($img, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 10]);
curl_exec($img);
echo curl_getinfo($img, CURLINFO_HTTP_CODE), ' ', curl_getinfo($img, CURLINFO_CONTENT_TYPE), ' ', $posterUrl, PHP_EOL;
curl_close($img);
```

```go
package main

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

type Images struct {
	Posters []struct {
		FilePath string `json:"file_path"`
		Language string `json:"iso_639_1"`
	} `json:"posters"`
}

func main() {
	url := "https://api.amodb.dev/3/movie/550/images?include_image_language=en,null"
	req, _ := http.NewRequest("GET", url, 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 images Images
	if err := json.NewDecoder(res.Body).Decode(&images); err != nil || len(images.Posters) == 0 {
		panic("no posters")
	}
	poster := images.Posters[0]
	for _, p := range images.Posters {
		if p.Language == "en" {
			poster = p
			break
		}
	}
	posterURL := "https://img.amodb.dev/t/p/w500" + poster.FilePath
	img, err := client.Get(posterURL)
	if err != nil {
		panic(err)
	}
	defer img.Body.Close()
	fmt.Println(img.StatusCode, img.Header.Get("Content-Type"), posterURL)
}
```

### Parámetros

| Parámetro                | En       | Obligatorio    | Descripción                                                                                                                                                                       |
| ------------------------ | -------- | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `movie_id`               | ruta     | sí             | Id numérico de la película, por ejemplo `550`.                                                                                                                                    |
| `api_key`                | consulta | uno de los dos | Tu clave. Usa esta o el encabezado `Authorization: Bearer`.                                                                                                                       |
| `include_image_language` | consulta | no             | Códigos ISO 639-1 separados por comas. Añade `null` para incluir imágenes sin texto, por ejemplo `en,null`. Solo llegan los idiomas indicados. Sin él obtienes todos los idiomas. |
| `language`               | consulta | no             | Se acepta pero se ignora en este endpoint. Usa `include_image_language` para elegir idiomas.                                                                                      |

### Campos de la respuesta

| Campo                           | Tipo           | Notas                                                                                                                                             |
| ------------------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`                            | entero         | El id de la película.                                                                                                                             |
| `backdrops`, `logos`, `posters` | array          | Un array por tipo de imagen, en ese orden de claves. Cada uno puede estar vacío.                                                                  |
| `file_path`                     | texto          | Empieza con una barra. Añádelo a un tamaño en el host de imágenes. Los pósters y las imágenes de fondo son `.jpg`, los logos son `.png` o `.svg`. |
| `width`, `height`               | entero         | Tamaño en píxeles del archivo original. `0` cuando el tamaño no se conoce.                                                                        |
| `aspect_ratio`                  | número         | Ancho dividido por alto. Los pósters rondan 0.667 y las imágenes de fondo 1.778. `0` cuando el tamaño no se conoce.                               |
| `iso_639_1`                     | texto o null   | Idioma del texto de la imagen. `null` significa sin texto.                                                                                        |
| `vote_average`, `vote_count`    | número, entero | Siempre `0` en las imágenes de películas y series, así que no sirven para ordenar imágenes. Conserva el orden que devuelve la API.                |

### Ejemplo de respuesta

Se muestran dos entradas por array.

```json
{
  "id": 550,
  "backdrops": [
    {
      "aspect_ratio": 1.778,
      "height": 1440,
      "iso_639_1": null,
      "file_path": "/c6OLXfKAk5BKeR6broC8pYiCquX.jpg",
      "vote_average": 0,
      "vote_count": 0,
      "width": 2560
    },
    {
      "aspect_ratio": 1.778,
      "height": 1080,
      "iso_639_1": "en",
      "file_path": "/b9HyPoxwxjxkWEUL5ErZdhApQe2.jpg",
      "vote_average": 0,
      "vote_count": 0,
      "width": 1920
    }
  ],
  "logos": [
    {
      "aspect_ratio": 4.638,
      "height": 389,
      "iso_639_1": "en",
      "file_path": "/7Uqhv24pGJs4Ns31NoOPWFJGWNG.png",
      "vote_average": 0,
      "vote_count": 0,
      "width": 1804
    },
    {
      "aspect_ratio": 0.848,
      "height": 1295,
      "iso_639_1": "en",
      "file_path": "/4XkF0Rf7gvSfea8fYLFbU5tmuJw.png",
      "vote_average": 0,
      "vote_count": 0,
      "width": 1098
    }
  ],
  "posters": [
    {
      "aspect_ratio": 0.667,
      "height": 3000,
      "iso_639_1": "en",
      "file_path": "/jSziioSwPVrOy9Yow3XhWIBDjq1.jpg",
      "vote_average": 0,
      "vote_count": 0,
      "width": 2000
    },
    {
      "aspect_ratio": 0,
      "height": 0,
      "iso_639_1": null,
      "file_path": "/qkrH7rjYKU4KOwwIl6wF6H3ISvm.jpg",
      "vote_average": 0,
      "vote_count": 0,
      "width": 0
    }
  ]
}
```

El segundo póster es una entrada cuyo tamaño no se conoce. El archivo se carga igualmente.

## Construir la URL de una imagen

Une tres partes: `https://img.amodb.dev/t/p/`, un segmento de tamaño y el `file_path`. La ruta ya empieza con una barra, así que `https://img.amodb.dev/t/p/w500` más `/jSziioSwPVrOy9Yow3XhWIBDjq1.jpg` es una URL completa.

Un tamaño es `w` más un ancho en píxeles, `h` más un alto en píxeles, o `original` para el archivo guardado. El host sirve diez tamaños: `w92`, `w154`, `w185`, `w300`, `w342`, `w500`, `w780`, `w1280`, `h632` y `original`. Cualquier otro tamaño, como `w400`, responde 404. `/3/configuration` lista los tamaños que encajan con cada tipo de imagen.

| Tipo            | Campo de configuración | Tamaños                                                   |
| --------------- | ---------------------- | --------------------------------------------------------- |
| Póster          | `poster_sizes`         | `w92`, `w154`, `w185`, `w342`, `w500`, `w780`, `original` |
| Imagen de fondo | `backdrop_sizes`       | `w300`, `w780`, `w1280`, `original`                       |
| Logo            | `logo_sizes`           | `w92`, `w154`, `w185`, `w300`, `w500`, `original`         |
| Perfil          | `profile_sizes`        | `w185`, `h632`, `original`                                |
| Fotograma       | `still_sizes`          | `w92`, `w185`, `w300`, `original`                         |

El host no comprueba el tipo, así que un póster también se carga en `w1280`. Quédate con los tamaños listados para cada tipo, para que tu código coincida con la configuración y con cualquier cliente de TMDB.

El host de imágenes no necesita clave, y la caché perimetral guarda cada archivo 30 días. Como no se envía clave, las cargas de imágenes no cuentan para tus solicitudes por minuto. Las respuestas llevan `Access-Control-Allow-Origin: *`, así que un navegador puede cargarlas desde cualquier página. Un tamaño desconocido o un archivo desconocido responde 404 con un cuerpo JSON.

## Imágenes responsivas con srcset

Elige el tamaño más pequeño que aún cubra el ancho mostrado multiplicado por la densidad de pantalla. Un póster que se muestra con 171 píxeles CSS de ancho necesita `w342` en una pantalla 2x. Esta función auxiliar construye un `srcset` a partir de una ruta guardada.

```js
const WIDTHS = [185, 342, 500, 780];

function posterSrcset(filePath) {
  return WIDTHS.map((w) => `https://img.amodb.dev/t/p/w${w}${filePath} ${w}w`).join(', ');
}

const path = '/jSziioSwPVrOy9Yow3XhWIBDjq1.jpg';
console.log(`<img src="https://img.amodb.dev/t/p/w342${path}" srcset="${posterSrcset(path)}" sizes="(max-width: 600px) 50vw, 342px" alt="Fight Club poster">`);
```

## Otros endpoints de imágenes

Todas las rutas de abajo usan la base `https://api.amodb.dev/3` y devuelven los arrays que indica la segunda columna.

| Método y ruta                                                                | Arrays devueltos                                  | Parámetros               |
| ---------------------------------------------------------------------------- | ------------------------------------------------- | ------------------------ |
| `GET /tv/{series_id}/images`                                                 | `backdrops`, `logos`, `posters`                   | `include_image_language` |
| `GET /tv/{series_id}/season/{season_number}/images`                          | `posters`, siempre vacío                          | ninguno                  |
| `GET /tv/{series_id}/season/{season_number}/episode/{episode_number}/images` | `stills`, una entrada con `width` y `height` en 0 | ninguno                  |
| `GET /person/{person_id}/images`                                             | `profiles`                                        | ninguno                  |

Para películas y series también puedes añadir `append_to_response=images` a una llamada de detalles. `include_image_language` funciona ahí también. El bloque añadido no tiene un `id` propio.

Los perfiles de personas son el único lugar donde `vote_average` lleva una puntuación real. El `id` de una respuesta de temporada o de episodio es el id de la temporada o del episodio. Consulta [personas](https://amodb.dev/es/people/) y [series de TV](https://amodb.dev/es/tv-series/) para los registros principales.

amodb no ofrece rutas de imágenes para colecciones, productoras y cadenas. Sus registros ya contienen un `poster_path`, `backdrop_path` o `logo_path`, descritos en [colecciones](https://amodb.dev/es/collections/) y [productoras y cadenas de TV](https://amodb.dev/es/companies-networks/).

## El endpoint de configuración

`GET /3/configuration` devuelve un bloque `images` con `secure_base_url` fijado en `https://img.amodb.dev/t/p/`, `base_url` (la forma http simple) y las listas de tamaños `backdrop_sizes`, `logo_sizes`, `poster_sizes`, `profile_sizes` y `still_sizes`. Léelo una vez al iniciar, usa la forma segura y construye las URL a partir de él en lugar de fijar los tamaños en el código. La caché perimetral lo guarda 24 horas.

## Errores

| HTTP | status_code | Cuándo                                                                                                                    |
| ---- | ----------- | ------------------------------------------------------------------------------------------------------------------------- |
| 401  | 7           | La clave falta o es incorrecta en una llamada JSON.                                                                       |
| 402  | 36          | El periodo del plan ha terminado.                                                                                         |
| 404  | 34          | No hay ninguna persona, temporada o episodio con ese id, o hay un tamaño o un archivo desconocido en el host de imágenes. |
| 405  | 37          | Usaste un método de escritura en una ruta de imágenes.                                                                    |
| 429  | 25          | Superaste tus solicitudes por minuto. Espera los segundos de `Retry-After`.                                               |

Un id de película o serie que no existe no es un error aquí: la ruta de imágenes responde 200 con arrays vacíos, mientras que la ruta de detalles responde 404. Consulta [errores](https://amodb.dev/es/errors/) para ver la lista completa. Las solicitudes de archivos de imagen son cargas HTTP simples, así que comprueba el código de estado de la respuesta en lugar de analizar un cuerpo JSON.

## Notas prácticas

- Guarda `file_path` en tu base de datos y construye la URL al mostrar la imagen. Así, un tamaño o un host nuevo cuesta un solo cambio de código.
- Pasa `include_image_language` con tu idioma de visualización más `null`, por ejemplo `ru,null`, para que no aparezcan pósters con texto en otros idiomas.
- Un array vacío es un 200 normal. Recurre al `poster_path` del registro de [detalles de película](https://amodb.dev/es/movies/).
- Usa `w1280` para imágenes de fondo a todo el ancho y `w780` para tarjetas. `original` es el archivo guardado a resolución completa y es mucho más grande que `w780`.
- Las copias de la caché perimetral viven 30 días y se comparten, así que un archivo que pidió un cliente se sirve desde la caché al siguiente.

## Preguntas y respuestas

### ¿Las solicitudes de imágenes necesitan una clave de API?

No. Los archivos en img.amodb.dev/t/p/{size}/{file} son públicos, así que puedes usarlos directamente en etiquetas img y en CSS. Solo los endpoints JSON que listan las rutas de archivo necesitan tu clave.

### ¿Qué tamaños de imagen puedo pedir?

w92, w154, w185, w300, w342, w500, w780, w1280, h632 y original. Cualquier otro tamaño responde 404. /3/configuration lista cuáles encajan con cada tipo de imagen, y la tabla de tamaños de esta página lo repite.

### ¿Cómo obtengo pósters en un solo idioma?

Pasa include_image_language con una lista separada por comas, por ejemplo en,null. El valor null añade las imágenes sin texto. Solo llegan los idiomas indicados. El parámetro language no filtra las imágenes.

### ¿Por qué la ruta del archivo empieza con una barra?

Las rutas al estilo TMDB incluyen la barra inicial para que puedas añadirlas directamente al segmento de tamaño. Guarda solo la ruta y construye la URL completa al mostrar la imagen.

## Páginas relacionadas

- [API de detalles de película](https://amodb.dev/es/movies/): API de detalles de película con rutas y JSON de TMDB v3. Obtén una película por id y añade créditos, puntuaciones y moods con append_to_response, en 14 idiomas.
- [API de series de TV](https://amodb.dev/es/tv-series/): API de series de TV con las mismas rutas y JSON que TMDB v3. Obtén una serie con temporadas, cadenas y próximo episodio, más clasificaciones y plataformas.
- [API de detalles de persona](https://amodb.dev/es/people/): API de detalles de persona con rutas y JSON de TMDB v3. Obtén un actor o miembro del equipo por id, con biografía, filmografía, ids externos y populares.
- [API de colecciones](https://amodb.dev/es/collections/): API de colecciones de películas con rutas TMDB v3: obtén una saga por id con todas sus partes, lee belongs_to_collection en una película y busca por nombre.
- [API de pósters de películas y CDN de imágenes](https://amodb.dev/es/movie-poster-api/): API de pósters de películas con host de imágenes sin clave. Tamaños de w92 a original, listas srcset y pósters por idioma con include_image_language.
- [Inicio rápido](https://amodb.dev/es/quickstart/): Haz tu primera llamada a amodb: consigue una clave, pide los detalles de una película en curl, JavaScript, Python, PHP o Go y carga el póster. En 2 minutos.

Actualizado: 2026-10-18. Source: https://amodb.dev/es/images-api/
