# Puntuaciones de películas y series

> GET /3/movie/{movie_id}/ratings y GET /3/tv/{tv_id}/ratings devuelven las puntuaciones de IMDb, Kinopoisk, Metacritic, Rotten Tomatoes y TMDB. Cada fuente es un objeto con value y votes, o null si se desconoce. IMDb, Kinopoisk y TMDB van sobre 10, las otras dos sobre 100. Añade append_to_response=ratings para unirlo a los detalles.

## Endpoint

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

```bash
curl "https://api.amodb.dev/3/movie/550/ratings" \
  -H "Authorization: Bearer $AMODB_KEY"
```

Respuesta:

```json
{
  "id": 550,
  "imdb": {
    "value": 8.8,
    "votes": 2669989
  },
  "kinopoisk": {
    "value": 8.7,
    "votes": null
  },
  "metacritic": {
    "value": 67,
    "votes": null
  },
  "rotten_tomatoes": {
    "value": 81,
    "votes": null
  },
  "tmdb": {
    "value": 8.437,
    "votes": 33042
  }
}
```

## Obtener las puntuaciones de una película

`GET /3/movie/{movie_id}/ratings` devuelve las puntuaciones que publican las fuentes de valoración para una película. La respuesta trae el `id` de la película y cinco claves de fuente: `imdb`, `kinopoisk`, `metacritic`, `rotten_tomatoes` y `tmdb`. Cada clave de fuente contiene un objeto con `value` y `votes`, o `null` cuando esa fuente no se conoce para el título.

El ejemplo carga Fight Club (id 550) e imprime todas las fuentes, marcando las desconocidas.

```bash
curl -sf "https://api.amodb.dev/3/movie/550/ratings" \
  -H "Authorization: Bearer $AMODB_KEY"
```

```js
const res = await fetch('https://api.amodb.dev/3/movie/550/ratings', {
  headers: { Authorization: `Bearer ${process.env.AMODB_KEY}` },
});
if (!res.ok) throw new Error(`amodb returned ${res.status}`);
const ratings = await res.json();
for (const source of ['imdb', 'kinopoisk', 'metacritic', 'rotten_tomatoes', 'tmdb']) {
  const score = ratings[source];
  console.log(source, score ? `${score.value} (votes: ${score.votes ?? 'unknown'})` : 'not known');
}
```

```python
import os
import requests

r = requests.get(
    "https://api.amodb.dev/3/movie/550/ratings",
    headers={"Authorization": f"Bearer {os.environ['AMODB_KEY']}"},
    timeout=10,
)
r.raise_for_status()
ratings = r.json()
for source in ("imdb", "kinopoisk", "metacritic", "rotten_tomatoes", "tmdb"):
    score = ratings[source]
    if score is None:
        print(source, "not known")
    else:
        print(source, score["value"], "votes:", score["votes"] or "unknown")
```

```php
<?php
$ch = curl_init('https://api.amodb.dev/3/movie/550/ratings');
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");
}
$ratings = json_decode($body, true);
foreach (['imdb', 'kinopoisk', 'metacritic', 'rotten_tomatoes', 'tmdb'] as $source) {
    $score = $ratings[$source];
    echo $source, ' ', $score === null ? 'not known' : $score['value'] . ' votes: ' . ($score['votes'] ?? 'unknown'), PHP_EOL;
}
```

```go
package main

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

type Score struct {
	Value float64 `json:"value"`
	Votes *int    `json:"votes"`
}

type Ratings struct {
	IMDb           *Score `json:"imdb"`
	Kinopoisk      *Score `json:"kinopoisk"`
	Metacritic     *Score `json:"metacritic"`
	RottenTomatoes *Score `json:"rotten_tomatoes"`
	TMDB           *Score `json:"tmdb"`
}

func show(name string, s *Score) {
	if s == nil {
		fmt.Println(name, "not known")
		return
	}
	if s.Votes == nil {
		fmt.Println(name, s.Value, "votes: unknown")
		return
	}
	fmt.Println(name, s.Value, "votes:", *s.Votes)
}

func main() {
	req, _ := http.NewRequest("GET", "https://api.amodb.dev/3/movie/550/ratings", 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 r Ratings
	if err := json.NewDecoder(res.Body).Decode(&r); err != nil {
		panic(err)
	}
	show("imdb", r.IMDb)
	show("kinopoisk", r.Kinopoisk)
	show("metacritic", r.Metacritic)
	show("rotten_tomatoes", r.RottenTomatoes)
	show("tmdb", r.TMDB)
}
```

### 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`. |

### Campos de la respuesta

| Campo             | Tipo          | Notas                                                                                                   |
| ----------------- | ------------- | ------------------------------------------------------------------------------------------------------- |
| `id`              | entero        | Id de la película. No aparece cuando usas `append_to_response`.                                         |
| `imdb`            | objeto o null | Puntuación de IMDb, sobre 10 con un decimal.                                                            |
| `kinopoisk`       | objeto o null | Puntuación de Kinopoisk, sobre 10 con un decimal.                                                       |
| `metacritic`      | objeto o null | Puntuación de Metacritic, sobre 100 como entero.                                                        |
| `rotten_tomatoes` | objeto o null | Puntuación de Rotten Tomatoes, sobre 100 como entero.                                                   |
| `tmdb`            | objeto o null | Puntuación de usuarios de TMDB, sobre 10 con hasta tres decimales.                                      |
| `value`           | número        | Dentro de cada objeto de fuente. La puntuación en la escala propia de esa fuente.                       |
| `votes`           | entero o null | Dentro de cada objeto de fuente. Número de votos detrás de la puntuación, o `null` cuando no se conoce. |

Lee las cinco claves de fuente por nombre y omite cualquier otra clave. Las claves de fuente siempre llegan en el mismo orden: `imdb`, `kinopoisk`, `metacritic`, `rotten_tomatoes`, `tmdb`.

### Ejemplo de respuesta

```json
{
  "id": 550,
  "imdb": { "value": 8.8, "votes": 2669989 },
  "kinopoisk": { "value": 8.7, "votes": null },
  "metacritic": { "value": 67, "votes": null },
  "rotten_tomatoes": { "value": 81, "votes": null },
  "tmdb": { "value": 8.437, "votes": 33039 }
}
```

Aquí solo IMDb y TMDB traen número de votos. Kinopoisk, Metacritic y Rotten Tomatoes tienen una puntuación y un número de votos `null`.

## Obtener las puntuaciones de una serie de TV

`GET /3/tv/{tv_id}/ratings` tiene las mismas claves y las mismas reglas de null. Pasa el id de la serie, por ejemplo `1396` para Breaking Bad.

| Método y ruta                     | Devuelve             | Parámetros |
| --------------------------------- | -------------------- | ---------- |
| `GET /3/movie/{movie_id}/ratings` | `id` y cinco fuentes | `movie_id` |
| `GET /3/tv/{tv_id}/ratings`       | `id` y cinco fuentes | `tv_id`    |

```bash
curl -sf "https://api.amodb.dev/3/tv/1396/ratings" -H "Authorization: Bearer $AMODB_KEY"
```

Breaking Bad no tiene puntuación de Metacritic, así que esa fuente es `null`:

```json
{
  "id": 1396,
  "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 }
}
```

## Añadir puntuaciones a una llamada de detalles

`append_to_response=ratings` funciona en los detalles de películas y de TV. El objeto llega bajo la clave `ratings` junto a los campos habituales, sin su propio `id`. Una página de lista necesita una solicitud por título en lugar de dos.

| Solicitud                                       | Dónde aparecen las puntuaciones                  |
| ----------------------------------------------- | ------------------------------------------------ |
| `/3/movie/550?append_to_response=ratings`       | `ratings` en el registro de la película          |
| `/3/tv/1396?append_to_response=credits,ratings` | `ratings` y `credits` en el registro de la serie |

Consulta los [detalles de película](https://amodb.dev/es/movies/) y las [series de TV](https://amodb.dev/es/tv-series/) para ver los demás valores que puedes añadir.

## Fuentes y valores null

Una fuente null no es una puntuación cero. Significa que la puntuación falta para el título.

| Clave             | Fuente          | Escala  | Etiqueta que mostrar |
| ----------------- | --------------- | ------- | -------------------- |
| `imdb`            | IMDb            | 0 a 10  | IMDb                 |
| `kinopoisk`       | Kinopoisk       | 0 a 10  | Kinopoisk            |
| `metacritic`      | Metacritic      | 0 a 100 | Metacritic           |
| `rotten_tomatoes` | Rotten Tomatoes | 0 a 100 | Rotten Tomatoes      |
| `tmdb`            | TMDB            | 0 a 10  | TMDB                 |

La cobertura varía según el título, así que programa contra null, no contra una lista fija de fuentes. Cualquiera de las cinco claves puede ser null para cualquier título.

## Cómo se diferencian las puntuaciones de vote_average

Los campos `vote_average` y `vote_count` de un registro de película o serie son la puntuación de usuarios de TMDB. La clave `tmdb` lleva la misma puntuación con la misma forma que las otras cuatro, así que una llamada te da las cinco fuentes en un mismo formato.

Cada fuente tiene su propia audiencia y escala. No las promedies y no compares un valor de una fuente con el número de votos de otra.

## Mostrar puntuaciones en una aplicación

Muestra solo las fuentes presentes. Una lista corta de insignias basta para una tarjeta. Añade la escala para que el lector distinga 8.8 sobre 10 de 67 sobre 100.

```js
const labels = {
  imdb: ['IMDb', 10],
  kinopoisk: ['Kinopoisk', 10],
  metacritic: ['Metacritic', 100],
  rotten_tomatoes: ['Rotten Tomatoes', 100],
  tmdb: ['TMDB', 10],
};

function badges(ratings) {
  return Object.entries(labels)
    .filter(([key]) => ratings[key])
    .map(([key, [label, max]]) => `${label} ${ratings[key].value}/${max}`);
}
```

Muestra la etiqueta con cada valor. Cuando las cinco son null, oculta el bloque en lugar de mostrar insignias vacías.

## Errores

Los fallos conservan el cuerpo de error de TMDB, donde `success` es false y `status_code` nombra el problema. Un título sin puntuaciones no es uno de ellos.

| HTTP | status_code | Cuándo                                                                      |
| ---- | ----------- | --------------------------------------------------------------------------- |
| 401  | 7           | La clave falta o es incorrecta.                                             |
| 402  | 36          | El periodo del plan ha terminado.                                           |
| 404  | 34          | No hay ninguna película o serie con ese id.                                 |
| 429  | 25          | Superaste tus solicitudes por minuto. Espera los segundos de `Retry-After`. |

Una puntuación desconocida es `null`, no un error. Los detalles están en [errores](https://amodb.dev/es/errors/) y [límites de solicitudes](https://amodb.dev/es/rate-limits/).

## Notas prácticas

- Las puntuaciones se guardan en la caché perimetral 6 horas, igual que los detalles. Actualizar con más frecuencia devuelve el mismo cuerpo.
- Una solicitud con `append_to_response=ratings` cuenta como una sola de tus 20, 40 o 120 solicitudes por minuto.
- Guarda las puntuaciones con la fecha en que las obtuviste. Los votos crecen con el tiempo y las cifras cambian.
- Para asignar primero un id de IMDb o de Kinopoisk a un título, usa la [búsqueda por id externo](https://amodb.dev/es/find-by-external-id/). Para sensaciones en lugar de puntuaciones, consulta los [moods](https://amodb.dev/es/moods/).

## Preguntas y respuestas

### ¿Por qué una fuente es null?

Null significa que la puntuación falta o es cero para ese título. Un estreno reciente o una película regional suele tener menos fuentes que una famosa, así que trata siempre el null antes de dar formato a un número. El campo votes también puede ser null.

### ¿En qué se diferencia de vote_average?

El campo vote_average de un registro de detalles es solo la puntuación de usuarios de TMDB. El endpoint de puntuaciones la devuelve de nuevo bajo la clave tmdb, con tres decimales, y añade las otras cuatro fuentes, cada una con value y votes.

### ¿Puedo promediar las cinco puntuaciones?

No lo hagas. IMDb, Kinopoisk y TMDB van sobre 10, mientras que Metacritic y Rotten Tomatoes van sobre 100. Además, cada fuente tiene su propia audiencia, y algunas son null. Muestra las fuentes que tengas una junto a otra, con sus etiquetas.

### ¿La llamada de puntuaciones cuesta solicitudes extra?

Es una solicitud como cualquier otra. Con append_to_response=ratings las puntuaciones llegan dentro de una llamada de detalles, así que gastas una solicitud de tu cupo por minuto en lugar de dos.

## 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.
- [Buscar por id externo](https://amodb.dev/es/find-by-external-id/): Busca una película, serie o persona por id de IMDb, TVDB, Wikidata o Kinopoisk con el endpoint find de TMDB, y lee los ids externos y los datos de Wikidata.
- [Medidores de mood](https://amodb.dev/es/moods/): API de moods con medidores de 0 a 10 por título. Lee los moods de una película o serie, únelos con append_to_response=moods y crea insignias o filtros.
- [Límites de solicitudes](https://amodb.dev/es/rate-limits/): amodb limita cada clave por solicitudes por minuto en una ventana deslizante de 60 segundos: 20, 40 o 120 según el plan. Lee los encabezados y gestiona el 429.
- [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/ratings/
