martincamen/laravel-jellyseerr

Laravel integration for Jellyseerr PHP SDK

Installs: 0

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/martincamen/laravel-jellyseerr

0.1.0 2026-01-21 10:06 UTC

This package is auto-updated.

Last update: 2026-01-21 10:08:12 UTC


README

Laravel integration for the Jellyseerr PHP SDK, providing a seamless experience for interacting with Jellyseerr using unified domain models from php-arr-core.

Important

This project is still being developed and breaking changes might occur even between patch versions.

The aim is to follow semantic versioning as soon as possible.

Ecosystem

Package Description
radarr-php PHP SDK for Radarr
sonarr-php PHP SDK for Sonarr
jellyseerr-php PHP SDK for Jellyseerr
laravel-radarr Laravel integration for Radarr
laravel-sonarr Laravel integration for Sonarr
laravel-jellyseerr Laravel integration for Jellyseerr

Features

  • Unified API using canonical domain models from php-arr-core
  • Type-safe interactions with Jellyseerr
  • Laravel facade with full IDE autocompletion
  • Testing utilities for mocking responses
  • Automatic service discovery via Laravel's package auto-discovery

Requirements

  • PHP 8.3+
  • Laravel 10.0+, 11.0+ or 12.0+

Installation

composer require martincamen/laravel-jellyseerr

The package will auto-register its service provider in Laravel.

Configuration

Publish the configuration file:

php artisan vendor:publish --provider="MartinCamen\LaravelJellyseerr\JellyseerrServiceProvider"

Add the following environment variables to your .env file:

JELLYSEERR_HOST=localhost
JELLYSEERR_PORT=5055
JELLYSEERR_API_KEY=your-api-key
JELLYSEERR_USE_HTTPS=false
JELLYSEERR_TIMEOUT=30
JELLYSEERR_URL_BASE=

Configuration Options

Option Description Default
JELLYSEERR_HOST Hostname or IP address of your Jellyseerr server localhost
JELLYSEERR_PORT Port number for your Jellyseerr server 5055
JELLYSEERR_API_KEY Your Jellyseerr API key (Settings > General > API Key) -
JELLYSEERR_USE_HTTPS Use HTTPS for connections false
JELLYSEERR_TIMEOUT Request timeout in seconds 30
JELLYSEERR_URL_BASE URL base for reverse proxy subpaths (e.g., /jellyseerr) -

Usage

Using the Facade

The Jellyseerr facade provides access to the SDK client via an action-based API:

use MartinCamen\LaravelJellyseerr\Facades\Jellyseerr;

// Get all media requests
$requests = Jellyseerr::requests()->all();

// Get a specific request by ID
$request = Jellyseerr::requests()->find(1);

// Search for media
$results = Jellyseerr::search()->search('Breaking Bad');

// Get system information
$status = Jellyseerr::system()->status();

Dependency Injection

You can also inject Jellyseerr directly:

use MartinCamen\Jellyseerr\Jellyseerr;

class RequestController
{
    public function __construct(private Jellyseerr $jellyseerr) {}

    public function index()
    {
        return view('requests.index', ['requests' => $this->jellyseerr->requests()->all()]);
    }
}

Working with Requests

The requests() method provides access to media request management:

use MartinCamen\LaravelJellyseerr\Facades\Jellyseerr;
use MartinCamen\Jellyseerr\Data\Responses\RequestPage;
use MartinCamen\Jellyseerr\Data\Responses\MediaRequest;

// Get all requests (paginated)
/** @var RequestPage $requestPage */
$requestPage = Jellyseerr::requests()->all();

foreach ($requestPage as $request) {
    echo $request->id;
    echo $request->status->value;
}

// Get a specific request
$request = Jellyseerr::requests()->find(1);

// Get request counts
$count = Jellyseerr::requests()->count();
echo "Pending: {$count->pending}";
echo "Approved: {$count->approved}";

// Create a movie request
$request = Jellyseerr::requests()->movie(550); // TMDB ID

// Create a series request with specific seasons
$request = Jellyseerr::requests()->series(1396, [1, 2]); // TMDB ID, seasons

// Approve a request
$request = Jellyseerr::requests()->approve(1);

// Decline a request
$request = Jellyseerr::requests()->decline(1);

// Retry a failed request
$request = Jellyseerr::requests()->retry(1);

// Delete a request
Jellyseerr::requests()->delete(1);

Working with Movies

The movies() method provides access to movie details via TMDB:

use MartinCamen\LaravelJellyseerr\Facades\Jellyseerr;
use MartinCamen\Jellyseerr\Data\Responses\MovieDetails;

// Get movie details by TMDB ID
$movie = Jellyseerr::movies()->find(550);
echo $movie->title;
echo $movie->overview;

// Get movie recommendations
$recommendations = Jellyseerr::movies()->recommendations(550);

// Get similar movies
$similar = Jellyseerr::movies()->similar(550);

Working with Series

The series() method provides access to TV series details via TMDB:

use MartinCamen\LaravelJellyseerr\Facades\Jellyseerr;
use MartinCamen\Jellyseerr\Data\Responses\SeriesDetails;

// Get series details by TMDB ID
$series = Jellyseerr::series()->find(1396);
echo $series->name;
echo $series->overview;

// Get series recommendations
$recommendations = Jellyseerr::series()->recommendations(1396);

// Get similar series
$similar = Jellyseerr::series()->similar(1396);

// Get season details
$season = Jellyseerr::series()->season(1396, 1);

Searching Media

The search() method provides search and discovery functionality:

use MartinCamen\LaravelJellyseerr\Facades\Jellyseerr;
use MartinCamen\Jellyseerr\Data\Responses\SearchPage;

// Search for any media
$results = Jellyseerr::search()->search('Breaking Bad');

foreach ($results as $result) {
    echo $result->title ?? $result->name;
    echo $result->mediaType;
}

// Discover movies
$movies = Jellyseerr::search()->discoverMovies();

// Discover series
$series = Jellyseerr::search()->discoverSeries();

// Get trending media
$trending = Jellyseerr::search()->trending();

// Get upcoming movies
$upcoming = Jellyseerr::search()->upcoming();

Working with Users

The users() method provides access to user management:

use MartinCamen\LaravelJellyseerr\Facades\Jellyseerr;
use MartinCamen\Jellyseerr\Data\Responses\UserPage;
use MartinCamen\Jellyseerr\Data\Responses\User;

// Get all users
/** @var UserPage $users */
$users = Jellyseerr::users()->all();

foreach ($users as $user) {
    echo $user->displayName;
    echo $user->email;
}

// Get a specific user
$user = Jellyseerr::users()->find(1);

// Get the current authenticated user
$me = Jellyseerr::users()->me();

// Get a user's requests
$requests = Jellyseerr::users()->requests(1);

System

use MartinCamen\LaravelJellyseerr\Facades\Jellyseerr;

// Get system status
$status = Jellyseerr::system()->status();
echo $status->version;

// Get appdata information
$appdata = Jellyseerr::system()->appdata();

// Get public settings
$settings = Jellyseerr::system()->publicSettings();

Response Types

All responses use typed DTOs from the SDK:

Type Description
RequestPage Paginated media requests
MediaRequest Individual media request
RequestCount Request count statistics
MovieDetails Movie details from TMDB
SeriesDetails TV series details from TMDB
SearchPage Paginated search results
UserPage Paginated users
User Individual user
SystemSummary System status information

Testing

Using the Fake

The package provides JellyseerrFake for testing:

use MartinCamen\LaravelJellyseerr\Facades\Jellyseerr;

class RequestTest extends TestCase
{
    public function testDisplaysRequests(): void
    {
        // Create a fake instance
        $fake = Jellyseerr::fake();

        // Make request
        $response = $this->get('/requests');

        // Assert the method was called
        $fake->assertCalled('requests');
        $response->assertOk();
    }

    public function testSearchesMedia(): void
    {
        $fake = Jellyseerr::fake();

        // Make request that calls search()->search()
        $this->get('/search?q=test');

        // Assert called
        $fake->assertCalled('search');
    }

    public function testNothingWasCalled(): void
    {
        $fake = Jellyseerr::fake();

        // No API calls made
        $this->get('/about');

        $fake->assertNothingCalled();
    }
}

Assertion Methods

The fake provides several assertion methods:

use MartinCamen\LaravelJellyseerr\Facades\Jellyseerr;

$fake = Jellyseerr::fake();

// Assert a method was called
$fake->assertCalled('requests');

// Assert a method was not called
$fake->assertNotCalled('movies');

// Assert a method was called a specific number of times
$fake->assertCalledTimes('requests', 3);

// Assert nothing was called
$fake->assertNothingCalled();

// Get all recorded calls
$calls = $fake->getCalls();

Example: Building a Request Dashboard

use MartinCamen\LaravelJellyseerr\Facades\Jellyseerr;

class DashboardController extends Controller
{
    public function index()
    {
        // Get system status
        $status = Jellyseerr::system()->status();

        // Get request counts
        $counts = Jellyseerr::requests()->count();

        // Get recent requests
        $requests = Jellyseerr::requests()->all();

        // Get trending media for suggestions
        $trending = Jellyseerr::search()->trending();

        return view('dashboard', [
            'version'        => $status->version,
            'pendingCount'   => $counts->pending,
            'approvedCount'  => $counts->approved,
            'requests'       => $requests,
            'trending'       => $trending,
        ]);
    }
}

Error Handling

use MartinCamen\LaravelJellyseerr\Facades\Jellyseerr;
use MartinCamen\ArrCore\Exceptions\AuthenticationException;
use MartinCamen\ArrCore\Exceptions\ConnectionException;
use MartinCamen\ArrCore\Exceptions\NotFoundException;

try {
    $request = Jellyseerr::requests()->find(999);
} catch (AuthenticationException $e) {
    // Invalid API key
    return back()->with('error', 'Invalid Jellyseerr API key');
} catch (NotFoundException $e) {
    // Request not found
    abort(404, 'Request not found');
} catch (ConnectionException $e) {
    // Connection error
    logger()->error('Could not connect to Jellyseerr: ' . $e->getMessage());

    return back()->with('error', 'Jellyseerr server unavailable');
}

License

The MIT License (MIT). Please see License File for more information.

Credits

Built on top of the Jellyseerr PHP SDK and php-arr-core.