Rate Limits

RiskOS™ implements rate limiting to ensure optimal performance, prevent abuse, and maintain service reliability across all tenants.

Overview

Rate limits control the number of API requests your application can make within a specific time. These limits apply to each API key and help maintain system stability while ensuring fair resource allocation.


Rate limit tiers

Sandbox environment

  • Rate Limit: 10 requests per second (TPS)
  • Daily Quota: 1,000 requests per day
  • Purpose: Development, testing, and integration validation
  • Billing: Free tier included with all accounts

Production environment

  • Initial State: 0 TPS (all requests blocked)
  • Activation: Requires approval and configuration
  • Purpose: Live production traffic
  • Custom Limits: Tailored to your specific use case and volume requirements
📘

Production Access Required:

Production accounts start with rate limits disabled (0 TPS) as a safety measure. Contact Socure Support to activate your production environment with appropriate limits.


Requesting production access

Contact Socure Support with the following information:

  • Expected request volume (TPS and daily totals)
  • Peak usage patterns and time periods
  • Integration timeline and go-live date

Socure evaluates your request and updates your production limits to an approved throughput level.


Rate limits and subaccounts

Rate limits apply per API key. If your organization uses multiple subaccounts, each subaccount's API key has its own rate limit allocation.

📘

Multi-subaccount deployments:

If you operate multiple subaccounts with separate API keys, contact Socure Support to review your rate limit allocation across subaccounts. Ensure each subaccount's limits align with its expected traffic volume to avoid 429 errors on high-throughput subaccounts.


Rate limit response headers

RiskOS™ returns rate limit headers on every API response, enabling your application to monitor usage and implement proactive throttling.

Headers on all responses

HeaderDescription
X-RateLimit-Limit-DayTotal number of requests allowed per day for your API key
X-RateLimit-Limit-WindowTotal number of requests allowed in the current rate limit window
X-RateLimit-Remaining-DayNumber of requests remaining in the current day
X-RateLimit-Remaining-WindowNumber of requests remaining in the current rate limit window

Additional header on 429 responses

HeaderDescription
X-Retry-AfterNumber of seconds to wait before retrying the request
📘

Proactive throttling:

Use the X-RateLimit-Remaining-Day and X-RateLimit-Remaining-Window headers to monitor your usage in real time. By tracking remaining capacity, your application can slow down or queue requests before hitting the limit — avoiding 429 errors entirely.


Handling rate limit exceeded

HTTP 429 response

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

{
  "error": "rate_limit_exceeded",
  "message": "Rate limit exceeded for this resource"
}

All 429 responses include an X-Retry-After header that specifies how many seconds to wait before retrying. The response also includes the standard rate limit headers:

HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit-Day: 1000
X-RateLimit-Limit-Window: 10
X-RateLimit-Remaining-Day: 0
X-RateLimit-Remaining-Window: 0
X-Retry-After: 2

Exponential backoff

To prevent retry storms and ensure smooth recovery from rate limits or transient errors, implement exponential backoff with jitter.

Exponential backoff spaces out retries and randomizes delays to avoid simultaneous retry spikes across multiple clients.

Recommended pattern

When receiving a 429 or 5xx error:

  1. Read the X-Retry-After header (if present) and wait that many seconds.
  2. If the header is missing, retry using exponential backoff:
    • Start with a 1–2 second delay.
    • Double the delay after each retry (2s, 4s, 8s, 16s...).
    • Add a random "jitter" (±1s) to avoid retry collisions.
    • Stop after about 5 attempts or 1 minute.

Example implementation of exponential backoff with jitter:

import time, random

def retry_with_backoff(request_fn, max_attempts=5):
    for attempt in range(max_attempts):
        response = request_fn()
        if response.status_code not in (429, 500, 503):
            return response
        wait = (2 ** attempt) + random.uniform(0, 1)
        print(f"Rate limited. Retrying in {wait:.2f} seconds...")
        time.sleep(wait)
    raise Exception("Max retries exceeded")

Best practices

  • Always respect X-Retry-After when provided — it overrides your local delay.
  • Don't retry indefinitely; cap retries and log rate-limit events.
  • Queue non-urgent requests to smooth burst traffic.
  • Use idempotency keys to safely retry without duplicating requests.