API Reference
The Vertex API is REST-based, JSON-encoded, and versioned from /v1/. All endpoints require an API key unless otherwise noted.
Authentication
Authenticate using an API key in the Authorization header. API keys are prefixed with vrx_.
Authorization: Bearer vrx_your_api_key_here
Obtain an API key from your dashboard. Keys never expire but can be rotated at any time.
Shorten a URL
POST/v1/shortenCreates a new short link. Returns a vrx.li short URL immediately. Short codes are base58-encoded, crypto-random, and 6–8 characters.
curl -X POST https://api.vrx.li/v1/shorten \
-H "Authorization: Bearer vrx_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"url": "https://yoursite.com/very/long/path",
"mask": false,
"custom_code": "launch"
}'Request body
urlstringrequiredThe destination URL to shorten. Must use http:// or https://. Private IPs, javascript:, and data: URIs are rejected.
maskbooleanIf true, hides the destination URL from the recipient. Defaults to false.
custom_codestringOptional custom short code (3–32 chars, alphanumeric and hyphens). Must be unique. Omit to auto-generate.
Response
codestringThe short code. 6–8 characters, base58-encoded.
short_urlstringThe full short URL, e.g. https://vrx.li/aX9kpQ.
created_atstringISO 8601 timestamp of creation.
Redirect
GET/:codeRedirects to the destination URL. Click events are logged asynchronously — the redirect never waits for analytics writes. Target latency: p50 <10ms.
Response
302 FoundReturns a 302 redirect. Use 301 for permanent/cacheable links (configurable per link). The Location header contains the destination URL.
Link stats
GET/v1/stats/:codeReturns aggregate click statistics for a single link. No auth required for public links.
{
"code": "aX9kpQ",
"clicks": 1402,
"unique_clicks": 891,
"created_at": "2024-01-15T10:32:00Z",
"last_clicked": "2024-02-14T08:17:00Z"
}Full analytics
GET/v1/analytics/:codeFull analytics breakdown including geo, device, UTM, referrer, and time-of-day heatmap. Requires authentication. Use the range query parameter to filter.
Query parameters
rangestringTime range: 7d, 30d, or 90d. Defaults to 30d.
tzstringIANA timezone for grouping (e.g. America/New_York). Defaults to UTC.
curl https://api.vrx.li/v1/analytics/aX9kpQ?range=30d \ -H "Authorization: Bearer vrx_your_api_key"
Analytics export
GET/v1/analytics/:code/exportExports raw click events as CSV. Each row is one click event with all captured signals. Useful for loading into data warehouses, BI tools, or ad platforms.
Query parameters
formatstringrequiredMust be "csv". JSON support planned.
fromstringStart date, ISO 8601 (e.g. 2024-01-01).
tostringEnd date, ISO 8601 (e.g. 2024-01-31).
CSV columns: timestamp, country, city, device, browser, os, referrer, utm_source, utm_medium, utm_campaign, is_unique, is_bot
Health
GET/v1/healthReturns service health. No auth required. Used by the status page and uptime monitors.
{
"status": "ok",
"services": {
"db": "ok",
"cache": "ok"
},
"uptime_seconds": 2847392
}Rate limits
Rate limiting is enforced per IP using a Redis-backed token bucket. Limits reset on a rolling window. Exceeded requests receive a 429 Too Many Requests response.
POST /v1/shorten60 req / minuteGET /v1/stats/:code300 req / minuteGET /v1/analytics/:code120 req / minuteGET /:code (redirect)No limit (cached)Rate limit headers: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset
Error codes
All errors return JSON with a typed error field.
invalid_urlURL failed validation (protocol, private IP, etc.)unauthorizedMissing or invalid API key.not_foundShort code does not exist.code_conflictCustom code is already in use.validation_errorRequest body malformed or missing required fields.rate_limitedToo many requests. Retry after X-RateLimit-Reset.internal_errorServer error. Retry with exponential backoff.{
"error": {
"type": "invalid_url",
"message": "URL uses disallowed protocol: javascript:",
"code": 400
}
}