Skip to content

Rate Limits

Fair usage for everyone. Rate limits protect the API and ensure consistent performance. Limits vary by subscription tier.


Rate Limit Tiers

Tier Requests/min Requests/day Characters/day Concurrent
Pauhu® 60 1,000 100,000 5
Pro 600 100,000 10,000,000 50
Max 3,000 1,000,000 100,000,000 200
Ops Custom Custom Custom Custom

Rate Limit Headers

Every response includes rate limit headers:

X-RateLimit-Limit: 600
X-RateLimit-Remaining: 599
X-RateLimit-Reset: 1705312800
X-RateLimit-Resource: translate
Header Description
X-RateLimit-Limit Maximum requests per window
X-RateLimit-Remaining Requests remaining in window
X-RateLimit-Reset Unix timestamp when window resets
X-RateLimit-Resource Which resource this limit applies to

Rate Limit Response

When rate limited, you receive a 429 Too Many Requests:

{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Rate limit exceeded. Please retry after 60 seconds.",
    "status": 429,
    "details": {
      "limit": 60,
      "remaining": 0,
      "reset_at": "2025-01-15T10:31:00Z",
      "retry_after": 60
    }
  }
}

The response includes a Retry-After header:

Retry-After: 60

Resource-Specific Limits

Different endpoints have different limits:

Resource Pauhu® Pro Max
/translate 60/min 600/min 3000/min
/translate/batch 10/min 100/min 500/min
/documents 10/hour 100/hour 500/hour
/detect 120/min 1200/min 6000/min
/languages No limit No limit No limit

Handling Rate Limits

Python

import time
from pauhu import Pauhu
from pauhu.exceptions import RateLimitError

client = Pauhu()

def translate_with_backoff(text: str, target: str, max_retries: int = 3):
    for attempt in range(max_retries):
        try:
            return client.translate(text, target=target)
        except RateLimitError as e:
            if attempt < max_retries - 1:
                print(f"Rate limited. Waiting {e.retry_after}s...")
                time.sleep(e.retry_after)
            else:
                raise

result = translate_with_backoff("Hello", "fi")

TypeScript

import { Pauhu, RateLimitError } from '@pauhu/sdk';

const client = new Pauhu({ apiKey: 'pk_...' });

async function translateWithBackoff(
  text: string,
  target: string,
  maxRetries = 3
) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      return await client.translate({ text, target });
    } catch (e) {
      if (e instanceof RateLimitError && attempt < maxRetries - 1) {
        console.log(`Rate limited. Waiting ${e.retryAfter}s...`);
        await new Promise(r => setTimeout(r, e.retryAfter * 1000));
      } else {
        throw e;
      }
    }
  }
}

Best Practices

1. Check Headers Before Retrying

response = client._last_response

remaining = int(response.headers.get('X-RateLimit-Remaining', 0))
if remaining < 10:
    print("Warning: Running low on rate limit")

2. Implement Exponential Backoff

import random

def backoff_delay(attempt: int, base: float = 1.0) -> float:
    """Calculate delay with exponential backoff and jitter."""
    delay = base * (2 ** attempt)
    jitter = random.uniform(0, delay * 0.1)
    return delay + jitter

3. Use Batch Endpoints

Instead of:

# Bad: 100 separate requests
for text in texts:
    client.translate(text, target="fi")

Do:

# Good: 1 batch request
client.translate_batch(texts, target="fi")

4. Cache Results

from functools import lru_cache

@lru_cache(maxsize=1000)
def cached_translate(text: str, target: str) -> str:
    result = client.translate(text, target=target)
    return result.translation

5. Use Webhooks for Long Operations

# Instead of polling
result = client.translate_document(
    file_path="large_doc.pdf",
    target="fi",
    webhook_url="https://yourapp.com/webhook"
)
# Don't poll - wait for webhook callback

Quota Management

Check Current Usage

usage = client.usage.current()

print(f"Characters used: {usage.characters_used:,}")
print(f"Characters limit: {usage.characters_limit:,}")
print(f"Requests today: {usage.requests_today:,}")
print(f"Reset at: {usage.reset_at}")

Set Usage Alerts

client.usage.set_alert(
    threshold=0.8,  # 80% of limit
    webhook_url="https://yourapp.com/usage-alert"
)

Requesting Higher Limits

For higher limits, contact sales:

Include:

  • Current tier
  • Required limits
  • Use case description
  • Expected volume