Skip to content
API Reference

Rate Limits

Understand the API rate limits and how to handle them.

The linked.is API implements rate limiting to ensure fair usage and maintain service stability for all users.

Default Limits

EndpointLimitCounted per
POST /v1/links (create link)100 requests per minuteAPI token

The limit is the same on every plan, and there is no daily limit. Other API endpoints have no rate limit.

Each token has its own quota, so several tokens used from the same server don't share one limit. A request without a token is counted per IP address. Requests count toward the limit even when they fail, for example with an invalid token.

Rate Limit Headers

Every response from a rate limited endpoint includes headers that provide information about your current rate limit status:

<script setup lang="ts">
const rateLimitHeaders = {
  "X-RateLimit-Limit": 100,
  "X-RateLimit-Remaining": 95,
  "X-RateLimit-Reset": 1640995200
};
</script>

<template>
  <div>
    <h3>Rate Limit Headers:</h3>
    <pre>{{ JSON.stringify(rateLimitHeaders, null, 2) }}</pre>
  </div>
</template>
HeaderDescription
X-RateLimit-LimitMaximum number of requests allowed per minute
X-RateLimit-RemainingNumber of requests remaining in the current window
X-RateLimit-ResetUnix timestamp (in seconds) when the current window resets
Retry-AfterOnly on 429 responses: seconds to wait before retrying

Handling Rate Limits

When you exceed the rate limit, the API will return a 429 Too Many Requests response with a Retry-After header:

<script setup lang="ts">
const rateLimitErrorResponse = {
  error: true,
  url: "https://linked.is/api/v1/links",
  statusCode: 429,
  statusMessage: "Too Many Requests",
  message: "Rate limit exceeded. Please try again later."
};
</script>

<template>
  <pre>{{ JSON.stringify(rateLimitErrorResponse, null, 2) }}</pre>
</template>

Best Practices

  1. Cache responses - Store API responses locally to reduce the number of requests
  2. Respect Retry-After - When rate limited, wait the number of seconds in the Retry-After header before retrying
  3. Implement exponential backoff - If no Retry-After is available, wait progressively longer between retries
  4. Spread out bulk creation - When creating many links, keep below 100 per minute per token

Exponential Backoff Example

<script setup lang="ts">
const fetchWithRetry = async (url: string, options: RequestInit, maxRetries = 3) => {
  for (let i = 0; i < maxRetries; i++) {
    const response = await fetch(url, options)
    
    if (response.status === 429) {
      const retryAfter = Number(response.headers.get('Retry-After')) || Math.pow(2, i)
      await new Promise(resolve => setTimeout(resolve, retryAfter * 1000))
      continue
    }
    
    return response
  }
  
  throw new Error('Max retries exceeded')
};

const handleRetryRequest = async () => {
  try {
    const response = await fetchWithRetry(
      "https://linked.is/api/v1/links",
      {
        method: "POST",
        headers: {
          Authorization: "Bearer YOUR_API_TOKEN",
          "Content-Type": "application/json",
        },
        body: JSON.stringify({ url: "https://example.com" }),
      }
    );
    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.error("Max retries exceeded:", error);
  }
};
</script>

<template>
  <div>
    <button @click="handleRetryRequest">Make Retry Request</button>
  </div>
</template>

Increasing Your Limits

If you need a higher limit for creating links, contact us.