Skip to content

Rate Limits

API usage is subject to fair-use limits that may change without notice.

Results per page. List endpoints return at most 100 results per page on all paid tiers (10 on Free), controlled by the per_page query parameter. There is no pagination depth cap on paid tiers, so the full result set is retrievable by paging through it — see Pagination for Large Datasets.

Monthly API-call allowance. Each organization has a monthly allowance for calls made with a bs_live_ API key: 25,000/month on Professional, unlimited on Enterprise. Every API-key response reports your current position via headers:

Header Meaning
X-RateLimit-Limit Your monthly allowance (unlimited on unlimited tiers)
X-RateLimit-Used Calls made so far this calendar month
X-RateLimit-Remaining Calls left this month (unlimited on unlimited tiers)

These headers are informational: the allowance is currently tracked and reported but not enforced, so calls are not rejected for exceeding it. The counter resets at the start of each calendar month (UTC).

Per-key limits (correlation endpoints). POST /api/v1/assets/correlate-cves (and /check) and every Windows patch-level endpoint (/api/v2/assets/...) are limited per API key: by default 60 requests and 5,000 assets or hosts per minute, shared across v1 and v2. Each call takes at most 200 assets or hosts; for Windows hosts, send 100 or fewer per call so each response completes within 100 seconds. Partners doing an initial bulk load can ask for a temporary raise on their key; it lapses automatically at the agreed time.

Per-address limits. Requests without an API key (browser sessions, demo tokens, anonymous calls) are limited per client IP address at the edge: 60 API requests per minute with a short burst allowance. Requests that carry an API key are counted against that key instead, so one key is not throttled by other traffic from the same network.

Burst rate. Whatever the limit, a 429 response has error code RATE_LIMITED. The wait time is in the body as error.detail.retry_after (seconds); some edge responses use the Retry-After header instead. Back off and retry. See Correlate CVEs and Windows Patch Level.

Handling Rate Limits

When you receive HTTP 429 (error code RATE_LIMITED), back off and retry.

import time
import requests

def api_request(url, headers, max_retries=3):
    for attempt in range(max_retries):
        response = requests.get(url, headers=headers)
        if response.status_code == 429:
            detail = ((response.json() or {}).get("error") or {}).get("detail") or {}
            retry_after = (detail.get("retry_after") if isinstance(detail, dict) else None) \
                or response.headers.get("Retry-After") or 60
            time.sleep(float(retry_after))
            continue
        return response
    raise Exception("Rate limit exceeded after retries")

Pagination for Large Datasets

Always paginate large requests rather than fetching all at once.

def fetch_all_cves(api_key, severity="CRITICAL"):
    headers = {"Authorization": f"Bearer {api_key}"}
    base_url = "https://breachspider.com/api/v1/cves"
    page = 1

    while True:
        response = requests.get(
            f"{base_url}?severity={severity}&page={page}&per_page=100",
            headers=headers
        )
        data = response.json()
        yield from data["data"]

        if not data["pagination"]["has_next"]:
            break
        page += 1