API Documentation
Integrate ttny.io URL shortener into your applications with our powerful API.
Introduction
The ttny.io API allows you to create, manage, and track short links programmatically. Our RESTful API uses standard HTTP methods and returns responses in JSON format.
Base URL for all API requests:
https://ttny.io/api/v1
API Versioning
The current API version is v1. We maintain backward compatibility within a major version. When we make breaking changes, we'll release a new major version (e.g., v2) and provide migration guides.
Authentication
All API requests require authentication using an API key. You can generate an API key in your ttny.io dashboard under Settings > API.
There are two ways to include your API key in the request:
1. Using the Authorization header with Bearer token
Authorization: Bearer YOUR_API_KEY
2. Using the X-API-KEY header
X-API-KEY: YOUR_API_KEY
API Key Security
Your API key grants full access to your ttny.io account. Keep it secure and never expose it in client-side code or public repositories. If you suspect your API key has been compromised, you can regenerate it in your dashboard.
Keep your API key secure. Do not share it in publicly accessible areas such as GitHub, client-side code, etc.
Rate Limits
To ensure the stability of our service, we apply rate limits to API requests:
- Free accounts: 60 requests per minute
- Pro accounts: 120 requests per minute
- Business accounts: 300 requests per minute
Rate limit information is included in the response headers:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 58
X-RateLimit-Reset: 1617203160
Rate Limit Best Practices
To avoid hitting rate limits, consider implementing these strategies:
- Implement exponential backoff for retries
- Cache frequently accessed data
- Use bulk operations when possible
- Monitor your usage with the rate limit headers
Endpoints
Create Link
Create a new short link.
POST /shorten
Request Parameters
Parameter | Type | Required | Description |
---|---|---|---|
url | string | Yes | The URL to shorten |
custom_url | string | No | Custom alias for the shortened URL |
password | string | No | Password to protect the link |
title | string | No | Title for the link |
description | string | No | Description for the link |
expires_at | string | No | Expiration date (YYYY-MM-DD HH:MM:SS) |
tags | string | No | Comma-separated tags |
Example Request
curl -X POST "https://ttny.io/api/v1/shorten" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"url": "https://example.com/very/long/url/that/needs/shortening",
"custom_url": "mylink",
"title": "My Example Link",
"description": "This is an example link",
"expires_at": "2023-12-31 23:59:59",
"tags": "example,demo"
}'
Example Response
{
"success": true,
"message": "URL shortened successfully",
"data": {
"id": 123,
"destination_url": "https://example.com/very/long/url/that/needs/shortening",
"custom_url": "mylink",
"password": null,
"secondary_link": null,
"tags": "example,demo",
"metadata": {
"title": "My Example Link",
"description": "This is an example link"
},
"is_metadata_enabled": 1,
"expires_at": "2023-12-31 23:59:59",
"views": 0,
"created_at": "2023-05-01 12:34:56",
"updated_at": "2023-05-01 12:34:56",
"short_url": "https://ttny.io/mylink"
}
}
Get All Links
Retrieve all your shortened links with pagination.
GET /links
Query Parameters
Parameter | Type | Default | Description |
---|---|---|---|
limit | integer | 10 | Number of links to return (max 100) |
offset | integer | 0 | Number of links to skip |
tag | string | null | Filter links by tag |
sort | string | created_at | Sort field (created_at, updated_at, views, custom_url, destination_url) |
order | string | DESC | Sort order (ASC, DESC) |
status | string | all | Filter by status (all, active, expired) |
Example Request
curl -X GET "https://ttny.io/api/v1/links?limit=5&offset=0&sort=views&order=DESC" \
-H "Authorization: Bearer YOUR_API_KEY"
Example Response
{
"success": true,
"message": "Links retrieved successfully",
"data": {
"links": [
{
"id": 123,
"destination_url": "https://example.com/page1",
"custom_url": "page1",
"password": null,
"secondary_link": null,
"tags": "example,page",
"metadata": {
"title": "Example Page 1"
},
"is_metadata_enabled": 1,
"expires_at": null,
"views": 150,
"created_at": "2023-04-15 10:30:00",
"updated_at": "2023-04-15 10:30:00",
"short_url": "https://ttny.io/page1",
"status": "active"
},
// More links...
],
"pagination": {
"total": 25,
"limit": 5,
"offset": 0,
"has_more": true
}
}
}
Get Link
Retrieve information about a specific short link.
GET /links/{id}
Path Parameters
Parameter | Type | Required | Description |
---|---|---|---|
id | integer | Yes | The ID of the link to retrieve |
Example Request
curl -X GET "https://ttny.io/api/v1/links/123" \
-H "Authorization: Bearer YOUR_API_KEY"
Example Response
{
"success": true,
"message": "Link retrieved successfully",
"data": {
"id": 123,
"destination_url": "https://example.com/page1",
"custom_url": "page1",
"password": null,
"secondary_link": null,
"tags": "example,page",
"metadata": {
"title": "Example Page 1"
},
"is_metadata_enabled": 1,
"expires_at": null,
"views": 150,
"created_at": "2023-04-15 10:30:00",
"updated_at": "2023-04-15 10:30:00",
"short_url": "https://ttny.io/page1",
"status": "active",
"analytics": {
"total_clicks": 150,
"unique_visitors": 120,
"days_with_clicks": 15,
"top_referrers": [
{"referrer": "google.com", "count": 45},
{"referrer": "twitter.com", "count": 30}
],
"clicks_by_date": [
{"date": "2023-04-20", "count": 25},
{"date": "2023-04-19", "count": 18}
]
}
}
}
Update Link
Update an existing short link.
PUT /links/{id}
Path Parameters
Parameter | Type | Required | Description |
---|---|---|---|
id | integer | Yes | The ID of the link to update |
Request Parameters
Parameter | Type | Required | Description |
---|---|---|---|
destination_url | string | No | New destination URL |
custom_url | string | No | New custom URL |
password | string | No | New password (empty to remove) |
title | string | No | New title |
description | string | No | New description |
expires_at | string | No | New expiration date (empty to remove) |
tags | string | No | New comma-separated tags |
Example Request
curl -X PUT "https://ttny.io/api/v1/links/123" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"destination_url": "https://updated-example.com/page",
"title": "Updated Title",
"description": "Updated description",
"tags": "updated,example"
}'
Example Response
{
"success": true,
"message": "Link updated successfully",
"data": {
"id": 123,
"destination_url": "https://updated-example.com/page",
"custom_url": "mylink",
"password": null,
"secondary_link": null,
"tags": "updated,example",
"metadata": {
"title": "Updated Title",
"description": "Updated description"
},
"is_metadata_enabled": 1,
"expires_at": null,
"views": 150,
"created_at": "2023-04-15 10:30:00",
"updated_at": "2023-05-01 15:45:22",
"short_url": "https://ttny.io/mylink"
}
}
Delete Link
Delete a shortened link.
DELETE /links/{id}
Path Parameters
Parameter | Type | Required | Description |
---|---|---|---|
id | integer | Yes | The ID of the link to delete |
Example Request
curl -X DELETE "https://ttny.io/api/v1/links/123" \
-H "Authorization: Bearer YOUR_API_KEY"
Example Response
{
"success": true,
"message": "Link deleted successfully"
}
Warning: Deleting a link is permanent and cannot be undone. All analytics data associated with the link will also be deleted.
Get Analytics
Retrieve analytics for a specific short link.
GET /links/{custom_url}/stats
Path Parameters
Parameter | Type | Required | Description |
---|---|---|---|
custom_url | string | Yes | The custom URL of the link |
Query Parameters
Parameter | Type | Default | Description |
---|---|---|---|
start_date | string | 30 days ago | Start date (YYYY-MM-DD) |
end_date | string | today | End date (YYYY-MM-DD) |
group_by | string | day | Group by (day, week, month) |
Example Request
curl -X GET "https://ttny.io/api/v1/links/mylink/stats?start_date=2023-04-01&end_date=2023-04-30&group_by=day" \
-H "Authorization: Bearer YOUR_API_KEY"
Example Response
{
"success": true,
"message": "Statistics retrieved successfully",
"data": {
"total_clicks": 250,
"unique_visitors": 180,
"clicks_by_period": [
{"period": "2023-04-01", "clicks": 15},
{"period": "2023-04-02", "clicks": 22},
// More dates...
],
"clicks_by_country": [
{"country": "United States", "clicks": 120},
{"country": "United Kingdom", "clicks": 45},
// More countries...
],
"clicks_by_device": [
{"device_type": "desktop", "clicks": 150},
{"device_type": "mobile", "clicks": 80},
{"device_type": "tablet", "clicks": 20}
],
"clicks_by_browser": [
{"browser": "Chrome", "clicks": 140},
{"browser": "Safari", "clicks": 60},
// More browsers...
],
"clicks_by_referrer": [
{"referrer": "google.com", "clicks": 85},
{"referrer": "twitter.com", "clicks": 45},
// More referrers...
],
"clicks_by_hour": [
{"hour": 0, "clicks": 5},
{"hour": 1, "clicks": 3},
// More hours...
],
"clicks_by_day_of_week": [
{"day_of_week": 1, "day_name": "Sunday", "clicks": 30},
{"day_of_week": 2, "day_name": "Monday", "clicks": 42},
// More days...
],
"date_range": {
"start_date": "2023-04-01",
"end_date": "2023-04-30",
"group_by": "day"
}
}
}
Export Statistics
Export link statistics in various formats.
GET /links/{custom_url}/export
Path Parameters
Parameter | Type | Required | Description |
---|---|---|---|
custom_url | string | Yes | The custom URL of the link |
Query Parameters
Parameter | Type | Default | Description |
---|---|---|---|
format | string | csv | Export format (csv, json, pdf, xlsx) |
start_date | string | 30 days ago | Start date (YYYY-MM-DD) |
end_date | string | today | End date (YYYY-MM-DD) |
Example Request
curl -X GET "https://ttny.io/api/v1/links/mylink/export?format=csv&start_date=2023-04-01&end_date=2023-04-30" \
-H "Authorization: Bearer YOUR_API_KEY" \
-o "mylink_stats.csv"
This will download a file with the statistics in the requested format.
Generate QR Code
Generate a QR code for a shortened link.
GET /links/{custom_url}/qr
Path Parameters
Parameter | Type | Required | Description |
---|---|---|---|
custom_url | string | Yes | The custom URL of the link |
Query Parameters
Parameter | Type | Default | Description |
---|---|---|---|
size | integer | 300 | Size of the QR code in pixels |
format | string | png | Image format (png, svg, jpeg) |
color | string | 000000 | Foreground color (hex without #) |
background | string | FFFFFF | Background color (hex without #) |
margin | integer | 1 | Margin around the QR code |
Example Request
curl -X GET "https://ttny.io/api/v1/links/mylink/qr?size=400&format=svg&color=0066CC&background=F5F5F5" \
-H "Authorization: Bearer YOUR_API_KEY" \
-o "mylink_qr.svg"
This will download a QR code image in the requested format.
User Management
Get User Profile
Retrieve the current user's profile information.
GET /user/profile
Example Request
curl -X GET "https://ttny.io/api/v1/user/profile" \
-H "Authorization: Bearer YOUR_API_KEY"
Example Response
{
"success": true,
"message": "Profile retrieved successfully",
"data": {
"id": 456,
"name": "John Doe",
"email": "john.doe@example.com",
"created_at": "2023-01-15 08:30:00",
"subscription": {
"plan": "pro",
"status": "active",
"expires_at": "2023-12-31 23:59:59"
},
"settings": {
"default_domain": "ttny.io",
"default_redirect_type": 302,
"enable_tracking": true,
"enable_password_protection": true
},
"stats": {
"total_links": 125,
"total_clicks": 15680,
"links_this_month": 12,
"clicks_this_month": 2450
}
}
}
Regenerate API Key
Generate a new API key for your account. This will invalidate your current API key.
POST /user/regenerate-key
Example Request
curl -X POST "https://ttny.io/api/v1/user/regenerate-key" \
-H "Authorization: Bearer YOUR_CURRENT_API_KEY"
Example Response
{
"success": true,
"message": "API key regenerated successfully",
"data": {
"api_key": "your_new_api_key_here"
}
}
After regenerating your API key, your old key will no longer work. Make sure to update all your applications with the new key.
Error Handling
The API uses standard HTTP status codes to indicate the success or failure of a request. In case of an error, the response body will contain additional information.
Example Error Response
{
"success": false,
"message": "The URL provided is not valid",
"error_code": "invalid_url"
}
Common Error Codes
invalid_request
- The request was malformed or missing required parametersauthentication_error
- Invalid or missing API keynot_found
- The requested resource was not foundrate_limit_exceeded
- You have exceeded the rate limitserver_error
- An unexpected error occurred on our serversduplicate_error
- The custom alias is already in usevalidation_error
- One or more fields failed validationinvalid_url
- The URL provided is not valid
HTTP Status Codes
Status Code | Description |
---|---|
200 OK | The request was successful |
201 Created | A new resource was successfully created |
400 Bad Request | The request was invalid or malformed |
401 Unauthorized | Authentication failed or was not provided |
403 Forbidden | The authenticated user does not have permission |
404 Not Found | The requested resource was not found |
409 Conflict | The request conflicts with the current state (e.g., duplicate alias) |
429 Too Many Requests | Rate limit exceeded |
500 Internal Server Error | An unexpected error occurred on the server |
Best Practices
Error Handling
Always implement proper error handling in your API integrations. Check for error responses and handle them gracefully.
// Example of proper error handling
try {
const response = await fetch('https://ttny.io/api/v1/shorten', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_API_KEY'
},
body: JSON.stringify({ url: 'https://example.com' })
});
const data = await response.json();
if (!data.success) {
// Handle error
console.error('API Error:', data.message);
return;
}
// Handle success
console.log('Short URL:', data.data.short_url);
} catch (error) {
console.error('Network Error:', error);
}
Rate Limiting
To avoid hitting rate limits, implement exponential backoff for retries and monitor your usage with the rate limit headers.
// Example of handling rate limits with exponential backoff
async function makeRequestWithBackoff(url, options, maxRetries = 5) {
let retries = 0;
while (retries < maxRetries) {
const response = await fetch(url, options);
if (response.status !== 429) {
return response;
}
// Get retry-after header or use exponential backoff
const retryAfter = response.headers.get('Retry-After') || Math.pow(2, retries);
console.log(`Rate limited. Retrying after ${retryAfter} seconds...`);
// Wait for the specified time
await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
retries++;
}
throw new Error('Max retries exceeded');
}
Security
Keep your API keys secure and never expose them in client-side code. Use environment variables to store API keys in your applications.
// Node.js example using environment variables
require('dotenv').config();
const apiKey = process.env.TTNY_API_KEY;
// Make API request
fetch('https://ttny.io/api/v1/shorten', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${apiKey}`
},
body: JSON.stringify({ url: 'https://example.com' })
});
Caching
To improve performance and reduce API calls, consider caching frequently accessed data. For example, you might cache link details and analytics data for a short period.
Pagination
When retrieving large sets of data, use pagination to limit the amount of data returned in a single request. This improves performance and reduces memory usage.
// Example of pagination
async function getAllLinks() {
const links = [];
let offset = 0;
let hasMore = true;
const limit = 100;
while (hasMore) {
const response = await fetch(`https://ttny.io/api/v1/links?limit=${limit}&offset=${offset}`, {
headers: {
'Authorization': 'Bearer YOUR_API_KEY'
}
});
const data = await response.json();
links.push(...data.data.links);
if (data.data.pagination.has_more) {
offset += limit;
} else {
hasMore = false;
}
}
return links;
}