API & Webhooks

Integrate ShrinkLink into your applications with our RESTful API. Automate link creation, retrieve analytics, and receive real-time notifications via webhooks.

API Overview

The ShrinkLink API enables you to programmatically manage your links, retrieve analytics, and integrate link shortening into your workflows. All API endpoints use JSON for requests and responses.

RESTful
Standard HTTP methods
Secure
API key authentication
Rate Limited
Fair usage policies

Authentication

All API requests require authentication using an API key. Include your API key in the request header:

Authorization: Bearer YOUR_API_KEY

Getting Your API Key

  1. Go to SettingsAPI Keys
  2. Click Generate API Key
  3. Copy and securely store your key
Security: Keep your API key secret. Never expose it in client-side code or public repositories. Regenerate immediately if compromised.

API Key Scopes

Create keys with specific permissions:

links:readRead link data
links:writeCreate and modify links
analytics:readAccess analytics data
domains:readList custom domains
domains:writeManage custom domains

Base URL

https://sl.cloudcopy.me/api/v1
POST /api/v1/links

Request Body

{
  "url": "https://example.com/my-long-url",
  "slug": "my-custom-slug",       // optional
  "title": "My Link Title",        // optional
  "domain_id": "dom_123",          // optional
  "tags": ["marketing", "email"],  // optional
  "password": "secret123",         // optional
  "expires_at": "2024-12-31T23:59:59Z",  // optional
  "max_clicks": 1000               // optional
}

Response

{
  "success": true,
  "data": {
    "id": "lnk_abc123",
    "short_url": "https://sl.cloudcopy.me/my-custom-slug",
    "original_url": "https://example.com/my-long-url",
    "slug": "my-custom-slug",
    "title": "My Link Title",
    "clicks": 0,
    "created_at": "2024-01-15T10:30:00Z",
    "expires_at": "2024-12-31T23:59:59Z"
  }
}
GET /api/v1/links/{link_id}

Response

{
  "success": true,
  "data": {
    "id": "lnk_abc123",
    "short_url": "https://sl.cloudcopy.me/my-custom-slug",
    "original_url": "https://example.com/my-long-url",
    "slug": "my-custom-slug",
    "title": "My Link Title",
    "clicks": 1234,
    "unique_clicks": 987,
    "created_at": "2024-01-15T10:30:00Z",
    "updated_at": "2024-01-20T15:45:00Z"
  }
}
GET /api/v1/links

Query Parameters

pagePage number (default: 1)
per_pageResults per page (max: 100)
searchSearch by URL or title
tagFilter by tag
domain_idFilter by domain
PATCH /api/v1/links/{link_id}

Request Body

{
  "url": "https://example.com/new-destination",
  "title": "Updated Title",
  "is_active": false
}
DELETE /api/v1/links/{link_id}

Analytics API

GET /api/v1/links/{link_id}/stats

Query Parameters

start_dateStart of date range (ISO 8601)
end_dateEnd of date range (ISO 8601)
group_byday, week, month

Response

{
  "success": true,
  "data": {
    "total_clicks": 5432,
    "unique_clicks": 3210,
    "by_date": [
      {"date": "2024-01-15", "clicks": 234},
      {"date": "2024-01-16", "clicks": 312}
    ],
    "by_country": [
      {"country": "US", "clicks": 2100},
      {"country": "UK", "clicks": 890}
    ],
    "by_device": [
      {"device": "mobile", "clicks": 3200},
      {"device": "desktop", "clicks": 2000}
    ],
    "by_referrer": [
      {"referrer": "twitter.com", "clicks": 1500},
      {"referrer": "direct", "clicks": 1200}
    ]
  }
}

Get Click Log

GET /api/v1/links/{link_id}/clicks

Returns individual click records with timestamp, location, device, and referrer data.

Domains API

List Domains

GET /api/v1/domains

Add Domain

POST /api/v1/domains

Request Body

{
  "domain": "links.example.com"
}

Bulk Operations

Bulk Create Links

POST /api/v1/links/bulk

Request Body

{
  "links": [
    {"url": "https://example.com/page1", "title": "Page 1"},
    {"url": "https://example.com/page2", "title": "Page 2"},
    {"url": "https://example.com/page3", "title": "Page 3"}
  ]
}

Create up to 100 links in a single request.

Webhooks

Receive real-time notifications when events occur. Configure webhook endpoints to integrate ShrinkLink events into your systems.

Setting Up Webhooks

  1. Go to SettingsWebhooks
  2. Click Add Webhook
  3. Enter your endpoint URL
  4. Select events to subscribe to
  5. Save and test

Available Events

link.clicked Fired when a link receives a click
link.created Fired when a new link is created
link.updated Fired when a link is modified
link.deleted Fired when a link is deleted
conversion.recorded Fired when a conversion is tracked

Webhook Payload

{
  "event": "link.clicked",
  "timestamp": "2024-01-15T10:30:45Z",
  "data": {
    "link_id": "lnk_abc123",
    "short_url": "https://sl.cloudcopy.me/promo",
    "click": {
      "country": "US",
      "city": "New York",
      "device": "mobile",
      "browser": "Chrome",
      "referrer": "twitter.com"
    }
  }
}

Webhook Security

Verify webhook authenticity using the signature header:

X-Signature: sha256=abc123...

Compute HMAC-SHA256 of the request body using your webhook secret and compare with the signature header.

Rate Limits

API requests are rate limited to ensure fair usage:

Standard100 requests per minute
Pro500 requests per minute
EnterpriseCustom limits

Rate limit headers are included in every response:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1705312800

Error Handling

Errors return appropriate HTTP status codes with JSON details:

{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "URL is required",
    "field": "url"
  }
}

Common Error Codes

400Bad Request - Invalid parameters
401Unauthorized - Invalid or missing API key
403Forbidden - Insufficient permissions
404Not Found - Resource doesn't exist
429Too Many Requests - Rate limit exceeded
500Server Error - Something went wrong

SDKs & Libraries

Official and community SDKs for popular languages:

  • JavaScript/Node.js: npm install shrinklink-sdk
  • Python: pip install shrinklink
  • PHP: composer require shrinklink/sdk
  • Ruby: gem install shrinklink

Code Examples

JavaScript (Node.js)

const response = await fetch('https://sl.cloudcopy.me/api/v1/links', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    url: 'https://example.com/my-page',
    title: 'My Awesome Link'
  })
});

const data = await response.json();
console.log(data.data.short_url);

Python

import requests

response = requests.post(
    'https://sl.cloudcopy.me/api/v1/links',
    headers={'Authorization': 'Bearer YOUR_API_KEY'},
    json={
        'url': 'https://example.com/my-page',
        'title': 'My Awesome Link'
    }
)

data = response.json()
print(data['data']['short_url'])

cURL

curl -X POST https://sl.cloudcopy.me/api/v1/links \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/my-page","title":"My Link"}'

Best Practices

Use Scoped Keys

Create separate API keys with minimal permissions for different use cases.

Handle Rate Limits

Implement exponential backoff when you receive 429 responses.

Verify Webhooks

Always verify webhook signatures before processing events.

Cache Responses

Cache analytics data locally to reduce API calls and improve performance.

Manage Your Data

Learn about bulk import, export, and organizing your links with tags and folders.

Data Management