Skip to content

Rate Limiting

FormSentry applies rate limiting to every form using a token bucket algorithm, enforced per API key and IP address combination. This protects individual forms from abuse and ensures fair usage.

Each unique combination of API key and IP address gets its own token bucket per form:

  1. The bucket starts full at burst capacity (default: 10 tokens)
  2. Each submission consumes one token
  3. Tokens refill continuously over refillWindow seconds (at a rate of burst / refillWindow tokens per second)
  4. When tokens are exhausted, the request is blocked and returns a 429 response
  5. Rate limiting is always enabled and cannot be disabled

The minimum time between requests is enforced at 0.5 seconds (a hard floor of 2 requests per second).

New forms are created with the following defaults:

SettingDefaultDescription
burst10Maximum tokens in the bucket (peak capacity)
refillWindow60 secondsTime to fully refill the bucket from empty

At the default settings, the refill rate is 10 / 60 = 0.167 tokens per second, meaning a sustained rate of about 10 requests per minute with short bursts up to 10 requests allowed immediately.

You can adjust rate limiting for each form in the FormSentry web app at app.formsentry.ai/forms

SettingMinMaxDefaultDescription
burst15010Peak capacity — maximum requests allowed in a short burst
refillWindow10s86400s (24h)60sTime to fully refill the bucket from empty

Refill rate = burst / refillWindow tokens per second. For example:

  • burst: 10, refillWindow: 60 -> 0.167 tokens/sec (10 requests/minute sustained)
  • burst: 5, refillWindow: 30 -> 0.167 tokens/sec (same sustained rate, smaller bursts)
  • burst: 20, refillWindow: 60 -> 0.333 tokens/sec (20 requests/minute sustained)

When a submission is rate limited, the API returns a 429 status:

{
"error": "Rate limit exceeded",
"retryAfter": 60,
"message": "Too many requests. Please wait before trying again.",
"processingTime": 45
}

Every response includes rate limit headers:

X-RateLimit-Limit: 10
X-RateLimit-Remaining: 7
X-RateLimit-Reset: 1640995200

On 429 responses, an additional header is included:

Retry-After: 60
HeaderDescription
X-RateLimit-LimitBurst capacity (maximum tokens in the bucket)
X-RateLimit-RemainingTokens currently available
X-RateLimit-ResetUnix timestamp when the bucket will be fully refilled
Retry-AfterSeconds to wait before retrying (429 responses only)

Use the Retry-After header to determine how long to wait before retrying:

const response = await fetch('https://api.formsentry.ai/v1/verify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After');
console.log(`Rate limited. Retry in ${retryAfter}s`);
}

FormSentry includes an internal abuse protection mechanism. Repeated violations while already rate limited trigger progressively longer blocks:

ViolationsBlock Duration
5+2 minutes
15+10 minutes
30+60 minutes

Violations decay as legitimate submissions come through, so the escalation resets naturally over time.

See Errors for retry strategies.