Rate Limits

Understand request limits, response headers, and how to handle throttling gracefully.

The AskEdgar API enforces rate limits using a sliding window counter. Limits are applied per 1-minute window and scoped to your organization.

Limits by plan

PlanRequests per minuteScoped by
Retail200Organization
Enterprise1,000Organization

All API keys within the same organization share the same rate limit pool. If you have multiple keys, their usage counts together toward the limit.

📬

Need higher throughput? Contact us about Enterprise plans with up to 1,000 requests per minute.


Response headers

Every successful response includes rate limit headers so you can track your usage in real time:

HeaderDescription
X-RateLimit-LimitMaximum requests allowed in the current window
X-RateLimit-RemainingRequests remaining in the current window
X-RateLimit-ResetUnix timestamp when the current window resets
X-Credits-RemainingRemaining account balance in US dollars, on billed responses

Rate limit exceeded (HTTP 429)

When you exceed your limit, the API returns a 429 status with details on when you can retry:

{
  "status": "error",
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Rate limit exceeded.",
    "details": {
      "limit": 200,
      "window": "1m",
      "retry_after": 42
    }
  },
  "request_id": "a1b2c3d4-5678-90ab-cdef-1234567890ab"
}

The response also includes a Retry-After header with the number of seconds to wait, and an X-Request-ID header for tracing.


Handling rate limits in your code

The most reliable approach is to monitor the headers proactively and back off before you hit the wall. Here's a pattern that handles both normal throttling and retry logic:

import time
import requests

BASE_URL = "https://eapi.askedgar.io"
HEADERS = {"API-KEY": "your_api_key"}

def fetch(endpoint, params):
    for attempt in range(5):
        resp = requests.get(f"{BASE_URL}{endpoint}", params=params, headers=HEADERS)

        if resp.status_code == 200:
            remaining = int(resp.headers.get("X-RateLimit-Remaining", 1))
            if remaining < 10:
                reset_at = int(resp.headers.get("X-RateLimit-Reset", 0))
                wait = max(reset_at - time.time(), 0.5)
                time.sleep(wait)
            return resp.json()

        if resp.status_code == 429:
            wait = int(resp.headers.get("Retry-After", 2 ** attempt))
            time.sleep(wait)
            continue

        if resp.status_code == 503:
            time.sleep(5)
            continue

        resp.raise_for_status()

    raise Exception("Max retries exceeded")

Key takeaways

  • Monitor X-RateLimit-Remaining to slow down before hitting the limit, rather than reacting to 429s.
  • Use the Retry-After header on 429 responses — it tells you exactly how long to wait.
  • Fall back to exponential backoff if Retry-After isn't available for any reason.
  • Handle 503s with a short fixed delay. These are transient infrastructure issues and resolve quickly.

Service unavailable (HTTP 503)

In rare cases, the rate limiting infrastructure may be temporarily unavailable. The API returns a 503 with Retry-After: 5:

{
  "status": "error",
  "error": {
    "code": "service_unavailable",
    "message": "Service temporarily unavailable. Please retry."
  },
  "request_id": "a1b2c3d4-5678-90ab-cdef-1234567890ab"
}

This does not mean your API key or account has an issue — just retry after a few seconds.


Next steps


Did this page help you?