Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.have-foresight.app/llms.txt

Use this file to discover all available pages before exploring further.

The Foresight RCM API rate-limits requests per API key. When you exceed your limit, the API returns 429 Too Many Requests and a Retry-After header indicating how long to wait before retrying.

Default limits

TierRequests per secondDaily quotaBurst
Sandbox10100,00020 (5s sustained)
Production base505,000,000100 (5s sustained)
Production high20025,000,000400 (5s sustained)
EnterpriseNegotiatedNegotiatedNegotiated
Limits are per API key, not per organization — you can create multiple keys to parallelize work that would otherwise saturate one limit. Some endpoints have stricter, endpoint-specific limits (typically high-cost operations like eligibility checks against payers, or LLM-backed decisions). Those are documented on the relevant endpoint reference page.

Response headers

Every response (success or failure) includes the current limit state:
HeaderMeaning
X-RateLimit-LimitYour per-second limit.
X-RateLimit-RemainingRequests remaining in the current second.
X-RateLimit-ResetUnix timestamp when the per-second window resets.
X-RateLimit-Daily-LimitYour daily quota.
X-RateLimit-Daily-RemainingRequests remaining today (UTC).
Retry-After(only on 429) Seconds to wait before retrying.
Use these headers to back off proactively before hitting 429.

Handling 429

Always honor Retry-After. The response body uses the standard error envelope:
{
  "error": {
    "type": "rate_limit_error",
    "code": "rate_limit_exceeded",
    "message": "Rate limit exceeded. Retry after 2 seconds.",
    "requestId": "req_..."
  }
}
A robust retry implementation:
async function callWithRetry(url, options, maxAttempts = 5) {
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
    const res = await fetch(url, options);
    if (res.status !== 429) return res;

    const retryAfter = Number(res.headers.get('Retry-After') ?? '1');
    const jitter = Math.random() * 0.5;
    await new Promise((r) => setTimeout(r, (retryAfter + jitter) * 1000));
  }
  throw new Error('Rate limit retry budget exhausted');
}

Best practices

  • Spread bursts. If you have a batch of 10,000 claims to submit, queue them and submit at a steady rate instead of in parallel.
  • Use webhooks instead of polling. Polling list endpoints in tight loops is the most common cause of 429. Subscribe to the relevant events and let us push state changes to you.
  • Read the headers. Backing off when X-RateLimit-Remaining is low is cheaper than getting 429d.
  • One key per workload. Parallel pipelines should use separate keys so one runaway loop doesn’t starve the others.

Need more headroom?

If your workload exceeds the production tier limits, contact support@have-foresight.com — we can provision higher per-second and daily quotas for vetted use cases without re-architecting your integration.