Documentation
Rate Limits
Understand API rate limits and how to handle them gracefully
Rate Limit Headers
Every API response includes rate limit headers so you can monitor your usage and avoid hitting limits.
Response Headers
X-RateLimit-LimitMaximum requests allowed in the current window
X-RateLimit-RemainingRequests remaining in the current window
X-RateLimit-ResetUnix timestamp when the rate limit resets
Retry-AfterSeconds to wait before retrying (only on 429 responses)
Limits by Subscription Tier
| Limit Type | FREE | STARTER | PROFESSIONAL | ENTERPRISE | CUSTOM |
|---|---|---|---|---|---|
| API Requests/minute | 10 | 30 | 100 | 500 | Unlimited |
| Concurrent uploads | 10 | 20 | 30 | 50 | Unlimited |
| Batch upload size | 10 files | 50 files | 100 files | 200 files | Unlimited |
| Max batch payload | 2 GB | 2 GB | 2 GB | 2 GB | 2 GB |
| Max file size (images) | 100MB | 100MB | 100MB | 100MB | 100MB |
| Max file size (documents) | 50MB | 50MB | 50MB | 50MB | 50MB |
| AI descriptions/month | 10 | 500 | 2,500 | 10,000 | Unlimited |
| Chat messages/month | 10 | 200 | 2,000 | 500,000 | Unlimited |
CUSTOM is an invite-only tier for negotiated contracts. All CUSTOM-tier limits default to unlimited; specific caps are set per customer.
FREE Tier API Access
The FREE tier does not include API key access. API keys are available from the STARTER tier and above. FREE tier users can only access the platform through the web dashboard.
Session Authentication
Rate limits apply to both API key and session authenticated requests. Session-authenticated users (web dashboard) have a generous limit of 300 requests per minute.
Unauthenticated Requests
Requests that arrive without a valid session cookie or API key are rate limited per source IP. The unauthenticated limit is deliberately lower than any authenticated tier to discourage probing and credential stuffing; invalid API keys fall back to this limit as well.
Sensitive Endpoint Limits
A handful of authentication, account, and OAuth endpoints are rate limited per source IP regardless of subscription tier. These limits are intentionally strict to prevent brute-force attacks, email enumeration, and OAuth abuse.
| Endpoint | Limit / minute (per IP) |
|---|---|
POST /auth/session/login | 5 |
POST /auth/session/register | 10 |
POST /auth/session/google | 10 |
POST /auth/session/resend-verification | 5 |
POST /auth/session/resend-verification-by-email | 5 |
POST /auth/session/password-reset/request | 3 |
POST /auth/session/password-reset/validate | 10 |
POST /auth/session/password-reset/complete | 5 |
POST /auth/session/verify-email | 5 |
POST /auth/session/link-provider | 5 |
POST /auth/session/unlink-provider | 3 |
POST /auth/session/rotate-session | 10 |
POST /cloud-storage/auth/google_drive | 10 |
GET /cloud-storage/auth/google_drive/callback | 10 |
POST /cloud-storage/import | 30 |
POST /cloud-storage/export | 30 |
POST /support/contact | 3 |
Batch Upload & Webhook Limits
Batch upload and webhook endpoints use dedicated IP-based buckets that are higher than the per-tier API rate limit, so bulk imports and Stripe event bursts do not starve regular API calls.
Batch upload endpoints (authenticated)
500 requests per minute per IP across POST /files/upload, POST /files/upload/batch, POST /files/uploads, and per-upload sub-routes under /files/uploads/{upload_id}.
Batch upload endpoints (unauthenticated / invalid auth)
200 requests per minute per IP for the same endpoints.
Stripe webhooks
POST /payment/webhooks/stripe is capped at 200 requests per minute per source IP.
Upload Limits
Uploads are subject to concurrency and size limits to ensure reliability.
Per-File Limit
100MB per file for image uploads. Documents are limited to 50MB.
Concurrent Uploads
See the tier table above for concurrent upload limits per plan
429 Too Many Requests
When upload limits are exceeded, the API returns 429 Too Many Requests. Wait for the Retry-After duration before retrying.
Handling Rate Limits
1. Monitor Headers Proactively
def check_rate_limits(response): remaining = int(response.headers.get('X-RateLimit-Remaining', 0)) reset_time = int(response.headers.get('X-RateLimit-Reset', 0))
if remaining < 10: wait_time = reset_time - time.time() print(f"Warning: Only {remaining} requests left. Resets in {wait_time:.0f}s")
return remaining > 02. Implement Exponential Backoff
import timeimport random
def exponential_backoff(attempt, base_delay=1, max_delay=60): """Calculate delay with jitter for retry.""" delay = min(base_delay * (2 ** attempt), max_delay) jitter = random.uniform(0, delay * 0.1) return delay + jitter
def request_with_backoff(func, max_retries=5): for attempt in range(max_retries): response = func()
if response.status_code == 429: retry_after = response.headers.get('Retry-After') if retry_after: time.sleep(int(retry_after)) else: time.sleep(exponential_backoff(attempt)) continue
return response
raise Exception("Max retries exceeded")3. Use Request Queuing
import asynciofrom asyncio import Semaphore
class RateLimitedClient: def __init__(self, requests_per_second=10): self.semaphore = Semaphore(requests_per_second) self.delay = 1.0 / requests_per_second
async def request(self, func): async with self.semaphore: result = await func() await asyncio.sleep(self.delay) return result
# Usageclient = RateLimitedClient(requests_per_second=10)results = await asyncio.gather(*[ client.request(lambda: upload_file(f)) for f in files])Best Practices
Use Multi-File Endpoints
Instead of 50 individual uploads, use /files/upload/batch to upload multiple files in one request. For single images, use /images/analyze for the simplest one-call workflow.
Implement Client-Side Throttling
Don't wait for 429 errors. Track your usage and slow down proactively when approaching limits.
Cache Responses
Cache API responses locally to avoid repeated calls for the same data. File listings and search results are good candidates.
Spread Requests Over Time
If you have bulk processing jobs, spread them across the minute rather than sending all requests at once.
Enterprise Rate Limits
Enterprise customers can request custom rate limits based on their needs. Contact your account manager or email enterprise@scopix.ai.
Need Higher Limits?
If you're consistently hitting rate limits, consider upgrading your plan or contact us to discuss enterprise options with custom limits.

