PHPackages                             bjthecod3r/laravel-tmdb - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. bjthecod3r/laravel-tmdb

ActiveLibrary[API Development](/categories/api)

bjthecod3r/laravel-tmdb
=======================

A fluent, fully-typed Laravel wrapper for The Movie Database (TMDB) API.

0.1.1(1mo ago)1142MITPHPPHP ^8.2CI passing

Since Jun 3Pushed 1mo agoCompare

[ Source](https://github.com/BJTheCod3r/laravel-tmdb)[ Packagist](https://packagist.org/packages/bjthecod3r/laravel-tmdb)[ Docs](https://github.com/BJTheCod3r/laravel-tmdb)[ RSS](/packages/bjthecod3r-laravel-tmdb/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (2)Dependencies (12)Versions (5)Used By (0)

 [![Laravel TMDB — a fluent, fully-typed Laravel wrapper for The Movie Database API](art/banner.png)](art/banner.png)

 [![Tests](https://github.com/BJTheCod3r/laravel-tmdb/actions/workflows/tests.yml/badge.svg)](https://github.com/BJTheCod3r/laravel-tmdb/actions/workflows/tests.yml) [![Latest Stable Version](https://camo.githubusercontent.com/029f98aee5cf3a7425abf5d3573d919ce983db12b9886d34e0a4e63929980dbd/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f626a746865636f6433722f6c61726176656c2d746d64622e7376673f6c6162656c3d737461626c65)](https://packagist.org/packages/bjthecod3r/laravel-tmdb) [![Total Downloads](https://camo.githubusercontent.com/0e79af8fb7d4980e0cfe62601ebe551c5aa90f45fddc3fe404686fea51ee349b/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f626a746865636f6433722f6c61726176656c2d746d64622e737667)](https://packagist.org/packages/bjthecod3r/laravel-tmdb) [![License](https://camo.githubusercontent.com/074b89bca64d3edc93a1db6c7e3b1636b874540ba91d66367c0e5e354c56d0ea/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e737667)](LICENSE.md)

Laravel TMDB
============

[](#laravel-tmdb)

A fluent, fully-typed Laravel wrapper for [The Movie Database (TMDB)](https://developer.themoviedb.org/docs/getting-started) API.

```
use BjTheCod3r\Tmdb\Facades\Tmdb;

$movie = Tmdb::movies()->details(27205);

$movie->title;          // "Inception"
$movie->year();         // 2010
$movie->genres->pluck('name'); // Illuminate\Support\Collection

Tmdb::image()->url($movie->posterPath, 'w500');
```

Supports **Laravel 11, 12 and 13** on **PHP 8.2+**.

Installation
------------

[](#installation)

```
composer require bjthecod3r/laravel-tmdb
```

Publish the config file (optional):

```
php artisan vendor:publish --tag=tmdb-config
```

Configuration
-------------

[](#configuration)

Add your credentials to `.env`. The package prefers the **v4 Read Access Token**(sent as a `Bearer` header); if it is absent it falls back to the classic **v3 API key** (sent as an `api_key` query parameter).

```
TMDB_TOKEN=your-read-access-token
# or, for the v3 key:
TMDB_API_KEY=your-api-key

# optional
TMDB_LANGUAGE=en-US
TMDB_REGION=US
TMDB_INCLUDE_ADULT=false
```

You can find both credentials under **Settings → API** in your TMDB account.

Usage
-----

[](#usage)

The `Tmdb` facade exposes one accessor per endpoint group. Calls return typed [resource objects](#resources); list endpoints return a [`Paginated`](#pagination)wrapper. Every method accepts an optional `$params` array for extra TMDB query parameters (`page`, `append_to_response`, `region`, …).

### Movies

[](#movies)

```
Tmdb::movies()->details(27205);
Tmdb::movies()->details(27205, ['append_to_response' => ['credits', 'videos']]);
Tmdb::movies()->credits(27205);          // Credits (cast + crew)
Tmdb::movies()->images(27205);           // Collection
Tmdb::movies()->videos(27205);           // Collection
Tmdb::movies()->reviews(27205);          // Paginated
Tmdb::movies()->recommendations(27205);  // Paginated
Tmdb::movies()->similar(27205);          // Paginated
Tmdb::movies()->watchProviders(27205);
Tmdb::movies()->popular();
Tmdb::movies()->topRated();
Tmdb::movies()->nowPlaying();
Tmdb::movies()->upcoming();
```

### TV

[](#tv)

```
Tmdb::tv()->details(1396);
Tmdb::tv()->season(1396, 1);             // Season (with episodes)
Tmdb::tv()->episode(1396, 1, 1);         // Episode
Tmdb::tv()->credits(1396);
Tmdb::tv()->popular();
Tmdb::tv()->topRated();
Tmdb::tv()->onTheAir();
Tmdb::tv()->airingToday();
```

### People

[](#people)

```
Tmdb::people()->details(6193);
Tmdb::people()->movieCredits(6193);
Tmdb::people()->tvCredits(6193);
Tmdb::people()->images(6193);            // Collection
Tmdb::people()->popular();
```

### Search

[](#search)

```
Tmdb::search()->movies('inception', ['year' => 2010]); // Paginated
Tmdb::search()->tv('breaking bad');                    // Paginated
Tmdb::search()->people('nolan');                       // Paginated
Tmdb::search()->companies('warner');                   // Paginated
Tmdb::search()->collections('matrix');                 // Paginated
Tmdb::search()->keywords('superhero');                 // Paginated

// Multi-search returns mixed media; asResource() promotes each result
// to its concrete type (Movie | TvShow | Person):
Tmdb::search()->multi('matrix')->results->map->asResource();
```

Search and discover requests send the configured `TMDB_INCLUDE_ADULT` default as `include_adult`; pass `['include_adult' => 'true']` to override per call.

### Discover

[](#discover)

`discover()` returns a fluent builder; call `get()` to execute.

```
Tmdb::discover()->movies()
    ->withGenres([28, 12])          // Action, Adventure
    ->year(2023)
    ->withMinimumVoteAverage(7.5)
    ->sortBy('popularity.desc')
    ->page(1)
    ->get();                        // Paginated

// Any TMDB discover filter is available via where():
Tmdb::discover()->tv()->where('with_networks', 213)->get();
```

### Trending

[](#trending)

```
Tmdb::trending()->movies('week');  // Paginated
Tmdb::trending()->tv('day');       // Paginated
Tmdb::trending()->people('week');  // Paginated
Tmdb::trending()->all('day');      // Paginated
```

### Genres &amp; Configuration

[](#genres--configuration)

```
Tmdb::genres()->movies();          // Collection
Tmdb::genres()->tv();              // Collection

Tmdb::configuration()->details();  // image base URLs & sizes
Tmdb::configuration()->countries();
Tmdb::configuration()->languages();
```

Resources
---------

[](#resources)

Endpoint methods return typed objects (`Movie`, `TvShow`, `Person`, …) with documented properties — your IDE autocompletes them and dates come back as `CarbonImmutable` instances:

```
$movie = Tmdb::movies()->details(27205);

$movie->title;           // string
$movie->releaseDate;     // CarbonImmutable
$movie->voteAverage;     // float
$movie->genres;          // Collection
```

Every resource also keeps the raw TMDB payload. Any field — even one not mapped to a typed property — is reachable via property access, array access, `get()`(dot notation supported), and `toArray()` / `jsonSerialize()`:

```
$movie->get('belongs_to_collection.name');
$movie['original_title'];
return $movie; // a controller can return it directly as JSON
```

Pagination
----------

[](#pagination)

List endpoints return a `Paginated` wrapper that is iterable and JSON-serializable:

```
$page = Tmdb::movies()->popular(['page' => 1]);

$page->results;        // Collection
$page->page;           // 1
$page->totalPages;     // 500
$page->totalResults;   // 10000
$page->hasMorePages(); // true
$page->nextPage();     // 2

$page->results->each(function (Movie $movie) {
    // ...
});
```

Image URLs
----------

[](#image-urls)

TMDB resources expose relative image paths. Build absolute URLs with the `image()` helper (sizes come from `Tmdb::configuration()->details()`):

```
Tmdb::image()->url($movie->posterPath, 'w500');
Tmdb::image()->original($movie->backdropPath);
```

The CDN root defaults to `https://image.tmdb.org/t/p/` and can be changed via `TMDB_IMAGE_BASE_URL` (config key `image_base_url`).

Error handling
--------------

[](#error-handling)

Failed requests throw typed exceptions, all extending `TmdbException`:

ExceptionWhen`AuthenticationException`401 — invalid/missing credentials`ResourceNotFoundException`404 — unknown resource`ValidationException`400 / 422 — invalid request`RateLimitException`429 — exposes `->retryAfter` (seconds)`ApiException`connection errors and unexpected 5xxIf neither credential is configured, an `AuthenticationException` is thrown before any request is sent.

Rate-limit (429) and 5xx responses to GET requests are retried automatically per the `retry` config before the exception is thrown, honouring the TMDB `Retry-After` header when present. Write requests (POST/DELETE) are never retried, since they are not idempotent.

```
use BjTheCod3r\Tmdb\Exceptions\ResourceNotFoundException;

try {
    Tmdb::movies()->details(999999999);
} catch (ResourceNotFoundException $e) {
    // ...
}
```

Dependency injection
--------------------

[](#dependency-injection)

The facade is convenient, but you can also type-hint the manager or the underlying client:

```
use BjTheCod3r\Tmdb\Tmdb;

public function __construct(private Tmdb $tmdb) {}
```

An escape hatch for endpoints not yet wrapped:

```
Tmdb::client()->get('movie/27205/keywords');
```

Testing
-------

[](#testing)

Because the client is built on Laravel's `Http` facade, you can fake TMDB in your own app's tests:

```
use Illuminate\Support\Facades\Http;

Http::fake([
    'api.themoviedb.org/3/movie/*' => Http::response(['id' => 27205, 'title' => 'Inception']),
]);
```

The package's own suite:

```
composer install
vendor/bin/phpunit
```

License
-------

[](#license)

The MIT License (MIT). See [LICENSE.md](LICENSE.md).

###  Health Score

40

—

FairBetter than 86% of packages

Maintenance90

Actively maintained with recent releases

Popularity16

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity39

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~3 days

Total

2

Last Release

48d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/7c9d0cfc944007a872649f1e04921e82d5f0b5bc18de0bc8866a1e00b0db970e?d=identicon)[bjthecod3r](/maintainers/bjthecod3r)

---

Top Contributors

[![BJTheCod3r](https://avatars.githubusercontent.com/u/21208572?v=4)](https://github.com/BJTheCod3r "BJTheCod3r (9 commits)")

---

Tags

apilaravelwrappermoviestvtmdbthemoviedb

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/bjthecod3r-laravel-tmdb/health.svg)

```
[![Health](https://phpackages.com/badges/bjthecod3r-laravel-tmdb/health.svg)](https://phpackages.com/packages/bjthecod3r-laravel-tmdb)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3345.3M347](/packages/psalm-plugin-laravel)[laravel/horizon

Dashboard and code-driven configuration for Laravel queues.

4.2k95.4M321](/packages/laravel-horizon)[laravel/cashier

Laravel Cashier provides an expressive, fluent interface to Stripe's subscription billing services.

2.5k30.2M151](/packages/laravel-cashier)[laravel/pulse

Laravel Pulse is a real-time application performance monitoring tool and dashboard for your Laravel application.

1.7k15.1M136](/packages/laravel-pulse)[defstudio/telegraph

A laravel facade to interact with Telegram Bots

813336.8k3](/packages/defstudio-telegraph)[laravel/mcp

Rapidly build MCP servers for your Laravel applications.

77922.3M186](/packages/laravel-mcp)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
