Revised

Rate limits

Per-key, per-plan limits counted in fixed one-minute windows, the headers on every response, and how to recover from a 429.

The rate limit is per key, per plan, counted in fixed one-minute windows. REST calls and MCP calls come out of the same window: one key, one counter, whichever interface it is used through.

The counter lives in Postgres rather than in each server instance, so the published number is a real shared ceiling rather than a per-instance one.

Limits

PlanRequests a minute, per keyLive keys per account
Free202
Pro605
Business12010

Source: PLAN_LIMITS in the application. GET /api/v1/me returns the live figure for the key you hold, under rate_limit.limit — read it rather than hard-coding a row of this table. A key carries no plan of its own; the owner’s current plan is resolved behind it on every request, so an upgrade or a lapse moves the limit without the key being reissued. See Authentication.

Two keys on one account get two counters. That separates the rate-limit bookkeeping and nothing else — reveals, holds and the reveal ledger are account-scoped.

The window is fixed, not sliding

The counter is keyed on the truncated minute. It resets on the wall-clock minute boundary, not sixty seconds after your first request.

The practical consequence: X-RateLimit-Remaining can read the same before and after a burst simply because the minute turned over, which looks like the limit not working. It is working; you crossed a boundary. Pace against X-RateLimit-Reset rather than counting your own calls.

Headers on every response

http
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 47
X-RateLimit-Reset: 1758506460
HeaderValue
X-RateLimit-LimitThe plan’s per-minute ceiling.
X-RateLimit-RemainingWhat is left in the current one-minute window.
X-RateLimit-ResetAn epoch second — when the current window rolls over. Not a duration, so you can schedule against it without knowing when the response was generated.

These ride on every response, the 429 included. They are least useful on a 200 and most useful on the response that tells you to slow down. From a browser they are exposed through Access-Control-Expose-Headers.

When you hit a 429

http
HTTP/1.1 429 Too Many Requests
Retry-After: 14
X-RateLimit-Limit: 20
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1758506460
json
{
  "error": {
    "code": "rate_limited",
    "message": "Rate limit is 20 requests a minute per key on the free plan. Retry in 14s."
  }
}

Sleep for Retry-After seconds and retry. The header is the number of seconds until the current window ends, so a client that honours it lands in a fresh window rather than in the tail of the one it just exhausted.

python
import os, time, requests

BASE = "https://getrevised.com/api/v1"
AUTH = {"Authorization": f"Bearer {os.environ['REVISED_API_KEY']}"}

def get(path: str, **params) -> dict:
    """GET with one retry per 429, paced by Retry-After."""
    while True:
        res = requests.get(f"{BASE}{path}", headers=AUTH, params=params, timeout=30)
        if res.status_code != 429:
            res.raise_for_status()
            return res.json()
        wait = int(res.headers.get("Retry-After", "5"))
        print(f"rate limited, sleeping {wait}s")
        time.sleep(wait)

page = get("/domains", limit=250, rsMin=60)
print(len(page["data"]), "listings")
Output
text
rate limited, sleeping 14s
250 listings

Staying under it

  • Read fewer, larger pages. limit goes to 250 and a request costs the same whether it returns 1 row or 250. A full pass at limit=250 on the free plan is 20 pages a minute, which is 5,000 listings a minute. See Pagination.
  • Poll with since rather than re-reading the directory, on a plan that includes it. A delta is a handful of pages; a full pass is not.
  • Do not retry a 401, a 400 or a 404. Failed requests still spend the counter.
  • Do not spread one job across several keys to dodge the limit. Use the key ceiling for separate systems that genuinely need separate budgets, and upgrade the plan if one system needs more throughput.
  • GET /api/v1/me costs one request and no reveals. Calling it once at startup is cheap; calling it before every request is not.

Failed authentication is limited separately

Requests that fail authentication are counted against a separate in-memory budget keyed by client IP — generous for a client with a stale key in its configuration, hostile to a loop guessing prefixes. Over it, the response is 429 rate_limited with Too many failed key attempts. Retry in Ns. and a Retry-After, raised before any database lookup. Authenticated traffic never touches that guard — only a failure spends a token from it.

Type to search…

↑↓ navigate openesc close