Movie API for search, details and ratings

amodb is a paid movie API at https://api.amodb.dev/3 with the same paths and JSON as TMDB v3. Search for a title with /search/movie, then read the movie with append_to_response to get cast, trailers and ratings in one request. Responses come in 14 languages, from 20 requests per minute.

A movie API that speaks TMDB v3 and OMDb

amodb is an independent movie API. It speaks the same protocol as TMDB v3 and OMDb, so a client written for either one works after you change the base URL to https://api.amodb.dev/3 (or https://api.amodb.dev/omdb/ for OMDb style calls). You find a movie with /search/movie, then read it with /movie/{movie_id} and append_to_response.

What you get:

  • JSON in the TMDB v3 shape, with the same paths and query parameters.
  • Titles and overviews in 14 languages, selected with language.
  • Cast, crew, trailers, keywords, images and release dates through append_to_response.
  • Ratings from IMDb, Kinopoisk, Metacritic, Rotten Tomatoes and TMDB where known.
  • Posters from https://img.amodb.dev/t/p/{size}/{file}, with no key.

What data you get

You needCallNotes
Find a movie by titleGET /3/search/movie?query=Paged, up to 20 results per page, edge cache 10 minutes. See search.
The core recordGET /3/movie/{movie_id}Titles, overview, runtime, genres, release date. See movies.
Cast and crewappend_to_response=creditsFields are described on credits.
Trailersappend_to_response=videosReturns the results array with key, site and type.
Scoresappend_to_response=ratingsFive sources, each { value, votes } or null. See ratings.
An OMDb style answerGET /omdb/?t=InceptionSame body fields as OMDb. See OMDb endpoint.

Start in 3 steps

  1. Choose a plan on pricing. Plans differ only in rate: 20, 40 or 120 requests per minute.
  2. Create a key in your account dashboard. A key is 32 lowercase hex characters.
  3. Call the endpoint with the key in the api_key parameter or in an Authorization: Bearer header. See authentication.

Example request

The sample finds Inception by title, takes the first hit, and reads the movie with cast, trailers and ratings in one more call. That is two requests in total.

# 1. find the id
curl -s "https://api.amodb.dev/3/search/movie?query=inception&language=en-US" \
  -H "Authorization: Bearer $AMODB_KEY"

# 2. read the movie with extras
curl -s "https://api.amodb.dev/3/movie/27205?language=en-US&append_to_response=credits,videos,ratings" \
  -H "Authorization: Bearer $AMODB_KEY"
const base = 'https://api.amodb.dev/3';
const headers = { Authorization: `Bearer ${process.env.AMODB_KEY}` };

async function get(path, params) {
  const res = await fetch(`${base}${path}?${new URLSearchParams(params)}`, { headers });
  if (res.status === 429) {
    throw new Error(`Over the limit, retry in ${res.headers.get('Retry-After')} s`);
  }
  if (!res.ok) throw new Error(`amodb returned ${res.status}`);
  return res.json();
}

const found = await get('/search/movie', { query: 'inception', language: 'en-US' });
if (!found.results.length) throw new Error('No match');

const movie = await get(`/movie/${found.results[0].id}`, {
  language: 'en-US',
  append_to_response: 'credits,videos,ratings',
});
const director = movie.credits.crew.find((c) => c.job === 'Director');
console.log(movie.title, movie.release_date, movie.runtime, director?.name);
console.log('IMDb', movie.ratings.imdb?.value);

The trimmed reply. Only some fields of the movie record are kept, credits is cut to one cast member and the director, and the videos block is left out.

JSON
{
  "genres": [
    {
      "id": 12,
      "name": "Adventure"
    },
    {
      "id": 28,
      "name": "Action"
    },
    {
      "id": 80,
      "name": "Crime"
    }
  ],
  "id": 27205,
  "imdb_id": "tt1375666",
  "poster_path": "/xlaY2zyzMfkhk0HSC5VUwzoZPU1.jpg",
  "release_date": "2010-07-15",
  "runtime": 148,
  "title": "Inception",
  "credits": {
    "cast": [
      {
        "adult": false,
        "gender": 2,
        "id": 6193,
        "known_for_department": "Acting",
        "name": "Leonardo DiCaprio",
        "original_name": "Leonardo DiCaprio",
        "popularity": 9.3213,
        "profile_path": "/wo2hJpn04vbtmh0B9utCFdsQhxM.jpg",
        "character": "Dom Cobb",
        "credit_id": "52fe4534c3a368484e04de03",
        "order": 0
      }
    ],
    "crew": [
      {
        "adult": false,
        "gender": 2,
        "id": 525,
        "known_for_department": "Directing",
        "name": "Christopher Nolan",
        "original_name": "Christopher Nolan",
        "popularity": 8.578,
        "profile_path": "/xuAIuYSmsUzKlUMBFGVZaWsY3DZ.jpg",
        "credit_id": "5e83ac2ee33f830018359a00",
        "department": "Directing",
        "job": "Director"
      }
    ]
  },
  "ratings": {
    "imdb": {
      "value": 8.8,
      "votes": 2877173
    },
    "kinopoisk": {
      "value": 8.7,
      "votes": null
    },
    "metacritic": {
      "value": 74,
      "votes": null
    },
    "rotten_tomatoes": {
      "value": 86,
      "votes": null
    },
    "tmdb": {
      "value": 8.373,
      "votes": 40457
    }
  }
}

Ways to find a movie

Pick the call that matches what you already hold.

You start withCallResult
A title typed by a userGET /3/search/movie?query=results array with id, title, release_date, poster_path
An IMDb id such as tt0133093GET /3/find/tt0133093?external_source=imdb_idmovie_results array
A numeric movie id such as 603GET /3/movie/603The full record
An existing OMDb clientGET /omdb/?i=tt0133093OMDb body with Title, Year, Ratings

Store both ids. The numeric id is the key for every other call, and imdb_id joins your data to other systems. The lookup rules are on find by external id.

Empty fields and failed lookups

Real movie data has gaps, so write the display code for them. A search with no hit is not an error: it returns HTTP 200 with an empty results array. An unknown id is an error.

CaseWhat you seeWhat to do
No search hit200 and "results": []Show "no match", do not retry
Unknown movie id404 with status_code 34Drop the id from your list
Missing or wrong key401 with status_code 7Stop and fix the key
Empty overviewAn empty stringRequest again with language=en-US
Unknown scorenull inside ratingsHide that badge
No release dateEmpty release_dateSort the title last

The full error list is on errors.

Staying inside the rate limit

A search and a details call cost one request each. At 20 requests per minute that is ten title lookups a minute, at 120 requests per minute it is sixty. A cache hit at the edge still counts, because the key check and the rate limit run before the cache. Keep a cache of your own for repeat lookups, and read X-RateLimit-Remaining to see how much of the minute is left. When you get a 429, wait the Retry-After seconds. Limits per plan are on rate limits.

How it compares

CapabilityScrape pages yourselfFree-tier metadata APIamodb
Response formatHTML you must parseJSONJSON in the TMDB v3 shape
Schema stabilityBreaks when page markup changesSet by the providerFixed paths and fields, new fields can appear
Access termsThe terms of each site applyFree tier with usage terms, check themPaid, prepaid, no free tier
Rate limitNothing you can rely onSet by the provider20, 40 or 120 requests per minute per key
Ratings from several sourcesOne scraper per siteVaries, check the docsratings in the same call, null when unknown
LanguagesWhatever each page offersVaries14, chosen with language
Reuse of TMDB v3 and OMDb clientsNoOnly if it uses the same protocolYes, change the base URL

Pricing

Access is prepaid for 1, 3, 6, 12 or 24 months, with 0, 10, 20, 30 and 40 percent off the longer periods. There is no automatic renewal and no free tier. Every plan gets all data, and the plans differ only in rate: 20, 40 or 120 requests per minute. Pick one on pricing and make your first call in a few minutes.

Questions and answers

Is this movie API compatible with TMDB?

Yes for the read endpoints a movie app needs. Paths, query parameters and JSON match TMDB v3 at https://api.amodb.dev/3, so you change the base URL and use your amodb key. Account, session, rating and list write methods return 405 with status_code 37. The changes feeds, aggregate_credits, credit and review lookups return 404.

Can I look up a movie by IMDb id?

Yes. Call /3/find/tt0133093?external_source=imdb_id and read movie_results, or use the OMDb style endpoint at /omdb/?i=tt0133093. Both accept the same key as the TMDB style calls.

How many requests does one movie page need?

Two at most: one search to get the id, then one /movie/{id} call with append_to_response=credits,videos,ratings. If you already store the id, a single request is enough.

Which languages does the movie API return?

Fourteen: English, Russian, Ukrainian, Belarusian, Chinese, Portuguese, Bulgarian, Hebrew, Czech, Romanian, French, Polish, Italian and Spanish. Pass a TMDB tag such as pt-BR in language. Any other tag falls back to English.

Is there a free tier or a trial?

No. Access is prepaid for 1, 3, 6, 12 or 24 months, with discounts of 0, 10, 20, 30 and 40 percent. There is no automatic renewal. The 20, 40 and 120 requests per minute plans are on the pricing page.