# API de imagens e host de imagens

> Os endpoints de imagens listam pôsteres, backdrops, logos, perfis e stills de um título como caminhos de arquivo. Você carrega cada arquivo de img.amodb.dev em um tamanho fixo, sem chave e com cache de borda de 30 dias. Caminhos e JSON seguem o TMDB v3, então o código de imagens existente funciona após trocar a 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"
```

Resposta:

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

## Obter as imagens de um filme

`GET /3/movie/{movie_id}/images` lista todas as imagens conhecidas de um filme em três arrays: `backdrops`, `logos` e `posters`. Cada entrada tem um `file_path`, o tamanho em pixels e uma tag de idioma. O arquivo em si não vem no JSON. Você o carrega do host de imagens em uma segunda etapa.

O exemplo pede imagens em inglês e sem texto, escolhe o primeiro pôster em inglês e depois busca esse arquivo com 500 pixels de largura.

```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                | Em       | Obrigatório | Descrição                                                                                                                                                                                |
| ------------------------ | -------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `movie_id`               | caminho  | sim         | Id numérico do filme, por exemplo `550`.                                                                                                                                                 |
| `api_key`                | consulta | um dos dois | Sua chave. Use este parâmetro ou o header `Authorization: Bearer`.                                                                                                                       |
| `include_image_language` | consulta | não         | Códigos ISO 639-1 separados por vírgulas. Acrescente `null` para incluir imagens sem texto, por exemplo `en,null`. Só os idiomas listados voltam. Sem ele, você recebe todos os idiomas. |
| `language`               | consulta | não         | Aceito, mas ignorado neste endpoint. Use `include_image_language` para escolher idiomas.                                                                                                 |

### Campos da resposta

| Campo                           | Tipo            | Observações                                                                                                                      |
| ------------------------------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `id`                            | inteiro         | O id do filme.                                                                                                                   |
| `backdrops`, `logos`, `posters` | array           | Um array por tipo de imagem, nessa ordem de chaves. Cada um pode vir vazio.                                                      |
| `file_path`                     | string          | Começa com uma barra. Acrescente-o a um tamanho no host de imagens. Pôsteres e backdrops são `.jpg`, logos são `.png` ou `.svg`. |
| `width`, `height`               | inteiro         | Tamanho em pixels do arquivo original. `0` quando o tamanho não é conhecido.                                                     |
| `aspect_ratio`                  | número          | Largura dividida pela altura. Pôsteres ficam perto de 0.667, backdrops perto de 1.778. `0` quando o tamanho não é conhecido.     |
| `iso_639_1`                     | string ou null  | Idioma do texto na imagem. `null` significa sem texto.                                                                           |
| `vote_average`, `vote_count`    | número, inteiro | Sempre `0` em imagens de filmes e séries, então não servem para ordenar imagens. Mantenha a ordem que a API retorna.             |

### Exemplo de resposta

Duas entradas por array aparecem aqui.

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

O segundo pôster mostra uma entrada cujo tamanho não é conhecido. O arquivo carrega normalmente.

## Montar a URL de uma imagem

Junte três partes: `https://img.amodb.dev/t/p/`, um segmento de tamanho e o `file_path`. O caminho já começa com uma barra, então `https://img.amodb.dev/t/p/w500` mais `/jSziioSwPVrOy9Yow3XhWIBDjq1.jpg` é uma URL completa.

Um tamanho é `w` mais uma largura em pixels, `h` mais uma altura em pixels, ou `original` para o arquivo armazenado. O host serve dez tamanhos: `w92`, `w154`, `w185`, `w300`, `w342`, `w500`, `w780`, `w1280`, `h632` e `original`. Qualquer outro tamanho, como `w400`, responde 404. `/3/configuration` lista os tamanhos que servem para cada tipo de imagem.

| Tipo                 | Campo na configuração | Tamanhos                                                  |
| -------------------- | --------------------- | --------------------------------------------------------- |
| Pôster               | `poster_sizes`        | `w92`, `w154`, `w185`, `w342`, `w500`, `w780`, `original` |
| Backdrop             | `backdrop_sizes`      | `w300`, `w780`, `w1280`, `original`                       |
| Logo                 | `logo_sizes`          | `w92`, `w154`, `w185`, `w300`, `w500`, `original`         |
| Perfil               | `profile_sizes`       | `w185`, `h632`, `original`                                |
| Still (foto de cena) | `still_sizes`         | `w92`, `w185`, `w300`, `original`                         |

O host não verifica o tipo, então um pôster também carrega em `w1280`. Fique nos tamanhos listados para o tipo, para que seu código corresponda à configuração e a qualquer cliente do TMDB.

O host de imagens não exige chave, e a borda guarda cada arquivo por 30 dias. Como nenhuma chave é enviada, o carregamento de imagens não consome o seu limite de requisições por minuto. As respostas trazem `Access-Control-Allow-Origin: *`, então um navegador pode carregá-las de qualquer página. Um tamanho desconhecido ou um arquivo desconhecido responde 404 com um corpo JSON.

## Imagens responsivas com srcset

Escolha o menor tamanho que ainda cubra a largura exibida vezes a densidade da tela. Um pôster exibido com 171 pixels CSS de largura precisa de `w342` em uma tela 2x. Esta função auxiliar monta um `srcset` a partir de um caminho guardado.

```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">`);
```

## Outros endpoints de imagens

Todos os caminhos abaixo usam a base `https://api.amodb.dev/3` e retornam os arrays citados na segunda coluna.

| Método e caminho                                                             | Arrays retornados                                             | Parâmetros               |
| ---------------------------------------------------------------------------- | ------------------------------------------------------------- | ------------------------ |
| `GET /tv/{series_id}/images`                                                 | `backdrops`, `logos`, `posters`                               | `include_image_language` |
| `GET /tv/{series_id}/season/{season_number}/images`                          | `posters`, sempre vazio                                       | nenhum                   |
| `GET /tv/{series_id}/season/{season_number}/episode/{episode_number}/images` | `stills`, uma entrada com `width` e `height` definidos como 0 | nenhum                   |
| `GET /person/{person_id}/images`                                             | `profiles`                                                    | nenhum                   |

Para filmes e séries, você também pode acrescentar `append_to_response=images` a uma chamada de detalhes. `include_image_language` funciona ali também. O bloco anexado não tem um `id` próprio.

Os perfis de pessoas são o único lugar em que `vote_average` traz uma nota real. O `id` da resposta de uma temporada ou de um episódio é o id da temporada ou do episódio. Veja [pessoas](https://amodb.dev/pt/people/) e [séries de TV](https://amodb.dev/pt/tv-series/) para os registros principais.

O amodb não oferece caminhos de imagens para coleções, produtoras e emissoras. Os registros delas já têm um `poster_path`, `backdrop_path` ou `logo_path`, descritos em [coleções](https://amodb.dev/pt/collections/) e em [produtoras e emissoras](https://amodb.dev/pt/companies-networks/).

## O endpoint de configuração

`GET /3/configuration` retorna um bloco `images` com `secure_base_url` definido como `https://img.amodb.dev/t/p/`, `base_url` (a forma http simples) e as listas de tamanhos `backdrop_sizes`, `logo_sizes`, `poster_sizes`, `profile_sizes` e `still_sizes`. Leia-o uma vez na inicialização, use a forma segura e monte as URLs a partir dele em vez de fixar os tamanhos no código. A borda o guarda em cache por 24 horas.

## Erros

| HTTP | status_code | Quando                                                                                                       |
| ---- | ----------- | ------------------------------------------------------------------------------------------------------------ |
| 401  | 7           | A chave está ausente ou incorreta em uma chamada JSON.                                                       |
| 402  | 36          | O período do plano terminou.                                                                                 |
| 404  | 34          | Nenhuma pessoa, temporada ou episódio com esse id, ou um tamanho ou arquivo desconhecido no host de imagens. |
| 405  | 37          | Você usou um método de escrita em um caminho de imagens.                                                     |
| 429  | 25          | Você passou do seu limite de requisições por minuto. Espere os segundos indicados em `Retry-After`.          |

Um id de filme ou série que não existe não é um erro aqui: o caminho de imagens responde 200 com arrays vazios, enquanto o caminho de detalhes responde 404. Veja [erros](https://amodb.dev/pt/errors/) para a lista completa. As requisições de arquivos de imagem são cargas HTTP simples, então confira o código de status da resposta em vez de interpretar um corpo JSON.

## Notas práticas

- Guarde o `file_path` no seu banco de dados e monte a URL na hora de renderizar. Assim, um novo tamanho ou host custa uma só mudança de código.
- Passe `include_image_language` com o seu idioma de exibição mais `null`, por exemplo `ru,null`, para que pôsteres com texto em outros idiomas não apareçam.
- Um array vazio é um 200 normal. Use como alternativa o `poster_path` do registro de [detalhes do filme](https://amodb.dev/pt/movies/).
- Use `w1280` para backdrops de destaque em largura total e `w780` para cards. `original` é o arquivo armazenado em resolução máxima e é bem maior que `w780`.
- As cópias na borda duram 30 dias e são compartilhadas, então um arquivo que um cliente pediu é servido do cache para o próximo.

## Perguntas e respostas

### As requisições de imagem precisam de chave de API?

Não. Os arquivos em img.amodb.dev/t/p/{size}/{file} são públicos, então você pode usá-los direto em tags img e no CSS. Só os endpoints JSON que listam os caminhos dos arquivos exigem a sua chave.

### Quais tamanhos de imagem posso pedir?

w92, w154, w185, w300, w342, w500, w780, w1280, h632 e original. Qualquer outro tamanho responde 404. /3/configuration lista quais deles servem para cada tipo de imagem, e a tabela de tamanhos desta página repete isso.

### Como obtenho pôsteres em um só idioma?

Passe include_image_language com uma lista separada por vírgulas, por exemplo en,null. O valor null acrescenta imagens sem texto. Só os idiomas listados voltam. O parâmetro language não filtra imagens.

### Por que o caminho do arquivo começa com uma barra?

Os caminhos no estilo TMDB incluem a barra inicial para você acrescentá-los direto ao segmento do tamanho. Guarde só o caminho e monte a URL completa na hora de renderizar.

## Páginas relacionadas

- [API de detalhes de filmes](https://amodb.dev/pt/movies/): API de detalhes de filmes com caminhos e JSON do TMDB v3. Busque um filme por id e junte créditos, avaliações e moods com append_to_response, em 14 idiomas.
- [API de séries de TV](https://amodb.dev/pt/tv-series/): API de séries de TV com os mesmos caminhos e JSON do TMDB v3. Busque uma série por id com temporadas, emissoras, próximo episódio e classificações.
- [API de detalhes de pessoas](https://amodb.dev/pt/people/): API de detalhes de pessoas com os caminhos e o JSON do TMDB v3. Busque um ator ou membro da equipe por id, com biografia, filmografia e ids externos.
- [API de coleções](https://amodb.dev/pt/collections/): API de coleções de filmes com caminhos do TMDB v3: busque uma franquia por id com todas as partes, leia belongs_to_collection de um filme e pesquise por nome.
- [API de pôsteres de filmes e CDN de imagens](https://amodb.dev/pt/movie-poster-api/): API de pôsteres de filmes com host de imagens sem chave. Use tamanhos de w92 a original, monte listas srcset e escolha o idioma com include_image_language.
- [Início rápido](https://amodb.dev/pt/quickstart/): Faça sua primeira chamada ao amodb: obtenha uma chave, peça um filme em curl, JavaScript, Python, PHP ou Go e carregue o pôster. Menos de 2 minutos.

Atualizado: 2026-10-18. Source: https://amodb.dev/pt/images-api/
