# Genres and lookup lists

> Genre and lookup endpoints return small reference lists you load once: movie and TV genre ids with names in 14 languages, plus countries, languages, crew jobs, age certifications and streaming providers. They use TMDB v3 paths and shapes, need no paging, and change rarely, so cache them for a day.

## Endpoint

`GET /3/genre/movie/list`

```bash
curl "https://api.amodb.dev/3/genre/movie/list?language=en-US" \
  -H "Authorization: Bearer $AMODB_KEY"
```

Response:

```json
{
  "genres": [
    {
      "id": 28,
      "name": "Action"
    },
    {
      "id": 12,
      "name": "Adventure"
    },
    {
      "id": 16,
      "name": "Animation"
    }
  ]
}
```

## Get the movie genre list

`GET /3/genre/movie/list` returns every movie genre as an `id` and a `name`. The ids are the numbers that `genre_ids` carries on list items and that `with_genres` expects in [discover](https://amodb.dev/discover/). The names follow the `language` parameter.

The example loads the list and builds an id to name map, the first thing most apps need.

```bash
curl -s "https://api.amodb.dev/3/genre/movie/list?language=en-US" \
  -H "Authorization: Bearer $AMODB_KEY"
```

```js
const url = 'https://api.amodb.dev/3/genre/movie/list?language=en-US';
const res = await fetch(url, { headers: { Authorization: `Bearer ${process.env.AMODB_KEY}` } });
if (!res.ok) throw new Error(`amodb returned ${res.status}`);
const { genres } = await res.json();
const names = new Map(genres.map((g) => [g.id, g.name]));
console.log(names.get(878), names.size);
```

```python
import os
import requests

r = requests.get(
    "https://api.amodb.dev/3/genre/movie/list",
    params={"language": "en-US"},
    headers={"Authorization": f"Bearer {os.environ['AMODB_KEY']}"},
    timeout=10,
)
r.raise_for_status()
names = {g["id"]: g["name"] for g in r.json()["genres"]}
print(names[878], len(names))
```

```php
<?php
$url = 'https://api.amodb.dev/3/genre/movie/list?language=en-US';
$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");
}
$names = [];
foreach (json_decode($body, true)['genres'] as $g) {
    $names[$g['id']] = $g['name'];
}
echo $names[878], ' ', count($names), PHP_EOL;
```

```go
package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"os"
	"time"
)

type Genres struct {
	Genres []struct {
		ID   int    `json:"id"`
		Name string `json:"name"`
	} `json:"genres"`
}

func main() {
	url := "https://api.amodb.dev/3/genre/movie/list?language=en-US"
	req, _ := http.NewRequest("GET", url, 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 g Genres
	if err := json.NewDecoder(res.Body).Decode(&g); err != nil {
		panic(err)
	}
	names := map[int]string{}
	for _, x := range g.Genres {
		names[x.ID] = x.Name
	}
	fmt.Println(names[878], len(names))
}
```

### Parameters

| Parameter  | In    | Required   | Description                                                                                         |
| ---------- | ----- | ---------- | --------------------------------------------------------------------------------------------------- |
| `api_key`  | query | one of two | Your key. Use this or the `Authorization: Bearer` header.                                           |
| `language` | query | no         | TMDB tag such as `en-US`, `ru-RU` or `pt-BR`. Names are returned in this language. Default `en-US`. |

### Response fields

| Field           | Type    | Notes                                      |
| --------------- | ------- | ------------------------------------------ |
| `genres`        | array   | The whole list in one response, no paging. |
| `genres[].id`   | integer | Stable genre id.                           |
| `genres[].name` | string  | Genre name in the requested language.      |

### Example response

```json
{
  "genres": [
    { "id": 12, "name": "Adventure" },
    { "id": 14, "name": "Fantasy" },
    { "id": 16, "name": "Animation" },
    { "id": 18, "name": "Drama" }
  ]
}
```

The reply holds 27 genres sorted by id. This one is cut to the first 4.

## Genre ids

Both genre paths return these 27 genres, sorted by id. The names below are the English ones. Other languages return the same ids with translated names.

| Id    | Name               |
| ----- | ------------------ |
| 12    | Adventure          |
| 14    | Fantasy            |
| 16    | Animation          |
| 18    | Drama              |
| 27    | Horror             |
| 28    | Action             |
| 35    | Comedy             |
| 36    | History            |
| 37    | Western            |
| 53    | Thriller           |
| 80    | Crime              |
| 99    | Documentary        |
| 878   | Science Fiction    |
| 9648  | Mystery            |
| 10402 | Music              |
| 10749 | Romance            |
| 10751 | Family             |
| 10752 | War                |
| 10759 | Action & Adventure |
| 10762 | Kids               |
| 10763 | News               |
| 10764 | Reality            |
| 10765 | Sci-Fi & Fantasy   |
| 10766 | Soap               |
| 10767 | Talk               |
| 10768 | War & Politics     |
| 10770 | TV Movie           |

## TV genre list

`GET /3/genre/tv/list` takes the same `language` parameter and returns the identical list, so one id to name map covers movies and TV. In list data, ids `10759` and `10762` to `10768` appear on TV items only, and ids such as `28`, `12` and `878` appear on movie items. When you filter TV in [discover](https://amodb.dev/discover/), use the TV ids, for example `10765` for Sci-Fi and Fantasy.

## Lookup lists

These paths return reference data for forms, filters and settings screens. All take the key; none take `page`.

| Method and path                           | Parameters                 | Each item or shape                                                             |
| ----------------------------------------- | -------------------------- | ------------------------------------------------------------------------------ |
| `GET /configuration/countries`            | none                       | Array of `{ iso_3166_1, english_name, native_name }`                           |
| `GET /configuration/languages`            | none                       | Array of `{ iso_639_1, english_name, name }`                                   |
| `GET /configuration/primary_translations` | none                       | Array of 14 strings such as `ru-RU`                                            |
| `GET /configuration/jobs`                 | none                       | Array of `{ department, jobs }` where `jobs` lists job titles                  |
| `GET /certification/movie/list`           | none                       | `{ certifications }` keyed by country code, 10 countries                       |
| `GET /certification/tv/list`              | none                       | `{ certifications }` keyed by country code, one key per country in the catalog |
| `GET /watch/providers/regions`            | `language`                 | `{ results }` of `{ iso_3166_1, english_name, native_name }`                   |
| `GET /watch/providers/movie`              | `language`, `watch_region` | `{ results }` of providers                                                     |
| `GET /watch/providers/tv`                 | `language`, `watch_region` | `{ results }` of providers                                                     |

`/configuration/countries` and `/configuration/languages` ignore `language` and always return the same names. `native_name` in the regions list follows `language`. amodb does not offer `/configuration/timezones`.

A certification entry names the rating, what it means and its sort order. Entries are grouped by country code, so one call covers every market. The movie list has the rating texts. On the TV list `meaning` is an empty string.

```json
{
  "certifications": {
    "US": [
      { "certification": "PG", "meaning": "Some material may not be suitable for children under 10.", "order": 3 },
      { "certification": "R", "meaning": "Under 17 requires accompanying parent or adult guardian.", "order": 5 }
    ]
  }
}
```

The example is cut to 2 of the 6 US entries. The movie list covers AU, BR, CA, DE, ES, FR, GB, IT, RU and US.

A provider entry has `provider_id`, `provider_name`, `logo_path`, `display_priority` and `display_priorities`, a map of country code to priority. Without `watch_region` you get every provider. With `watch_region=US` you keep only providers that serve that country. An unknown region returns an empty `results` array. Pass a code from `/watch/providers/regions`. Provider logos load from the image host, see [images](https://amodb.dev/images-api/).

```json
{
  "display_priorities": { "AT": 1, "DE": 1, "GB": 1, "JP": 1, "US": 3 },
  "display_priority": 3,
  "logo_path": "/gMZdpavHmxFNnLpMHwVxfqeux2g.png",
  "provider_name": "Amazon Prime Video",
  "provider_id": 9
}
```

This is one entry from `/watch/providers/movie?watch_region=US`.

## Errors

| HTTP | status_code | When                                                                        |
| ---- | ----------- | --------------------------------------------------------------------------- |
| 401  | 7           | The key is missing or wrong.                                                |
| 402  | 36          | The plan period has ended.                                                  |
| 404  | 34          | The path does not exist, for example `/genre/book/list`.                    |
| 405  | 37          | You used a write method on a lookup path.                                   |
| 429  | 25          | You went over your requests per minute. Wait for the `Retry-After` seconds. |

Details for every code are on [errors](https://amodb.dev/errors/). Plan limits are on [rate limits](https://amodb.dev/rate-limits/).

## Practical notes

- Load the lists once per language at startup and keep them in memory or a file. The edge caches the `/configuration` paths for 24 hours, so a daily refresh on your side is enough.
- Store genre ids in your database, not names. A name changes with the language, an id does not.
- Both genre paths return the same 27 entries, so one map covers movies and TV. Ids 10759 and 10762 to 10768 appear on TV items only.
- `with_genres=28,12` in [discover](https://amodb.dev/discover/) means Action and Adventure together. `with_genres=28|12` means either one.
- Genre names follow the `language` parameter. A tag outside the 14 base languages in [languages](https://amodb.dev/languages/) falls back to English, and a few names stay in English in some languages, for example `10759` in Italian.

## Questions and answers

### Do genre ids change between languages?

No. The id stays the same and only the name is translated. Request the list with the language you display, then keep one id to name map per language in your app.

### Do movies and TV use different genre ids?

They share one id space. Both genre paths return the same 27 genres. Movie items use ids such as 28 and 12, while TV items use merged ids such as 10759 for Action and Adventure. One map covers both.

### How do I filter by two genres at once?

Pass with_genres to discover. A comma between ids means all of them, so 28,12 is Action and Adventure together. A vertical bar means any of them. Use without_genres to exclude.

### Do the lookup lists need paging?

No. Each lookup path returns the full list in one response. Load them at startup and cache them for a day. The configuration paths are cached at the edge for 24 hours.

## Related pages

- [TMDB discover API for movies and TV shows](https://amodb.dev/discover/): TMDB discover API with the same filters as TMDB v3. Discover movies and TV shows by genre, cast, company, keyword, year, rating, runtime and provider.
- [Movie details API](https://amodb.dev/movies/): Movie details API with the same paths and JSON as TMDB v3. Get one movie by id, add credits, ratings and moods with append_to_response, in 14 languages.
- [TV series API, the TV show endpoint](https://amodb.dev/tv-series/): TV show API reference for GET /3/tv/{series_id}: names, status, seasons, networks and the next episode, in TMDB v3 JSON with content ratings and providers.
- [Languages](https://amodb.dev/languages/): amodb serves titles, overviews and names in 14 languages. Pass a TMDB style tag such as ru-RU or pt-BR in language; any other tag falls back to English.
- [Images API and the TMDB image path](https://amodb.dev/images-api/): Build a TMDB image path: https://img.amodb.dev/t/p/{size}/{file}. List posters, backdrops and logos per title, then load them in 10 sizes with no key.
- [Quickstart](https://amodb.dev/quickstart/): Make your first amodb call: get a key, request movie details in curl, JavaScript, Python, PHP or Go, then load the poster from img.amodb.dev. Under 2 minutes.

Updated: 2026-10-18. Source: https://amodb.dev/genres/
