ttny.io

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

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 parameters
  • authentication_error - Invalid or missing API key
  • not_found - The requested resource was not found
  • rate_limit_exceeded - You have exceeded the rate limit
  • server_error - An unexpected error occurred on our servers
  • duplicate_error - The custom alias is already in use
  • validation_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:

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 created
  • link.updated - Triggered when a link is updated
  • link.deleted - Triggered when a link is deleted
  • link.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.