API Documentation

The yourshortsite.link REST API lets you shorten URLs, generate QR codes, build UTM links, and retrieve stats — programmatically from any language or platform.

Base URL: https://yourshortsite.link/api/v1

Introduction

All API requests are made over HTTPS. Request bodies are JSON. Responses are always JSON (except the /qr endpoint which returns a PNG image).

API plans are separate from website plans. A website Pro account (£3.99/mo) does not include API access. API plans are standalone subscriptions managed from your account dashboard.

Authentication

Every request must include your API key in the X-Api-Key header:

# Example with curl
curl https://yourshortsite.link/api/v1/shorten \
  -H "X-Api-Key: ysl_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/long-url"}'

You can also pass the key as a Bearer token in the Authorization header:

Authorization: Bearer ysl_your_api_key_here

Generate API keys from your account dashboard. Keys are prefixed ysl_ and are shown only once at creation — store them securely.

API Plans

API usage is metered per day, resetting at midnight UTC. Plans are independent of website plans.

Pro API
£4.99
/month
100 calls/day
  • All endpoints
  • QR up to 400px
  • 5 API keys
  • Usage dashboard
Scale API
£24.99
/month
750 calls/day
  • All endpoints
  • QR up to 1000px
  • 5 API keys
  • Priority support

Subscribe to an API plan →

Rate Limits

Every response includes rate limit headers:

HeaderDescription
X-RateLimit-LimitYour daily call limit
X-RateLimit-RemainingCalls remaining today
X-RateLimit-ResetISO 8601 timestamp when the limit resets (midnight UTC)

When you exceed your daily limit the API returns 429 Too Many Requests. Limits reset at 00:00:00 UTC each day.

Errors

All errors return a JSON object with an error field:

{
  "error":  "Invalid URL. Must start with http:// or https://",
  "status": 400
}
StatusMeaning
401Missing or invalid API key
402No active API plan
403Forbidden (e.g. accessing another user's link)
404Resource not found
409Conflict (e.g. slug already taken)
429Daily rate limit exceeded
500Internal server error

POST /shorten

Shorten a URL. Returns the short URL, slug, and a QR code URL.

POST /api/v1/shorten Shorten a URL

Request body

FieldTypeRequiredDescription
urlstringYesThe destination URL to shorten. Must start with http:// or https://
custom_slugstringNoCustom back-half, e.g. my-campaign. Alphanumeric, hyphens and underscores only. Max 48 chars.

Example request

curl -X POST https://yourshortsite.link/api/v1/shorten \
  -H "X-Api-Key: ysl_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "url":         "https://example.com/very/long/path?with=params",
    "custom_slug": "my-campaign"
  }'

Example response 201 Created

{
  "shortUrl":  "https://yourshortsite.link/my-campaign",
  "slug":      "my-campaign",
  "url":       "https://example.com/very/long/path?with=params",
  "createdAt": "2025-04-16T12:00:00+00:00",
  "qrUrl":     "https://yourshortsite.link/api/qr.php?slug=my-campaign"
}

POST /utm

Build a UTM-tagged URL and optionally shorten it in one step.

POST /api/v1/utm Build UTM URL

Request body

FieldTypeRequiredDescription
urlstringYesBase destination URL
utm_sourcestringYesTraffic source, e.g. google, discord
utm_mediumstringNoMarketing medium, e.g. cpc, email
utm_campaignstringYesCampaign name, e.g. spring_sale
utm_termstringNoPaid search keyword
utm_contentstringNoAd variant identifier
shortenboolNoWhether to also shorten the UTM URL. Default: true

Example request

curl -X POST https://yourshortsite.link/api/v1/utm \
  -H "X-Api-Key: ysl_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "url":          "https://example.com/landing",
    "utm_source":   "discord",
    "utm_medium":   "social",
    "utm_campaign": "summer_launch",
    "shorten":      true
  }'

Example response 201 Created

{
  "utmUrl":   "https://example.com/landing?utm_source=discord&utm_medium=social&utm_campaign=summer_launch",
  "shortUrl": "https://yourshortsite.link/aB3xY2",
  "slug":     "aB3xY2",
  "qrUrl":    "https://yourshortsite.link/api/qr.php?slug=aB3xY2"
}

Retrieve a paginated list of your short links, newest first.

GET /api/v1/links List your links

Query parameters

ParamTypeDefaultDescription
limitinteger20Results per page (max 100)
offsetinteger0Pagination offset

Example request

curl "https://yourshortsite.link/api/v1/links?limit=5&offset=0" \
  -H "X-Api-Key: ysl_your_key"

Example response 200 OK

{
  "links": [
    {
      "slug":      "my-campaign",
      "url":       "https://example.com/...",
      "shortUrl":  "https://yourshortsite.link/my-campaign",
      "clicks":    142,
      "createdAt": "2025-04-16T12:00:00+00:00",
      "utmTagged": false,
      "qrUrl":     "https://yourshortsite.link/api/qr.php?slug=my-campaign"
    }
  ],
  "total":  47,
  "limit":  5,
  "offset": 0
}

GET /stats/{slug}

Get detailed stats for a specific short link. Only links belonging to your account can be queried.

GET /api/v1/stats/{slug} Stats for a slug

Example request

curl https://yourshortsite.link/api/v1/stats/my-campaign \
  -H "X-Api-Key: ysl_your_key"

Example response 200 OK

{
  "slug":      "my-campaign",
  "url":       "https://example.com/...",
  "shortUrl":  "https://yourshortsite.link/my-campaign",
  "clicks":    142,
  "createdAt": "2025-04-16T12:00:00+00:00",
  "utmTagged": false
}

GET /qr/{slug}

Returns a QR code PNG image for the given slug. Use directly as an <img src="..."> in your app.

GET /api/v1/qr/{slug} QR code PNG

Query parameters

ParamTypeDefaultDescription
sizeinteger300Image size in pixels. Max: Pro 400, Business 600, Scale 1000.

Example request

curl "https://yourshortsite.link/api/v1/qr/my-campaign?size=400" \
  -H "X-Api-Key: ysl_your_key" \
  --output qr.png
The response is a raw image/png — not JSON. Rate limit headers are still returned.

GET /usage

Check your API usage for today.

GET /api/v1/usage Today's API usage

Example request

curl https://yourshortsite.link/api/v1/usage \
  -H "X-Api-Key: ysl_your_key"

Example response 200 OK

{
  "plan":      "api_business",
  "planLabel": "Business API",
  "used":      87,
  "limit":     250,
  "remaining": 163,
  "resetAt":   "2025-04-17T00:00:00Z",
  "date":      "2025-04-16"
}

Code examples

JavaScript (fetch)

const response = await fetch('https://yourshortsite.link/api/v1/shorten', {
  method:  'POST',
  headers: {
    'X-Api-Key':     'ysl_your_key',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ url: 'https://example.com/long' }),
});
const data = await response.json();
console.log(data.shortUrl); // https://yourshortsite.link/abc123

Python (requests)

import requests

response = requests.post(
    'https://yourshortsite.link/api/v1/shorten',
    headers={'X-Api-Key': 'ysl_your_key'},
    json={'url': 'https://example.com/long'},
)
data = response.json()
print(data['shortUrl'])

PHP

$ch = curl_init('https://yourshortsite.link/api/v1/shorten');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_POSTFIELDS     => json_encode(['url' => 'https://example.com/long']),
    CURLOPT_HTTPHEADER     => [
        'X-Api-Key: ysl_your_key',
        'Content-Type: application/json',
    ],
]);
$data = json_decode(curl_exec($ch), true);
echo $data['shortUrl'];