# Find by external id

> GET /3/find/{external_id} turns an IMDb, TVDB, Wikidata, Kinopoisk, Facebook, Twitter or Instagram id into TMDB style results, and the external_ids endpoints go the other way. A Wikidata endpoint adds budget, box office, awards and linked titles for a movie or series. All of it uses your normal key.

## Endpoint

`GET /3/find/{external_id}`

```bash
curl "https://api.amodb.dev/3/find/tt0137523?external_source=imdb_id" \
  -H "Authorization: Bearer $AMODB_KEY"
```

Response:

```json
{
  "movie_results": [
    {
      "adult": false,
      "backdrop_path": "/c6OLXfKAk5BKeR6broC8pYiCquX.jpg",
      "genre_ids": [
        18,
        53
      ],
      "id": 550,
      "original_language": "en",
      "original_title": "Fight Club",
      "overview": "A ticking-time-bomb insomniac and a slippery soap salesman channel primal male aggression into a shocking new form of therapy. Their concept catches on, with underground \"fight clubs\" forming in every town, until an eccentric gets in the wa...",
      "popularity": 39.0054,
      "poster_path": "/jSziioSwPVrOy9Yow3XhWIBDjq1.jpg",
      "release_date": "1999-10-15",
      "title": "Fight Club",
      "video": false,
      "vote_average": 8.437,
      "vote_count": 33042,
      "media_type": "movie"
    }
  ],
  "person_results": [],
  "tv_results": [],
  "tv_episode_results": [],
  "tv_season_results": []
}
```

## Find a title by external id

`GET /3/find/{external_id}` takes an id from another system and returns the matching records. The path holds the id, and the `external_source` query parameter says which system it comes from. amodb accepts twelve sources and seven of them resolve to records: `imdb_id`, `tvdb_id`, `wikidata_id`, `kinopoisk_id`, `facebook_id`, `twitter_id` and `instagram_id`.

The sample maps the IMDb id `tt0137523` to a TMDB id.

```bash
curl -sf "https://api.amodb.dev/3/find/tt0137523?external_source=imdb_id" \
  -H "Authorization: Bearer $AMODB_KEY"
```

```js
const url = 'https://api.amodb.dev/3/find/tt0137523?external_source=imdb_id';
const res = await fetch(url, { headers: { Authorization: `Bearer ${process.env.AMODB_KEY}` } });
if (!res.ok) throw new Error(`amodb returned ${res.status}`);
const found = await res.json();
const movie = found.movie_results[0];
console.log(movie ? `${movie.id} ${movie.title}` : 'no match');
```

```python
import os
import requests

r = requests.get(
    "https://api.amodb.dev/3/find/tt0137523",
    params={"external_source": "imdb_id"},
    headers={"Authorization": f"Bearer {os.environ['AMODB_KEY']}"},
    timeout=10,
)
r.raise_for_status()
results = r.json()["movie_results"]
print(f"{results[0]['id']} {results[0]['title']}" if results else "no match")
```

```php
<?php
$url = 'https://api.amodb.dev/3/find/tt0137523?external_source=imdb_id';
$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");
}
$movies = json_decode($body, true)['movie_results'];
echo $movies ? $movies[0]['id'] . ' ' . $movies[0]['title'] : 'no match', PHP_EOL;
```

```go
package main

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

type Found struct {
	MovieResults []struct {
		ID    int    `json:"id"`
		Title string `json:"title"`
	} `json:"movie_results"`
}

func main() {
	url := "https://api.amodb.dev/3/find/tt0137523?external_source=imdb_id"
	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 f Found
	if err := json.NewDecoder(res.Body).Decode(&f); err != nil {
		panic(err)
	}
	if len(f.MovieResults) == 0 {
		fmt.Println("no match")
		return
	}
	fmt.Println(f.MovieResults[0].ID, f.MovieResults[0].Title)
}
```

### Parameters

| Parameter         | In    | Required   | Description                                                                                                                                                                                                                |
| ----------------- | ----- | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `external_id`     | path  | yes        | The id in the other system, for example `tt0137523`.                                                                                                                                                                       |
| `external_source` | query | yes        | One of `imdb_id`, `tvdb_id`, `wikidata_id`, `kinopoisk_id`, `facebook_id`, `twitter_id`, `instagram_id`. Five more are accepted and return nothing: `freebase_mid`, `freebase_id`, `tvrage_id`, `tiktok_id`, `youtube_id`. |
| `language`        | query | no         | One of 14 languages such as `en` or `ru-RU`. Other values fall back to `en`.                                                                                                                                               |
| `api_key`         | query | one of two | Your key. Use this or the `Authorization: Bearer` header.                                                                                                                                                                  |

A missing `external_source`, or one that is not in the list, answers 400 with `status_code` 22. The value must be lower case.

### Response fields

| Field                | Type  | Notes                                                                                              |
| -------------------- | ----- | -------------------------------------------------------------------------------------------------- |
| `movie_results`      | array | Movie records with the same fields as a search result, plus `media_type` set to `movie`.           |
| `person_results`     | array | People matched by the id. Each has `known_for` as an empty array and `media_type` set to `person`. |
| `tv_results`         | array | TV series records with `media_type` set to `tv`.                                                   |
| `tv_episode_results` | array | Always empty.                                                                                      |
| `tv_season_results`  | array | Always empty.                                                                                      |

### Example response

```json
{
  "movie_results": [
    {
      "adult": false,
      "backdrop_path": "/c6OLXfKAk5BKeR6broC8pYiCquX.jpg",
      "genre_ids": [18, 53],
      "id": 550,
      "original_language": "en",
      "original_title": "Fight Club",
      "overview": "A ticking-time-bomb insomniac and a slippery soap salesman channel primal male aggression into a shocking n...",
      "popularity": 39.0054,
      "poster_path": "/jSziioSwPVrOy9Yow3XhWIBDjq1.jpg",
      "release_date": "1999-10-15",
      "title": "Fight Club",
      "video": false,
      "vote_average": 8.437,
      "vote_count": 33039,
      "media_type": "movie"
    }
  ],
  "person_results": [],
  "tv_results": [],
  "tv_episode_results": [],
  "tv_season_results": []
}
```

The overview is cut.

### Which source finds what

| `external_source`                           | Id looks like                                            | Example                                                              | Usual result array                                |
| ------------------------------------------- | -------------------------------------------------------- | -------------------------------------------------------------------- | ------------------------------------------------- |
| `imdb_id`                                   | `tt` plus digits for titles, `nm` plus digits for people | `tt0137523`, `nm0000093` (Brad Pitt)                                 | `movie_results`, `tv_results` or `person_results` |
| `tvdb_id`                                   | Number                                                   | `81189` (Breaking Bad)                                               | `tv_results`                                      |
| `wikidata_id`                               | `Q` plus digits                                          | `Q190050` (Fight Club), `Q1079` (Breaking Bad), `Q35332` (Brad Pitt) | `movie_results`, `tv_results` or `person_results` |
| `kinopoisk_id`                              | Number                                                   | `361` (Fight Club), `404900` (Breaking Bad)                          | `movie_results` or `tv_results`                   |
| `facebook_id`, `twitter_id`, `instagram_id` | Account name                                             | `FightClub`                                                          | Depends on the account                            |

One account name can match more than one title. For example `instagram_id=breakingbad` returns the series and the film El Camino, so read every array.

```bash
curl -sf "https://api.amodb.dev/3/find/361?external_source=kinopoisk_id" \
  -H "Authorization: Bearer $AMODB_KEY"
```

## External ids of a known title

The reverse direction is a set of `external_ids` endpoints. They return the ids that other systems use for a record you already have.

| Method and path                        | Returns                                                                                          | Parameters  |
| -------------------------------------- | ------------------------------------------------------------------------------------------------ | ----------- |
| `GET /movie/{movie_id}/external_ids`   | `imdb_id`, `wikidata_id`, `facebook_id`, `instagram_id`, `twitter_id`, `kinopoisk_id`            | `movie_id`  |
| `GET /tv/{tv_id}/external_ids`         | The same plus `freebase_mid`, `freebase_id`, `tvdb_id`, `tvrage_id`                              | `tv_id`     |
| `GET /person/{person_id}/external_ids` | `imdb_id`, `wikidata_id`, `facebook_id`, `instagram_id`, `tiktok_id`, `twitter_id`, `youtube_id` | `person_id` |

An id that a title does not have comes back as `null`. `kinopoisk_id` is a string and is only present for a movie or series when amodb knows it. A real answer for `/3/movie/550/external_ids`:

```json
{
  "id": 550,
  "imdb_id": "tt0137523",
  "wikidata_id": "Q190050",
  "facebook_id": "FightClub",
  "instagram_id": null,
  "twitter_id": null,
  "kinopoisk_id": "361"
}
```

A real answer for `/3/tv/1396/external_ids`:

```json
{
  "id": 1396,
  "imdb_id": "tt0903747",
  "freebase_mid": null,
  "freebase_id": null,
  "tvdb_id": 81189,
  "tvrage_id": null,
  "wikidata_id": "Q1079",
  "facebook_id": "BreakingBad",
  "instagram_id": "breakingbad",
  "twitter_id": "BreakingBad",
  "kinopoisk_id": "404900"
}
```

The season and episode `external_ids` endpoints exist, but every id in them is `null` today, so skip them.

## Wikidata facts

`GET /3/movie/{movie_id}/wikidata` and `GET /3/tv/{tv_id}/wikidata` return the Wikidata id of a title and facts about it: money, neighbours in a series, Wikipedia pages, awards and places. Every key is always present. A fact that is not known is `null` for a single value and `[]` for a list.

| Method and path                  | Returns                                    | Parameters              |
| -------------------------------- | ------------------------------------------ | ----------------------- |
| `GET /movie/{movie_id}/wikidata` | Wikidata id and facts                      | `movie_id`, `language`  |
| `GET /tv/{tv_id}/wikidata`       | Wikidata id and facts                      | `tv_id`, `language`     |
| `append_to_response=wikidata`    | Same block under `wikidata`, with its `id` | Added to a details call |

This is the answer for Fight Club (movie 550), cut to a readable size:

```json
{
  "id": 550,
  "wikidata_id": "Q190050",
  "budget": {
    "value": 63000000,
    "currency": "USD"
  },
  "box_office": {
    "value": 101209702,
    "currency": "USD",
    "worldwide": true
  },
  "follows": null,
  "followed_by": null,
  "sitelinks": {
    "en": "Fight Club",
    "ru": "Бойцовский клуб (фильм)",
    "uk": "Бійцівський клуб (фільм)"
  },
  "awards": [
    {
      "wikidata_id": "Q28044798",
      "label": "Empire Awards, UK for best british actress"
    },
    {
      "wikidata_id": "Q943908",
      "label": "Jupiter Award",
      "year": 2000
    }
  ],
  "nominations": [
    {
      "wikidata_id": "Q488645",
      "label": "Academy Award for Best Sound Editing",
      "year": 2000
    }
  ],
  "based_on": [
    {
      "wikidata_id": "Q837283",
      "label": "Fight Club",
      "author": {
        "wikidata_id": "Q268181",
        "label": "Chuck Palahniuk"
      }
    }
  ],
  "filming_locations": [
    {
      "wikidata_id": "Q65",
      "label": "Los Angeles"
    }
  ],
  "narrative_locations": [
    {
      "wikidata_id": "Q65",
      "label": "Los Angeles"
    }
  ],
  "original_broadcasters": []
}
```

The `sitelinks` object has 14 entries and `awards` has 5. Both are cut here.

| Field                                                               | Type           | Notes                                                                                               |
| ------------------------------------------------------------------- | -------------- | --------------------------------------------------------------------------------------------------- |
| `id`                                                                | integer        | TMDB id of the title. It stays when you use `append_to_response`.                                   |
| `wikidata_id`                                                       | string or null | Wikidata item such as `Q190050`.                                                                    |
| `budget`                                                            | object or null | `value` is a rounded integer and `currency` is an ISO code or `null`.                               |
| `box_office`                                                        | object or null | Same as `budget`, plus `worldwide` set to `true` or `false`.                                        |
| `follows`, `followed_by`                                            | object or null | The previous and next title in a series of films, as a link.                                        |
| `sitelinks`                                                         | object         | Maps a language code to the Wikipedia page title. Keys are the 14 served languages. `{}` when none. |
| `awards`, `nominations`                                             | array          | Links with an optional `year`.                                                                      |
| `based_on`                                                          | array          | Source works with `wikidata_id`, `label` and an `author` object or `null`.                          |
| `filming_locations`, `narrative_locations`, `original_broadcasters` | array          | Links. Breaking Bad has AMC in `original_broadcasters`.                                             |

A link has `wikidata_id`, `label` and, when the item is a title in the catalog, `tmdb_id` and `media_type`. For The Matrix Reloaded (movie 604) the neighbours are links to movies 603 and 605:

```json
{
  "follows": {
    "wikidata_id": "Q83495",
    "label": "The Matrix",
    "tmdb_id": 603,
    "media_type": "movie"
  },
  "followed_by": {
    "wikidata_id": "Q207536",
    "label": "The Matrix Revolutions",
    "tmdb_id": 605,
    "media_type": "movie"
  }
}
```

Each `label` comes in the request `language` and falls back to English. With `language=ru` the author above reads `Чак Паланик`.

## Errors

Errors use the TMDB body, for example `{"success": false, "status_code": 7, "status_message": "Invalid API key: You must be granted a valid key."}`.

| HTTP | status_code | When                                                               |
| ---- | ----------- | ------------------------------------------------------------------ |
| 400  | 22          | `external_source` is missing, not lower case or not in the list.   |
| 401  | 7           | The key is missing or wrong.                                       |
| 402  | 36          | The plan period has ended.                                         |
| 404  | 34          | The title id in a `wikidata` path does not exist.                  |
| 429  | 25          | Over your requests per minute. Wait for the `Retry-After` seconds. |

An unknown external id on `find` is not an error: expect all five arrays to be empty. The `external_ids` endpoints do not answer 404 for an unknown id either. They answer 200 with every id `null`. See [errors](https://amodb.dev/errors/) and [authentication](https://amodb.dev/authentication/).

## Practical notes

- Save the TMDB id the first time you resolve an external id. Later calls then skip `find` and go straight to the details path, which saves one request per title.
- Always test that the array you want has an item. `find` can return several arrays at once for one id.
- Details and external ids are cached at the edge for 6 hours. A repeated lookup inside that time returns the stored answer.
- `wikidata_id` works both ways: pass it to `find` to get a title, or read it from `external_ids` to link out.
- To bring OMDb style IMDb lookups over, see the [OMDb endpoint](https://amodb.dev/omdb-endpoint/). For scores after you resolve a title, see [ratings](https://amodb.dev/ratings/).

## Questions and answers

### Which external sources does find accept?

Twelve values are accepted for external_source. Seven of them resolve: imdb_id, tvdb_id, wikidata_id, kinopoisk_id, facebook_id, twitter_id and instagram_id. The other five return empty arrays. The value is required, lower case and exact, for example external_source=imdb_id.

### Why does find return five arrays?

An id can point to a movie, a person, a series, an episode or a season, so the reply has one array for each kind. In amodb only movie_results, person_results and tv_results hold items. tv_episode_results and tv_season_results are always empty.

### What happens when the id is unknown?

You get status 200 with all five arrays empty, as in TMDB. Check that at least one array has an item before you read it. A missing or unknown external_source is different: it answers 400 with status_code 22.

### How do I get a Kinopoisk id for a title I already have?

Call the external_ids endpoint of the movie or series. It returns kinopoisk_id as a string such as 361 for Fight Club, or null when amodb does not know it. Pass that string to find with external_source=kinopoisk_id to go back.

### Can I append wikidata to a details call?

Yes. Add append_to_response=wikidata to a movie or TV details request and the Wikidata block arrives under the wikidata key, in the same request and with no extra call.

## Related pages

- [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.
- [Movie and TV ratings](https://amodb.dev/ratings/): Movie ratings API that returns IMDb, Kinopoisk, Metacritic, Rotten Tomatoes and TMDB scores for a title in one call, with null for any source not known.
- [Person details API](https://amodb.dev/people/): Person details API with the same paths and JSON as TMDB v3. Get an actor or crew member by id, with biography, filmography, external ids and the popular list.
- [OMDb compatible endpoint](https://amodb.dev/omdb-endpoint/): OMDb API compatible endpoint at api.amodb.dev/omdb/. Look up by i or t, search with s, read the Ratings array and keep your client by changing the base URL.
- [Authentication](https://amodb.dev/authentication/): How to send your amodb key: api_key in the query, an Authorization Bearer header, or apikey for OMDb calls. Key format, storage, rotation and the 401 errors.

Updated: 2026-10-18. Source: https://amodb.dev/find-by-external-id/
