Sink provides a complete RESTful API for managing short links. Full API documentation is available via OpenAPI.
- OpenAPI JSON:
/_docs/openapi.json - Scalar UI:
/_docs/scalar - Swagger UI:
/_docs/swagger
Visit your Sink instance at https://your-domain/_docs/scalar for interactive API documentation.
All API endpoints accept the site token in the Authorization header:
Authorization: Bearer YOUR_SITE_TOKENThe token is the same as NUXT_SITE_TOKEN configured in your environment variables.
When Cloudflare Access authentication is configured, browser requests from an authenticated dashboard session can use the signed Access application token instead. Sink validates the token signature, issuer, audience, and expiration. Clients must not construct or trust Cf-Access-Jwt-Assertion themselves; Cloudflare Access supplies the token or authorization cookie.
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/link/create |
Create a new short link |
PUT |
/api/link/edit |
Update an existing link |
POST |
/api/link/upsert |
Create or update a link by slug |
POST |
/api/link/delete |
Delete a link |
GET |
/api/link/query |
Get a link by slug |
GET |
/api/link/search |
Search links |
GET |
/api/link/list |
List all links (paginated) |
GET |
/api/link/export |
Export all links as paginated JSON |
POST |
/api/link/import |
Import links from exported JSON |
GET |
/api/link/ai |
Generate an AI-powered slug suggestion |
GET |
/api/link/og-ai |
Generate AI-powered OpenGraph metadata |
POST |
/api/upload/image |
Upload an OpenGraph image to R2 |
POST |
/api/backup |
Trigger a manual KV backup to R2 |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/stats/counters |
Get analytics counters |
GET |
/api/stats/metrics |
Get detailed metrics by dimension |
GET |
/api/stats/views |
Get time-series view counts |
GET |
/api/stats/heatmap |
Get heatmap data |
GET |
/api/stats/export |
Export access analytics as CSV |
GET |
/api/logs/events |
Get real-time event logs |
GET |
/api/logs/locations |
Get recent access locations |
POST /api/link/create
Authorization: Bearer SinkCool
Content-Type: application/json
{
"url": "https://github.com/miantiao-me/Sink",
"slug": "sink",
"comment": "GitHub repo",
"expiration": 1767225599,
"apple": "https://apps.apple.com/app/id6745417598",
"google": "https://play.google.com/store/apps/details?id=com.example",
"geo": {
"US": "https://example.com/us",
"JP": "https://example.com/jp"
},
"title": "Sink - Link Shortener",
"description": "A simple, speedy, secure link shortener",
"image": "/_assets/images/sink/cover.webp",
"password": "correct-horse-battery-staple",
"unsafe": false,
"redirectWithQuery": true
}{
"link": {
"id": "01jxyz...",
"url": "https://github.com/miantiao-me/Sink",
"slug": "sink",
"comment": "GitHub repo",
"createdAt": 1718119809,
"updatedAt": 1718119809
}
}| Field | Type | Required | Description |
|---|---|---|---|
url |
string |
✅ | Target URL (max 2048 chars) |
slug |
string |
❌ | Custom slug (auto-generated if omitted) |
comment |
string |
❌ | Internal note for the link |
expiration |
number |
❌ | Unix timestamp in seconds; must be in the future |
apple |
string |
❌ | Apple device redirect URL |
google |
string |
❌ | Android/Google Play redirect URL |
geo |
object |
❌ | Country-specific routing map, for example { "US": "https://..." } |
title |
string |
❌ | OpenGraph title |
description |
string |
❌ | OpenGraph description |
image |
string |
❌ | OpenGraph image URL or uploaded asset path |
cloaking |
boolean |
❌ | Enable link cloaking (mask destination URL with short link) |
redirectWithQuery |
boolean |
❌ | Append query parameters to destination URL (overrides global setting) |
password |
string |
❌ | Password protection for the link (stored hashed) |
unsafe |
boolean |
❌ | Mark link as unsafe (shows warning page before redirect) |
- Geo-routing uses Cloudflare's
request.cf.countryvalue and two-letter ISO country codes. Keys are normalized to uppercase. - Device routing takes precedence over the default or geo-routed target when the visitor matches Apple or Android user agents.
- If
redirectWithQueryis enabled, query parameters from the short link are appended to the final target URL.
Password-protected links render an HTML password form for browser visitors. API or scripted clients can pass x-link-password when requesting the short link. Unsafe links require confirmation before redirecting; scripted clients can pass x-link-confirm: true after validating the destination.
GET /api/link/og-ai?url=https%3A%2F%2Fgithub.com%2Fmiantiao-me%2FSink&locale=en-US
Authorization: Bearer SinkCool{
"title": "Sink",
"description": "A simple, speedy, secure link shortener with analytics on Cloudflare."
}GET /api/stats/export?startAt=1717200000&endAt=1719791999&slug=sink
Authorization: Bearer SinkCoolThe response is text/csv with these columns:
slug,url,viewer,views,referer
sink,https://github.com/miantiao-me/Sink,123,456,12To enable CORS for API endpoints, set NUXT_API_CORS=true during build.