# API des mots-clés

> Les points de terminaison de mots-clés renvoient les tags d'intrigue d'un film ou d'une série, chacun sous forme d'id et de nom. Vous pouvez chercher un mot-clé, lister les films qui le portent, ou passer les ids à discover avec with_keywords pour bâtir des pages thématiques. Les films répondent sous keywords, les séries sous results.

## Point de terminaison

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

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

Réponse:

```json
{
  "id": 550,
  "keywords": [
    {
      "id": 818,
      "name": "based on novel or book"
    },
    {
      "id": 825,
      "name": "support group"
    },
    {
      "id": 851,
      "name": "dual identity"
    }
  ]
}
```

## Obtenir les mots-clés d'un film

`GET /3/movie/{movie_id}/keywords` renvoie les tags d'intrigue d'un film. Un mot-clé est une courte expression comme un thème, un décor ou un type de source, et il a un identifiant numérique que vous pouvez réutiliser dans [découverte](https://amodb.dev/fr/discover/).

L'exemple charge les mots-clés d'un film puis demande à discover les films les plus populaires qui partagent son premier mot-clé.

```bash
curl -s "https://api.amodb.dev/3/movie/550/keywords" \
  -H "Authorization: Bearer $AMODB_KEY"

curl -s "https://api.amodb.dev/3/discover/movie?with_keywords=818&sort_by=popularity.desc" \
  -H "Authorization: Bearer $AMODB_KEY"
```

```js
const base = 'https://api.amodb.dev/3';
const headers = { Authorization: `Bearer ${process.env.AMODB_KEY}` };

const kw = await fetch(`${base}/movie/550/keywords`, { headers });
if (!kw.ok) throw new Error(`keywords failed with ${kw.status}`);
const { keywords } = await kw.json();
console.log(keywords.map((k) => `${k.id}:${k.name}`).join(', '));

if (keywords.length > 0) {
  const first = keywords[0];
  const found = await fetch(`${base}/discover/movie?with_keywords=${first.id}&sort_by=popularity.desc`, { headers });
  if (!found.ok) throw new Error(`discover failed with ${found.status}`);
  const page = await found.json();
  console.log(first.name, page.results.slice(0, 5).map((m) => m.title));
}
```

```python
import os
import requests

base = "https://api.amodb.dev/3"
headers = {"Authorization": f"Bearer {os.environ['AMODB_KEY']}"}

r = requests.get(f"{base}/movie/550/keywords", headers=headers, timeout=10)
r.raise_for_status()
keywords = r.json()["keywords"]
print(", ".join(f"{k['id']}:{k['name']}" for k in keywords))

if keywords:
    first = keywords[0]
    d = requests.get(
        f"{base}/discover/movie",
        params={"with_keywords": first["id"], "sort_by": "popularity.desc"},
        headers=headers,
        timeout=10,
    )
    d.raise_for_status()
    print(first["name"], [m["title"] for m in d.json()["results"][:5]])
```

```php
<?php
function amodb_get(string $url): array {
    $ch = curl_init($url);
    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");
    }
    return json_decode($body, true);
}

$base = 'https://api.amodb.dev/3';
$keywords = amodb_get("$base/movie/550/keywords")['keywords'];
if ($keywords) {
    $first = $keywords[0];
    $found = amodb_get("$base/discover/movie?with_keywords={$first['id']}&sort_by=popularity.desc");
    $titles = array_column(array_slice($found['results'], 0, 5), 'title');
    echo $first['name'], ': ', implode(', ', $titles), PHP_EOL;
}
```

```go
package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"os"
	"time"
)

var client = &http.Client{Timeout: 10 * time.Second}

func get(path string, out any) error {
	req, _ := http.NewRequest("GET", "https://api.amodb.dev/3"+path, nil)
	req.Header.Set("Authorization", "Bearer "+os.Getenv("AMODB_KEY"))
	res, err := client.Do(req)
	if err != nil {
		return err
	}
	defer res.Body.Close()
	if res.StatusCode != http.StatusOK {
		return fmt.Errorf("amodb returned %s", res.Status)
	}
	return json.NewDecoder(res.Body).Decode(out)
}

type Keywords struct {
	Keywords []struct {
		ID   int    `json:"id"`
		Name string `json:"name"`
	} `json:"keywords"`
}

type Page struct {
	Results []struct {
		Title string `json:"title"`
	} `json:"results"`
}

func main() {
	var kw Keywords
	if err := get("/movie/550/keywords", &kw); err != nil {
		panic(err)
	}
	if len(kw.Keywords) == 0 {
		return
	}
	first := kw.Keywords[0]
	var page Page
	if err := get(fmt.Sprintf("/discover/movie?with_keywords=%d&sort_by=popularity.desc", first.ID), &page); err != nil {
		panic(err)
	}
	fmt.Println(first.Name)
	for i, m := range page.Results {
		if i == 5 {
			break
		}
		fmt.Println(" ", m.Title)
	}
}
```

### Paramètres

| Paramètre  | Dans    | Requis        | Description                                                  |
| ---------- | ------- | ------------- | ------------------------------------------------------------ |
| `movie_id` | chemin  | oui           | Identifiant numérique du film, par exemple `550`.            |
| `api_key`  | requête | l'un des deux | Votre clé. Utilisez-la ou l'en-tête `Authorization: Bearer`. |

### Champs de la réponse

| Champ             | Type    | Remarques                                                                                             |
| ----------------- | ------- | ----------------------------------------------------------------------------------------------------- |
| `id`              | entier  | L'identifiant du film.                                                                                |
| `keywords`        | tableau | Objets avec `id` et `name`. Vide quand le film n'en a aucun.                                          |
| `keywords[].id`   | entier  | Identifiant du mot-clé. Utilisez-le dans `with_keywords` et dans les chemins de mots-clés ci-dessous. |
| `keywords[].name` | chaîne  | Le texte du mot-clé.                                                                                  |

### Exemple de réponse

```json
{
  "id": 550,
  "keywords": [
    { "id": 818, "name": "based on novel or book" },
    { "id": 825, "name": "support group" },
    { "id": 851, "name": "dual identity" }
  ]
}
```

La vraie réponse contient 14 mots-clés. Celle-ci est réduite aux 3 premiers. Les noms de mots-clés ne sont pas traduits : `language` n'a donc aucun effet ici.

## Mots-clés d'une série

`GET /3/tv/{series_id}/keywords` prend la même clé et renvoie les mêmes objets, mais le tableau s'appelle `results`. L'identifiant dans le chemin est celui de la série, par exemple `1396`.

```json
{
  "id": 1396,
  "results": [
    { "id": 1508, "name": "new mexico" },
    { "id": 2231, "name": "drug dealer" }
  ]
}
```

La vraie réponse contient 29 entrées et celle-ci est réduite aux 2 premières. Un client qui sert les deux types de médias peut lire `data.keywords ?? data.results` et traiter les deux de la même façon.

## Fiches de mots-clés et leurs films

| Méthode et chemin                  | Renvoie                                                                             | Paramètres         |
| ---------------------------------- | ----------------------------------------------------------------------------------- | ------------------ |
| `GET /keyword/{keyword_id}`        | `{ id, name }`                                                                      | aucun              |
| `GET /keyword/{keyword_id}/movies` | Liste paginée de films avec `id`, `page`, `results`, `total_pages`, `total_results` | `language`, `page` |

Les deux chemins utilisent l'identifiant numérique d'un tableau de mots-clés. La liste de films donne la même forme d'élément que les autres [listes de films](https://amodb.dev/fr/trending-lists/), y compris `genre_ids` et `poster_path`, plus l'`id` du mot-clé en haut. `include_adult` est accepté et ignoré. Une page au-delà de `total_pages` renvoie un tableau `results` vide. Il n'existe pas de liste de séries pour un mot-clé : utilisez `/discover/tv?with_keywords=` pour les séries.

## Combiner des mots-clés avec discover

Pour tout ce qui dépasse une simple liste, filtrez dans [découverte](https://amodb.dev/fr/discover/). Il trie, pagine et combine les mots-clés avec d'autres filtres, et il couvre les séries comme les films.

| Objectif                                      | Chaîne de requête                                  |
| --------------------------------------------- | -------------------------------------------------- |
| Films avec un mot-clé                         | `/discover/movie?with_keywords=818`                |
| Films avec les deux mots-clés                 | `/discover/movie?with_keywords=818,4565`           |
| Films sans un mot-clé                         | `/discover/movie?without_keywords=818`             |
| Séries avec un mot-clé                        | `/discover/tv?with_keywords=9712`                  |
| Séries avec l'un ou l'autre de deux mots-clés | `/discover/tv?with_keywords=818%7C9712`            |
| Un mot-clé dans un genre                      | `/discover/movie?with_keywords=818&with_genres=18` |

Une virgule entre des identifiants signifie tous. Écrivez une barre verticale entre les identifiants, comme dans `with_keywords=818|4565`, pour correspondre à n'importe lequel. Les résultats de discover sont mis en cache 30 minutes en périphérie.

## Trouver l'identifiant d'un mot-clé

Pour transformer du texte en identifiant, appelez `GET /3/search/keyword?query=heist`. Il renvoie une liste paginée de paires `id` et `name`, 20 par page. Voir [recherche](https://amodb.dev/fr/search/) pour l'ensemble des chemins de recherche. Une recherche de mots-clés qui ne correspond à rien répond actuellement 500 avec `status_code` 11 au lieu d'une liste vide. Les réponses de recherche sont mises en cache 10 minutes, mais chaque appel compte quand même dans vos requêtes par minute : appliquez donc un délai anti-rebond à une zone de saisie prédictive.

## Erreurs

| HTTP | status_code | Quand                                                                                |
| ---- | ----------- | ------------------------------------------------------------------------------------ |
| 401  | 7           | La clé est absente ou fausse.                                                        |
| 402  | 36          | La période de l'offre est terminée.                                                  |
| 404  | 34          | Aucun mot-clé avec cet identifiant sur `/keyword/{keyword_id}` et sa liste de films. |
| 405  | 37          | Vous avez utilisé une méthode d'écriture sur un chemin de mots-clés.                 |
| 429  | 25          | Vous avez dépassé vos requêtes par minute. Attendez les secondes de `Retry-After`.   |
| 500  | 11          | Une requête `/search/keyword` qui ne correspond à rien.                              |

Un identifiant de film ou de série inconnu sur les chemins de mots-clés n'est pas un 404. Vous obtenez un HTTP 200 avec l'identifiant et un tableau vide.

Voir [erreurs](https://amodb.dev/fr/errors/) pour tous les codes et [limites de débit](https://amodb.dev/fr/rate-limits/) pour les limites des offres.

## Remarques pratiques

- Stockez l'`id` du mot-clé, pas le nom. Un nom peut être reformulé, un identifiant ne change pas.
- Les listes de mots-clés sont mises en cache avec les détails du titre, pendant 6 heures. Une actualisation hebdomadaire pour les pages de tags est largement suffisante.
- Un même titre a une courte liste de tags. Pour des pages thématiques, partez d'un identifiant de mot-clé et listez ses titres dans discover, pas l'inverse.
- Utilisez `without_keywords` pour retirer le bruit, par exemple un tag que vous ne voulez jamais sur une page familiale.
- Un tableau vide est une réponse valide pour les titres obscurs. Masquez la ligne de tags au lieu d'afficher une erreur.

## Questions et réponses

### Pourquoi la réponse des séries utilise-t-elle results alors que les films utilisent keywords ?

C'est ainsi que TMDB v3 les structure, et amodb le conserve pour que les clients existants fonctionnent. Les films renvoient un tableau keywords. Les séries renvoient les mêmes objets sous results. Lisez data.keywords, ou data.results à défaut.

### Comment trouver l'id d'un mot-clé à partir de son nom ?

Appelez le chemin de recherche de mots-clés avec une requête, par exemple /3/search/keyword?query=heist. Il renvoie une liste paginée de paires id et name. Choisissez la correspondance exacte et stockez l'id.

### Puis-je utiliser un même id de mot-clé pour les films et les séries ?

Oui. Un id de mot-clé est la même valeur dans discover pour les films et dans discover pour les séries : with_keywords fonctionne donc sur les deux chemins. Stockez un id par thème et réutilisez-le pour les deux types de médias.

### Comment combiner plusieurs mots-clés dans une requête ?

Joignez les ids dans with_keywords avec une virgule pour les exiger tous, ou avec une barre verticale pour en accepter n'importe lequel. Utilisez without_keywords pour exclure des ids. Gardez l'URL dans la limite de longueur de votre client HTTP.

## Pages liées

- [API Discover](https://amodb.dev/fr/discover/): API Discover avec les mêmes filtres que TMDB v3. Listez films et séries par genre, distribution, société, mot-clé, année, note, durée et plateforme.
- [API de recherche](https://amodb.dev/fr/search/): API de recherche aux chemins et au JSON de TMDB v3 : films, séries, personnes, collections, sociétés et mots-clés par texte, filtres d'année et pagination.
- [API de détails de film](https://amodb.dev/fr/movies/): API de détails de film aux chemins et au JSON de TMDB v3. Obtenez un film par id, ajoutez crédits, notes et ambiances avec append_to_response, en 14 langues.
- [API des séries TV](https://amodb.dev/fr/tv-series/): API de séries TV aux chemins et au JSON de TMDB v3 : une série par id avec saisons, chaînes et prochain épisode, plus classifications et plateformes.
- [Genres et listes de référence](https://amodb.dev/fr/genres/): API de genres aux chemins TMDB v3 : identifiants de genres films et séries avec noms traduits, plus pays, langues, métiers, classifications et plateformes.
- [Démarrage rapide](https://amodb.dev/fr/quickstart/): Faites votre premier appel amodb : obtenez une clé, demandez un film en curl, JavaScript, Python, PHP ou Go, puis chargez l'affiche. En moins de 2 minutes.

Mis à jour: 2026-10-18. Source: https://amodb.dev/fr/keywords/
