enflow / redirect-pizza-php-sdk
An SDK to easily work with the redirect.pizza API
Fund package maintenance!
Requires
- php: ^8.3
- saloonphp/pagination-plugin: ^2.2
- saloonphp/saloon: ^4.0
Requires (Dev)
- laravel/pint: ^1.27
- pestphp/pest: ^2.35|^3.8.2
- phpstan/phpstan: ^2.1
README
This package is the official PHP SDK for the redirect.pizza API, built with Saloon v4.
use RedirectPizza\PhpSdk\RedirectPizza; $redirectPizza = new RedirectPizza('your-api-token'); $redirect = $redirectPizza->createRedirect([ 'sources' => ['old-source.nl'], 'destination' => 'new-fancy-site.nl', 'redirect_type' => 'permanent', 'keep_query_string' => false, ]); // returns an iterator of RedirectPizza\PhpSdk\Dto\Redirect $redirects = $redirectPizza->redirects(); foreach ($redirects as $redirect) { echo "Redirect: {$redirect->destination} (ID: {$redirect->id})\n"; }
Behind the scenes, the SDK uses Saloon to make the HTTP requests.
Installation
composer require enflow/redirect-pizza-php-sdk
Upgrading from 2.x? See UPGRADE.md.
Usage
use RedirectPizza\PhpSdk\RedirectPizza; $redirectPizza = new RedirectPizza('rpa_XXXXXXXXXXXXXXXXXXX'); // https://redirect.pizza/api
Setting a timeout
By default, the SDK will wait for a response for 10 seconds. You can change this by passing a timeoutInSeconds option to the constructor:
$redirectPizza = new RedirectPizza('your-api-token', timeoutInSeconds: 30);
Handling errors
The SDK will throw an exception if the API returns an error. For validation errors, the SDK will throw a ValidationException.
try { $redirectPizza->createRedirect([ 'destination' => 'invalid', ]); } catch (\RedirectPizza\PhpSdk\Exceptions\ValidationException $exception) { $exception->getMessage(); // string describing the errors $exception->getErrors(); // array with all validation errors }
For all other errors, the SDK will throw a \RedirectPizza\PhpSdk\Exceptions\RedirectPizzaException.
Redirects
// returns an iterator of RedirectPizza\PhpSdk\Dto\Redirect $redirects = $redirectPizza->redirects(); // Optional search/filter query (status:active, tag:marketing, source:..., destination:...) $redirects = $redirectPizza->redirects('status:active tag:marketing'); $redirect = $redirectPizza->createRedirect([ 'sources' => ['old-source.nl'], 'destination' => 'new-fancy-site.nl', 'redirect_type' => 'permanent', 'keep_query_string' => false, ]); $redirect = $redirectPizza->redirect($redirectId); $redirect = $redirectPizza->updateRedirect($redirectId, [ 'sources' => ['old-source.nl'], 'destination' => 'new-fancy-site-v2.nl', 'redirect_type' => 'permanent', 'keep_query_string' => true, ]); $redirectPizza->pauseRedirect($redirectId); $redirectPizza->resumeRedirect($redirectId); $redirectPizza->pauseSource($redirectId, $sourceId); $redirectPizza->resumeSource($redirectId, $sourceId); $redirectPizza->deleteRedirect($redirectId);
Domains
$domains = $redirectPizza->domains(); // Optional search/filter query (status:verified, status:unverified, tag:marketing, or free-text FQDN) $domains = $redirectPizza->domains('status:unverified example.com'); $domain = $redirectPizza->domain($domainId); $domain = $redirectPizza->updateDomain($domainId, [ 'hsts' => ['status' => 'enabled', 'max_age' => 31536000], 'waf' => ['status' => 'inherit'], ]); $domain = $redirectPizza->checkDomainDns($domainId); $result = $redirectPizza->applyAutomaticDns($domainId); // $result->successful, $result->output $redirectPizza->deleteDomain($domainId);
Email forwards
$emailForwards = $redirectPizza->emailForwards(); $emailForward = $redirectPizza->emailForward($emailForwardId); $emailForward = $redirectPizza->createEmailForward([ 'domain_id' => 1, 'alias' => 'hello', 'destination' => 'you@example.com', ]); $emailForward = $redirectPizza->updateEmailForward($emailForwardId, [ 'destination' => 'new@example.com', ]); $redirectPizza->deleteEmailForward($emailForwardId);
Analytics (beta)
use RedirectPizza\PhpSdk\Enums\AnalyticsDimension; $hits = $redirectPizza->hitsTotal(start: '2025-04-30', end: '2025-05-20'); echo $hits->count; $series = $redirectPizza->timeSeries(start: '2025-04-30', end: '2025-05-20'); $dimensions = $redirectPizza->dimensions( AnalyticsDimension::Countries, start: '2025-04-30', end: '2025-05-20', );
Raw hits and cursor pagination
Unlike redirects, domains, and users (page-based), raw hits use cursor pagination. The API returns meta.next_cursor; the SDK follows that cursor until it is null.
rawHits() returns an iterable that walks every page for you:
use RedirectPizza\PhpSdk\Dto\RawHit; use RedirectPizza\PhpSdk\Requests\Analytics\GetRawHitsRequest; // Automatically requests the next page while meta.next_cursor is present foreach ($redirectPizza->rawHits(start: '2025-04-30', end: '2025-05-20', query: 'redirect:123') as $hit) { /** @var RawHit $hit */ echo "{$hit->createdAt} {$hit->fullUrl}\n"; }
For more control (for example limiting page size), build the Saloon paginator yourself:
$request = new GetRawHitsRequest(start: '2025-04-30', end: '2025-05-20'); $paginator = $redirectPizza->paginate($request); $paginator->setPerPageLimit(100); foreach ($paginator->items() as $hit) { // ... }
Each page is fetched only as you iterate. Stop early by breaking out of the loop when you have enough results.
Team
$team = $redirectPizza->team(); $team = $redirectPizza->updateTeam([ 'name' => 'Acme Inc', 'summary_frequency' => 'weekly', ]);
Users
$users = $redirectPizza->users(); $user = $redirectPizza->inviteUser([ 'email' => 'colleague@example.com', 'role' => 'member', 'access_type' => 'all', ]); $user = $redirectPizza->updateUser($userId, [ 'role' => 'readonly', 'access_type' => 'allowed', 'tags' => ['marketing'], ]); $redirectPizza->deleteUser($userId);
Utils
These endpoints do not require authentication.
$result = $redirectPizza->testRedirect('https://example.com'); echo $result->status; // success, redirecting, upgrading, error $qr = $redirectPizza->qrCode('https://example.com'); // JSON metadata + base64 image // or binary: $response = $redirectPizza->qrCode('https://example.com', format: 'png');
Security
If you discover any security related issues, please email support@redirect.pizza instead of using the issue tracker.
Credits
This package is greatly inspired by the Oh Dear PHP SDK by Freek van der Herten and Mattias Geniar.
License
The MIT License (MIT). Please see License File for more information.