Short Link API
Create and manage short links programmatically with RESTful API
Overview
The Short Link API allows you to create, retrieve, update, and list short links programmatically using API key authentication. All endpoints follow RESTful design principles.
Playground
You can try the API endpoints in the API Playground.
Authentication
All endpoints require API key authentication. Use your API key in one of two ways:
-
Authorization Header (Recommended):
Authorization: Bearer YOUR_API_KEY -
Query Parameter:
?key=YOUR_API_KEY
Rate Limits
Rate limits are configured based on your subscription tier:
- Free Plan: 200 requests per hour
- Pro Plan: 2000 requests per hour
- Lifetime Plan: 5000 requests per hour
Monthly Quotas
Link creation is subject to monthly quotas based on your subscription:
- Free Plan: 50 links per month
- Pro Plan: 1,000 links per month
- Lifetime Plan: Unlimited
Endpoints
List Links
GET /api/v1/linksRetrieve a paginated list of your short links with filtering and sorting options.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
page | number | 1 | Page number (minimum: 1) |
limit | number | 10 | Items per page (1-100) |
search | string | - | Search in slug, target URL, description |
sortBy | string | createdAt | Sort field: slug, createdAt, clicks, domain |
sortOrder | string | desc | Sort order: asc or desc |
domain | string | - | Filter by domain |
tag | string | - | Filter by tag |
active | boolean | - | Filter by active status |
visible | boolean | - | Filter by visibility |
Example Request
curl -X GET "https://like.do/api/v1/links?page=1&limit=10&sortBy=clicks&sortOrder=desc" \
-H "Authorization: Bearer YOUR_API_KEY"Success Response (200 OK)
{
"success": true,
"data": {
"items": [
{
"id": "abc123xyz",
"slug": "example",
"targetUrl": "https://example.com",
"domain": "ig.do",
"shortUrl": "https://ig.do/example",
"description": "Example link",
"tag": "marketing",
"clicks": 42,
"active": true,
"visible": false,
"expiration": "-1",
"createdAt": "2026-01-04T12:00:00.000Z",
"updatedAt": "2026-01-04T12:00:00.000Z"
}
],
"pagination": {
"page": 1,
"limit": 10,
"total": 25,
"totalPages": 3
}
}
}Create Link
POST /api/v1/linksCreate a new short link. Subject to monthly quota limits.
Request Body
{
"slug": "my-link",
"targetUrl": "https://example.com",
"domain": "ig.do",
"visible": false,
"active": true,
"expiration": "-1",
"password": "123456",
"description": "My short link",
"tag": "marketing"
}Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
slug | string | Yes | URL slug (3-100 characters, alphanumeric, hyphens, underscores) |
targetUrl | string | Yes | Destination URL (must be valid URL) |
domain | string | Yes | Domain to use for short link |
visible | boolean | No | Whether link is visible in public listings (default: false) |
active | boolean | No | Whether link is active (default: true) |
expiration | string | No | Expiration setting (default: "-1" for never) |
password | string | No | 6-character password for link protection |
description | string | No | Link description (max 500 characters) |
tag | string | No | Tag for categorization (max 50 characters) |
Example Request
curl -X POST https://like.do/api/v1/links \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"slug": "example",
"targetUrl": "https://example.com",
"domain": "ig.do"
}'Success Response (201 Created)
{
"success": true,
"data": {
"id": "abc123xyz",
"slug": "example",
"targetUrl": "https://example.com",
"domain": "ig.do",
"shortUrl": "https://ig.do/example",
"visible": false,
"active": true,
"expiration": "-1",
"createdAt": "2026-01-04T12:00:00.000Z"
}
}Error Response - Quota Exceeded (403 Forbidden)
{
"success": false,
"error": "You have reached your monthly limit of 50 links on the Free plan. Upgrade to Pro for 1,000 links/month or Lifetime for unlimited links.",
"quota": {
"planType": "free",
"currentCount": 50,
"limit": 50,
"remaining": 0
}
}Get Link
GET /api/v1/links/{id}Retrieve details of a specific short link by ID.
Example Request
curl -X GET https://like.do/api/v1/links/abc123xyz \
-H "Authorization: Bearer YOUR_API_KEY"Success Response (200 OK)
{
"success": true,
"data": {
"id": "abc123xyz",
"slug": "example",
"targetUrl": "https://example.com",
"domain": "ig.do",
"shortUrl": "https://ig.do/example",
"description": "Example link",
"tag": "marketing",
"clicks": 42,
"active": true,
"visible": false,
"expiration": "-1",
"createdAt": "2026-01-04T12:00:00.000Z",
"updatedAt": "2026-01-04T12:00:00.000Z"
}
}Update Link
PUT /api/v1/links/{id}Update an existing short link. You can only update links you own.
Request Body
{
"targetUrl": "https://new-example.com",
"description": "Updated description",
"tag": "updated-tag",
"active": true,
"visible": false,
"password": "newpwd",
"expiration": "-1"
}Parameters
All parameters are optional. Only include the fields you want to update.
| Parameter | Type | Description |
|---|---|---|
targetUrl | string | New destination URL |
description | string | New description (max 500 characters) |
tag | string | New tag (max 50 characters) |
active | boolean | Active status |
visible | boolean | Visibility status |
password | string | New 6-character password (or null to remove) |
expiration | string | Expiration setting |
Example Request
curl -X PUT https://like.do/api/v1/links/abc123xyz \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"targetUrl": "https://new-example.com",
"description": "Updated link"
}'Success Response (200 OK)
{
"success": true,
"data": {
"id": "abc123xyz",
"updatedAt": "2026-01-04T13:00:00.000Z"
}
}Domain Access
Access to domains is based on your subscription tier:
- Free Domains (
ig.do): Available to all users - Pro Domains (
kfc.sh,uv.do): Requires Pro subscription or Lifetime plan - Custom Domains: User-created domains available based on subscription
If you attempt to use a Pro domain without proper subscription, you'll receive a 403 error.
Error Responses
401 Unauthorized - Missing API Key
{
"success": false,
"error": "Missing API key. Provide it via Authorization header (Bearer token) or ?key= query parameter"
}401 Unauthorized - Invalid API Key
{
"success": false,
"error": "Invalid or expired API key: [error details]"
}400 Bad Request - Invalid Data
{
"success": false,
"error": "Invalid request data",
"details": [
{
"path": ["slug"],
"message": "Slug must be at least 3 characters"
}
]
}403 Forbidden - Domain Permission
{
"success": false,
"error": "You don't have permission to use the domain \"kfc.sh\". Premium domains require an active Pro subscription or Lifetime plan."
}404 Not Found
{
"success": false,
"error": "Link not found or access denied"
}409 Conflict - Slug Exists
{
"success": false,
"error": "A link with this slug already exists"
}Code Examples
JavaScript (Fetch)
// Create a link
const response = await fetch('https://like.do/api/v1/links', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
slug: 'example',
targetUrl: 'https://example.com',
domain: 'ig.do',
}),
});
const data = await response.json();
console.log(data);
// Get link details
const linkId = data.data.id;
const getResponse = await fetch(`https://like.do/api/v1/links/${linkId}`, {
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
},
});
const linkData = await getResponse.json();
console.log(linkData);
// Update link
const updateResponse = await fetch(`https://like.do/api/v1/links/${linkId}`, {
method: 'PUT',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
description: 'Updated description',
}),
});
const updateData = await updateResponse.json();
console.log(updateData);Python (requests)
import requests
api_key = 'YOUR_API_KEY'
base_url = 'https://like.do/api/v1/links'
headers = {
'Authorization': f'Bearer {api_key}',
'Content-Type': 'application/json',
}
# Create a link
data = {
'slug': 'example',
'targetUrl': 'https://example.com',
'domain': 'ig.do',
}
response = requests.post(base_url, headers=headers, json=data)
print(response.json())
# Get link details
link_id = response.json()['data']['id']
get_response = requests.get(f'{base_url}/{link_id}', headers=headers)
print(get_response.json())
# Update link
update_data = {
'description': 'Updated description',
}
update_response = requests.put(f'{base_url}/{link_id}', headers=headers, json=update_data)
print(update_response.json())
# List links
list_response = requests.get(f'{base_url}?page=1&limit=10', headers=headers)
print(list_response.json())Creating API Keys
- Navigate to Settings > API Keys in your dashboard
- Click Create API Key
- Configure your rate limits based on your plan
- Save your API key securely (it's only shown once)
Best Practices
- Store API keys securely: Never commit API keys to version control
- Use environment variables: Store keys in
.envfiles or secure vaults - Monitor rate limits: Track your usage to avoid hitting limits
- Validate slugs: Check slug availability before creation to avoid conflicts
- Handle errors gracefully: Implement proper error handling for quota limits
- Use HTTPS: Always use secure connections for API requests
- Check quota: Monitor your monthly link creation quota
- Batch operations: Use list endpoint efficiently for bulk operations
Notes
- All links created via API are marked with
channel: "api"for tracking - Slug uniqueness is enforced globally across all users and domains
- Reserved words (e.g.,
api,admin,dashboard) cannot be used as slugs - Monthly quotas reset at the beginning of each month
- Quota limits are based on the first day of subscription in each month
- API call logging is available for Pro and Lifetime users
LikeDo Docs