⚡ SwiftLink

API v1

REST API for creating short links, reading analytics, generating QR codes and managing your account. Every response is JSON: {"ok": true, "data": …} on success, {"ok": false, "error": "…"} on failure.

1. Authentication

Create an API key in your dashboard → API keys. Send it on every request as a Bearer token (preferred) or as the ?api_key= query parameter.

Authorization: Bearer YOUR_API_KEY

Paste your key below to use the live try-it console. It is stored only in this browser's local storage.

Rate limits & plans

Each key has its own per-minute limit (default 60, shown in the X-RateLimit-Limit / X-RateLimit-Remaining headers; 429 when exceeded). API access requires the Pro or Business plan, and custom aliases additionally require a plan with the custom-alias feature — otherwise the API returns 403.

2. Endpoints

MethodPathDescriptionParameters
POST /api/v1/links Create a short link url (required), alias, title, description, password, expires_at, max_clicks, redirect_type
GET /api/v1/links List your links (paginated) page, per_page (max 100), search
GET /api/v1/links/{id} Get one link —
PUT /api/v1/links/{id} Update a link destination/url, alias, title, description, redirect_type, is_active, password, expires_at, max_clicks
DELETE /api/v1/links/{id} Delete a link —
GET /api/v1/analytics Account analytics overview —
GET /api/v1/analytics/{id} Per-link analytics —
POST /api/v1/qr QR code for a link (client-side snippet) link_id (required), size, ec_level, fg, bg
GET /api/v1/account Account, plan and usage —

About QR codes

Honest note: POST /api/v1/qr does not return a server-side PNG — SwiftLink ships no server-side QR renderer. It returns the short URL plus a ready-to-paste client-side snippet that renders a crisp SVG QR with the bundled MIT-licensed qrcode.js library. Nothing is faked; the response field server_side is false.

3. Try it live

Fires real fetch() requests against this installation's /api/v1/* endpoints using your saved key.

// response appears here

4. Code examples

# Create a link
curl -X POST "https://YOUR-DOMAIN/api/v1/links" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/some/long/page","alias":"launch-2026","title":"Launch page"}'

# List links (page 2, 10 per page)
curl "https://YOUR-DOMAIN/api/v1/links?page=2&per_page=10" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Account analytics overview
curl "https://YOUR-DOMAIN/api/v1/analytics" \
  -H "Authorization: Bearer YOUR_API_KEY"
<?php
$key = 'YOUR_API_KEY';
$ctx = stream_context_create(['http' => [
    'method'  => 'POST',
    'header'  => "Authorization: Bearer $key\r\nContent-Type: application/json\r\n",
    'content' => json_encode([
        'url'   => 'https://example.com/some/long/page',
        'alias' => 'launch-2026',
        'title' => 'Launch page',
    ]),
    'ignore_errors' => true,
]]);
$res = file_get_contents('https://YOUR-DOMAIN/api/v1/links', false, $ctx);
$data = json_decode($res, true);
if ($data['ok']) {
    echo $data['data']['short_url'], PHP_EOL; // https://YOUR-DOMAIN/launch-2026
} else {
    echo 'Error: ', $data['error'], PHP_EOL;
}
const res = await fetch('https://YOUR-DOMAIN/api/v1/links', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    url: 'https://example.com/some/long/page',
    alias: 'launch-2026',
  }),
});
const data = await res.json();
if (data.ok) {
  console.log(data.data.short_url);
} else {
  console.error(res.status, data.error);
}

Error format & status codes

CodeMeaningExample
200OKRead / update / delete succeeded
201CreatedPOST /api/v1/links succeeded
400Bad requestMissing field, malformed URL, bad alias format
401UnauthorizedMissing or invalid API key, disabled account
403ForbiddenPlan lacks API access or the custom-alias feature
404Not foundLink id does not exist (or belongs to another account)
409ConflictAlias already taken
422UnprocessableMonthly link quota reached, reserved alias, bad expiry
429Too many requestsPer-key per-minute limit exceeded

Full reference with every field documented lives in API.md at the project root.