PHP SDK

Official PHP client for shorter.sh. A type-safe Composer package for shortening URLs, managing links, and viewing analytics. Requires PHP ≥8.1 and Guzzle 7.

Installation

Composer
composer require shorter/sdk
ℹ️

You need an API key to use the SDK. Create one from your dashboard.


Quick Start

PHP
use Shorter\Sdk\ShorterClient;

$client = new ShorterClient(
    api_key: 'sk_your_api_key_here',
);

$result = $client->shorten('https://example.com');
echo $result->short_url; // https://shorter.sh/xK9mP2

Authentication

The API key is resolved in order:

  1. api_key constructor parameter
  2. SHORTER_API_KEY environment variable

The key must start with sk_.


Shorten URLs

$client->shorten(url)
$result = $client->shorten('https://example.com/very/long/url');

echo $result->short_code;   // "xK9mP2"
echo $result->short_url;    // "https://shorter.sh/xK9mP2"
echo $result->original_url; // "https://example.com/very/long/url"

List URLs

$client->list(page?, limit?)
$result = $client->list(page: 1, limit: 50);

foreach ($result->urls as $url) {
    echo "{$url->short_url} → {$url->original_url} ({$url->click_count} clicks)\n";
}

echo "Total: {$result->total_clicks} clicks";

Each URL object contains: id, short_code, short_url, original_url, click_count, created_at.


Delete URLs

$client->delete(short_code)
$client->delete('xK9mP2');
// Deleted URLs return 410 Gone when visited

Analytics

Overview (all URLs)

$client->analytics->overview(start?, end?)
$overview = $client->analytics->overview(
    start: '2024-01-01',
    end: '2024-01-31',
);

echo $overview->total_clicks;
echo $overview->unique_visitors;
echo count($overview->top_urls);          // Top performing URLs
echo count($overview->country_breakdown); // Clicks by country
echo count($overview->device_breakdown);  // Clicks by device type

Per-URL analytics

$client->analytics->url(short_code, ...options)
// Basic stats
$stats = $client->analytics->url('xK9mP2');
echo $stats->summary->total_clicks;

// With dimension breakdown
$byCountry = $client->analytics->url('xK9mP2', dimension: 'country');
echo $byCountry->breakdown->dimension; // "country"

// Full detail (all breakdowns at once)
$detail = $client->analytics->url('xK9mP2', detail: true);
foreach ($detail->breakdowns as $dim => $breakdown) {
    echo "{$dim}: {$breakdown->total} total\n";
}

Available dimensions

country device_type browser os referrer_domain language

Error Handling

All exceptions extend ShorterException with getMessage(), $status, and $errorCode properties.

Error handling
use Shorter\Sdk\Exceptions\ValidationException;
use Shorter\Sdk\Exceptions\NotFoundException;
use Shorter\Sdk\Exceptions\ShorterException;

try {
    $client->shorten('not-a-url');
} catch (ValidationException $e) {
    echo $e->getMessage(); // "Invalid URL"
    echo $e->errorCode;    // "VALIDATION_ERROR"
    echo $e->status;       // 400
} catch (ShorterException $e) {
    // Any other API error
}
Exception ClassStatusWhen
ValidationException400Invalid URL, missing fields, unsafe URL
AuthenticationException401Invalid or missing API key
ForbiddenException403Account suspended, access denied
NotFoundException404URL not found or not owned by you
RateLimitException429Too many requests
ServerException500Server-side error
NetworkException0DNS failure, timeout, no internet

View the package on Packagist or the source on GitHub.