Short Link API Documentation

Authentication

Session Cookie (Browser)

If you're using the dashboard from a browser, authentication is handled automatically via session cookies.

API Key (Programmatic)

For programmatic access (curl, scripts, applications), use the X-API-Key header:

curl -X POST https://yourdomain.com/api/shortlinks \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY_HERE" \
  -d '{"url":"https://example.com","slug":"myslug"}'

Creating a Short Link

Request

Endpoint: POST /api/shortlinks

Headers:

  • Content-Type: application/json
  • X-API-Key: YOUR_API_KEY_HERE (required for API access, optional for browser)

Request Body:

{
  "url": "https://destination-url.com",
  "slug": "optional-custom-slug"
}

Parameters:

  • url (required): Valid URL to redirect to
  • slug (optional): Custom slug for the short link. If omitted, one will be auto-generated. Must be 2+ characters.

Response

Success (200):

{
  "link": {
    "id": 123,
    "slug": "myslug",
    "url": "https://example.com",
    "ownerId": 456,
    "createdAt": "2025-12-19T01:00:00Z",
    "lastVisitedAt": null,
    "visitCount": 0,
    "guestSessionId": null,
    "available": true
  },
  "owner": {
    "id": 456,
    "email": "user@example.com",
    "displayName": "John Doe"
  },
  "message": "Link saved to your account."
}

Error (400/401/409/429):

{
  "error": "Error message describing what went wrong"
}

Error Responses

Status Error Reason
400 "URL is required" Missing or empty URL
400 "Invalid URL" URL format is invalid
400 "Slug is reserved" Custom slug is a reserved system slug
401 "Invalid API key" X-API-Key header is invalid or doesn't exist
401 "Invalid API key format" X-API-Key header format is invalid
409 "Slug already exists" Custom slug is already taken
429 "Too much request. Try again later." Rate limit exceeded (20 requests per minute)

Examples

Create with auto-generated slug

curl -X POST https://yourdomain.com/api/shortlinks \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"url":"https://google.com"}'

Create with custom slug

curl -X POST https://yourdomain.com/api/shortlinks \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"url":"https://github.com","slug":"github"}'

Using Python

import requests

API_KEY = "YOUR_API_KEY"
headers = {
    "Content-Type": "application/json",
    "X-API-Key": API_KEY
}
data = {
    "url": "https://example.com",
    "slug": "myslug"
}

response = requests.post(
    "https://yourdomain.com/api/shortlinks",
    headers=headers,
    json=data
)

if response.status_code == 200:
    print(f"Short link created: /{response.json()['link']['slug']}")
else:
    print(f"Error: {response.json()['error']}")

Using JavaScript

const API_KEY = "YOUR_API_KEY";

async function createShortLink(url, slug) {
  const response = await fetch("/api/shortlinks", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-API-Key": API_KEY,
    },
    body: JSON.stringify({ url, slug }),
  });

  const data = await response.json();
  
  if (response.ok) {
    console.log(`Short link: /${data.link.slug}`);
  } else {
    console.error(`Error: ${data.error}`);
  }
}

createShortLink("https://example.com", "myslug");

Rate Limiting

  • Limit: 20 requests per minute
  • Per: API key (for authenticated users)
  • Response: 429 Too Many Requests

API Key Management

  1. View your API key in the dashboard at /r
  2. Copy the key by clicking the Copy button
  3. Rotate your API key anytime by clicking the Rotate button
  4. Old keys are invalidated immediately after rotation

Security Notes

  • Never commit your API key to version control
  • Store API keys in environment variables
  • Rotate your API key if you suspect it's been compromised
  • The X-API-Key header requires HTTPS in production