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/jsonX-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 toslug(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
- View your API key in the dashboard at
/r - Copy the key by clicking the Copy button
- Rotate your API key anytime by clicking the Rotate button
- 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