Files
tmdb-ts/DOCUMENTATION.md

32 KiB

TMDB-TS - Comprehensive Documentation

Table of Contents

  1. Overview
  2. Architecture
  3. Installation
  4. Quick Start
  5. Core Components
  6. API Endpoints
  7. Type System
  8. Advanced Usage
  9. Error Handling
  10. Best Practices

Overview

tmdb-ts is a TypeScript library that provides a fully-typed wrapper around The Movie Database (TMDB) API v3. It simplifies interaction with the TMDB API by offering:

  • Type Safety: Complete TypeScript type definitions for all API responses
  • Modern Authentication: Uses JWT Bearer token authentication (no need for API keys in URLs)
  • Modular Design: Organized endpoints for different resource types
  • Promise-based: Modern async/await support
  • Zero Configuration: Simple instantiation with access token

Key Features

  • Full TypeScript support with comprehensive type definitions
  • All TMDB API v3 endpoints covered
  • Automatic query parameter parsing
  • Error handling with typed error responses
  • Support for append_to_response functionality
  • Cross-platform fetch implementation via cross-fetch

Architecture

Project Structure

tmdb-ts/
├── src/
│   ├── api.ts                 # Core HTTP client
│   ├── tmdb.ts               # Main TMDB class
│   ├── index.ts              # Public exports
│   ├── common/
│   │   └── constants.ts      # API base URLs and constants
│   ├── endpoints/            # Endpoint implementations
│   │   ├── base.ts          # Base endpoint class
│   │   ├── movies.ts        # Movie-related endpoints
│   │   ├── tv-shows.ts      # TV show endpoints
│   │   ├── people.ts        # People/cast endpoints
│   │   ├── search.ts        # Search endpoints
│   │   ├── credits.ts       # Credits endpoints
│   │   ├── genres.ts        # Genre endpoints
│   │   ├── discover.ts      # Discover endpoints
│   │   ├── trending.ts      # Trending endpoints
│   │   ├── collections.ts   # Collection endpoints
│   │   ├── companies.ts     # Company endpoints
│   │   ├── networks.ts      # Network endpoints
│   │   ├── keywords.ts      # Keyword endpoints
│   │   ├── configuration.ts # Configuration endpoints
│   │   ├── certifications.ts# Certification endpoints
│   │   ├── changes.ts       # Change tracking endpoints
│   │   ├── account.ts       # Account endpoints
│   │   ├── review.ts        # Review endpoints
│   │   ├── watch-providers.ts# Watch provider endpoints
│   │   ├── tv-seasons.ts    # TV season endpoints
│   │   ├── tv-episode.ts    # TV episode endpoints
│   │   └── find.ts          # External ID lookup
│   ├── types/               # TypeScript type definitions
│   │   ├── index.ts         # Main type exports
│   │   ├── options.ts       # Query option types
│   │   ├── movies.ts        # Movie-related types
│   │   ├── tv-shows.ts      # TV show types
│   │   ├── people.ts        # People/person types
│   │   ├── credits.ts       # Credits types
│   │   ├── search.ts        # Search result types
│   │   └── [other types]    # Additional type definitions
│   └── utils/               # Utility functions
│       ├── parseOptions.ts  # Query parameter parser
│       ├── getImagePath.ts  # Image URL helper
│       └── index.ts         # Utility exports
├── package.json
├── tsconfig.json
└── README.md

Design Patterns

1. Lazy Instantiation Pattern

class TMDB {
  get movies(): MoviesEndpoint {
    return new MoviesEndpoint(this.accessToken);
  }
}

Endpoints are instantiated on-demand via getter properties, keeping memory footprint low.

2. Base Endpoint Pattern

abstract class BaseEndpoint {
  protected api: Api;
  constructor(protected readonly accessToken: string) {
    this.api = new Api(accessToken);
  }
}

All endpoints extend a base class that provides HTTP client access.

3. Type-safe Append Pattern

type AppendToResponse<K, T extends AppendToResponseMovieKey[] | undefined>

Compile-time type safety for dynamic API response composition.


Installation

# Using npm
npm install tmdb-ts

# Using yarn
yarn add tmdb-ts

# Using pnpm
pnpm add tmdb-ts

# Using bun
bun add tmdb-ts

Requirements

  • Node.js >= 14.x
  • TypeScript >= 4.5 (for type definitions)

Quick Start

1. Get TMDB Access Token

  1. Create an account at themoviedb.org
  2. Go to Settings → API
  3. Generate an API Read Access Token (JWT)

2. Basic Usage

import { TMDB } from 'tmdb-ts';

// Initialize the client
const tmdb = new TMDB('your_access_token_here');

// Search for movies
async function searchMovies() {
  try {
    const results = await tmdb.search.movies({ 
      query: 'Inception' 
    });
    console.log(results.results);
  } catch (error) {
    console.error('Error:', error);
  }
}

// Get movie details
async function getMovieDetails() {
  const movie = await tmdb.movies.details(550); // Fight Club
  console.log(movie.title, movie.overview);
}

Core Components

1. TMDB Class

The main entry point for all API interactions.

class TMDB {
  constructor(accessToken: string);
  
  // Endpoint accessors (getters)
  get movies(): MoviesEndpoint;
  get tvShows(): TvShowsEndpoint;
  get people(): PeopleEndpoint;
  get search(): SearchEndpoint;
  get credits(): CreditsEndpoint;
  get discover(): DiscoverEndpoint;
  get genres(): GenreEndpoint;
  get trending(): TrendingEndpoint;
  get collections(): CollectionsEndpoint;
  get companies(): CompaniesEndpoint;
  get networks(): NetworksEndpoint;
  get keywords(): KeywordsEndpoint;
  get configuration(): ConfigurationEndpoint;
  get certifications(): CertificationEndpoint;
  get changes(): ChangeEndpoint;
  get account(): AccountEndpoint;
  get review(): ReviewEndpoint;
  get watchProviders(): WatchProvidersEndpoint;
  get tvSeasons(): TvSeasonsEndpoint;
  get tvEpisode(): TvEpisodesEndpoint;
  get find(): FindEndpoint;
}

2. Api Class

Internal HTTP client handling all requests.

class Api {
  constructor(accessToken: string);
  
  async get<T>(path: string, options?: Record<string, any>): Promise<T>;
}

Features:

  • Automatically adds Bearer token authentication
  • Converts options object to URL query parameters
  • Returns typed responses
  • Throws typed errors on failure

3. BaseEndpoint Class

Abstract base class for all endpoint implementations.

abstract class BaseEndpoint {
  protected api: Api;
  constructor(protected readonly accessToken: string);
}

API Endpoints

Movies Endpoint

Comprehensive movie-related operations.

Methods

class MoviesEndpoint {
  // Get detailed information about a movie
  async details<T extends AppendToResponseMovieKey[]>(
    id: number,
    appendToResponse?: T,
    language?: string
  ): Promise<AppendToResponse<MovieDetails, T, 'movie'>>;

  // Get alternative titles for a movie
  async alternativeTitles(id: number): Promise<AlternativeTitles>;

  // Get the recent changes for a movie
  async changes(id: number, options?: ChangeOption): Promise<Changes<MovieChangeValue>>;

  // Get the cast and crew for a movie
  async credits(id: number, options?: LanguageOption): Promise<Credits>;

  // Get external IDs for a movie
  async externalIds(id: number): Promise<ExternalIds>;

  // Get images for a movie
  async images(id: number, options?: MoviesImageSearchOptions): Promise<Images>;

  // Get keywords for a movie
  async keywords(id: number): Promise<Keywords>;

  // Get lists that this movie belongs to
  async lists(id: number, options?: LanguageOption & PageOption): Promise<MovieLists>;

  // Get movie recommendations
  async recommendations(id: number, options?: LanguageOption & PageOption): Promise<Recommendations>;

  // Get release dates for a movie
  async releaseDates(id: number): Promise<ReleaseDates>;

  // Get user reviews for a movie
  async reviews(id: number, options?: LanguageOption & PageOption): Promise<Reviews>;

  // Get similar movies
  async similar(id: number, options?: LanguageOption & PageOption): Promise<SimilarMovies>;

  // Get translations for a movie
  async translations(id: number): Promise<Translations>;

  // Get videos (trailers, teasers) for a movie
  async videos(id: number, options?: LanguageOption): Promise<Videos>;

  // Get watch providers for a movie
  async watchProviders(id: number): Promise<WatchProviders>;

  // Get the latest movie
  async latest(): Promise<LatestMovie>;

  // Get movies now playing in theaters
  async nowPlaying(options?: PageOption & LanguageOption & RegionOption): Promise<MoviesPlayingNow>;

  // Get popular movies
  async popular(options?: LanguageOption & PageOption): Promise<PopularMovies>;

  // Get top rated movies
  async topRated(options?: PageOption & LanguageOption & RegionOption): Promise<TopRatedMovies>;

  // Get upcoming movies
  async upcoming(options?: PageOption & LanguageOption & RegionOption): Promise<UpcomingMovies>;
}

Examples

// Basic movie details
const movie = await tmdb.movies.details(550);
console.log(movie.title, movie.release_date);

// Movie details with additional data (append_to_response)
const movieWithExtras = await tmdb.movies.details(
  550,
  ['credits', 'videos', 'images'],
  'en-US'
);
console.log(movieWithExtras.credits.cast);
console.log(movieWithExtras.videos.results);

// Get movie credits
const credits = await tmdb.movies.credits(550);
console.log('Director:', credits.crew.find(c => c.job === 'Director')?.name);

// Search for similar movies
const similar = await tmdb.movies.similar(550, { page: 1 });
console.log('Similar movies:', similar.results.map(m => m.title));

// Get popular movies
const popular = await tmdb.movies.popular({ language: 'en-US', page: 1 });

TV Shows Endpoint

TV series and episode management.

class TvShowsEndpoint {
  // Get TV show details
  async details<T extends AppendToResponseTvKey[]>(
    id: number,
    appendToResponse?: T,
    language?: string
  ): Promise<AppendToResponse<TvShowDetails, T, 'tvShow'>>;

  // Get aggregate credits (all seasons)
  async aggregateCredits(id: number, options?: LanguageOption): Promise<AggregateCredits>;

  // Get alternative titles
  async alternativeTitles(id: number): Promise<AlternativeTitles>;

  // Get changes for a TV show
  async changes(id: number, options?: ChangeOption): Promise<Changes<TvShowChangeValue>>;

  // Get content ratings
  async contentRatings(id: number): Promise<ContentRatings>;

  // Get credits for a TV show
  async credits(id: number, options?: LanguageOption): Promise<Credits>;

  // Get episode groups
  async episodeGroups(id: number): Promise<EpisodeGroups>;

  // Get external IDs
  async externalIds(id: number): Promise<ExternalIds>;

  // Get images
  async images(id: number, options?: LanguageOption): Promise<Images>;

  // Get keywords
  async keywords(id: number): Promise<Keywords>;

  // Get recommendations
  async recommendations(id: number, options?: LanguageOption & PageOption): Promise<Recommendations>;

  // Get reviews
  async reviews(id: number, options?: LanguageOption & PageOption): Promise<Reviews>;

  // Get screened theatrically episodes
  async screenedTheatrically(id: number): Promise<ScreenedTheatrically>;

  // Get similar TV shows
  async similar(id: number, options?: LanguageOption & PageOption): Promise<SimilarTvShows>;

  // Get translations
  async translations(id: number): Promise<Translations>;

  // Get videos
  async videos(id: number, options?: LanguageOption): Promise<Videos>;

  // Get watch providers
  async watchProviders(id: number): Promise<WatchProviders>;

  // Get latest TV show
  async latest(): Promise<TvShowDetails>;

  // Get TV shows airing today
  async airingToday(options?: PageOption & LanguageOption & TimezoneOption): Promise<TvShowsAiringToday>;

  // Get TV shows on the air
  async onTheAir(options?: PageOption & LanguageOption & TimezoneOption): Promise<TvShowsOnTheAir>;

  // Get popular TV shows
  async popular(options?: LanguageOption & PageOption): Promise<PopularTvShows>;

  // Get top rated TV shows
  async topRated(options?: LanguageOption & PageOption): Promise<TopRatedTvShows>;
}

People Endpoint

Person/celebrity information and credits.

class PeopleEndpoint {
  // Get person details
  async details<T extends AppendToResponsePersonKey[]>(
    id: number,
    appendToResponse?: T,
    language?: string
  ): Promise<AppendToResponse<PersonDetails, T, 'person'>>;

  // Get changes for a person
  async changes(id: number, options?: ChangeOption): Promise<Changes<PersonChangeValue>>;

  // Get movie credits for a person
  async movieCredits(id: number, options?: LanguageOption): Promise<PersonMovieCredit>;

  // Get TV show credits for a person
  async tvShowCredits(id: number, options?: LanguageOption): Promise<PersonTvShowCredit>;

  // Get combined movie and TV credits
  async combinedCredits(id: number, options?: LanguageOption): Promise<PersonCombinedCredits>;

  // Get external IDs for a person
  async externalId(id: number): Promise<ExternalIds>;

  // Get images for a person
  async images(id: number): Promise<PeopleImages>;

  // Get tagged images (deprecated)
  async taggedImages(id: number, options?: PageOption): Promise<TaggedImages>;

  // Get translations
  async translation(id: number): Promise<PersonTranslations>;

  // Get the latest person
  async latest(): Promise<PersonDetails>;

  // Get popular people
  async popular(options?: LanguageOption & PageOption): Promise<PopularPeople>;
}

Examples

// Get person details
const person = await tmdb.people.details(287); // Brad Pitt
console.log(person.name, person.biography);

// Get person with movie credits
const personWithCredits = await tmdb.people.details(
  287,
  ['movie_credits', 'tv_credits']
);
console.log('Movies:', personWithCredits.movie_credits.cast);

// Get combined credits
const credits = await tmdb.people.combinedCredits(287);
console.log('All credits:', [...credits.cast, ...credits.crew]);

// Get popular people
const popularPeople = await tmdb.people.popular({ page: 1 });

Search Endpoint

Search across all content types.

class SearchEndpoint {
  // Search for companies
  async companies(options: { query: string } & PageOption): Promise<CompanySearchResponse>;

  // Search for collections
  async collections(options: { query: string } & PageOption & LanguageOption): Promise<CollectionSearchResponse>;

  // Search for keywords
  async keywords(options: { query: string } & PageOption): Promise<KeywordSearchResponse>;

  // Search for movies
  async movies(options: MovieSearchOptions): Promise<MovieSearchResponse>;

  // Multi search (movies, TV shows, people)
  async multi(options: { query: string } & PageOption & LanguageOption): Promise<MultiSearchResponse>;

  // Search for people
  async people(options: { query: string } & PageOption & LanguageOption): Promise<PeopleSearchResponse>;

  // Search for TV shows
  async tvShows(options: TvShowSearchOptions): Promise<TvShowSearchResponse>;
}

Examples

// Search movies
const movies = await tmdb.search.movies({ 
  query: 'Matrix',
  year: 1999,
  page: 1
});

// Multi-search (searches movies, TV, people)
const results = await tmdb.search.multi({ 
  query: 'Tom Hanks'
});

// Search TV shows
const tvShows = await tmdb.search.tvShows({
  query: 'Breaking Bad',
  first_air_date_year: 2008
});

// Search people
const people = await tmdb.search.people({ 
  query: 'Leonardo DiCaprio'
});

Credits Endpoint

Individual credit information.

class CreditsEndpoint {
  // Get detailed information about a credit
  async getById(id: string): Promise<CreditResponse>;
}

Discover Endpoint

Discover movies and TV shows with filtering.

class DiscoverEndpoint {
  // Discover movies
  async movies(options?: DiscoverMoviesOptions): Promise<DiscoverMoviesResponse>;

  // Discover TV shows
  async tvShows(options?: DiscoverTvShowsOptions): Promise<DiscoverTvShowsResponse>;
}

Examples

// Discover movies with filters
const action = await tmdb.discover.movies({
  with_genres: '28', // Action genre
  'vote_average.gte': 7,
  sort_by: 'popularity.desc',
  page: 1
});

// Discover TV shows
const comedy = await tmdb.discover.tvShows({
  with_genres: '35', // Comedy genre
  'first_air_date.gte': '2020-01-01',
  sort_by: 'vote_average.desc'
});

Get trending content.

class TrendingEndpoint {
  // Get trending content
  async trending(
    mediaType: 'all' | 'movie' | 'tv' | 'person',
    timeWindow: 'day' | 'week',
    options?: PageOption & LanguageOption
  ): Promise<TrendingResponse>;
}

Configuration Endpoint

Get TMDB system configuration.

class ConfigurationEndpoint {
  // Get API configuration (image base URLs, etc.)
  async getApiConfiguration(): Promise<Configuration>;

  // Get list of countries
  async getCountries(): Promise<Country[]>;

  // Get list of jobs
  async getJobs(): Promise<Job[]>;

  // Get list of languages
  async getLanguages(): Promise<Language[]>;

  // Get list of primary translations
  async getPrimaryTranslations(): Promise<string[]>;

  // Get list of timezones
  async getTimezones(): Promise<Timezone[]>;
}

Other Endpoints

  • Collections: Movie collection information
  • Companies: Production company details
  • Networks: TV network information
  • Keywords: Keyword details
  • Genres: Genre lists for movies and TV
  • Certifications: Content rating certifications
  • Changes: Track content changes
  • Account: User account operations
  • Review: Review details
  • Watch Providers: Streaming availability
  • TV Seasons: Season-specific information
  • TV Episodes: Episode-specific information
  • Find: Lookup by external IDs (IMDb, TVDb, etc.)

Type System

Core Types

Movie Types

interface Movie {
  id: number;
  title: string;
  original_title: string;
  overview: string;
  release_date: string;
  poster_path: string;
  backdrop_path: string;
  genre_ids: number[];
  adult: boolean;
  original_language: string;
  popularity: number;
  vote_count: number;
  vote_average: number;
  video: boolean;
}

interface MovieDetails extends Omit<Movie, 'genre_ids'> {
  belongs_to_collection?: BelongsToCollection;
  budget: number;
  genres: Genre[];
  homepage: string;
  imdb_id: string | null;
  production_companies: ProductionCompany[];
  production_countries: ProductionCountry[];
  revenue: number;
  runtime: number;
  spoken_languages: SpokenLanguage[];
  status: string;
  tagline: string;
}

TV Show Types

interface TV {
  id: number;
  name: string;
  original_name: string;
  overview: string;
  first_air_date: string;
  poster_path: string;
  backdrop_path: string;
  genre_ids: number[];
  origin_country: string[];
  adult: boolean;
  original_language: string;
  popularity: number;
  vote_count: number;
  vote_average: number;
}

interface TvShowDetails extends Omit<TV, 'genre_ids'> {
  created_by: Creator[];
  episode_run_time: number[];
  genres: Genre[];
  homepage: string;
  in_production: boolean;
  languages: string[];
  last_air_date: string;
  last_episode_to_air: Episode;
  next_episode_to_air: Episode;
  networks: Network[];
  number_of_episodes: number;
  number_of_seasons: number;
  production_companies: ProductionCompany[];
  production_countries: ProductionCountry[];
  seasons: Season[];
  spoken_languages: SpokenLanguage[];
  status: string;
  tagline: string;
  type: string;
}

Person Types

interface Person {
  id: number;
  name: string;
  original_name: string;
  profile_path: string;
  adult: boolean;
  known_for_department: string;
  gender: number;
  popularity: number;
  known_for: KnownFor[];
}

interface PersonDetails {
  id: number;
  name: string;
  biography: string;
  birthday: string;
  deathday: string;
  place_of_birth: string;
  profile_path: string;
  adult: boolean;
  known_for_department: string;
  gender: number;
  popularity: number;
  also_known_as: string[];
  imdb_id: string;
  homepage: string;
}

Credits Types

interface Cast {
  adult: boolean;
  gender: number;
  id: number;
  known_for_department: string;
  name: string;
  original_name: string;
  popularity: number;
  profile_path: string;
  cast_id: number;
  character: string;
  credit_id: string;
  order: number;
}

interface Crew {
  adult: boolean;
  gender: number;
  id: number;
  known_for_department: string;
  name: string;
  original_name: string;
  popularity: number;
  profile_path: string;
  credit_id: string;
  department: string;
  job: string;
}

interface Credits {
  id: number;
  cast: Cast[];
  crew: Crew[];
}

Option Types

// Language options
interface LanguageOption {
  language?: AvailableLanguage; // e.g., 'en-US', 'fr-FR'
}

// Pagination
interface PageOption {
  page?: number;
}

// Region filtering
interface RegionOption {
  region?: string; // ISO 3166-1 code
}

// Date range for changes
interface ChangeOption extends PageOption {
  start_date?: string; // YYYY-MM-DD
  end_date?: string;   // YYYY-MM-DD
}

// Timezone
interface TimezoneOption {
  timezone?: string; // e.g., 'America/New_York'
}

Append to Response

The AppendToResponse type enables type-safe dynamic response composition:

type AppendToResponseMovieKey =
  | 'images'
  | 'videos'
  | 'credits'
  | 'recommendations'
  | 'reviews'
  | 'similar'
  | 'lists'
  | 'release_dates'
  | 'alternative_titles'
  | 'external_ids'
  | 'translations'
  | 'watch/providers'
  | 'keywords';

// Usage
const movie = await tmdb.movies.details(550, ['credits', 'videos']);
// TypeScript knows movie.credits and movie.videos exist!

Error Response

interface ErrorResponse {
  status_code: number;
  status_message: string;
  success: boolean;
}

Advanced Usage

Append to Response

Reduce API calls by requesting multiple resources in one request:

// Single request for movie with credits, videos, and images
const movie = await tmdb.movies.details(
  550,
  ['credits', 'videos', 'images', 'recommendations']
);

// All data is available in the response
console.log(movie.title);
console.log(movie.credits.cast);
console.log(movie.videos.results);
console.log(movie.images.posters);
console.log(movie.recommendations.results);

Pagination

// Get multiple pages of results
async function getAllPopularMovies() {
  const allMovies = [];
  let page = 1;
  let totalPages = 1;

  do {
    const response = await tmdb.movies.popular({ page });
    allMovies.push(...response.results);
    totalPages = response.total_pages;
    page++;
  } while (page <= totalPages && page <= 10); // Limit to 10 pages

  return allMovies;
}

Language Support

// Get movie details in different languages
const movieEN = await tmdb.movies.details(550, undefined, 'en-US');
const movieFR = await tmdb.movies.details(550, undefined, 'fr-FR');
const movieES = await tmdb.movies.details(550, undefined, 'es-ES');

console.log(movieEN.title); // "Fight Club"
console.log(movieFR.title); // "Fight Club" (French title)
console.log(movieES.title); // "El club de la lucha"

Image URLs

import { getImagePath } from 'tmdb-ts';

// Get configuration first
const config = await tmdb.configuration.getApiConfiguration();
const baseUrl = config.images.secure_base_url;

// Helper function to build image URLs
function getFullImagePath(path: string, size: string = 'original'): string {
  return `${baseUrl}${size}${path}`;
}

// Usage
const movie = await tmdb.movies.details(550);
const posterUrl = getFullImagePath(movie.poster_path, 'w500');
const backdropUrl = getFullImagePath(movie.backdrop_path, 'w1280');

Discover with Complex Filters

// Discover action movies from 2020 with high ratings
const movies = await tmdb.discover.movies({
  with_genres: '28', // Action
  'primary_release_date.gte': '2020-01-01',
  'primary_release_date.lte': '2020-12-31',
  'vote_average.gte': 7.0,
  'vote_count.gte': 100,
  sort_by: 'popularity.desc',
  page: 1,
  language: 'en-US'
});

Search with Filters

// Search movies with year filter
const movies = await tmdb.search.movies({
  query: 'Star Wars',
  year: 1977,
  include_adult: false,
  page: 1
});

// Search TV shows with first air date year
const tvShows = await tmdb.search.tvShows({
  query: 'Friends',
  first_air_date_year: 1994
});

Find by External ID

// Find movie/TV show by IMDb ID
const result = await tmdb.find.byId('tt0137523', { // Fight Club IMDb ID
  external_source: 'imdb_id'
});

console.log(result.movie_results);
console.log(result.tv_results);
// Get trending movies today
const trendingToday = await tmdb.trending.trending('movie', 'day');

// Get trending TV shows this week
const trendingWeek = await tmdb.trending.trending('tv', 'week');

// Get all trending (movies, TV, people)
const trendingAll = await tmdb.trending.trending('all', 'week');

Error Handling

Error Types

interface ErrorResponse {
  status_code: number;
  status_message: string;
  success: boolean;
}

Handling Errors

try {
  const movie = await tmdb.movies.details(999999999);
} catch (error) {
  const tmdbError = error as ErrorResponse;
  
  console.error(`Error ${tmdbError.status_code}: ${tmdbError.status_message}`);
  
  // Handle specific error codes
  switch (tmdbError.status_code) {
    case 7:
      console.error('Invalid API key');
      break;
    case 34:
      console.error('Resource not found');
      break;
    default:
      console.error('Unknown error');
  }
}

Common Error Codes

Code Description
7 Invalid API key
34 The resource you requested could not be found
404 Not Found
401 Invalid credentials

Best Practices

1. Reuse TMDB Instance

// ❌ Bad: Creating new instances
async function getMovie() {
  const tmdb = new TMDB(token);
  return await tmdb.movies.details(550);
}

// ✅ Good: Reuse instance
const tmdb = new TMDB(token);

async function getMovie() {
  return await tmdb.movies.details(550);
}

2. Use Append to Response

// ❌ Bad: Multiple requests
const movie = await tmdb.movies.details(550);
const credits = await tmdb.movies.credits(550);
const videos = await tmdb.movies.videos(550);

// ✅ Good: Single request
const movie = await tmdb.movies.details(550, ['credits', 'videos']);
console.log(movie.credits, movie.videos);

3. Handle Errors Gracefully

async function safeMovieDetails(id: number) {
  try {
    return await tmdb.movies.details(id);
  } catch (error) {
    console.error('Failed to fetch movie:', error);
    return null;
  }
}

4. Type Your Responses

import type { MovieDetails, Credits } from 'tmdb-ts';

async function getMovieWithCredits(id: number): Promise<MovieDetails & { credits: Credits }> {
  return await tmdb.movies.details(id, ['credits']);
}

5. Cache Configuration

// Cache configuration to avoid repeated requests
let cachedConfig: Configuration | null = null;

async function getConfig(): Promise<Configuration> {
  if (!cachedConfig) {
    cachedConfig = await tmdb.configuration.getApiConfiguration();
  }
  return cachedConfig;
}

6. Environment Variables

// Use environment variables for tokens
const tmdb = new TMDB(process.env.TMDB_ACCESS_TOKEN!);

7. Rate Limiting

// Implement rate limiting for bulk operations
async function fetchMoviesWithDelay(ids: number[]) {
  const movies = [];
  
  for (const id of ids) {
    movies.push(await tmdb.movies.details(id));
    // Add delay to avoid rate limits
    await new Promise(resolve => setTimeout(resolve, 100));
  }
  
  return movies;
}

8. Batch Operations

// Process items in batches
async function fetchMoviesBatch(ids: number[], batchSize: number = 10) {
  const results = [];
  
  for (let i = 0; i < ids.length; i += batchSize) {
    const batch = ids.slice(i, i + batchSize);
    const batchResults = await Promise.all(
      batch.map(id => tmdb.movies.details(id))
    );
    results.push(...batchResults);
  }
  
  return results;
}

Full Examples

Movie Search Application

import { TMDB } from 'tmdb-ts';

const tmdb = new TMDB(process.env.TMDB_ACCESS_TOKEN!);

interface MovieSearchResult {
  id: number;
  title: string;
  year: number;
  rating: number;
  posterUrl: string;
}

async function searchMovies(query: string): Promise<MovieSearchResult[]> {
  try {
    // Get configuration for image URLs
    const config = await tmdb.configuration.getApiConfiguration();
    const baseUrl = config.images.secure_base_url;
    
    // Search for movies
    const response = await tmdb.search.movies({ query, page: 1 });
    
    // Transform results
    return response.results.map(movie => ({
      id: movie.id,
      title: movie.title,
      year: new Date(movie.release_date).getFullYear(),
      rating: movie.vote_average,
      posterUrl: movie.poster_path 
        ? `${baseUrl}w500${movie.poster_path}` 
        : ''
    }));
  } catch (error) {
    console.error('Search failed:', error);
    return [];
  }
}

// Usage
const results = await searchMovies('Inception');
console.log(results);

TV Show Tracker

async function getTvShowInfo(id: number) {
  const show = await tmdb.tvShows.details(id, [
    'credits',
    'videos',
    'recommendations'
  ]);
  
  return {
    title: show.name,
    overview: show.overview,
    seasons: show.number_of_seasons,
    episodes: show.number_of_episodes,
    status: show.status,
    nextEpisode: show.next_episode_to_air,
    cast: show.credits.cast.slice(0, 10),
    trailer: show.videos.results.find(v => v.type === 'Trailer'),
    similar: show.recommendations.results.slice(0, 5)
  };
}

Person Profile

async function getPersonProfile(id: number) {
  const person = await tmdb.people.details(id, [
    'movie_credits',
    'tv_credits',
    'external_ids'
  ]);
  
  // Get top-rated movies
  const topMovies = person.movie_credits.cast
    .sort((a, b) => b.vote_average - a.vote_average)
    .slice(0, 10);
  
  return {
    name: person.name,
    biography: person.biography,
    birthday: person.birthday,
    birthplace: person.place_of_birth,
    knownFor: person.known_for_department,
    topMovies: topMovies,
    socialMedia: {
      imdb: person.external_ids.imdb_id,
      instagram: person.external_ids.instagram_id,
      twitter: person.external_ids.twitter_id
    }
  };
}

Recommendation Engine

async function getMovieRecommendations(movieId: number, limit: number = 10) {
  // Get similar movies
  const similar = await tmdb.movies.similar(movieId, { page: 1 });
  
  // Get recommendations
  const recommendations = await tmdb.movies.recommendations(movieId, { page: 1 });
  
  // Combine and deduplicate
  const allMovies = [...similar.results, ...recommendations.results];
  const uniqueMovies = Array.from(
    new Map(allMovies.map(m => [m.id, m])).values()
  );
  
  // Sort by popularity and limit
  return uniqueMovies
    .sort((a, b) => b.popularity - a.popularity)
    .slice(0, limit);
}


Contributing

This library is a wrapper around the TMDB API. For issues or feature requests, please refer to the official repository.


License

MIT License - See LICENSE.md for details


Support

For questions and support: