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://api.ttny.io/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.
Include your API key in the request header:
Authorization: Bearer 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.
For enhanced security, you can restrict API keys to specific IP addresses and set expiration dates.
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 /links
Request Body
{
"url": "https://example.com/very/long/url/that/needs/shortening",
"custom_alias": "my-brand", // Optional
"title": "My Website", // Optional
"tags": ["marketing", "q2"] // Optional
}
Response
{
"id": "abc123",
"short_url": "https://ttny.io/my-brand",
"original_url": "https://example.com/very/long/url/that/needs/shortening",
"created_at": "2024-04-05T12:00:00Z",
"title": "My Website",
"tags": ["marketing", "q2"],
"clicks": 0
}
Additional Options
password
- Add password protection to your linkexpiration_date
- Set an expiration date for the linkutm_source
,utm_medium
,utm_campaign
- Add UTM parametersdomain_id
- Use a custom domain (if configured)
Get Link
Retrieve information about a specific short link.
GET /links/{id}
Response
{
"id": "abc123",
"short_url": "https://ttny.io/my-brand",
"original_url": "https://example.com/very/long/url/that/needs/shortening",
"created_at": "2024-04-05T12:00:00Z",
"updated_at": "2024-04-05T12:00:00Z",
"title": "My Website",
"tags": ["marketing", "q2"],
"clicks": 42
}
Update Link
Update an existing short link.
PATCH /links/{id}
Request Body
{
"title": "Updated Title", // Optional
"tags": ["marketing", "q3"] // Optional
}
Response
{
"id": "abc123",
"short_url": "https://ttny.io/my-brand",
"original_url": "https://example.com/very/long/url/that/needs/shortening",
"created_at": "2024-04-05T12:00:00Z",
"updated_at": "2024-04-05T14:30:00Z",
"title": "Updated Title",
"tags": ["marketing", "q3"],
"clicks": 42
}
Updatable Fields
You can update the following fields:
title
- Change the link titletags
- Update or add tagspassword
- Add or remove password protectionexpiration_date
- Modify the expiration date
Note: You cannot update the original_url
or custom_alias
of an existing link. To change these, create a new link.
Delete Link
Delete a short link.
DELETE /links/{id}
Response
{
"success": true,
"message": "Link successfully deleted"
}
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/{id}/analytics
Query Parameters
start_date
- Start date for analytics (format: YYYY-MM-DD)end_date
- End date for analytics (format: YYYY-MM-DD)timezone
- Timezone for the data (default: UTC)granularity
- Data granularity: daily, weekly, or monthly (default: daily)
Response
{
"id": "abc123",
"total_clicks": 42,
"unique_clicks": 38,
"referrers": [
{ "source": "facebook.com", "count": 15 },
{ "source": "twitter.com", "count": 12 },
{ "source": "direct", "count": 10 },
{ "source": "other", "count": 5 }
],
"countries": [
{ "country": "US", "count": 20 },
{ "country": "GB", "count": 8 },
{ "country": "CA", "count": 6 },
{ "country": "other", "count": 8 }
],
"devices": [
{ "device": "mobile", "count": 25 },
{ "device": "desktop", "count": 15 },
{ "device": "tablet", "count": 2 }
],
"browsers": [
{ "browser": "Chrome", "count": 22 },
{ "browser": "Safari", "count": 12 },
{ "browser": "Firefox", "count": 5 },
{ "browser": "other", "count": 3 }
],
"daily_clicks": [
{ "date": "2024-04-01", "count": 5 },
{ "date": "2024-04-02", "count": 8 },
{ "date": "2024-04-03", "count": 12 },
{ "date": "2024-04-04", "count": 10 },
{ "date": "2024-04-05", "count": 7 }
]
}
Bulk Operations
For efficiency, you can perform operations on multiple links at once using our bulk endpoints.
Bulk Create Links
POST /links/bulk
Request Body
{
"links": [
{
"url": "https://example.com/page1",
"title": "Page 1",
"tags": ["example", "bulk"]
},
{
"url": "https://example.com/page2",
"title": "Page 2",
"tags": ["example", "bulk"]
}
]
}
Response
{
"success": true,
"links": [
{
"id": "abc123",
"short_url": "https://ttny.io/abc123",
"original_url": "https://example.com/page1",
"created_at": "2024-04-05T12:00:00Z",
"title": "Page 1",
"tags": ["example", "bulk"],
"clicks": 0
},
{
"id": "def456",
"short_url": "https://ttny.io/def456",
"original_url": "https://example.com/page2",
"created_at": "2024-04-05T12:00:00Z",
"title": "Page 2",
"tags": ["example", "bulk"],
"clicks": 0
}
]
}
Bulk Delete Links
DELETE /links/bulk
Request Body
{
"ids": ["abc123", "def456", "ghi789"]
}
Response
{
"success": true,
"deleted": 3,
"message": "3 links successfully deleted"
}
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
{
"error": {
"code": "invalid_request",
"message": "The URL provided is not valid",
"status": 400
}
}
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 validation
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 |
Client Libraries
We provide official client libraries to make integrating with the ttny.io API even easier:
JavaScript/Node.js
npm install ttny-api
Python
pip install ttny-api
PHP
composer require ttny/api
Ruby
gem install ttny-api
Example Usage (JavaScript)
const TtnyApi = require('ttny-api');
const api = new TtnyApi('YOUR_API_KEY');
// Create a new short link
api.createLink({
url: 'https://example.com/very/long/url',
title: 'My Example Link'
})
.then(link => {
console.log(`Short URL: ${link.short_url}`);
})
.catch(error => {
console.error(`Error: ${error.message}`);
});
Example Usage (Python)
from ttny_api import TtnyApi
api = TtnyApi('YOUR_API_KEY')
# Create a new short link
try:
link = api.create_link(
url='https://example.com/very/long/url',
title='My Example Link'
)
print(f"Short URL: {link['short_url']}")
except Exception as e:
print(f"Error: {str(e)}")
Webhooks
Webhooks allow you to receive real-time notifications when certain events occur in your ttny.io account. This is useful for integrating with other systems and automating workflows.
Available Events
link.created
- Triggered when a new link is createdlink.updated
- Triggered when a link is updatedlink.deleted
- Triggered when a link is deletedlink.clicked
- Triggered when a link is clicked
Setting Up Webhooks
You can configure webhooks in your ttny.io dashboard under Settings > Webhooks, or via the API:
Create Webhook
POST /webhooks
{
"url": "https://your-server.com/webhook",
"events": ["link.created", "link.clicked"],
"secret": "your_webhook_secret" // Optional
}
Webhook Payload
When an event occurs, we'll send a POST request to your webhook URL with a JSON payload:
{
"event": "link.clicked",
"created_at": "2024-04-05T12:34:56Z",
"data": {
"id": "abc123",
"short_url": "https://ttny.io/my-brand",
"original_url": "https://example.com/page",
"referrer": "https://twitter.com",
"ip": "192.0.2.1", // Anonymized for privacy
"user_agent": "Mozilla/5.0...",
"country": "US",
"device": "mobile",
"browser": "Chrome"
}
}
Webhook Security
To verify that webhook requests are coming from ttny.io, we include a signature in the X-Ttny-Signature
header. The signature is a HMAC SHA-256 hash of the request body using your webhook secret.
// Node.js example to verify webhook signature
const crypto = require('crypto');
function verifyWebhookSignature(payload, signature, secret) {
const hmac = crypto.createHmac('sha256', secret);
const digest = hmac.update(payload).digest('hex');
return crypto.timingSafeEqual(
Buffer.from(digest),
Buffer.from(signature)
);
}
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 api.createLink({ url: 'https://example.com' });
// Handle success
} catch (error) {
if (error.status === 429) {
// Handle rate limiting
console.log('Rate limit exceeded. Retrying after delay...');
await delay(1000);
// Retry the request
} else if (error.status === 400) {
// Handle validation errors
console.log('Invalid request:', error.message);
} else {
// Handle other errors
console.error('API Error:', error);
}
}
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.
Bulk Operations
When working with multiple links, use bulk operations instead of making individual API calls. This reduces the number of requests and improves performance.
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
const links = [];
let page = 1;
let hasMore = true;
while (hasMore) {
const response = await api.getLinks({ page, limit: 100 });
links.push(...response.links);
if (response.links.length < 100) {
hasMore = false;
} else {
page++;
}
}
Security
Keep your API keys secure and never expose them in client-side code. Use environment variables to store API keys in your applications.
When using webhooks, always verify the signature to ensure the request is coming from ttny.io.