Authentication
All API requests require authentication using a Bearer token. Generate your API token from your account settings or via the API.
Authorization: Bearer your_api_token_here
Paid Subscription Required
API access requires a paid subscription (Starter, Pro, Business, or Enterprise). Free accounts cannot use the Developer API.
Token Permissions
When creating API tokens, you can specify granular abilities to limit what the token can access:
| Ability | Access |
|---|---|
* |
Full access to all endpoints |
links:read |
View and list links |
links:write |
Create, update, and delete links |
analytics:read
|
View click analytics and metrics |
qr:read |
View and list QR codes |
qr:write |
Create, update, and delete QR codes |
user:read |
View profile, tokens, and teams |
user:write |
Update profile and manage tokens |
Token Security
Keep your API tokens secure. Never share them in public repositories or client-side code. Use limited abilities for integrations that don't need full access.
Rate Limiting
API requests are rate-limited based on your subscription plan:
| Plan | Rate Limit |
|---|---|
| Starter | 60 requests/minute |
| Pro / Business | 120 requests/minute |
| Enterprise | 500 requests/minute |
Response Format
All responses are returned in JSON format with a consistent structure.
Success Response
{
"status": true,
"message": "Success",
"data": { ... }
}
Paginated Response
{
"status": true,
"message": "Success",
"data": [ ... ],
"meta": {
"pagination": {
"current_page": 1,
"per_page": 25,
"total": 100,
"total_pages": 4,
"has_more": true
}
}
}
Error Response
{
"status": false,
"message": "An error occurred",
"data": [],
"errors": {
"long_url": ["The long url field is required."]
}
}
Error Codes
| HTTP Status | Description |
|---|---|
| 401 | Unauthenticated - Invalid or missing token |
| 403 | Forbidden - Insufficient permissions |
| 404 | Not Found - Resource not found |
| 422 | Validation Error - Request validation failed |
| 429 | Rate Limit Exceeded - Too many requests |
| 500 | Internal Error - Server error |
Links
/v1/shorten
Quick-shorten a URL with minimal parameters.
Request
{
"long_url": "https://example.com/very/long/url"
}
Response (201 Created)
{
"status": true,
"message": "Link created successfully.",
"data": {
"id": 42,
"slug": "aB3x7kL",
"link": "https://lynklens.com/aB3x7kL",
"long_url": "https://example.com/very/long/url",
"title": "Example",
"status": "active",
"source": "api",
"has_qr_attached": false,
"created_at": "2025-12-27T10:00:00+00:00"
}
}
/v1/links
Create a link with full customization options.
Request Body
| Field | Type | Description |
|---|---|---|
long_url |
string | Required. The destination URL |
title |
string | Custom title for the link |
description |
string | Description (max 1000 chars) |
tags |
array | Array of tags for categorization |
expires_at |
datetime | Expiration date (ISO 8601) |
team_id |
integer | Assign to a team |
Response same as POST /v1/shorten
/v1/links
List all links for the authenticated user.
Query Parameters
page |
Page number (default: 1) |
per_page |
Items per page, max 100 (default: 25) |
status |
Filter: active, inactive, archived |
source |
Filter: web, api |
query |
Search in title, URL, or slug |
tags |
Filter by tags (comma-separated) |
Response (200 OK)
{
"status": true,
"message": "Success",
"data": [
{
"id": 42,
"slug": "aB3x7kL",
"link": "https://lynklens.com/aB3x7kL",
"long_url": "https://example.com/page",
"title": "Example",
"status": "active",
"source": "api",
"has_qr_attached": true
}
],
"meta": {
"pagination": {
"current_page": 1,
"per_page": 25,
"total": 150,
"total_pages": 6,
"has_more": true
}
}
}
/v1/links/{slug}
Retrieve a specific link by its slug. Includes total click count.
Response (200 OK)
{
"status": true,
"data": {
"slug": "aB3x7kL",
"link": "https://lynklens.com/aB3x7kL",
"long_url": "https://example.com/page",
"title": "Example",
"tags": ["marketing", "campaign"],
"status": "active",
"source": "api",
"total_clicks": 1543
}
}
/v1/links/{slug}
Update a link's properties. All fields are optional.
Request
{
"long_url": "https://example.com/updated",
"title": "Updated Title",
"tags": ["updated"],
"status": "inactive"
}
Response (200 OK)
{
"status": true,
"message": "Link updated successfully.",
"data": { /* updated link object */ }
}
/v1/links/{slug}
Delete a link and its associated files (favicon, QR code).
Response (200 OK)
{
"status": true,
"message": "Link deleted successfully.",
"data": []
}
/v1/expand
Expand a short link to get the original long URL.
Request
{
"slug": "aB3x7kL"
}
Response (200 OK)
{
"status": true,
"data": {
"slug": "aB3x7kL",
"link": "https://lynklens.com/aB3x7kL",
"long_url": "https://example.com/page",
"created_at": "2025-12-27T10:00:00+00:00"
}
}
Analytics
All analytics endpoints accept these query parameters:
unit (minute/hour/day/week/month), units (number of periods 1-365),
size (results limit).
/v1/links/{slug}/clicks
Get click counts over time, grouped by time period.
Response (200 OK)
{
"status": true,
"data": {
"clicks": [
{ "date": "2025-12-27", "clicks": 45 },
{ "date": "2025-12-26", "clicks": 72 },
{ "date": "2025-12-25", "clicks": 31 }
],
"unit": "day",
"units": 7
}
}
/v1/links/{slug}/clicks/summary
Get total click count for a specified time period.
Response (200 OK)
{
"status": true,
"data": {
"total_clicks": 1543,
"unit": "month",
"units": 1
}
}
/v1/links/{slug}/countries
Get clicks breakdown by country.
Response (200 OK)
{
"status": true,
"data": {
"metrics": [
{ "country": "United States", "clicks": 523 },
{ "country": "United Kingdom", "clicks": 234 },
{ "country": "Germany", "clicks": 156 }
]
}
}
/v1/links/{slug}/devices
Get clicks breakdown by device type (desktop, mobile, tablet).
Response (200 OK)
{
"status": true,
"data": {
"metrics": [
{ "device": "mobile", "clicks": 823 },
{ "device": "desktop", "clicks": 612 },
{ "device": "tablet", "clicks": 108 }
]
}
}
Other Analytics Endpoints
/v1/links/{slug}/cities - Breakdown by city
/v1/links/{slug}/referrers - Breakdown by referrer source
/v1/links/{slug}/browsers - Breakdown by browser
/v1/links/{slug}/operating-systems - Breakdown by OS
All return the same response format as /countries and /devices.
QR Codes
/v1/qr-codes
Create a QR code for an existing link.
Request Body
link_slug |
Required. The link's slug |
color |
QR color hex (default: #000000) |
background_color |
Background hex (default: #ffffff) |
size |
Size in pixels, 100-1000 (default: 300) |
format |
png or svg (default: png) |
Response (201 Created)
{
"status": true,
"message": "QR code created successfully.",
"data": {
"link_slug": "aB3x7kL",
"qr_image_url": "https://lynklens.com/storage/qr/aB3x7kL.png",
"color": "#000000",
"size": 300
}
}
/v1/qr-codes/{slug}
Get QR code details including total scan count.
Response (200 OK)
{
"status": true,
"data": {
"link_slug": "aB3x7kL",
"link_url": "https://lynklens.com/aB3x7kL",
"long_url": "https://example.com/page",
"title": "Example",
"qr_image_url": "https://lynklens.com/storage/qr/aB3x7kL.png",
"total_scans": 234
}
}
Other QR Code Endpoints
/v1/qr-codes - List all QR codes (paginated)
/v1/qr-codes/{slug}/image - Get QR image file or base64
/v1/qr-codes/{slug} - Regenerate with new settings
/v1/qr-codes/{slug} - Remove QR code from link
/v1/qr-codes/{slug}/scans - Scan counts over time
/v1/qr-codes/{slug}/scans/summary - Total scan count
User
/v1/user
Get authenticated user information including subscription and stats.
Response (200 OK)
{
"status": true,
"data": {
"id": 1,
"name": "John Doe",
"email": "john@example.com",
"is_verified": true,
"subscription": { "plan": "Pro", "status": "active" },
"stats": { "total_links": 150, "total_qr_codes": 45 }
}
}
/v1/user/tokens
Create a new API token. Save the token immediately - it won't be shown again!
Response (201 Created)
{
"status": true,
"data": {
"token": "1|abc123def456...",
"id": 5,
"name": "My Integration"
}
}
Other User Endpoints
/v1/user - Update user profile
/v1/user/limits - Get API rate limits
/v1/user/tokens - List your API tokens
/v1/user/tokens/{id} - Revoke a token
Groups (Teams)
/v1/groups
List all teams the authenticated user has access to.
Response (200 OK)
{
"status": true,
"data": [
{
"id": 1,
"name": "Marketing Team",
"personal_team": false,
"role": "admin",
"is_owner": true
},
{
"id": 2,
"name": "Personal",
"personal_team": true,
"role": "owner",
"is_owner": true
}
]
}
Coming Soon
Additional group endpoints for accessing team-specific links, QR codes, and analytics will be available in a future API version.
Need Help?
Have questions about the API? We're here to help.
Contact Support