Skip to main content
The /api/ctai endpoint enforces a per-IP sliding window rate limit to protect the service from abuse. The /api/health endpoint is not rate-limited.

Default limits

SettingDefault value
Requests allowed per window5
Window duration60 seconds
Each IP address may make up to 5 requests within any 60-second window. Requests are tracked by IP using the cf-connecting-ip, x-forwarded-for, or x-real-ip headers (in that order of preference).
Server operators can override these defaults using the RATE_LIMIT_POINTS and RATE_LIMIT_DURATION environment variables. See the deployment guide for details.

429 response

When you exceed the rate limit, the API returns an HTTP 429 status with a JSON body and rate limit headers. Status: 429 Too Many Requests
Content-Type: application/json
{ "error": "Too many requests", "retryAfterSeconds": 12 }

Response body

error
string
required
Always "Too many requests".
retryAfterSeconds
number
required
The number of seconds to wait before retrying. Always at least 1.

Response headers

HeaderDescription
Retry-AfterSeconds to wait before retrying. Same value as retryAfterSeconds in the body.
X-RateLimit-LimitMaximum number of requests allowed per window.
X-RateLimit-WindowWindow duration in seconds.

Handling 429 in your client

Check the HTTP status before reading the response body. If you receive a 429, read retryAfterSeconds and pause before retrying.
async function analyzeWithRetry(ioc, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const res = await fetch(
      `http://localhost:4321/api/ctai?ioc=${encodeURIComponent(ioc)}`
    );

    if (res.status === 429) {
      const body = await res.json();
      const wait = (body.retryAfterSeconds ?? 60) * 1000;
      console.warn(`Rate limited. Retrying in ${body.retryAfterSeconds}s...`);
      await new Promise((resolve) => setTimeout(resolve, wait));
      continue;
    }

    return res; // success or non-429 error — handle upstream
  }

  throw new Error("Max retries exceeded.");
}

Configuration

Changing rate limit values requires restarting the server. The in-memory rate limiter is reset on restart.
Set these environment variables before starting the server:
RATE_LIMIT_POINTS=10
RATE_LIMIT_DURATION=60
VariableDefaultDescription
RATE_LIMIT_POINTS5Maximum requests per IP per window.
RATE_LIMIT_DURATION60Window duration in seconds.

Build docs developers (and LLMs) love