REST API Reference
Shorten links and read analytics from your own stack. Free tier: 120 requests/minute.
Authentication
Create an API key in Dashboard → Settings → API keys, then send it as a Bearer token:
Authorization: Bearer lf_xxxxxxxxxxxxxxxxxxxx
All endpoints are rooted at https://linkforge-tan.vercel.app/api/v1. Responses are JSON. Rate limit: 120 requests/minute per key (429 with Retry-After when exceeded).
Create a link
POST /api/v1/links
curl -X POST https://linkforge-tan.vercel.app/api/v1/links \
-H "Authorization: Bearer lf_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/launch", "slug": "launch"}'
Body parameters: url (required), slug, title, expiresAt (ISO 8601), maxClicks (integer, 1 = one-time link).
Returns 201:
{
"id": "clx…",
"slug": "launch",
"short_url": "https://linkforge-tan.vercel.app/launch",
"url": "https://example.com/launch",
"created_at": "2026-07-12T09:00:00.000Z"
}
List your links
GET /api/v1/links?page=1 — 50 per page, newest first.
Get a link + stats
GET /api/v1/links/:id
{
"id": "clx…",
"slug": "launch",
"short_url": "https://linkforge-tan.vercel.app/launch",
"stats": {
"total": 1204,
"unique": 861,
"returning": 343,
"qr": 87,
"countries": [{ "name": "US", "value": 402 }],
"devices": [{ "name": "mobile", "value": 700 }],
"sources": [{ "name": "instagram", "value": 214 }]
}
}
Delete a link
DELETE /api/v1/links/:id — soft-deletes; the short URL stops resolving immediately.
Node.js example
const res = await fetch("https://linkforge-tan.vercel.app/api/v1/links", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.LINKFORGE_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ url: "https://example.com" }),
});
const link = await res.json();
console.log(link.short_url);
Python example
import os, requests
r = requests.post( "https://linkforge-tan.vercel.app/api/v1/links", headers={"Authorization": f"Bearer {os.environ['LINKFORGE_KEY']}"}, json={"url": "https://example.com"}, ) print(r.json()["short_url"]) ```
Errors
- 401 — missing/invalid API key
- 409 — slug already taken
- 422 — validation error (details in
issues) - 429 — rate limited (respect
Retry-After)