Developer API
XURL API Documentation
Build against XURL with predictable authentication, clear endpoint contracts, and robust examples for production integrations.
Section
Introduction
Introduction
Understand the XURL Developer API surface and where requests are served from.
XURL Developer API lets you create, list, and analyze short links programmatically.
Base URL
https://xurl.eu.cc/api/v1
Key management
/dashboard/api
Response Format
All endpoints return JSON payloads for both success and failures.
Error responses consistently use {"error": "message"} and standard HTTP status codes.
Plan Access
API key access is controlled by plan capability and API enablement status.
- Business, Enterprise, and Big Enterprise can enable API access.
- Expired plans fall back to free plan behavior and API access is blocked.
- Disabled API keys return 403 with an access-not-enabled error.
Quick Start
Make your first authenticated API request in under a minute.
Start by creating an API key in Dashboard and sending a POST request to create a short link.
Get an API Key
- Open /dashboard/api
- Generate or rotate your API key
- Store it in a secret manager and never expose it client-side
Send First Request
/api/v1/linksCreate a short link for the authenticated user.
Source files
app/api/v1/links/route.ts (POST)
lib/api/auth.ts (authenticateApiRequest)
curl https://xurl.eu.cc/api/v1/links \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com"}'Authentication
All documented endpoints require Bearer API key authentication.
Authentication is validated via hashed API keys and plan checks before request handling.
Required Header
Authorization: Bearer xurl_sk_live_xxxxxxxxxValidation Rules
- Missing or malformed Bearer token returns 401 Invalid API key.
- Unknown key hash returns 401 Invalid API key.
- Disabled or unsupported plan returns 403 API access is not enabled for your current plan.
- Quota exhaustion returns 403 API quota exceeded.
Quota Side Effect
Every successful authentication increments API request usage before endpoint logic executes.
Create Link
Create a short URL with optional title and custom slug.
/api/v1/linksCreate a short link for the authenticated user.
Source files
app/api/v1/links/route.ts (POST)
lib/api/auth.ts (authenticateApiRequest)
Request Body
The url field is required. title and customSlug are optional.
{
"url": "https://example.com",
"title": "Launch page",
"customSlug": "launch"
}Successful Response
{
"id": "launch",
"shortUrl": "https://xurl.eu.cc/launch",
"url": "https://example.com",
"createdAt": 1710000000000
}Error Cases
- 400 when url is missing or malformed.
- 403 for plan restrictions or quota limits.
- 409 when customSlug is already taken.
- 429 when upstream rate limit is exceeded.
List Links
Fetch paginated links created by the authenticated user.
/api/v1/linksList authenticated user links with cursor pagination.
Source files
app/api/v1/links/route.ts (GET)
lib/api/auth.ts (authenticateApiRequest)
Query Parameters
- limit: integer from 1 to 100 (default 20)
- cursor: createdAt timestamp from previous response
curl "https://xurl.eu.cc/api/v1/links?limit=20&cursor=1710000000000" \
-H "Authorization: Bearer YOUR_API_KEY"Response Shape
{
"data": [
{
"id": "launch",
"shortUrl": "https://xurl.eu.cc/launch",
"url": "https://example.com",
"title": "Launch page",
"clicks": 42,
"createdAt": 1710000000000,
"expiresAt": null,
"status": "active"
}
],
"pagination": {
"limit": 20,
"nextCursor": 1710000000000,
"hasMore": true
}
}Status Field
- active when link is enabled and not expired
- deactivated when isActive is false
- expired when expiresAt is in the past
Analytics
Retrieve per-link click trends and country breakdown summaries.
/api/v1/links/{id}/analyticsFetch analytics timeline and geo summary for a link owned by the API key owner.
Source files
app/api/v1/links/[id]/analytics/route.ts (GET)
lib/api/auth.ts (authenticateApiRequest)
Ownership Rules
- 404 when the provided link slug does not exist.
- 403 when the slug exists but belongs to another user.
- 200 with analytics payload for owned links.
Response Example
{
"id": "launch",
"clicks": 42,
"countries": ["US", "IN"],
"timeline": [
{
"date": "2026-03-14",
"clicks": 12,
"uniqueVisitors": 10
}
]
}Data Window
The current endpoint returns a 30-day timeline with daily clicks and unique visitors.
Quota Limits
Understand plan limits and quota-exhaustion behavior.
Business
500
total API requests per active purchase
Enterprise
5000
total API requests per active purchase
Enforcement
{
"error": "API quota exceeded"
}Usage Tracking
Quota usage and totals are captured on each request and can be surfaced in request logs.
Errors
Common failure responses and troubleshooting pointers.
Every error payload follows a lightweight JSON shape to simplify client-side handling.
Payload Format
{
"error": "Invalid API key"
}{
"error": "API quota exceeded"
}Common Status Codes
- 400 validation failure
- 401 invalid API key
- 403 plan disabled, unauthorized resource, or quota exceeded
- 404 link not found
- 409 duplicate custom slug
- 429 rate limit exceeded
- 500 unexpected server failure
Debugging Checklist
- Confirm API key and plan status in /dashboard/api
- Verify you are calling /api/v1 routes with a Bearer header
- Check request body JSON and required fields
- Inspect returned error message and status code
Code Examples
Production-ready examples for curl, JavaScript, and Node.js.
Use these snippets as a starting point and inject API keys from your secure runtime environment.
curl
curl https://xurl.eu.cc/api/v1/links \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com"}'JavaScript
const response = await fetch("https://xurl.eu.cc/api/v1/links", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({
url: "https://example.com",
title: "Launch page"
})
});
const data = await response.json();
console.log(data);Node.js
import fetch from "node-fetch";
const response = await fetch("https://xurl.eu.cc/api/v1/links", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({ url: "https://example.com" })
});
console.log(await response.json());