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.
composer require enflow/redirect-pizza-php-sdk
Upgrading from 2.x? See UPGRADE.md.
use RedirectPizza\PhpSdk\RedirectPizza;
$redirectPizza = new RedirectPizza('rpa_XXXXXXXXXXXXXXXXXXX'); // https://redirect.pizza/apiBy 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);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.
// 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 = $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);$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);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',
);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 = $redirectPizza->team();
$team = $redirectPizza->updateTeam([
'name' => 'Acme Inc',
'summary_frequency' => 'weekly',
]);$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);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');If you discover any security related issues, please email support@redirect.pizza instead of using the issue tracker.
This package is greatly inspired by the Oh Dear PHP SDK by Freek van der Herten and Mattias Geniar.
The MIT License (MIT). Please see License File for more information.