# Рейтинги фильмов и сериалов

> GET /3/movie/{movie_id}/ratings и GET /3/tv/{tv_id}/ratings возвращают оценки IMDb, Kinopoisk, Metacritic, Rotten Tomatoes и TMDB. Каждый источник это объект с value и votes или null, если оценка неизвестна. IMDb, Kinopoisk и TMDB даны по шкале до 10, остальные два до 100. Добавьте append_to_response=ratings, чтобы получить их вместе с деталями.

## Эндпоинт

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

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

Ответ:

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

## Получение рейтингов фильма

`GET /3/movie/{movie_id}/ratings` возвращает оценки, которые публикуют источники рейтингов для одного фильма. В ответе есть `id` фильма и пять ключей источников: `imdb`, `kinopoisk`, `metacritic`, `rotten_tomatoes` и `tmdb`. Каждый ключ источника содержит объект с `value` и `votes` или `null`, если этот источник для тайтла неизвестен.

Пример загружает Fight Club (ID 550) и выводит каждый источник, помечая неизвестные.

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

### Параметры

| Параметр   | Где   | Обязателен   | Описание                                                         |
| ---------- | ----- | ------------ | ---------------------------------------------------------------- |
| `movie_id` | path  | да           | Числовой ID фильма, например `550`.                              |
| `api_key`  | query | один из двух | Ваш ключ. Используйте его или заголовок `Authorization: Bearer`. |

### Поля ответа

| Поле              | Тип                  | Примечания                                                                                                         |
| ----------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------ |
| `id`              | целое число          | ID фильма. Отсутствует, если вы используете `append_to_response`.                                                  |
| `imdb`            | объект или null      | Оценка IMDb, по шкале до 10 с одним десятичным знаком.                                                             |
| `kinopoisk`       | объект или null      | Оценка Kinopoisk, по шкале до 10 с одним десятичным знаком.                                                        |
| `metacritic`      | объект или null      | Оценка Metacritic, по шкале до 100, целое число.                                                                   |
| `rotten_tomatoes` | объект или null      | Оценка Rotten Tomatoes, по шкале до 100, целое число.                                                              |
| `tmdb`            | объект или null      | Пользовательская оценка TMDB, по шкале до 10 с тремя десятичными знаками.                                          |
| `value`           | число                | Внутри каждого объекта источника. Оценка по собственной шкале этого источника.                                     |
| `votes`           | целое число или null | Внутри каждого объекта источника. Количество голосов, на которых основана оценка, или `null`, если оно неизвестно. |

Читайте пять ключей источников по имени и пропускайте любые другие ключи. Ключи источников всегда идут в одном порядке: `imdb`, `kinopoisk`, `metacritic`, `rotten_tomatoes`, `tmdb`.

### Пример ответа

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

Количество голосов здесь есть только у IMDb и TMDB. У Kinopoisk, Metacritic и Rotten Tomatoes есть оценка, а количество голосов равно `null`.

## Получение рейтингов сериала

`GET /3/tv/{tv_id}/ratings` возвращает те же ключи и подчиняется тем же правилам для null. Передайте ID сериала, например `1396` для Breaking Bad.

| Метод и путь                      | Возвращает             | Параметры  |
| --------------------------------- | ---------------------- | ---------- |
| `GET /3/movie/{movie_id}/ratings` | `id` и пять источников | `movie_id` |
| `GET /3/tv/{tv_id}/ratings`       | `id` и пять источников | `tv_id`    |

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

У Breaking Bad нет оценки Metacritic, поэтому этот источник равен `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 }
}
```

## Добавление рейтингов к вызову деталей

`append_to_response=ratings` работает с деталями фильмов и сериалов. Объект приходит под ключом `ratings` рядом с обычными полями, без собственного `id`. Для страницы со списком нужен один запрос на тайтл вместо двух.

| Запрос                                          | Где появляются оценки                  |
| ----------------------------------------------- | -------------------------------------- |
| `/3/movie/550?append_to_response=ratings`       | `ratings` в записи фильма              |
| `/3/tv/1396?append_to_response=credits,ratings` | `ratings` и `credits` в записи сериала |

Другие значения, которые можно добавить, смотрите на страницах [детали фильма](https://amodb.dev/ru/movies/) и [сериалы](https://amodb.dev/ru/tv-series/).

## Источники и значения null

Источник со значением null не означает нулевую оценку. Это значит, что оценка для тайтла отсутствует.

| Ключ              | Источник        | Шкала       | Подпись для показа |
| ----------------- | --------------- | ----------- | ------------------ |
| `imdb`            | IMDb            | от 0 до 10  | IMDb               |
| `kinopoisk`       | Kinopoisk       | от 0 до 10  | Kinopoisk          |
| `metacritic`      | Metacritic      | от 0 до 100 | Metacritic         |
| `rotten_tomatoes` | Rotten Tomatoes | от 0 до 100 | Rotten Tomatoes    |
| `tmdb`            | TMDB            | от 0 до 10  | TMDB               |

Охват зависит от тайтла, поэтому ориентируйтесь на null, а не на фиксированный список источников. Любой из пяти ключей может быть null для любого тайтла.

## Чем рейтинги отличаются от vote_average

Поля `vote_average` и `vote_count` в записи фильма или сериала содержат пользовательскую оценку TMDB. Ключ `tmdb` несет ту же оценку в той же форме, что и остальные четыре, поэтому один вызов дает все пять источников в одном формате.

У каждого источника своя аудитория и шкала. Не усредняйте их и не сравнивайте значение одного источника с количеством голосов другого.

## Показ рейтингов в приложении

Отображайте только имеющиеся источники. Для карточки достаточно короткого списка бейджей. Добавляйте шкалу, чтобы читатель отличал 8.8 из 10 от 67 из 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}`);
}
```

Показывайте подпись с каждым значением. Если все пять равны null, скройте блок вместо пустых бейджей.

## Ошибки

Ошибки сохраняют тело TMDB: `success` равен false, а `status_code` указывает на проблему. Тайтл без оценок ошибкой не считается.

| HTTP | status_code | Когда                                                             |
| ---- | ----------- | ----------------------------------------------------------------- |
| 401  | 7           | Ключ отсутствует или неверен.                                     |
| 402  | 36          | Период тарифа закончился.                                         |
| 404  | 34          | Нет фильма или сериала с таким ID.                                |
| 429  | 25          | Превышен лимит запросов в минуту. Подождите `Retry-After` секунд. |

Неизвестная оценка передается как `null` и ошибкой не считается. Подробности на страницах [ошибки](https://amodb.dev/ru/errors/) и [лимиты запросов](https://amodb.dev/ru/rate-limits/).

## Практические советы

- Рейтинги кэшируются на edge на 6 часов, как и детали. Более частое обновление вернет то же тело ответа.
- Запрос с `append_to_response=ratings` считается одним запросом в вашем лимите 20, 40 или 120 запросов в минуту.
- Храните оценки вместе с датой получения. Голоса накапливаются со временем, и значения меняются.
- Чтобы сначала сопоставить ID IMDb или Kinopoisk с тайтлом, используйте [поиск по внешнему ID](https://amodb.dev/ru/find-by-external-id/). Для эмоций вместо оценок смотрите [настроения](https://amodb.dev/ru/moods/).

## Вопросы и ответы

### Почему источник равен null?

Null означает, что оценка для этого тайтла отсутствует или равна нулю. У новинки или регионального фильма источников часто меньше, чем у известного, поэтому всегда обрабатывайте null, прежде чем форматировать число. Поле votes тоже может быть null.

### Чем это отличается от vote_average?

Поле vote_average в записи деталей содержит только пользовательскую оценку TMDB. Эндпоинт рейтингов возвращает ее еще раз под ключом tmdb, с тремя десятичными знаками, и добавляет остальные четыре источника, каждый как value и votes.

### Можно ли усреднить пять оценок?

Не усредняйте их. IMDb, Kinopoisk и TMDB даны по шкале до 10, а Metacritic и Rotten Tomatoes по шкале до 100. У каждого источника своя аудитория, а некоторые значения равны null. Показывайте имеющиеся источники рядом, с подписями.

### Тратит ли вызов рейтингов дополнительные запросы?

Это один запрос, как и любой другой. С append_to_response=ratings оценки приходят внутри вызова деталей, поэтому вы тратите один запрос в минутном лимите вместо двух.

## Связанные страницы

- [API деталей фильма](https://amodb.dev/ru/movies/): API деталей фильма с теми же путями и JSON, что в TMDB v3. Получите фильм по ID, добавьте актеров, рейтинги и настроения через append_to_response, на 14 языках.
- [API сериалов](https://amodb.dev/ru/tv-series/): API сериалов с теми же путями и JSON, что в TMDB v3. Сериал по id с сезонами, телесетями и следующей серией, а также возрастные рейтинги и сервисы просмотра.
- [Поиск по внешнему ID](https://amodb.dev/ru/find-by-external-id/): Найдите фильм, сериал или персону по ID IMDb, TVDB, Wikidata или Kinopoisk через эндпоинт find TMDB, а также прочитайте внешние ID и факты Wikidata о проекте.
- [Шкалы настроения](https://amodb.dev/ru/moods/): API настроений фильмов: шкалы от 0 до 10 для каждого тайтла. Читайте настроения фильма или сериала, добавляйте через append_to_response=moods, стройте бейджи.
- [Лимиты запросов](https://amodb.dev/ru/rate-limits/): amodb ограничивает ключ запросами в минуту в скользящем окне 60 секунд: 20, 40 или 120 по тарифу. Читайте заголовки лимита и обрабатывайте 429 с Retry-After.
- [Быстрый старт](https://amodb.dev/ru/quickstart/): Первый вызов amodb: получите ключ, запросите детали фильма через curl, JavaScript, Python, PHP или Go и загрузите постер с img.amodb.dev. Меньше 2 минут.

Обновлено: 2026-10-18. Source: https://amodb.dev/ru/ratings/
