# Oceny filmów i seriali

> GET /3/movie/{movie_id}/ratings i GET /3/tv/{tv_id}/ratings zwracają wyniki z IMDb, Kinopoisk, Metacritic, Rotten Tomatoes i TMDB. Każde źródło to obiekt z value i votes albo null, gdy jest nieznane. IMDb, Kinopoisk i TMDB są w skali do 10, pozostałe dwa do 100. Dodaj append_to_response=ratings, by scalić je ze szczegółami.

## Endpoint

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

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

Odpowiedź:

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

## Pobieranie ocen filmu

`GET /3/movie/{movie_id}/ratings` zwraca wyniki, które źródła ocen publikują dla jednego filmu. Odpowiedź ma `id` filmu i pięć kluczy źródeł: `imdb`, `kinopoisk`, `metacritic`, `rotten_tomatoes` i `tmdb`. Każdy klucz źródła zawiera obiekt z `value` i `votes` albo `null`, gdy to źródło nie zna tytułu.

Przykład pobiera Fight Club (ID 550) i wypisuje każde źródło, oznaczając nieznane.

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

### Parametry

| Parametr   | Gdzie | Wymagany      | Opis                                                       |
| ---------- | ----- | ------------- | ---------------------------------------------------------- |
| `movie_id` | path  | tak           | Numeryczne ID filmu, na przykład `550`.                    |
| `api_key`  | query | jeden z dwóch | Twój klucz. Użyj go albo nagłówka `Authorization: Bearer`. |

### Pola odpowiedzi

| Pole              | Typ              | Uwagi                                                                                         |
| ----------------- | ---------------- | --------------------------------------------------------------------------------------------- |
| `id`              | integer          | ID filmu. Nieobecne przy użyciu `append_to_response`.                                         |
| `imdb`            | object lub null  | Wynik IMDb, w skali do 10 z jednym miejscem po przecinku.                                     |
| `kinopoisk`       | object lub null  | Wynik Kinopoisk, w skali do 10 z jednym miejscem po przecinku.                                |
| `metacritic`      | object lub null  | Wynik Metacritic, w skali do 100 jako liczba całkowita.                                       |
| `rotten_tomatoes` | object lub null  | Wynik Rotten Tomatoes, w skali do 100 jako liczba całkowita.                                  |
| `tmdb`            | object lub null  | Ocena użytkowników TMDB, w skali do 10 z maksymalnie trzema miejscami po przecinku.           |
| `value`           | number           | Wewnątrz każdego obiektu źródła. Wynik w skali tego źródła.                                   |
| `votes`           | integer lub null | Wewnątrz każdego obiektu źródła. Liczba głosów stojąca za wynikiem albo `null`, gdy nieznana. |

Pięć kluczy źródeł czytaj po nazwie, a inne klucze pomiń. Klucze źródeł zawsze przychodzą w tej samej kolejności: `imdb`, `kinopoisk`, `metacritic`, `rotten_tomatoes`, `tmdb`.

### Przykładowa odpowiedź

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

Liczbę głosów mają tu tylko IMDb i TMDB. Kinopoisk, Metacritic i Rotten Tomatoes mają wynik i liczbę głosów równą `null`.

## Pobieranie ocen serialu

`GET /3/tv/{tv_id}/ratings` ma te same klucze i te same reguły dla null. Przekaż ID serialu, na przykład `1396` dla Breaking Bad.

| Metoda i ścieżka                  | Zwraca             | Parametry  |
| --------------------------------- | ------------------ | ---------- |
| `GET /3/movie/{movie_id}/ratings` | `id` i pięć źródeł | `movie_id` |
| `GET /3/tv/{tv_id}/ratings`       | `id` i pięć źródeł | `tv_id`    |

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

Breaking Bad nie ma wyniku Metacritic, więc to źródło ma wartość `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 }
}
```

## Dołączanie ocen do wywołania szczegółów

`append_to_response=ratings` działa w szczegółach filmów i seriali. Obiekt przychodzi pod kluczem `ratings` obok zwykłych pól, bez własnego `id`. Strona z listą potrzebuje jednego żądania na tytuł zamiast dwóch.

| Żądanie                                         | Gdzie pojawiają się wyniki                |
| ----------------------------------------------- | ----------------------------------------- |
| `/3/movie/550?append_to_response=ratings`       | `ratings` w rekordzie filmu               |
| `/3/tv/1396?append_to_response=credits,ratings` | `ratings` i `credits` w rekordzie serialu |

Inne wartości, które można dołączyć, opisują [szczegóły filmu](https://amodb.dev/pl/movies/) i [seriale](https://amodb.dev/pl/tv-series/).

## Źródła i wartości null

Źródło null to nie wynik zerowy. Oznacza, że wyniku dla tytułu brak.

| Klucz             | Źródło          | Skala    | Etykieta do pokazania |
| ----------------- | --------------- | -------- | --------------------- |
| `imdb`            | IMDb            | 0 do 10  | IMDb                  |
| `kinopoisk`       | Kinopoisk       | 0 do 10  | Kinopoisk             |
| `metacritic`      | Metacritic      | 0 do 100 | Metacritic            |
| `rotten_tomatoes` | Rotten Tomatoes | 0 do 100 | Rotten Tomatoes       |
| `tmdb`            | TMDB            | 0 do 10  | TMDB                  |

Pokrycie zależy od tytułu, więc programuj pod null, a nie pod stałą listę źródeł. Dowolny z pięciu kluczy może mieć null dla dowolnego tytułu.

## Czym oceny różnią się od vote_average

Pola `vote_average` i `vote_count` w rekordzie filmu lub serialu to ocena użytkowników TMDB. Klucz `tmdb` niesie tę samą ocenę w takim samym kształcie jak pozostałe cztery, więc jedno wywołanie daje wszystkie pięć źródeł w jednym formacie.

Każde źródło ma własną publiczność i skalę. Nie uśredniaj ich i nie porównuj wartości jednego źródła z liczbą głosów innego.

## Pokazywanie ocen w aplikacji

Renderuj tylko źródła, które są obecne. Dla karty wystarczy krótka lista plakietek. Dodaj skalę, by czytelnik odróżnił 8.8 z 10 od 67 ze 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}`);
}
```

Pokaż etykietę przy każdej wartości. Gdy wszystkie pięć to null, ukryj blok zamiast pokazywać puste plakietki.

## Błędy

Błędy zachowują treść błędu TMDB, w której `success` ma wartość false, a `status_code` nazywa problem. Tytuł bez wyników do nich nie należy.

| HTTP | status_code | Kiedy                                                                               |
| ---- | ----------- | ----------------------------------------------------------------------------------- |
| 401  | 7           | Brakuje klucza lub jest błędny.                                                     |
| 402  | 36          | Okres planu dobiegł końca.                                                          |
| 404  | 34          | Brak filmu lub serialu o tym ID.                                                    |
| 429  | 25          | Przekroczono limit żądań na minutę. Poczekaj tyle sekund, ile podaje `Retry-After`. |

Nieznany wynik to `null`, a nie błąd. Szczegóły są na stronach [błędy](https://amodb.dev/pl/errors/) i [limity żądań](https://amodb.dev/pl/rate-limits/).

## Praktyczne uwagi

- Oceny są w cache na edge przez 6 godzin, tak jak szczegóły. Odświeżanie ich częściej zwraca tę samą treść.
- Żądanie z `append_to_response=ratings` liczy się jako jedno żądanie z twoich 20, 40 lub 120 żądań na minutę.
- Zapisuj wyniki z datą ich pobrania. Głosów przybywa i liczby się zmieniają.
- Aby najpierw zamienić ID z IMDb lub Kinopoisk na tytuł, użyj [wyszukiwania po zewnętrznym ID](https://amodb.dev/pl/find-by-external-id/). Dla odczuć zamiast wyników zobacz [nastroje](https://amodb.dev/pl/moods/).

## Pytania i odpowiedzi

### Dlaczego źródło ma wartość null?

Null oznacza, że wynik dla tego tytułu jest nieznany lub zerowy. Nowa premiera albo film regionalny ma często mniej źródeł niż głośny, więc zawsze obsłuż null, zanim sformatujesz liczbę. Pole votes też może mieć wartość null.

### Czym to się różni od vote_average?

Pole vote_average w rekordzie szczegółów to tylko ocena użytkowników TMDB. Endpoint ratings zwraca ją ponownie pod kluczem tmdb, z trzema miejscami po przecinku, i dodaje cztery inne źródła, każde jako value i votes.

### Czy mogę uśrednić pięć wyników?

Nie rób tego. IMDb, Kinopoisk i TMDB są w skali do 10, a Metacritic i Rotten Tomatoes do 100. Każde źródło ma też własną publiczność, a niektóre mają null. Pokaż dostępne źródła obok siebie z etykietami.

### Czy wywołanie ocen kosztuje dodatkowe żądania?

To jedno żądanie jak każde inne. Z append_to_response=ratings wyniki przychodzą w wywołaniu szczegółów, więc zużywasz jedno żądanie z minuty zamiast dwóch.

## Powiązane strony

- [API szczegółów filmu](https://amodb.dev/pl/movies/): API szczegółów filmu z tymi samymi ścieżkami i JSON co TMDB v3. Pobierz film po ID, dołącz obsadę, oceny i nastroje przez append_to_response, 14 języków.
- [API szczegółów serialu](https://amodb.dev/pl/tv-series/): API szczegółów serialu z tymi samymi ścieżkami i JSON co TMDB v3. Serial po ID z sezonami, sieciami, klasyfikacją wiekową i dostawcami streamingu.
- [Wyszukiwanie po zewnętrznym ID](https://amodb.dev/pl/find-by-external-id/): Znajdź film, serial lub osobę po ID z IMDb, TVDB, Wikidata lub Kinopoisk przez endpoint find z TMDB oraz odczytaj zewnętrzne ID i fakty z Wikidata o tytule.
- [Mierniki nastroju](https://amodb.dev/pl/moods/): API nastrojów z miernikami na skali od 0 do 10. Odczytaj nastroje filmu lub serialu, scal je przez append_to_response=moods i zbuduj plakietki albo filtry.
- [Limity żądań](https://amodb.dev/pl/rate-limits/): amodb limituje klucz liczbą żądań na minutę w przesuwanym oknie 60 sekund: 20, 40 lub 120 zależnie od planu. Czytaj nagłówki limitu i obsłuż 429 z Retry-After.
- [Szybki start](https://amodb.dev/pl/quickstart/): Pierwsze wywołanie amodb: zdobądź klucz, pobierz szczegóły filmu w curl, JavaScript, Python, PHP lub Go, potem załaduj plakat z img.amodb.dev. Poniżej 2 minut.

Zaktualizowano: 2026-10-18. Source: https://amodb.dev/pl/ratings/
