Rate limiting

The Sitepaste API implements rate limiting to ensure fair usage and platform stability. This guide explains the limits, how to monitor them, and best practices for staying within limits.

Rate limit tiers

Different API endpoints have different rate limits based on their resource cost:

Operation TypeLimitWindowApplies To
Write Operations60 requests1 minuteCreating/updating pages
Heavy Operations20 requests1 hourTriggering builds
IP Baseline120 requests1 minuteAll public API endpoints

Write operations

Endpoints:

  • POST /api/v1/public/pages

Limit: 60 requests per minute per business account

Scope: Shared across all your API tokens

This allows for reasonable bulk operations while preventing abuse.

Heavy operations

Endpoints:

  • POST /api/v1/public/builds

Limit: 20 requests per hour per business account

Scope: Shared across all your API tokens

Builds are expensive operations that regenerate your entire site. The hourly limit prevents resource exhaustion.

IP baseline

Limit: 120 requests per minute per IP address

Scope: All public API requests from the same IP

This is a protective baseline to prevent abuse from any single source.

Rate limit headers

Every API response includes rate limit information in the headers:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45

When you exceed the limit, you’ll also see:

Retry-After: 60

Header descriptions

HeaderDescription
X-RateLimit-LimitMaximum requests allowed in the current window
X-RateLimit-RemainingRequests remaining in the current window
Retry-AfterSeconds to wait before retrying (only on 429 errors)

Monitoring rate limits

Check headers in response

curl -i -X POST https://sitepaste.com/api/v1/public/pages \
  -H "Authorization: Bearer sp_your_token_here" \
  -H "Content-Type: application/json" \
  -d '{"title": "Test", "content": "Hello"}'

Response headers:

HTTP/2 200 OK
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 59
Content-Type: application/json

{"id":"...","slug":"test",...}

Track usage in your application

#!/bin/bash
# Example: Parse rate limit headers

response=$(curl -i -X POST https://sitepaste.com/api/v1/public/pages \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"title": "Test", "content": "Hello"}')

remaining=$(echo "$response" | grep -i "X-RateLimit-Remaining" | cut -d' ' -f2)

echo "Remaining requests: $remaining"

if [ "$remaining" -lt 5 ]; then
  echo "Warning: Approaching rate limit!"
fi

Rate limit exceeded

When you exceed a rate limit, you’ll receive a 429 Too Many Requests response:

Status: 429 Too Many Requests

Headers:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
Retry-After: 60

Body:

{
  "error": "rate limit exceeded",
  "message": "too many requests, please try again later"
}

What to do

  1. Stop making requests immediately - You’re already rate limited
  2. Wait for the duration in Retry-After - Usually 60 seconds (1 minute) or 3600 seconds (1 hour)
  3. Implement exponential backoff - Don’t retry immediately when the window resets
  4. Review your usage pattern - Optimize to stay within limits

Best practices

1. Batch operations

Don’t do this:

# Creates 50 pages with 50 requests
for i in {1..50}; do
  curl -X POST /api/v1/public/pages \
    -H "Authorization: Bearer $TOKEN" \
    -d "{\"title\": \"Post $i\", \"content\": \"Content\"}"

  # Triggers 50 builds!
  curl -X POST /api/v1/public/builds \
    -H "Authorization: Bearer $TOKEN"
done

Do this instead:

# Creates 50 pages with 50 requests
for i in {1..50}; do
  curl -X POST /api/v1/public/pages \
    -H "Authorization: Bearer $TOKEN" \
    -d "{\"title\": \"Post $i\", \"content\": \"Content\"}"
done

# Triggers ONE build at the end
curl -X POST /api/v1/public/builds \
  -H "Authorization: Bearer $TOKEN"

2. Implement rate limit awareness

import requests
import time

API_BASE = "https://sitepaste.com/api/v1"
TOKEN = "sp_your_token_here"

def create_page(data):
    response = requests.post(
        f"{API_BASE}/public/pages",
        headers={"Authorization": f"Bearer {TOKEN}"},
        json=data
    )

    # Check rate limit
    remaining = int(response.headers.get("X-RateLimit-Remaining", 0))

    if remaining < 5:
        print(f"Warning: Only {remaining} requests remaining")

    if response.status_code == 429:
        retry_after = int(response.headers.get("Retry-After", 60))
        print(f"Rate limited. Waiting {retry_after} seconds...")
        time.sleep(retry_after)
        return create_page(data)  # Retry

    return response.json()

# Create multiple pages with awareness
pages = [
    {"title": "Page 1", "content": "Content 1"},
    {"title": "Page 2", "content": "Content 2"},
    # ... more pages
]

for page in pages:
    result = create_page(page)
    print(f"Created: {result['slug']}")

3. Add delays between requests

If you’re making many requests, add small delays to stay well within limits:

# 60 requests per minute = 1 request per second
for i in {1..50}; do
  curl -X POST /api/v1/public/pages \
    -H "Authorization: Bearer $TOKEN" \
    -d "{\"title\": \"Post $i\", \"content\": \"Content\"}"

  sleep 1  # Wait 1 second between requests
done

4. Use exponential backoff

When you hit a rate limit, implement exponential backoff:

import time
import random

def make_request_with_backoff(func, max_retries=5):
    for attempt in range(max_retries):
        try:
            response = func()

            if response.status_code == 429:
                if attempt == max_retries - 1:
                    raise Exception("Max retries exceeded")

                # Exponential backoff with jitter
                wait = (2 ** attempt) + random.uniform(0, 1)
                print(f"Rate limited. Waiting {wait:.2f} seconds...")
                time.sleep(wait)
                continue

            return response

        except Exception as e:
            if attempt == max_retries - 1:
                raise
            wait = (2 ** attempt) + random.uniform(0, 1)
            time.sleep(wait)

    raise Exception("Failed after all retries")

5. Coordinate multiple tokens

If you’re using multiple API tokens for different integrations, remember:

  • Rate limits are per business account, not per token
  • Multiple tokens share the same rate limit pool
  • Coordinate your integrations to avoid conflicts

Rate limit windows

Sliding windows

Rate limits use sliding windows, not fixed time intervals:

Example (60 requests per minute):

  • 12:00:00 - Make 60 requests (allowed)
  • 12:00:30 - Make 1 request (rejected - still 60 requests in the last 60 seconds)
  • 12:01:01 - Make 1 request (allowed - only 1 request in the last 60 seconds)

This is more flexible than fixed windows and prevents burst abuse.

Build rate limit (hourly)

The 20 builds per hour limit works the same way:

  • Not reset at the top of every hour
  • Tracks the last 60 minutes of build requests
  • Resets gradually as old requests age out

Development mode

In development environments:

  • Rate limiting is disabled
  • Headers still appear but limits are not enforced
  • Use this to test your integration without restrictions

Production: Rate limits are strictly enforced

Troubleshooting

I’m getting rate limited but I’m not making many requests

Possible causes:

  1. Multiple tokens - Remember, limits are per business account, not per token
  2. Multiple sources - Check if you have multiple scripts/integrations running
  3. Dashboard usage - Manual dashboard operations don’t count, but dashboard API calls do

Can I request higher rate limits?

Currently, rate limits are fixed for all Pro plan users. If you have a legitimate use case requiring higher limits:

  1. Optimize your usage pattern first (batching, delays, etc.)
  2. Contact support with your use case details
  3. Enterprise plans with custom limits may be available in the future

What counts as a request?

  • Counts: All successful requests (200, 201, 202, etc.)
  • Counts: Failed requests (400, 404, etc.)
  • Counts: Unauthorized requests (401, 403)
  • Counts: Rate limited requests (429)
  • Doesn’t count: Requests that fail before authentication (500 errors, network issues)

Summary

  • Write operations: 60 per minute
  • Build operations: 20 per hour
  • Monitor headers: X-RateLimit-Remaining
  • Respect Retry-After when rate limited
  • Batch operations to stay within limits
  • Implement backoff for robustness

By following these guidelines, you’ll build reliable integrations that work within the API’s rate limits.