# Trilhas sonoras

> GET /3/movie/{movie_id}/soundtracks e GET /3/tv/{tv_id}/soundtracks retornam o álbum da trilha sonora de um título em uma lista results. Cada álbum tem fonte, nome, artista, data de lançamento, link e uma lista tracks com disco, número, título, artista e duração. Use append_to_response=soundtracks para juntá-lo aos detalhes.

## Endpoint

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

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

Resposta:

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

## Obter a trilha sonora de um filme

`GET /3/movie/{movie_id}/soundtracks` retorna o álbum da trilha sonora de um filme. A resposta traz o `id` do filme e um array `results`. Cada entrada é um álbum com seus detalhes e uma lista `tracks`.

O exemplo carrega The Dark Knight (id 155) e imprime o álbum e uma linha por faixa.

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

### Parâmetros

| Parâmetro  | Em       | Obrigatório | Descrição                                                          |
| ---------- | -------- | ----------- | ------------------------------------------------------------------ |
| `movie_id` | caminho  | sim         | Id numérico do filme, por exemplo `155`.                           |
| `api_key`  | consulta | um dos dois | Sua chave. Use este parâmetro ou o header `Authorization: Bearer`. |

### Campos da resposta

| Campo                            | Tipo           | Observações                                                           |
| -------------------------------- | -------------- | --------------------------------------------------------------------- |
| `id`                             | inteiro        | Id do filme. Não aparece quando você usa `append_to_response`.        |
| `results`                        | array          | Álbuns. Vazio quando nenhum álbum é conhecido. Hoje tem no máximo um. |
| `results[].source`               | string         | De onde vem o álbum: `musicbrainz` ou `deezer`.                       |
| `results[].album`                | string         | Título do álbum.                                                      |
| `results[].artist`               | string ou null | Artista do álbum, por exemplo `Hans Zimmer & James Newton Howard`.    |
| `results[].released`             | string ou null | Data de lançamento no formato `YYYY-MM-DD`.                           |
| `results[].url`                  | string ou null | Link para a página do álbum na fonte.                                 |
| `results[].track_count`          | inteiro        | Número de faixas do álbum.                                            |
| `results[].tracks`               | array          | Faixas na ordem do álbum.                                             |
| `results[].tracks[].disc`        | inteiro        | Número do disco, a partir de 1.                                       |
| `results[].tracks[].number`      | inteiro        | Número da faixa no disco.                                             |
| `results[].tracks[].title`       | string         | Título da faixa.                                                      |
| `results[].tracks[].artist`      | string         | Artista da faixa.                                                     |
| `results[].tracks[].duration_ms` | inteiro        | Duração em milissegundos.                                             |

Leia pelo nome as chaves que você usa e ignore as outras.

### Exemplo de resposta

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

A lista de faixas foi cortada para 3 de 14. Um título sem álbum conhecido, como Fight Club (id 550), responde com uma lista vazia:

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

## Obter a trilha sonora de uma série

`GET /3/tv/{tv_id}/soundtracks` retorna o mesmo formato para uma série. Passe o id da série, por exemplo `1396`. Breaking Bad não tem álbum conhecido, então o array `results` vem vazio.

| Método e caminho                    | Retorna                               | Parâmetros                                     |
| ----------------------------------- | ------------------------------------- | ---------------------------------------------- |
| `GET /movie/{movie_id}/soundtracks` | `id` e `results`                      | `movie_id`                                     |
| `GET /tv/{tv_id}/soundtracks`       | `id` e `results`                      | `tv_id`                                        |
| `append_to_response=soundtracks`    | Os mesmos `results` sob `soundtracks` | Acrescentado aos detalhes de filme ou de série |

Para receber o álbum ao carregar a página de um filme, acrescente-o aos detalhes:

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

O bloco acrescentado fica sob a chave `soundtracks` do registro. Ele contém `results` e não tem `id` próprio. Conta como uma requisição.

## Montar uma lista de músicas do filme

Ordene por `disc` e `number`, mostre o título e o artista, e esconda o bloco quando `results` estiver vazio. As funções abaixo retornam linhas de texto simples que você pode colocar em um elemento de 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)})`);
}
```

Algumas ideias de interface que não precisam de dados extras:

| Ideia          | Como                                                                                                           |
| -------------- | -------------------------------------------------------------------------------------------------------------- |
| Lista numerada | Use `number` como o número da lista e agrupe por `disc` quando houver vários discos.                           |
| Link do álbum  | Ligue o nome do álbum a `url` quando ele não for null.                                                         |
| Duração total  | Some `duration_ms` de todas as faixas.                                                                         |
| Par com o mood | Mostre a lista ao lado dos [medidores de mood](https://amodb.dev/pt/moods/) (clima emocional) do mesmo título. |

## Erros

Toda falha retorna `success` como false com um `status_code` numérico, como o TMDB faz.

| HTTP | status_code | Quando                                                                                              |
| ---- | ----------- | --------------------------------------------------------------------------------------------------- |
| 401  | 7           | A chave está ausente ou incorreta.                                                                  |
| 402  | 36          | O período do plano terminou.                                                                        |
| 429  | 25          | Você passou do seu limite de requisições por minuto. Espere os segundos indicados em `Retry-After`. |

O endpoint de trilhas sonoras não responde 404 para um id desconhecido. Ele responde 200 com um array `results` vazio. Quando acrescentado aos detalhes, um id desconhecido vira um 404 da chamada de detalhes. Veja [erros](https://amodb.dev/pt/errors/) para todos os códigos e [limites de requisições](https://amodb.dev/pt/rate-limits/) para os headers.

## Notas práticas

- Como os outros dados de detalhes, as trilhas sonoras têm cache de borda de 6 horas. Um cache de cliente mais curto não traz ganho.
- Use `append_to_response=soundtracks` em uma página de detalhes que você já carrega. Isso poupa uma das suas 20, 40 ou 120 requisições por minuto.
- Não exija que um álbum exista. Esconda o bloco de música quando `results` estiver vazio.
- Alguns álbuns vêm do MusicBrainz e outros do Deezer. O filme 27205 (Inception) tem um álbum do Deezer. O formato é o mesmo, então confira `source` só se você o mostrar.
- Nomes de faixas e de artistas são strings simples e podem conter qualquer caractere. Guarde-os em UTF-8 e escape-os ao colocá-los em HTML.
- Para o trailer do mesmo título, veja [vídeos e trailers](https://amodb.dev/pt/videos-trailers/).

## Perguntas e respostas

### O que uma entrada de trilha sonora contém?

Um objeto de álbum. Ele traz a fonte, o nome do álbum, o artista, a data de lançamento, um link e track_count. O array tracks lista cada faixa com disc, number, title, artist e duration_ms. A resposta também traz o id do título.

### Recebo arquivos de áudio ou links de streaming?

Não há áudio. O campo url leva à página do álbum no MusicBrainz ou no Deezer, e pode ser null. Para deixar os usuários ouvirem, procure o álbum no serviço de música que você já usa e abra-o a partir da sua própria interface.

### Todo título tem trilha sonora?

Não. Muitos títulos, Fight Club entre eles, não têm álbum conhecido, e a resposta é um array results vazio. Hoje um título tem no máximo um álbum. Projete o bloco de música para se esconder quando não houver nada a mostrar.

### Posso obter a trilha sonora de uma série?

Sim. Chame GET /3/tv/{tv_id}/soundtracks com o id da série. A resposta tem o mesmo formato do endpoint de filmes, então um único parser cobre os dois.

## Páginas relacionadas

- [API de detalhes de filmes](https://amodb.dev/pt/movies/): API de detalhes de filmes com caminhos e JSON do TMDB v3. Busque um filme por id e junte créditos, avaliações e moods com append_to_response, em 14 idiomas.
- [API de séries de TV](https://amodb.dev/pt/tv-series/): API de séries de TV com os mesmos caminhos e JSON do TMDB v3. Busque uma série por id com temporadas, emissoras, próximo episódio e classificações.
- [Medidores de mood](https://amodb.dev/pt/moods/): API de moods de filmes com medidores de 0 a 10 por título. Leia os moods de um filme ou série, junte-os com append_to_response=moods e crie selos ou filtros.
- [API de vídeos e trailers](https://amodb.dev/pt/videos-trailers/): API de vídeos de filmes com caminhos do TMDB v3: liste trailers, teasers, clipes e featurettes de um filme ou série e filtre por tipo e idioma no seu código.
- [Avaliações de filmes e séries](https://amodb.dev/pt/ratings/): API de avaliações de filmes com as notas do IMDb, Kinopoisk, Metacritic, Rotten Tomatoes e TMDB em uma só chamada, com null se a fonte for desconhecida.
- [Início rápido](https://amodb.dev/pt/quickstart/): Faça sua primeira chamada ao amodb: obtenha uma chave, peça um filme em curl, JavaScript, Python, PHP ou Go e carregue o pôster. Menos de 2 minutos.

Atualizado: 2026-10-18. Source: https://amodb.dev/pt/soundtracks/
