API Documentation
Navigation

Rate Limits

The GenerateInvoice API implements rate limiting to ensure fair usage and maintain service quality for all users. Rate limits vary based on your subscription plan.

Rate Limits by Plan

Each plan has different rate limits to accommodate various usage needs:

PlanRequests/HourDocuments/MonthBulk Jobs/Month
Free50501
Starter50050010
Pro2,0002,00050
Scale10,00010,000200
EnterpriseCustomUnlimitedUnlimited

How Rate Limits Work

Rate limits are applied using a sliding window algorithm:

  • Per-hour limits use a 1-hour sliding window
  • Per-month limits reset at the start of your billing cycle
  • Each API key has its own rate limit counter
  • Rate limits are applied per API key, not per IP address

Rate Limit Headers

Every API response includes headers to help you track your rate limit status:

HeaderDescription
X-RateLimit-LimitMaximum requests allowed per hour
X-RateLimit-RemainingRemaining requests in current window
X-RateLimit-ResetUnix timestamp when the rate limit resets
Retry-AfterSeconds to wait before retrying (only on 429 responses)

Example response headers:

HTTP/1.1 200 OK
X-RateLimit-Limit: 2000
X-RateLimit-Remaining: 1847
X-RateLimit-Reset: 1705324800
Content-Type: application/json

What Happens When Rate Limited

When you exceed your rate limit, the API returns a 429 Too Many Requests response:

{
  "success": false,
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded. Please retry after 847 seconds.",
    "details": {
      "limit": 2000,
      "remaining": 0,
      "reset_at": "2024-01-15T12:00:00Z",
      "retry_after": 847
    }
  },
  "meta": {
    "request_id": "req_abc123",
    "timestamp": "2024-01-15T11:45:53Z"
  }
}

Handling Rate Limits

Here's how to properly handle rate limits in your application:

rateLimitHandler.jsjavascript
async function makeApiRequest(url, options, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const response = await fetch(url, options);

    // Check remaining rate limit
    const remaining = parseInt(response.headers.get('X-RateLimit-Remaining'));
    const resetTime = parseInt(response.headers.get('X-RateLimit-Reset'));

    if (response.status === 429) {
      // Rate limited - wait and retry
      const retryAfter = parseInt(response.headers.get('Retry-After')) || 60;
      console.log(`Rate limited. Waiting ${retryAfter} seconds...`);
      await sleep(retryAfter * 1000);
      continue;
    }

    if (!response.ok) {
      throw new Error(`API error: ${response.status}`);
    }

    // Log warning if approaching limit
    if (remaining < 100) {
      console.warn(`Approaching rate limit: ${remaining} requests remaining`);
    }

    return response.json();
  }

  throw new Error('Max retries exceeded');
}

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

Python Example

rate_limit_handler.pypython
import time
import requests

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

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

        if response.status_code == 429:
            # Rate limited - wait and retry
            retry_after = int(response.headers.get('Retry-After', 60))
            print(f"Rate limited. Waiting {retry_after} seconds...")
            time.sleep(retry_after)
            continue

        response.raise_for_status()

        # Log warning if approaching limit
        if remaining < 100:
            print(f"Warning: Approaching rate limit ({remaining} requests remaining)")

        return response.json()

    raise Exception("Max retries exceeded")

Best Practices

Monitor Rate Limit Headers

Always check and log the rate limit headers in your responses to anticipate limits.

Implement Exponential Backoff

When retrying after a rate limit error, use exponential backoff to avoid hammering the API.

Use Bulk Operations

For creating multiple documents, use the bulk generation endpoint instead of individual calls.

Cache Responses When Possible

Cache document data locally to reduce API calls for frequently accessed information.

Use Webhooks for Updates

Instead of polling for status changes, set up webhooks to receive real-time notifications.

Usage Limits vs Rate Limits

It's important to understand the difference between rate limits and usage limits:

TypeRate LimitsUsage Limits
What it limitsAPI requests per hourDocuments created per month
Reset frequencyRolling 1-hour windowMonthly billing cycle
Error codeRATE_LIMIT_EXCEEDEDUSAGE_LIMIT_EXCEEDED
HTTP status429402 (Payment Required)

When you hit a usage limit, you'll need to upgrade your plan or wait for the next billing cycle. The API will return:

{
  "success": false,
  "error": {
    "code": "USAGE_LIMIT_EXCEEDED",
    "message": "Monthly document limit exceeded. Please upgrade your plan.",
    "details": {
      "limit": 500,
      "used": 500,
      "resets_at": "2024-02-01T00:00:00Z"
    }
  }
}

Need Higher Limits?

If you need higher rate limits or usage limits, consider upgrading your plan or contact us for a custom Enterprise plan.