SnipyDevelopers
Rate Limits & Errors

Rate Limits & Errors

Understand the rate limits applied to API requests and how to handle error responses in your integrations.

Rate limits by plan

Rate limits are applied per-user based on the authenticated identity. Requests that exceed the limit receive a 429 Too Many Requests response.

EndpointFreeStarterProBusiness
Default60/min60/min60/min60/min
Auth (/api/token)5/min5/min5/min5/min
Link Create20/min20/min20/min20/min
Export5/min5/min5/min5/min
Import3/min3/min3/min3/min
QR Download20/min20/min20/min20/min

Rate limit headers

Every API response includes headers to help you track your rate limit usage.

HeaderDescription
X-RateLimit-LimitMaximum number of requests allowed in the current window.
X-RateLimit-RemainingNumber of requests remaining in the current window.
Retry-AfterSeconds to wait before retrying (only present on 429 responses).
Example response headers
HTTP/1.1 200 OK
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 57
Content-Type: application/json
Rate limited response headers
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
Retry-After: 45
Content-Type: application/json

Handling rate limits

Implement exponential backoff with jitter when you receive a 429 response. Always respect the Retry-After header.

JavaScript: Retry with backoff
async function fetchWithRetry(url, options, maxRetries = 3) {
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    const response = await fetch(url, options);

    if (response.status === 429) {
      const retryAfter = parseInt(
        response.headers.get("Retry-After") || "60",
        10
      );
      const jitter = Math.random() * 1000;
      const delay = retryAfter * 1000 + jitter;

      console.log(
        `Rate limited. Retrying in ${Math.round(delay / 1000)}s...`
      );
      await new Promise((resolve) => setTimeout(resolve, delay));
      continue;
    }

    return response;
  }

  throw new Error("Max retries exceeded");
}
Python: Retry with backoff
import time
import random
import requests

def fetch_with_retry(url, headers, max_retries=3):
    for attempt in range(max_retries + 1):
        response = requests.get(url, headers=headers)

        if response.status_code == 429:
            retry_after = int(
                response.headers.get("Retry-After", 60)
            )
            jitter = random.uniform(0, 1)
            delay = retry_after + jitter

            print(f"Rate limited. Retrying in {delay:.0f}s...")
            time.sleep(delay)
            continue

        return response

    raise Exception("Max retries exceeded")

Error codes

The API uses standard HTTP status codes. Error responses always include an error: 1 field and a human-readable message.

400Bad Request

The request body is malformed, missing required fields, or contains invalid values.

Example response
{
  "error": 1,
  "message": "The 'url' field is required and must be a valid URL."
}
401Unauthorized

The request is missing authentication credentials, or the provided token/API key is invalid or expired.

Example response
{
  "error": 1,
  "message": "Invalid or expired access token."
}
403Forbidden

The authenticated user does not have permission to perform this action. This often means a feature is gated behind a higher plan.

Example response
{
  "error": 1,
  "message": "Custom aliases require the Starter plan or above."
}
404Not Found

The requested resource does not exist or the authenticated user does not have access to it.

Example response
{
  "error": 1,
  "message": "Link not found."
}
409Conflict

A resource with the same identifier already exists. Common when creating a link with an alias that is already taken.

Example response
{
  "error": 1,
  "message": "The alias 'my-link' is already in use."
}
429Too Many Requests

You have exceeded the rate limit for this endpoint. Wait for the duration specified in the Retry-After header before retrying.

Example response
{
  "error": 1,
  "message": "Rate limit exceeded. Try again in 45 seconds."
}
500Internal Server Error

An unexpected error occurred on our servers. If this persists, please contact support.

Example response
{
  "error": 1,
  "message": "An internal error occurred. Please try again later."
}

Best practices for error handling

  • 1.Always check the error field in the response body, not just the HTTP status code.
  • 2.Implement retry logic with exponential backoff for 429 and 5xx responses.
  • 3.Log the full error response including the message for debugging.
  • 4.Do not retry 400, 401, 403, or 404 errors -- these require changes to the request.
  • 5.Monitor your X-RateLimit-Remaining header to proactively throttle requests before hitting the limit.