# Indicatori de atmosferă

> GET /3/movie/{movie_id}/moods și GET /3/tv/{tv_id}/moods întorc o sursă și o listă results. Fiecare rezultat are un nume de atmosferă precum fear sau humor, un avg pe o scară de la 0 la 10 și valorile din spatele lui. Adaugă append_to_response=moods la un apel de detalii ca să îmbini indicatorii fără o a doua cerere.

## Endpoint

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

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

Răspuns:

```json
{
  "id": 155,
  "source": "measured",
  "results": [
    {
      "name": "action",
      "avg": 3.9,
      "values": [
        3.6,
        3.4,
        4.2
      ]
    },
    {
      "name": "fear",
      "avg": 5.2,
      "values": [
        3.6,
        6,
        4.8
      ]
    },
    {
      "name": "humor",
      "avg": 0.9,
      "values": [
        2.4,
        1.8,
        0.4
      ]
    }
  ]
}
```

## Obține indicatorii de atmosferă ai unui film

`GET /3/movie/{movie_id}/moods` întoarce indicatorii de atmosferă ai unui film. Un indicator de atmosferă este un nume și o medie pe o scară de la 0 la 10. Răspunsul conține `id`-ul filmului, un `source` și un array `results`. Fiecare rezultat are `name`, `avg` și `values`.

Exemplul încarcă indicatorii pentru The Dark Knight (ID 155) și îi afișează de la cel mai puternic la cel mai slab.

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

```js
const res = await fetch('https://api.amodb.dev/3/movie/155/moods', {
  headers: { Authorization: `Bearer ${process.env.AMODB_KEY}` },
});
if (!res.ok) throw new Error(`amodb returned ${res.status}`);
const { source, results } = await res.json();
console.log('source:', source);
for (const m of [...results].sort((a, b) => b.avg - a.avg)) {
  console.log(m.name.padEnd(10), m.avg);
}
```

```python
import os
import requests

r = requests.get(
    "https://api.amodb.dev/3/movie/155/moods",
    headers={"Authorization": f"Bearer {os.environ['AMODB_KEY']}"},
    timeout=10,
)
r.raise_for_status()
data = r.json()
print("source:", data.get("source"))
for m in sorted(data["results"], key=lambda m: m["avg"], reverse=True):
    print(f"{m['name']:<10} {m['avg']}")
```

```php
<?php
$ch = curl_init('https://api.amodb.dev/3/movie/155/moods');
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");
}
$data = json_decode($body, true);
echo 'source: ', $data['source'] ?? 'none', PHP_EOL;
$results = $data['results'];
usort($results, fn ($a, $b) => $b['avg'] <=> $a['avg']);
foreach ($results as $m) {
    printf("%-10s %.1f\n", $m['name'], $m['avg']);
}
```

```go
package main

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

type Mood struct {
	Name   string    `json:"name"`
	Avg    float64   `json:"avg"`
	Values []float64 `json:"values"`
}

func main() {
	req, _ := http.NewRequest("GET", "https://api.amodb.dev/3/movie/155/moods", 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 body struct {
		Source  string `json:"source"`
		Results []Mood `json:"results"`
	}
	if err := json.NewDecoder(res.Body).Decode(&body); err != nil {
		panic(err)
	}
	fmt.Println("source:", body.Source)
	sort.Slice(body.Results, func(i, j int) bool { return body.Results[i].Avg > body.Results[j].Avg })
	for _, m := range body.Results {
		fmt.Printf("%-10s %.1f\n", m.Name, m.Avg)
	}
}
```

### Parametri

| Parametru  | Loc        | Obligatoriu          | Descriere                                                             |
| ---------- | ---------- | -------------------- | --------------------------------------------------------------------- |
| `movie_id` | cale       | da                   | ID numeric de film, de exemplu `155`.                                 |
| `api_key`  | interogare | una dintre cele două | Cheia ta. Folosește-o pe aceasta sau antetul `Authorization: Bearer`. |

### Câmpurile răspunsului

| Câmp               | Tip             | Observații                                                                                                          |
| ------------------ | --------------- | ------------------------------------------------------------------------------------------------------------------- |
| `id`               | număr întreg    | ID-ul filmului.                                                                                                     |
| `source`           | șir sau null    | `measured` pentru date ale spectatorilor, `estimated` când este derivat din genuri, `null` când titlul nu are date. |
| `results`          | array           | Indicatori de atmosferă sortați după `name`. Gol când nu se știe nimic.                                             |
| `results[].name`   | șir             | Cuvânt scurt cu litere mici, precum `fear`.                                                                         |
| `results[].avg`    | număr           | Media pe o scară de la 0 la 10. O zecimală la titlurile măsurate, număr întreg la cele estimate.                    |
| `results[].values` | array de numere | Până la 24 de citiri pe aceeași scară de la 0 la 10. Titlurile măsurate văzute au 6, cele estimate au 5.            |

Numele văzute azi sunt `action`, `fear`, `humor`, `pace`, `profanity`, `romance`, `sadness`, `sex` și `violence`. Nu orice titlu le are pe toate nouă, deci afișează numele din date și nu dintr-o listă fixă.

### Exemplu de răspuns

```json
{
  "id": 155,
  "source": "measured",
  "results": [
    { "name": "action", "avg": 3.9, "values": [3.6, 3.4, 4.2, 4.2, 4.8, 3] },
    { "name": "fear", "avg": 5.2, "values": [3.6, 6, 4.8, 6.4, 6.4, 3.8] },
    { "name": "humor", "avg": 0.9, "values": [2.4, 1.8, 0.4, 0.4, 0, 0.5] }
  ]
}
```

Lista este tăiată la 3 din cele 9 rezultate.

### Titluri măsurate și estimate

Fight Club (ID 550) nu are încă date de la spectatori, deci indicatorii lui sunt derivați din genuri. Fiecare `avg` este un număr întreg, iar `values` are 5 intrări.

```json
{
  "id": 550,
  "source": "estimated",
  "results": [
    { "name": "action", "avg": 4, "values": [3, 4, 5, 4, 3] },
    { "name": "fear", "avg": 7, "values": [6, 7, 8, 7, 6] }
  ]
}
```

Verifică `source` dacă vrei să tratezi indicatorii estimați altfel decât pe cei măsurați.

## Obține indicatorii de atmosferă ai unui serial

`GET /3/tv/{tv_id}/moods` are aceeași structură de răspuns, cu ID-ul serialului în `id`. Pentru Breaking Bad folosește `1396`.

| Metodă și cale                | Întoarce                          | Parametri                           |
| ----------------------------- | --------------------------------- | ----------------------------------- |
| `GET /movie/{movie_id}/moods` | `id`, `source` și `results`       | `movie_id`                          |
| `GET /tv/{tv_id}/moods`       | `id`, `source` și `results`       | `tv_id`                             |
| `append_to_response=moods`    | `source` și `results` sub `moods` | Adăugat la detaliile de film sau TV |

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

Când atașezi `moods` la un apel de detalii, cheia `moods` stă la nivelul superior al înregistrării, lângă `title` sau `name`. Conține `source` și `results` și nu are un `id` propriu. Asta costă o cerere, în timp ce două apeluri separate costă două.

## Cum citești scala

Câmpul `avg` este o intensitate de la 0 la 10. Un număr mai mare înseamnă că atmosfera este mai puternică în titlu.

| Interval      | Interpretare                      |
| ------------- | --------------------------------- |
| 0 până la 2.9 | Atmosfera este slabă sau absentă. |
| 3 până la 5.9 | Atmosfera este prezentă.          |
| 6 până la 7.9 | Atmosfera este clară.             |
| 8 până la 10  | Atmosfera definește titlul.       |

Intervalele sunt o sugestie pentru interfața ta, nu un câmp din răspuns. Array-ul `values` conține citirile din spatele mediei, pe aceeași scară.

## Construiește insigne și filtre

Atmosferele se potrivesc cu trei tipare obișnuite de interfață. Alege praguri potrivite catalogului tău și ajustează-le.

| Tipar            | Regulă                                                         | Observații                                        |
| ---------------- | -------------------------------------------------------------- | ------------------------------------------------- |
| Insignă          | Arată până la 3 atmosfere cu `avg` 6 sau mai mare              | Sortează mai întâi după `avg`.                    |
| Bară indicator   | Setează lățimea barei la `avg` înmulțit cu 10, ca procent      | Scala este de la 0 la 10.                         |
| Chip de filtrare | Potrivește titlurile unde atmosfera aleasă este 7 sau mai mare | Preia indicatorii pe titlu, apoi filtrează local. |

```js
function topMoods(results, min = 6, limit = 3) {
  return results
    .filter((m) => m.avg >= min)
    .sort((a, b) => b.avg - a.avg)
    .slice(0, limit)
    .map((m) => m.name);
}

function matchesMood(results, name, min = 7) {
  return results.some((m) => m.name === name && m.avg >= min);
}
```

Un array `results` gol ar trebui afișat ca lipsă de insigne, nu ca eroare.

## Erori

Corpul de eroare are `success`, `status_code` și `status_message`, aceleași câmpuri pe care le folosește TMDB.

| HTTP | status_code | Când                                                                         |
| ---- | ----------- | ---------------------------------------------------------------------------- |
| 401  | 7           | Cheia lipsește sau este greșită.                                             |
| 402  | 36          | Perioada planului s-a încheiat.                                              |
| 429  | 25          | Ai depășit cererile pe minut. Așteaptă numărul de secunde din `Retry-After`. |

Endpoint-ul moods nu răspunde 404 pentru un ID necunoscut. Răspunde 200 cu un array `results` gol, iar `source` este `null` sau lipsește. Atașat la detalii, un ID necunoscut este un 404 de la apelul de detalii. Lista completă este la [erori](https://amodb.dev/ro/errors/), iar limitele sunt la [limite de cereri](https://amodb.dev/ro/rate-limits/).

## Note practice

- Ca alte date de detalii, indicatorii de atmosferă sunt ținuți în cache la margine 6 ore. Preluarea lor mai des întoarce același corp.
- O listă de 20 de titluri cere 20 de cereri de atmosferă. Dacă apelezi deja detaliile fiecărui titlu, atașează `moods` și economisești al doilea apel.
- Verifică `source` înainte să compari titlurile. Indicatorii măsurați și cei estimați folosesc aceeași scară, dar nu aceeași precizie.
- Stochează `name` și `avg` împreună cu ID-ul titlului în propria bază de date dacă filtrezi des. Un filtru local bate o cerere pe titlu.
- Combină indicatorii cu [evaluări](https://amodb.dev/ro/ratings/) pentru un scor și cu [coloane sonore](https://amodb.dev/ro/soundtracks/) pentru muzica aceluiași titlu.

## Întrebări și răspunsuri

### Ce înseamnă o valoare de atmosferă?

Câmpul avg este o intensitate pe o scară de la 0 la 10, cu o zecimală pentru titlurile măsurate. Un avg de 7 pentru fear înseamnă că titlul este înfricoșător, iar 0 înseamnă că atmosfera lipsește. Nu este un procent și nici un scor de recenzie.

### Este fixă lista numelor de atmosferă?

Nu presupune asta. Numele văzute azi sunt action, fear, humor, pace, profanity, romance, sadness, sex și violence, iar un titlu poate avea mai puține de nouă. Afișează șirurile de nume pe care le primești, ca un nume nou să apară și el.

### Ce înseamnă measured și estimated în source?

Measured înseamnă că indicatorii vin din date ale spectatorilor și au zecimale. Estimated înseamnă că sunt derivați din genurile titlului, deci avg este un număr întreg. Un titlu fără date are un array results gol și un source null.

### Cum filtrez o listă de titluri după atmosferă?

Preia indicatorii pentru fiecare titlu din listă, fie cu endpoint-ul moods, fie cu append_to_response la detalii, și păstrează titlurile a căror atmosferă aleasă trece de pragul tău. Filtrul rulează în codul tău.

### Au și serialele TV atmosfere?

Da. Folosește GET /3/tv/{tv_id}/moods, de exemplu cu ID-ul de serial 1396. Răspunsul are aceeași structură ca endpoint-ul pentru filme.

## Pagini conexe

- [API detalii film](https://amodb.dev/ro/movies/): API detalii film cu aceleași căi și același JSON ca TMDB v3. Preia un film după ID, adaugă credite, evaluări și atmosferă cu append_to_response, în 14 limbi.
- [API seriale TV](https://amodb.dev/ro/tv-series/): API seriale TV cu căile și JSON-ul TMDB v3. Preia un serial după ID cu sezoane, rețele și următorul episod, plus clasificări de conținut și furnizori.
- [Evaluări pentru filme și TV](https://amodb.dev/ro/ratings/): API evaluări filme ce întoarce scorurile IMDb, Kinopoisk, Metacritic, Rotten Tomatoes și TMDB pentru un titlu într-un apel, cu null pentru sursele necunoscute.
- [Coloane sonore](https://amodb.dev/ro/soundtracks/): API coloană sonoră ce întoarce albumul coloanei sonore a unui film sau serial, cu piesele. Apelează endpoint-ul sau adaugă append_to_response=soundtracks.
- [API discover](https://amodb.dev/ro/discover/): API discover cu filtrele TMDB v3. Listează filme și seriale după gen, distribuție, companie, cuvânt-cheie, an, evaluare, durată și furnizor, cu sortare.
- [Ghid rapid](https://amodb.dev/ro/quickstart/): Fă primul apel amodb: ia o cheie, cere detaliile unui film în curl, JavaScript, Python, PHP sau Go, apoi încarcă posterul de pe img.amodb.dev. Sub 2 minute.

Actualizat: 2026-10-18. Source: https://amodb.dev/ro/moods/
