# Colonne sonore

> GET /3/movie/{movie_id}/soundtracks e GET /3/tv/{tv_id}/soundtracks restituiscono l'album della colonna sonora di un titolo in una lista results. Ogni album ha source, nome, artista, data di uscita, link e una lista tracks con disco, numero, titolo, artista e durata. Aggiungi append_to_response=soundtracks per unirla ai dettagli.

## Endpoint

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

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

Risposta:

```json
{
  "id": 155,
  "results": [
    {
      "source": "musicbrainz",
      "album": "The Dark Knight",
      "artist": "Hans Zimmer & James Newton Howard",
      "released": "2008-07-15",
      "url": "https://musicbrainz.org/release/814b2f7b-c27c-451e-abac-a316d2e6cea9",
      "track_count": 14,
      "tracks": [
        {
          "disc": 1,
          "number": 1,
          "title": "Why So Serious?",
          "artist": "Hans Zimmer",
          "duration_ms": 554000
        },
        {
          "disc": 1,
          "number": 2,
          "title": "I'm Not a Hero",
          "artist": "Hans Zimmer",
          "duration_ms": 395000
        },
        {
          "disc": 1,
          "number": 3,
          "title": "Harvey Two-Face",
          "artist": "James Newton Howard",
          "duration_ms": 377000
        }
      ]
    }
  ]
}
```

## Ottenere la colonna sonora di un film

`GET /3/movie/{movie_id}/soundtracks` restituisce l'album della colonna sonora di un film. La risposta contiene l'`id` del film e un array `results`. Ogni voce è un album con i suoi dettagli e una lista `tracks`.

L'esempio carica The Dark Knight (id 155) e stampa l'album e una riga per brano.

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

```js
const res = await fetch('https://api.amodb.dev/3/movie/155/soundtracks', {
  headers: { Authorization: `Bearer ${process.env.AMODB_KEY}` },
});
if (!res.ok) throw new Error(`amodb returned ${res.status}`);
const { results } = await res.json();
if (results.length === 0) console.log('no soundtrack album known');
for (const album of results) {
  console.log(`${album.album} by ${album.artist} (${album.track_count} tracks)`);
  for (const t of album.tracks) {
    console.log(`${t.number}. ${t.title} by ${t.artist}`);
  }
}
```

```python
import os
import requests

r = requests.get(
    "https://api.amodb.dev/3/movie/155/soundtracks",
    headers={"Authorization": f"Bearer {os.environ['AMODB_KEY']}"},
    timeout=10,
)
r.raise_for_status()
results = r.json()["results"]
if not results:
    print("no soundtrack album known")
for album in results:
    print(f"{album['album']} by {album['artist']} ({album['track_count']} tracks)")
    for t in album["tracks"]:
        print(f"{t['number']}. {t['title']} by {t['artist']}")
```

```php
<?php
$ch = curl_init('https://api.amodb.dev/3/movie/155/soundtracks');
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");
}
$results = json_decode($body, true)['results'];
if (!$results) {
    echo 'no soundtrack album known', PHP_EOL;
}
foreach ($results as $album) {
    echo $album['album'], ' by ', $album['artist'] ?? 'unknown', ' (', $album['track_count'], ' tracks)', PHP_EOL;
    foreach ($album['tracks'] as $t) {
        echo $t['number'], '. ', $t['title'], ' by ', $t['artist'], PHP_EOL;
    }
}
```

```go
package main

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

type Track struct {
	Disc       int    `json:"disc"`
	Number     int    `json:"number"`
	Title      string `json:"title"`
	Artist     string `json:"artist"`
	DurationMs int    `json:"duration_ms"`
}

type Album struct {
	Source     string  `json:"source"`
	Album      string  `json:"album"`
	Artist     string  `json:"artist"`
	Released   string  `json:"released"`
	URL        string  `json:"url"`
	TrackCount int     `json:"track_count"`
	Tracks     []Track `json:"tracks"`
}

func main() {
	req, _ := http.NewRequest("GET", "https://api.amodb.dev/3/movie/155/soundtracks", 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 {
		Results []Album `json:"results"`
	}
	if err := json.NewDecoder(res.Body).Decode(&body); err != nil {
		panic(err)
	}
	if len(body.Results) == 0 {
		fmt.Println("no soundtrack album known")
	}
	for _, a := range body.Results {
		fmt.Printf("%s by %s (%d tracks)\n", a.Album, a.Artist, a.TrackCount)
		for _, t := range a.Tracks {
			fmt.Printf("%d. %s by %s\n", t.Number, t.Title, t.Artist)
		}
	}
}
```

### Parametri

| Parametro  | In       | Obbligatorio | Descrizione                                                   |
| ---------- | -------- | ------------ | ------------------------------------------------------------- |
| `movie_id` | percorso | sì           | ID numerico del film, per esempio `155`.                      |
| `api_key`  | query    | uno dei due  | La tua chiave. Usa questa o l'header `Authorization: Bearer`. |

### Campi della risposta

| Campo                            | Tipo           | Note                                                                         |
| -------------------------------- | -------------- | ---------------------------------------------------------------------------- |
| `id`                             | intero         | ID del film. Assente quando usi `append_to_response`.                        |
| `results`                        | array          | Album. Vuoto quando non è noto alcun album. Oggi ne contiene al massimo uno. |
| `results[].source`               | stringa        | Da dove viene l'album: `musicbrainz` o `deezer`.                             |
| `results[].album`                | stringa        | Titolo dell'album.                                                           |
| `results[].artist`               | stringa o null | Artista dell'album, per esempio `Hans Zimmer & James Newton Howard`.         |
| `results[].released`             | stringa o null | Data di uscita come `YYYY-MM-DD`.                                            |
| `results[].url`                  | stringa o null | Link alla pagina dell'album presso la fonte.                                 |
| `results[].track_count`          | intero         | Numero di brani dell'album.                                                  |
| `results[].tracks`               | array          | Brani nell'ordine dell'album.                                                |
| `results[].tracks[].disc`        | intero         | Numero del disco, a partire da 1.                                            |
| `results[].tracks[].number`      | intero         | Numero del brano sul disco.                                                  |
| `results[].tracks[].title`       | stringa        | Titolo del brano.                                                            |
| `results[].tracks[].artist`      | stringa        | Artista del brano.                                                           |
| `results[].tracks[].duration_ms` | intero         | Durata in millisecondi.                                                      |

Leggi per nome le chiavi che usi e salta le altre.

### Risposta di esempio

```json
{
  "id": 155,
  "results": [
    {
      "source": "musicbrainz",
      "album": "The Dark Knight",
      "artist": "Hans Zimmer & James Newton Howard",
      "released": "2008-07-15",
      "url": "https://musicbrainz.org/release/814b2f7b-c27c-451e-abac-a316d2e6cea9",
      "track_count": 14,
      "tracks": [
        { "disc": 1, "number": 1, "title": "Why So Serious?", "artist": "Hans Zimmer", "duration_ms": 554000 },
        { "disc": 1, "number": 2, "title": "I'm Not a Hero", "artist": "Hans Zimmer", "duration_ms": 395000 },
        { "disc": 1, "number": 3, "title": "Harvey Two-Face", "artist": "James Newton Howard", "duration_ms": 377000 }
      ]
    }
  ]
}
```

L'elenco dei brani è tagliato a 3 su 14. Un titolo senza un album noto, come Fight Club (id 550), risponde con una lista vuota:

```json
{
  "id": 550,
  "results": []
}
```

## Ottenere la colonna sonora di una serie

`GET /3/tv/{tv_id}/soundtracks` restituisce la stessa struttura per una serie. Passa l'ID della serie, per esempio `1396`. Breaking Bad non ha un album noto, quindi il suo array `results` è vuoto.

| Metodo e percorso                   | Restituisce                             | Parametri                                      |
| ----------------------------------- | --------------------------------------- | ---------------------------------------------- |
| `GET /movie/{movie_id}/soundtracks` | `id` e `results`                        | `movie_id`                                     |
| `GET /tv/{tv_id}/soundtracks`       | `id` e `results`                        | `tv_id`                                        |
| `append_to_response=soundtracks`    | Lo stesso `results` sotto `soundtracks` | Aggiunto ai dettagli di un film o di una serie |

Per ottenere l'album mentre carichi la pagina di un film, aggiungilo ai dettagli:

```bash
curl -sf "https://api.amodb.dev/3/movie/155?append_to_response=credits,soundtracks" \
  -H "Authorization: Bearer $AMODB_KEY"
```

Il blocco aggiunto sta sotto la chiave `soundtracks` della scheda. Contiene `results` e non ha un `id` proprio. Conta come una sola richiesta.

## Costruire una lista «musica in questo film»

Ordina per `disc` e `number`, mostra il titolo e l'artista, e nascondi il blocco quando `results` è vuoto. Le funzioni qui sotto restituiscono righe di testo semplice che puoi mettere in un elemento di lista.

```js
function clock(ms) {
  const s = Math.round(ms / 1000);
  return `${Math.floor(s / 60)}:${String(s % 60).padStart(2, '0')}`;
}

function musicLines(results) {
  const album = results[0];
  if (!album) return [];
  return [...album.tracks]
    .sort((a, b) => a.disc - b.disc || a.number - b.number)
    .map((t) => `${t.title} by ${t.artist} (${clock(t.duration_ms)})`);
}
```

Alcune idee di interfaccia che non richiedono dati aggiuntivi:

| Idea                   | Come                                                                                                  |
| ---------------------- | ----------------------------------------------------------------------------------------------------- |
| Elenco numerato        | Usare `number` come numero dell'elenco, e raggruppare per `disc` quando ci sono più dischi.           |
| Link all'album         | Collegare il nome dell'album a `url` quando non è null.                                               |
| Durata totale          | Sommare `duration_ms` su tutti i brani.                                                               |
| Abbinamento con i mood | Mostrare la lista accanto agli [indicatori di mood](https://amodb.dev/it/moods/) dello stesso titolo. |

## Errori

Ogni errore restituisce `success` a false con uno `status_code` numerico, come fa TMDB.

| HTTP | status_code | Quando                                                                |
| ---- | ----------- | --------------------------------------------------------------------- |
| 401  | 7           | La chiave manca o è sbagliata.                                        |
| 402  | 36          | Il periodo del piano è terminato.                                     |
| 429  | 25          | Oltre le tue richieste al minuto. Attendi i secondi di `Retry-After`. |

L'endpoint delle colonne sonore non risponde 404 per un ID sconosciuto. Risponde 200 con un array `results` vuoto. Aggiunto ai dettagli, un ID sconosciuto dà un 404 dalla chiamata dei dettagli. Vedi [errori](https://amodb.dev/it/errors/) per tutti i codici e [limiti di richieste](https://amodb.dev/it/rate-limits/) per gli header.

## Note pratiche

- Come gli altri dati dei dettagli, le colonne sonore restano in cache sull'edge per 6 ore. Una cache client più breve non porta nulla.
- Usa `append_to_response=soundtracks` su una pagina di dettagli che già carichi. Risparmia una richiesta delle tue 20, 40 o 120 richieste al minuto.
- Non pretendere che un album esista. Nascondi il blocco musicale quando `results` è vuoto.
- Alcuni album vengono da MusicBrainz e altri da Deezer. Il film 27205 (Inception) ha un album Deezer. La struttura è la stessa, quindi controlla `source` solo se la mostri.
- I nomi di brani e artisti sono semplici stringhe e possono contenere qualsiasi carattere. Salvali in UTF-8 e fai l'escape quando li metti nell'HTML.
- Per il trailer dello stesso titolo, vedi [video e trailer](https://amodb.dev/it/videos-trailers/).

## Domande e risposte

### Cosa contiene una voce di colonna sonora?

Un oggetto album. Ha la source, il nome dell'album, l'artista, la data di uscita, un link e track_count. Il suo array tracks elenca ogni brano con disc, number, title, artist e duration_ms. La risposta porta anche l'ID del titolo.

### Ottengo file audio o link di streaming?

Nessun audio. Il campo url rimanda alla pagina dell'album su MusicBrainz o Deezer, e può essere null. Per far ascoltare gli utenti, cerca l'album nel servizio musicale che già usi e aprilo dalla tua interfaccia.

### C'è una colonna sonora per ogni titolo?

No. Molti titoli, tra cui Fight Club, non hanno un album noto, e la risposta è un array results vuoto. Oggi un titolo ha al massimo un album. Progetta il blocco musicale in modo che si nasconda quando non c'è nulla da mostrare.

### Posso ottenere le colonne sonore di una serie?

Sì. Chiama GET /3/tv/{tv_id}/soundtracks con l'ID della serie. La risposta ha la stessa struttura dell'endpoint dei film, quindi un solo parser copre entrambi.

## Pagine correlate

- [API dei dettagli del film](https://amodb.dev/it/movies/): API dettagli film con gli stessi percorsi e JSON di TMDB v3. Ottieni un film per ID, aggiungi crediti, valutazioni e mood con append_to_response, in 14 lingue.
- [API delle serie TV](https://amodb.dev/it/tv-series/): API serie TV con gli stessi percorsi e JSON di TMDB v3. Ottieni una serie per ID con stagioni, emittenti e prossimo episodio, più classificazioni e piattaforme.
- [Indicatori di mood](https://amodb.dev/it/moods/): API mood dei film con indicatori da 0 a 10 per titolo. Leggi i mood di un film o serie, uniscili con append_to_response=moods e costruisci badge o filtri.
- [API dei video e dei trailer](https://amodb.dev/it/videos-trailers/): API video con percorsi TMDB v3: elenca trailer, teaser, clip e featurette di un film o serie TV, poi filtra per tipo e lingua nel tuo codice.
- [Valutazioni di film e serie TV](https://amodb.dev/it/ratings/): API valutazioni film: punteggi IMDb, Kinopoisk, Metacritic, Rotten Tomatoes e TMDB di un titolo in una chiamata, con null per le fonti non note.
- [Avvio rapido](https://amodb.dev/it/quickstart/): Fai la prima chiamata ad amodb: ottieni una chiave, richiedi i dettagli di un film in curl, JavaScript, Python, PHP o Go, carica la locandina. Meno di 2 minuti.

Aggiornato: 2026-10-18. Source: https://amodb.dev/it/soundtracks/
