Public REST API Reference
The Linkzly REST API lets you create, manage, and analyze all of your Linkzly resources programmatically. This reference covers authentication, rate limiting, p
Public REST API Reference
The Linkzly REST API lets you create, manage, and analyze all of your Linkzly resources programmatically. This reference covers authentication, rate limiting, pagination, and the available public endpoints. You can also explore the full interactive API documentation from within the Linkzly console at API Keys → API Docs (/dashboard/api-keys/docs).
16.1 Authentication
The Linkzly API supports two authentication methods. Both are accepted on all public API endpoints.
Method 1 — Bearer Token (Recommended)
Authorization: Bearer lzly_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Method 2 — X-API-Key Header
X-API-Key: lzly_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Use the API key you created under API Keys in the console. The key must have the appropriate permission scope for each endpoint you call.
API Key format: lzly_[live|test]_[32-character-id]
| Response | Meaning |
|---|---|
401 Unauthorized |
The API key is missing, malformed, expired, or revoked |
403 Forbidden |
The API key is valid, but it does not have the required permission for this endpoint |
16.2 Base URL
The Linkzly public API uses the prefix /api/use:
https://your-linkzly-instance.com/api/use
All endpoints are served over HTTPS. HTTP requests are automatically upgraded to HTTPS. The API version is v1.
Interactive Docs: The OpenAPI 3.0 specification is available at
/api/docs/openapi.json. A Swagger UI is available at/api/docs. A Postman collection can be downloaded at{API_BASE_URL}/docs/postman/collection.json.
16.3 Permissions
API keys are granted granular permissions at the time of creation. Each permission follows the format resource:action.
The 11 supported permissions are:
| Permission | Description |
|---|---|
links:read |
Read and list short links |
links:write |
Create and update short links |
links:delete |
Delete short links |
analytics:read |
Read analytics data |
qr:read |
Read and list QR codes |
qr:write |
Create and update QR codes |
qr:delete |
Delete QR codes |
domains:read |
Read and list custom domains |
domains:write |
Add and update custom domains |
domains:delete |
Delete custom domains |
webhooks:read |
Read and list webhooks |
webhooks:write |
Create, update, and delete webhooks |
16.4 Rate Limiting
Every response includes rate limit headers so you can track your usage in real time.
| Header | Description |
|---|---|
X-RateLimit-Limit |
Total number of requests allowed in the current time window |
X-RateLimit-Remaining |
Requests remaining before hitting the limit |
X-RateLimit-Reset |
Unix timestamp (seconds) when the rate limit window resets |
When you exceed the rate limit, the API returns 429 Too Many Requests along with a Retry-After header indicating how many seconds to wait before retrying.
Rate limits are tiered by scope: per IP address, per authenticated user, per organization, and per API key. API keys have a configurable rate limit (default: 1,000 requests/hour). The limit window can be set to per minute, per hour, or per day. Your per-key rate limit is configured in the API Keys console.
16.5 Idempotency
To prevent duplicate operations when retrying requests, include an idempotency key:
X-Idempotency-Key: <uuid>
Supply a unique UUID (v4 recommended) for each distinct operation. If a request with the same idempotency key is submitted more than once, the API returns the same response as the original request without performing the operation a second time.
16.6 Pagination
All list endpoints support pagination. Pass query parameters to control page size and position.
| Parameter | Description |
|---|---|
page |
Page number (integer, starts at 1) |
limit / perPage |
Number of results per page. Accepted values: 10, 20, 50, 100 |
Response Shape
Every paginated response wraps results in the following envelope:
{
"data": [ ... ],
"total": 243,
"page": 1,
"perPage": 20,
"hasMore": true
}
| Field | Description |
|---|---|
data |
Array of resource objects for the current page |
total |
Total count of matching records across all pages |
page |
The current page number |
perPage |
Number of records per page |
hasMore |
true if there are more pages after the current one |
16.7 Public API Endpoints
The public API (/api/use) exposes four verified endpoints for third-party integrations:
| Method | Endpoint | Description | Required Permission |
|---|---|---|---|
GET |
/api/use |
API discovery — returns API version and available endpoints | None |
POST |
/api/use/links |
Create a short link | links:write |
GET |
/api/use/links |
List all short links | links:read |
GET |
/api/use/analytics/links/:id |
Get analytics for a specific link | analytics:read |
Note: Additional endpoints for QR codes, custom domains, webhooks, and other resources are documented in the interactive console at
/dashboard/api-keys/docsand in the OpenAPI spec at/api/docs/openapi.json.
GET /api/use — API Discovery
Returns the current API version, available endpoints, and API health status.
Authentication: Not required.
Returns: API metadata object including version, available routes, and status.
POST /api/use/links — Create a Short Link
Required Permission: links:write
Body Fields
| Field | Type | Required | Description |
|---|---|---|---|
destinationUrl |
string | Yes | The full URL to redirect to. Must begin with http:// or https://. Maximum 2,048 characters. |
title |
string | No | Internal label for the link. Maximum 255 characters. |
customSlug |
string | No | Custom short code (e.g., summer-sale). Alphanumeric, hyphens, and underscores. Auto-generated if omitted. |
expiresAt |
string | No | ISO 8601 datetime after which the link stops redirecting. Must be a future date. |
tags |
string[] | No | Array of tag strings for filtering and categorization. |
metadata |
object | No | Arbitrary key-value metadata to attach to the link. |
Returns: The full link object including id, shortUrl, shortCode, destinationUrl, status, clicks, createdAt, and updatedAt.
Example Request
curl -X POST https://your-linkzly-instance.com/api/use/links \
-H "Authorization: Bearer lzly_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"destinationUrl": "https://example.com/landing-page",
"title": "Summer Campaign",
"customSlug": "summer-sale",
"tags": ["marketing", "summer"]
}'
Example Response
{
"id": "lnk_abc123",
"shortUrl": "https://linkz.ly/summer-sale",
"shortCode": "summer-sale",
"destinationUrl": "https://example.com/landing-page",
"title": "Summer Campaign",
"status": "active",
"clicks": 0,
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-15T10:30:00Z"
}
GET /api/use/links — List Short Links
Required Permission: links:read
Query Parameters
| Parameter | Type | Description |
|---|---|---|
page |
integer | Page number (starts at 1) |
limit |
integer | Results per page (10, 20, 50, 100) |
search |
string | Full-text search across title, short code, and destination URL |
status |
string | Filter by status: active, inactive, or expired |
tag |
string | Filter by tag name |
sortBy |
string | Sort field: createdAt or clicks |
sortOrder |
string | Sort direction: asc or desc |
Returns: A paginated array of link objects.
GET /api/use/analytics/links/:id — Link Analytics
Required Permission: analytics:read
Path Parameters
| Parameter | Description |
|---|---|
id |
The ID of the short link to retrieve analytics for |
Query Parameters
| Parameter | Type | Description |
|---|---|---|
startDate |
string | Start of the date range (ISO 8601) |
endDate |
string | End of the date range (ISO 8601) |
interval |
string | Time bucket size: hour, day, or week |
Response Fields
The analytics response includes summary metrics and breakdowns:
| Field | Description |
|---|---|
totalClicks |
Total click events in the selected period |
uniqueVisitors |
Count of distinct visitors |
botDetection |
Bot traffic count and percentage |
responseTime |
Average response time in milliseconds |
bounceRate |
Percentage of single-interaction visits |
geography[] |
Click breakdown by country and region |
devices[] |
Breakdown by device type (Mobile, Desktop, Tablet) |
browsers[] |
Browser breakdown with click counts and percentages |
referrers[] |
Top referring domains with click counts |
timeSeries[] |
Time-series click data at the requested interval |
utmSources[] |
UTM source values with click counts |
utmMediums[] |
UTM medium values with click counts |
utmCampaigns[] |
UTM campaign values with click counts |
16.8 Additional Endpoints (Console API)
The Linkzly console uses a broader internal API with additional resource endpoints. These are documented in the interactive API reference at /dashboard/api-keys/docs and in the OpenAPI 3.0 spec at /api/docs/openapi.json.
The full console API covers the following resources with their associated permissions:
| Resource | Available Permissions |
|---|---|
| Short Links | links:read, links:write, links:delete |
| QR Codes | qr:read, qr:write, qr:delete |
| Custom Domains | domains:read, domains:write, domains:delete |
| Analytics | analytics:read |
| Webhooks | webhooks:read, webhooks:write |
For endpoint details, request parameters, response shapes, and code examples in JavaScript, Python, Go, PHP, cURL, and Ruby, open the in-console documentation via API Keys → API Docs in the Linkzly dashboard.
16.9 Webhooks
Webhooks allow Linkzly to push real-time event notifications to your server. Configure and manage webhooks from the Webhooks page in the console (/dashboard/webhooks), or use the Webhooks API endpoints documented in the console API reference.
Webhooks are managed through your API key with the webhooks:read and webhooks:write permissions.
Webhook Payload Signing
Every webhook delivery is signed with HMAC-SHA256 to allow your server to verify the payload authenticity.
| Header | Value |
|---|---|
X-Webhook-Signature |
sha256=<signature> |
The signature is computed over the string {webhook_id}.{timestamp}.{body}. Verify it on your server by recomputing the HMAC-SHA256 with your webhook secret and comparing the result to the header value.
16.10 Error Responses
HTTP Status Codes
| Code | Meaning |
|---|---|
200 |
OK — Request was successful |
201 |
Created — A new resource was created |
204 |
No Content — Delete was successful; no response body |
400 |
Bad Request — Validation error; check the details array in the response |
401 |
Unauthorized — API key is missing, invalid, expired, or revoked |
403 |
Forbidden — API key is valid but does not have the required permission |
404 |
Not Found — The resource does not exist, or it belongs to a different organization |
409 |
Conflict — A resource with the same identifier already exists (e.g., duplicate short code or domain) |
422 |
Unprocessable Entity — The request body is well-formed but semantically invalid |
429 |
Too Many Requests — Rate limit exceeded; check the Retry-After header |
500 |
Internal Server Error — Contact support and include the request path and timestamp from the response |
Error Response Body Format
All error responses use the same JSON structure:
{
"error": "ErrorType",
"message": "Human-readable message",
"statusCode": 400,
"timestamp": "2024-01-15T10:30:00Z",
"path": "/api/use/links",
"details": []
}
| Field | Description |
|---|---|
error |
Machine-readable error type (e.g., ValidationError, NotFound, RateLimitExceeded) |
message |
A short, human-readable summary of what went wrong |
statusCode |
The HTTP status code for this error |
timestamp |
ISO 8601 timestamp of when the error occurred |
path |
The request path that produced the error |
details |
Array of additional error detail objects (present for validation errors) |
16.11 SDK Libraries
Official SDKs are available via standard package managers:
| Language | Install Command |
|---|---|
| JavaScript / Node.js | npm install @linkzly/sdk |
| Python | pip install linkzly |
| Go | go get github.com/linkzly/linkzly-go |
| PHP | composer require linkzly/linkzly-php |
| Ruby | gem install linkzly |
Code examples for all languages are available in the in-console documentation (API Keys → API Docs) and in the GitHub examples repository at https://github.com/linkzly/examples.
16.12 API Key Tester
Use the interactive Test API Key tool at /dashboard/api-keys/test to:
- Validate your API key format and active status
- View the rate limits and permissions assigned to a key
- See which endpoints the key is authorized to access
- Test key authentication in real time before writing integration code
Was this helpful?
Help us improve our documentation