API Reference¶
Base URL: https://usnp.me
For interactive exploration, use the Swagger UI.
Authentication¶
All endpoints except GET /{short_id} (redirect) and GET /{short_id}/qr (QR code)
require an X-API-Key header.
Endpoints¶
| Method | Path | Auth | Description |
|---|---|---|---|
GET |
/ |
No | Health check |
POST |
/shorten |
Yes | Create a shortlink |
GET |
/{short_id} |
No | Redirect to target URL |
GET |
/{short_id}/qr |
No | Generate QR code |
GET |
/{short_id}/webhooks/status |
Yes | Webhook delivery status |
POST |
/api-keys |
Yes | Create a new API key |
GET |
/api-keys |
Yes | List API keys |
DELETE |
/api-keys/{key_id} |
Yes | Revoke an API key |
POST |
/api-keys/{key_id}/rotate |
Yes | Rotate an API key |
GET |
/links/{short_id}/analytics |
Yes | Full link analytics |
GET |
/links/{short_id}/analytics/summary |
Yes | Lightweight analytics summary |
GET |
/usage |
Yes | Usage summary for current month |
POST /shorten¶
Create a new shortlink with an optional data payload and webhook URLs.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
redirect_url |
string (URL) | Yes | Target URL for the redirect |
data |
object | No | Custom JSON data (max 10 KB) delivered to webhooks |
webhooks |
array of URLs | No | Webhook endpoints to notify on each click |
Response (200):
{
"short_id": "abc123",
"short_url": "https://usnp.me/abc123",
"redirect_url": "https://example.com/landing",
"created_at": "2026-01-15T10:30:00Z"
}
Response headers (for scoped API keys):
| Header | Description |
|---|---|
X-Usage-Links-Created |
Links created this month |
X-Usage-Links-Limit |
Monthly link creation limit (or unlimited) |
GET /{short_id}¶
Resolves a shortlink and returns a 302 redirect. Records the hit and fires webhooks in the background.
GET /{short_id}/qr¶
Generate a QR code image for a shortlink.
Query parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
format |
png or svg |
png |
Output image format |
scale |
int (1-20) | 5 |
Size multiplier |
dark |
string | #000000 |
QR module color (hex or CMYK) |
light |
string | #FFFFFF |
Background color (hex, CMYK, or transparent) |
Webhook Payload¶
When a shortlink is clicked, each registered webhook receives a POST with:
{
"event": "hit",
"short_id": "abc123",
"redirect_url": "https://example.com/product",
"hit_id": "550e8400-...",
"hit_at": "2026-01-15T10:30:00Z",
"data": {"sku": "WIDGET-42"}
}
Headers:
| Header | Description |
|---|---|
X-Webhook-Signature |
sha256=<HMAC-SHA256 hex digest> — sign the raw JSON body with your webhook_secret to verify |
Content-Type |
application/json |
Webhooks retry up to 3 times with exponential backoff (1s, 5s delays).
Scanalytics¶
GET /links/{short_id}/analytics¶
Full analytics breakdown for a tracked link.
Response (200):
{
"total_hits": 1042,
"last_7_days": 87,
"daily": [{"date": "2026-04-26", "count": 12}, "..."],
"referrers": [{"label": "google.com", "count": 45}],
"countries": [{"label": "US", "count": 320}],
"regions": [{"label": "California", "count": 98}],
"cities": [{"label": "San Francisco", "count": 41}],
"devices": [{"label": "desktop", "count": 610}]
}
| Field | Description |
|---|---|
total_hits |
Lifetime hit count |
last_7_days |
Hits in the last 7 days |
daily |
Per-day hit counts for the last 30 days |
referrers |
Top 10 referring domains |
countries |
Top 10 countries by hit count |
regions |
Top 10 regions by hit count |
cities |
Top 10 cities by hit count |
devices |
Device type breakdown (desktop, mobile, tablet) |
Errors:
| Status | Reason |
|---|---|
| 401 | Missing or invalid API key |
| 403 | Link is untracked, or you don't own it |
| 404 | Link not found |
| 429 | Rate limit exceeded |
GET /links/{short_id}/analytics/summary¶
Lightweight analytics summary for embedding or dashboards.
Response (200):
| Field | Description |
|---|---|
short_id |
The shortlink identifier |
total_hits |
Lifetime hit count |
last_7_days |
Hits in the last 7 days |
last_30_days |
Hits in the last 30 days |
Same error responses as the full analytics endpoint.
GET /usage¶
Returns usage counters for the current month.
Response:
{
"api_key_id": "550e8400-...",
"month": "2026-05",
"usage": {
"links_created": {"current": 42, "limit": 100},
"hits_served": {"current": 1583, "limit": null},
"webhook_deliveries": {"current": 312, "limit": 1000}
}
}
limit: null means unlimited for that metric.