Rate limits
This page lists the HostRepute API rate limits, how requests are counted against them, the headers that report them, and how to back off when you reach one.
Limits for developers
Section titled “Limits for developers”- REST API: 120 requests per minute per team. All of a team’s API tokens share one budget, so two scripts with
different tokens slow each other down. Every request that gets past authentication counts, including those answered
with
403,404or422. Requests refused with401, and requests to a path that doesn’t exist, don’t count. - Test alerts: 5 per minute per team.
POST /api/v1/alerts/{uuid}/testcounts against this limit and the team’s 120. The portal’s test button uses the same 5, so tests from the portal and the API add up. - Private agents: 60 requests per minute per agent token, and 60 per IP address. Both apply to every request to
/api/v1/certificate-agent, and they’re separate from the team’s 120. Requests are counted before the token is checked, so requests with a wrong token use up the IP address’s limit. Read check internal certificates with a private agent. - MCP server: 60 requests per minute per person. The limit belongs to your HostRepute account and covers every AI client you connect, for every team. Read connect AI clients with MCP.
Each limit counts requests in a one-minute window that starts with the first request. When the window ends, the count starts again from zero.
Rate-limit headers
Section titled “Rate-limit headers”Every counted response carries the state of the limit:
| Header | Sent on | Value |
|---|---|---|
X-RateLimit-Limit |
Every counted response | The number of requests the window allows. |
X-RateLimit-Remaining |
Every counted response | How many requests are left in this window. |
Retry-After |
429 only |
The number of seconds until the window ends and you can send again. |
X-RateLimit-Reset |
429 only |
The same moment as a Unix timestamp, in seconds. |
When two limits apply to a request, as with test alerts, the headers describe the one with fewer requests left. A
test alert therefore shows X-RateLimit-Limit: 5.
HTTP/1.1 200 OKContent-Type: application/jsonX-RateLimit-Limit: 120X-RateLimit-Remaining: 118When you reach a limit
Section titled “When you reach a limit”The request isn’t carried out and the API answers 429:
HTTP/1.1 429 Too Many RequestsContent-Type: application/jsonX-RateLimit-Limit: 120X-RateLimit-Remaining: 0Retry-After: 59X-RateLimit-Reset: 1793047746{ "message": "Too Many Attempts."}Because nothing was carried out, you can send the same request again after Retry-After seconds, even one that starts
a check. A 429 uses no credits.
Back off
Section titled “Back off”- Wait for
Retry-After. Sending again sooner gets another429and doesn’t shorten the wait. - Pace your loops. Poll a running check every few seconds, not in a tight loop, or give a
callback_urland let HostRepute call you: read run checks and wait for results. - Read lists in big pages.
per_page=100reads 100 items in one request: read pagination. - Spread the work across the minute. A job that changes many items is better off sending a request every second than a burst of 120.
- Watch
X-RateLimit-Remainingand slow down before it reaches 0, especially when several scripts share the team.
These examples retry a read after a 429, waiting as long as Retry-After says:
curl’s --retry waits for Retry-After on a 429 (curl manual, checked
October 2026). It also retries after a timeout or a 5xx, so use it for reads, not for a POST that starts a check.
--fail keeps the body of the refused attempt out of the output; if the request still fails, curl prints the status
code and exits with an error.
curl --fail --retry 5 "https://app.hostrepute.com/api/v1/hosts?per_page=100" \ -H "Authorization: Bearer $HOSTREPUTE_TOKEN" \ -H "Accept: application/json"import jsonimport osimport timeimport urllib.errorimport urllib.request
API = "https://app.hostrepute.com/api/v1"TOKEN = os.environ["HOSTREPUTE_TOKEN"]
def get(path, attempts=5): request = urllib.request.Request( API + path, headers={"Authorization": f"Bearer {TOKEN}", "Accept": "application/json"}, ) for attempt in range(1, attempts + 1): try: with urllib.request.urlopen(request) as response: return json.load(response) except urllib.error.HTTPError as error: if error.code != 429 or attempt == attempts: raise time.sleep(int(error.headers.get("Retry-After", "60")))
hosts = get("/hosts?per_page=100")print(hosts["meta"]["total"], "domains and IPs")const API = 'https://app.hostrepute.com/api/v1'
async function get(path, attempts = 5) { for (let attempt = 1; ; attempt++) { const response = await fetch(API + path, { headers: { Authorization: `Bearer ${process.env.HOSTREPUTE_TOKEN}`, Accept: 'application/json', }, }) if (response.status !== 429 || attempt === attempts) { if (!response.ok) throw new Error(`${response.status}: ${await response.text()}`) return response.json() } const seconds = Number(response.headers.get('Retry-After') ?? 60) await new Promise((resolve) => setTimeout(resolve, seconds * 1000)) }}
const hosts = await get('/hosts?per_page=100')console.log(hosts.meta.total, 'domains and IPs')All rate limits
Section titled “All rate limits”Every rate limit in HostRepute, including the portal’s and the sign-in limits:
| Setting | Default | How to change |
|---|---|---|
| API requests | 120 requests per minute per team | Fixed |
| Test alerts (portal and API) | 5 per minute per team | Fixed |
| MCP server requests | 60 requests per minute per user | Fixed |
| Certificate agent requests, per IP address | 60 requests per minute per IP address | Fixed |
| Certificate agent requests, per agent token | 60 requests per minute per agent token | Fixed |
| AI assistant requests (chat, summaries and playbooks) | 20 requests per minute per team | Fixed |
| Manual scans | 10 per minute per user | Fixed |
| Adding, editing or removing Domains & IPs and check profiles | 60 changes per minute per user | Fixed |
| Running a certificate, domain expiry or uptime check on demand | 6 per minute per user | Fixed |
| Sending a test scheduled report | 6 per minute per user | Fixed |
| Syncing an integration on demand (Microsoft SNDS, Gmail Postmaster Tools, ESP) | 6 per minute per user | Fixed |
| Member invitations | 10 invitations per minute per member, in each team | Fixed |
| Failed sign-in attempts | 5 failed attempts per email address and IP address in a 60-second window | Fixed |
| Two-factor codes at sign-in | 6 attempts per minute per account and per IP address, and 10 per 30 minutes per account | Fixed |
| Starting single sign-on | 10 per minute per email address, and 60 per minute per IP address | Fixed |
| Password reset emails | One every 60 seconds per account | Fixed |
| Shared report links, reputation badges and public status pages | 120 requests per minute per IP address | Fixed |
Reputation check on the HostRepute website (/check) | 3 scans per IP address per day | Fixed |
Related
Section titled “Related”- Errors lists the other error answers.
- Authentication and API tokens explains why all of a team’s tokens share one budget.
- Limits and defaults lists every other limit.
- Build on HostRepute compares the API, webhooks, MCP and metrics.

