๐Ÿš€ Welcome to IMDb Resolver

A high-performance REST API that resolves movie and TV show titles to IMDb IDs using advanced matching algorithms.

๐Ÿ”‘ API Key Required

All API endpoints require authentication. Include your API key in requests:

# Via header (recommended)
curl -H "X-API-Key: your-api-key" https://imdb.newzburners.in/v1/resolve

# Via query parameter  
curl "https://imdb.newzburners.in/v1/resolve?api_key=your-api-key"

Contact the administrator to request an API key.

โšก

Lightning Fast

Sub-second response times with Redis caching and connection pooling

๐ŸŽฏ

Fuzzy Matching

Find matches even with typos, abbreviations, and variations

๐ŸŒ

Multi-Language

Supports alternative titles (AKAs) in multiple languages

๐Ÿ“Š

Production Ready

Rate limiting, health monitoring, and comprehensive logging

๐Ÿ”ง Features

  • โšก FTS5 Full-Text Search with BM25 relevance scoring
  • โœ… Exact matching with year-based scoring
  • ๐Ÿ” Optional fuzzy search with configurable thresholds
  • ๐Ÿ“บ TV Show Support - Movies AND TV series by default! โœจ
  • ๐ŸŽฏ Content-Specific Endpoints - `/resolve/movie`, `/resolve/tv`, `/resolve/any` โœจ
  • ๐ŸŽฌ Configurable content types (movies, TV series, documentaries)
  • ๐ŸŒ AKA support for international titles
  • ๐Ÿ“Š Multiple results with confidence ranking
  • ๐Ÿ”ค Unicode normalization for special characters
  • โšก Redis caching for performance
  • ๐Ÿ›ก๏ธ Rate limiting and input validation

๐Ÿ“ก API Endpoints

POST /resolve

Resolve movie/TV title to IMDb ID with enhanced search capabilities.

Request Body:

{
  "title": "The Matrix",                              // Required: Movie/TV title
  "year": 1999,                                      // Optional: Release year for accuracy
  "allow_aka": true,                                 // Optional: Search alternative titles (default: true)
  "fuzzy": false,                                    // Optional: Enable fuzzy matching (default: false)
  "fuzzy_threshold": 0.8,                           // Optional: Fuzzy match threshold 0.1-1.0 (default: 0.8)
  "title_types": ["movie", "tvSeries"],             // Optional: Content types (default: movies + TV shows)
  "max_results": 1                                  // Optional: Number of results 1-10 (default: 1)
}

Response:

{
  "results": [
    {
      "imdb_id": "tt0133093",
      "score": 1.0,
      "matched_title": "The Matrix",
      "matched_year": 1999,
      "source": "primary",
      "similarity": 1.0
    }
  ],
  "total_found": 1,
  "query_time_ms": 12.5
}

๐Ÿ”ง Advanced Parameters:

  • title_types: Content type options:
    • Default: ["movie", "tvMovie", "tvSeries", "tvMiniSeries", "short"]
    • ๐ŸŽฌ movie - Feature films
    • ๐Ÿ“บ tvSeries - TV series โœจ Now included by default!
    • ๐ŸŽญ tvMovie - Made-for-TV movies
    • ๐Ÿ“– tvMiniSeries - Limited series โœจ Now included by default!
    • ๐ŸŽž๏ธ short - Short films
    • โญ tvSpecial - TV specials
    • ๐Ÿ“‘ documentary - Documentaries
  • fuzzy_threshold: Controls fuzzy matching sensitivity:
    • ๐ŸŽฏ 1.0 - Exact matches only
    • ๐Ÿ” 0.8 - Recommended for typos
    • ๐ŸŒŠ 0.6 - More permissive matching
    • ๐Ÿ”“ 0.3 - Very loose matching

POST /v1/resolve

Explicit v1 endpoint (same as /resolve).

โ„น๏ธ Note: Both /resolve and /v1/resolve provide the same functionality with all enhanced features.

๐ŸŽฏ Content-Specific Endpoints

For simplified usage, we provide content-type specific endpoints that automatically configure the search scope:

POST /v1/resolve/movie ๐ŸŽฌ

Search movies only (feature films, TV movies, shorts).

Request Body (Simplified):

{
  "title": "The Godfather",                   // Required: Movie title
  "year": 1972,                             // Optional: Release year
  "allow_aka": true,                        // Optional: Search alternative titles
  "fuzzy": false,                           // Optional: Enable fuzzy matching
  "fuzzy_threshold": 0.8,                   // Optional: Fuzzy threshold (0.1-1.0)
  "max_results": 1                          // Optional: Number of results
}
๐ŸŽฌ Automatically searches: movie, tvMovie, short

POST /v1/resolve/tv ๐Ÿ“บ

Search TV content only (series, mini-series, specials).

Request Body (Simplified):

{
  "title": "Breaking Bad",                   // Required: TV show title
  "year": 2008,                             // Optional: First air year
  "allow_aka": true,                        // Optional: Search alternative titles
  "fuzzy": false,                           // Optional: Enable fuzzy matching
  "max_results": 1                          // Optional: Number of results
}
๐Ÿ“บ Automatically searches: tvSeries, tvMiniSeries, tvSpecial

POST /v1/resolve/any ๐ŸŒ

Search all content types (movies, TV, documentaries, everything).

๐ŸŒ Searches everything: movie, tvSeries, tvMovie, tvMiniSeries, tvSpecial, short, documentary

GET /api

API information and capabilities.

{
  "name": "IMDb Resolver",
  "version": "0.2.0",
  "status": "running",
  "current_version": "v1",
  "endpoints": {
    "primary": "/resolve (main endpoint)",
    "versioned": "/v1/resolve (explicit v1)"
  },
  "features": ["fts_search", "configurable_fuzzy", "configurable_types", "aka_support"]
}

GET /health

Comprehensive health check including database and system status.

{
  "status": "healthy",
  "timestamp": 1769665212.53,
  "uptime_seconds": 597.47,
  "database": {
    "status": "healthy",
    "query_time_ms": 0.0,
    "title_count": 10234567,
    "aka_count": 15678901,
    "has_data": true
  },
  "disk": {
    "status": "healthy",
    "total_gb": 879.14,
    "available_gb": 363.31
  }
}

GET /health/quick

Quick health check for load balancers.

{"status": "ok"}

GET /docs

Interactive OpenAPI documentation (Swagger UI).

๐Ÿ’ก Getting Started

๐Ÿš€ Quick Start

The IMDb Resolver API helps you find IMDb IDs for movies and TV shows. Here's how to get started:

๐ŸŽฌ

Movies

/resolve/movie
๐Ÿ“บ

TV Shows

/resolve/tv
๐ŸŒ

Everything

/resolve/any

๐Ÿ”ง Code Examples

๐Ÿ Python

import requests

# Find a movie
response = requests.post('https://imdb.yourdomain.com/v1/resolve/movie', 
    headers={'X-API-Key': 'your-api-key'},
    json={
        'title': 'The Matrix',
        'year': 1999
    })

data = response.json()
if data['results']:
    imdb_id = data['results'][0]['imdb_id']
    print(f"IMDb ID: {imdb_id}")

# Find a TV show with fuzzy matching
response = requests.post('https://imdb.yourdomain.com/resolve/tv', json={
    'title': 'Breaking Bad',  # Works even with typos!
    'fuzzy': True,
    'max_results': 3
})

for result in response.json()['results']:
    print(f"{result['matched_title']} ({result['matched_year']}) - {result['imdb_id']}")

โšก JavaScript

// Find a movie
const response = await fetch('https://imdb.yourdomain.com/resolve/movie', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    title: 'The Matrix',
    year: 1999
  })
});

const data = await response.json();
if (data.results.length > 0) {
  console.log('IMDb ID:', data.results[0].imdb_id);
}

// Find TV shows
async function findTVShow(title) {
  const response = await fetch('https://imdb.yourdomain.com/resolve/tv', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ title, fuzzy: true })
  });
  
  const data = await response.json();
  return data.results.map(r => ({
    title: r.matched_title,
    year: r.matched_year,
    imdbId: r.imdb_id
  }));
}

๐Ÿ˜ PHP

<?php
function findMovie($title, $year = null) {
    $data = [
        'title' => $title,
        'year' => $year,
        'fuzzy' => true
    ];
    
    $options = [
        'http' => [
            'header' => "Content-Type: application/json\r\n",
            'method' => 'POST',
            'content' => json_encode($data)
        ]
    ];
    
    $context = stream_context_create($options);
    $result = file_get_contents(
        'https://imdb.yourdomain.com/resolve/movie', 
        false, 
        $context
    );
    
    $response = json_decode($result, true);
    return $response['results'][0]['imdb_id'] ?? null;
}

// Usage
$imdbId = findMovie('The Godfather', 1972);
echo "IMDb ID: $imdbId";
?>

๐ŸŒ cURL

# Find a movie
curl -X POST https://imdb.yourdomain.com/resolve/movie \
  -H "Content-Type: application/json" \
  -d '{"title": "The Godfather", "year": 1972}'

# Find TV show with fuzzy matching
curl -X POST https://imdb.yourdomain.com/resolve/tv \
  -H "Content-Type: application/json" \
  -d '{"title": "Breking Bad", "fuzzy": true}'

# Search everything 
curl -X POST https://imdb.yourdomain.com/resolve/any \
  -H "Content-Type: application/json" \
  -d '{"title": "Planet Earth", "max_results": 5}'

# International titles
curl -X POST https://imdb.yourdomain.com/resolve/movie \
  -H "Content-Type: application/json" \
  -d '{"title": "Le Parrain", "allow_aka": true}'

๐ŸŽฏ Real-World Integration Examples

๐ŸŽฌ Plex Media Server Integration

Automatically tag your Plex content with IMDb IDs:

import requests
from plexapi.server import PlexServer

# Connect to Plex
plex = PlexServer('http://localhost:32400', 'your-plex-token')

async def tag_movie_with_imdb(movie_title, movie_year):
    """Add IMDb ID to Plex movie"""
    try:
        # Find IMDb ID
        response = requests.post('https://imdb.yourdomain.com/resolve/movie', json={
            'title': movie_title,
            'year': movie_year,
            'fuzzy': True  # Handle small variations in titles
        })
        
        data = response.json()
        if data['results']:
            imdb_id = data['results'][0]['imdb_id']
            
            # Update Plex metadata
            movie = plex.library.section('Movies').get(movie_title)
            movie.edit(**{
                'guid': f'com.imdb://{imdb_id}',
                'summary': f'IMDb: {imdb_id}'
            })
            
            print(f"โœ… Tagged '{movie_title}' with {imdb_id}")
            return imdb_id
            
    except Exception as e:
        print(f"โŒ Failed to tag '{movie_title}': {e}")
        return None

# Usage: Tag all movies in your library
for movie in plex.library.section('Movies').all():
    tag_movie_with_imdb(movie.title, movie.year)

๐Ÿค– Discord Bot Integration

Create a Discord bot that helps users find movie/TV info:

import discord
import requests
from discord.ext import commands

bot = commands.Bot(command_prefix='!')

@bot.command()
async def movie(ctx, *, title):
    """Find a movie: !movie The Matrix"""
    try:
        response = requests.post('https://imdb.yourdomain.com/resolve/movie', 
                               json={'title': title, 'fuzzy': True}, 
                               timeout=5)
        data = response.json()
        
        if data['results']:
            result = data['results'][0]
            embed = discord.Embed(
                title=result['matched_title'],
                description=f"Year: {result['matched_year']}",
                color=0xf5c518,  # IMDb yellow
                url=f"https://imdb.com/title/{result['imdb_id']}"
            )
            embed.add_field(name="IMDb ID", value=result['imdb_id'], inline=True)
            embed.add_field(name="Confidence", value=f"{result['score']:.1%}", inline=True)
            await ctx.send(embed=embed)
        else:
            await ctx.send(f"โŒ No movie found for '{title}'")
            
    except Exception as e:
        await ctx.send(f"โŒ Error: {e}")

@bot.command()
async def tv(ctx, *, title):
    """Find a TV show: !tv Breaking Bad"""
    # Similar implementation for TV shows using /resolve/tv

bot.run('your-discord-token')

๐Ÿ“บ Sonarr/Radarr Custom Script

Enhance your *arr applications with IMDb resolution:

#!/bin/bash
# save as: /config/custom-scripts/imdb-resolver.sh

# Environment variables from Radarr/Sonarr
TITLE="$radarr_movie_title"
YEAR="$radarr_movie_year"
TYPE="${1:-movie}"  # movie or tv

echo "๐Ÿ” Resolving: $TITLE ($YEAR)"

# Resolve IMDb ID
RESPONSE=$(curl -s -X POST "https://imdb.yourdomain.com/resolve/$TYPE" \
  -H "Content-Type: application/json" \
  -d "{\"title\": \"$TITLE\", \"year\": $YEAR, \"fuzzy\": true}")

IMDB_ID=$(echo "$RESPONSE" | jq -r '.results[0].imdb_id // empty')

if [ ! -z "$IMDB_ID" ]; then
    echo "โœ… Found IMDb ID: $IMDB_ID"
    
    # Save to file for other scripts
    echo "$IMDB_ID" > "/downloads/$TITLE.imdbid"
    
    # Send notification
    curl -X POST "https://your-webhook-url" \
      -d "{\"text\": \"๐ŸŽฌ $TITLE ($YEAR) resolved to $IMDB_ID\"}"
else
    echo "โŒ No IMDb ID found for: $TITLE"
fi

๐ŸŒ Web Application (React)

Build a movie search component:

import React, { useState } from 'react';

function MovieSearcher() {
  const [query, setQuery] = useState('');
  const [results, setResults] = useState([]);
  const [loading, setLoading] = useState(false);

  const searchMovies = async () => {
    if (!query) return;
    
    setLoading(true);
    try {
      const response = await fetch('https://imdb.yourdomain.com/resolve/movie', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          title: query,
          fuzzy: true,
          max_results: 5
        })
      });
      
      const data = await response.json();
      setResults(data.results || []);
    } catch (error) {
      console.error('Search failed:', error);
    } finally {
      setLoading(false);
    }
  };

  return (
    <div className="movie-searcher">
      <input
        type="text"
        placeholder="Search for a movie..."
        value={query}
        onChange={(e) => setQuery(e.target.value)}
        onKeyPress={(e) => e.key === 'Enter' && searchMovies()}
      />
      <button onClick={searchMovies} disabled={loading}>
        {loading ? 'Searching...' : 'Search'}
      </button>
      
      {results.map(movie => (
        <div key={movie.imdb_id} className="movie-result">
          <h3>{movie.matched_title} ({movie.matched_year})</h3>
          <p>IMDb: <a href={`https://imdb.com/title/${movie.imdb_id}`}>
            {movie.imdb_id}
          </a></p>
          <p>Confidence: {(movie.score * 100).toFixed(1)}%</p>
        </div>
      ))}
    </div>
  );
}

export default MovieSearcher;

๐Ÿ’ก Best Practices

โœ… Performance Tips

  • Use specific endpoints (/movie, /tv)
  • Include release year when possible
  • Enable fuzzy matching for user input
  • Cache results in your application
  • Use reasonable max_results limits

๐Ÿ”ง Error Handling

  • Check results.length before accessing
  • Handle rate limiting (429 errors)
  • Implement retry logic with backoff
  • Validate response structure
  • Log failed requests for debugging

โš ๏ธ Rate Limiting

  • Default: 100 requests per minute
  • Check X-RateLimit-* headers
  • Implement client-side rate limiting
  • Batch requests when possible
  • Contact us for higher limits

๐ŸŽฏ Fuzzy Matching

  • 0.9+: Near-exact matches only
  • 0.8: Good for small typos (recommended)
  • 0.6: More permissive matching
  • 0.3: Very loose (use carefully)
  • Lower = more results, less precision

๐Ÿ“– Quick Reference

๐ŸŽฌ Movies

POST /resolve/movie
{
  "title": "Movie Title",
  "year": 2023,
  "fuzzy": true
}

๐Ÿ“บ TV Shows

POST /resolve/tv
{
  "title": "Show Title",
  "year": 2023,
  "fuzzy": true
}

๐ŸŒ Everything

POST /resolve/any
{
  "title": "Any Title",
  "max_results": 5
}

๐Ÿงช Live API Testing

Test the API directly from this page:

Health Check

Movie Resolution

Test with "The Matrix" (1999):

Comprehensive Health

๐Ÿ”— Integration Examples

๐ŸŽฌ Plex Integration

Use with Plex webhooks to automatically tag content:

# Plex webhook handler
async def handle_plex_webhook(title: str, year: int):
    async with httpx.AsyncClient() as client:
        response = await client.post('https://imdb.yourdomain.com/resolve', json={
            'title': title,
            'year': year,
            'fuzzy': True
        })
        
        data = response.json()
        if data['results']:
            imdb_id = data['results'][0]['imdb_id']
            # Update Plex metadata with IMDb ID
            return imdb_id

๐Ÿ“บ Sonarr/Radarr Integration

Connect with *arr applications for metadata enrichment:

# Custom script for Radarr
#!/bin/bash

TITLE="$radarr_movie_title"
YEAR="$radarr_movie_year"

IMDB_ID=$(curl -s -X POST https://imdb.yourdomain.com/resolve \
  -H "Content-Type: application/json" \
  -d "{\"title\": \"$TITLE\", \"year\": $YEAR}" \
  | jq -r '.results[0].imdb_id // empty')

if [ ! -z "$IMDB_ID" ]; then
    echo "Found IMDb ID: $IMDB_ID"
    # Process with IMDb ID
fi

๐Ÿค– Discord Bot

@bot.command()
async def movie(ctx, *, title):
    """Look up movie on IMDb"""
    async with aiohttp.ClientSession() as session:
        async with session.post('https://imdb.yourdomain.com/resolve', json={
            'title': title,
            'fuzzy': True,
            'max_results': 1
        }) as response:
            data = await response.json()
            
            if data['results']:
                result = data['results'][0]
                imdb_url = f"https://imdb.com/title/{result['imdb_id']}"
                await ctx.send(f"**{result['matched_title']}** ({result['matched_year']})\n{imdb_url}")
            else:
                await ctx.send("Movie not found!")

โš™๏ธ Rate Limiting

The API includes built-in rate limiting:

  • โœ… Default: 100 requests per minute per IP
  • โœ… Burst: Up to 20 requests at once
  • โœ… Headers: Rate limit info in response headers
  • โœ… 429 Error: When limit exceeded

๐Ÿ”ง Error Handling

try:
    response = requests.post('https://imdb.yourdomain.com/resolve', json={
        'title': title,
        'year': year
    })
    
    if response.status_code == 200:
        data = response.json()
        # Process results
    elif response.status_code == 429:
        print("Rate limited - wait and retry")
    elif response.status_code == 400:
        print("Invalid request data")
    elif response.status_code >= 500:
        print("Server error - retry later")
        
except requests.exceptions.RequestException as e:
    print(f"Connection error: {e}")