Rate Limits

The previous version of this page described only the enterprise API-key limit.

That was incomplete.

The live platform has multiple rate-limit layers depending on which surface you are using:

  • Shared product gateway routes
  • Auth and signup abuse controls
  • OTP-specific cooldowns
  • Public portal anti-abuse limits
  • Enterprise API-key limits

Shared Product Gateway

Shared product traffic through the main gateway uses the current default below:

SurfaceDefault limitScope
/api/* on the shared gateway500 requests / minutePer client IP in production

This is the default from the shared security config used by the gateway.

Notes:

  • Non-production environments can override this with API_RATE_LIMIT_MAX.
  • This is separate from auth-specific abuse controls below.
  • Hitting this limit commonly returns 429 with a retry window from the Fastify rate-limit middleware.

Auth Abuse Controls

Authentication routes have stricter controls than normal API reads.

RouteDefault limitScope
POST /auth/register3 requests / hourPer IP
POST /auth/login5 attempts / 15 minutesPer IP + email
POST /auth/forgot-password3 requests / hourPer email

When these controls trigger, the response body includes a retryAfterMs field when applicable.

Example:

{
  "success": false,
  "error": "Too many login attempts. Please try again later.",
  "retryAfterMs": 847000
}

OTP Limits

OTP routes have their own cooldowns and attempt caps:

RouteDefault limit
POST /auth/otp/request1 OTP request per 60 seconds per email
POST /auth/otp/verify5 verification attempts per OTP
POST /auth/otp/reauth1 OTP request per 60 seconds per email

These are not the same as the gateway-wide limit.

Public Portal

The public portal has a dedicated anti-abuse limiter:

SurfaceDefault limitScope
Public portal routes30 requests / minutePer IP in production

This value can be overridden with PUBLIC_PORTAL_RATE_LIMIT_MAX and PUBLIC_PORTAL_RATE_LIMIT_WINDOW.

Enterprise API

The enterprise API still has its own API-key limit:

SurfaceDefault limitScope
/api/v1/*1,000 requests / hourPer API key

This is the limit that the older version of this page described, but it does not represent the whole platform.

Response Format

There is no single universal rate-limit header contract across every route in the platform.

  • Shared auth abuse responses often return retryAfterMs in the JSON body.
  • Fastify middleware-based limits can also emit standard rate-limit headers depending on the route and middleware layer.
  • Clients should handle 429 generically and back off instead of assuming one header format everywhere.

When Youโ€™re Rate Limited

If you exceed a limit, the API returns 429 Too Many Requests.

Two common response shapes are currently in use:

Shared auth or abuse-control response:

{
  "success": false,
  "error": "Too many login attempts. Please try again later.",
  "retryAfterMs": 847000
}

Middleware-based response:

{
  "success": false,
  "error": "Rate limit exceeded, retry in 1 minute"
}

Best Practices

  • Cache responses where possible.
  • Use pagination with reasonable page sizes.
  • Do not brute-force login or OTP flows.
  • Treat 429 as a normal retry/backoff signal.
  • Avoid assuming that one routeโ€™s limit equals every other routeโ€™s limit.

Custom Limits

Enterprise tenants on dedicated infrastructure can request custom limits and dedicated abuse-control policies. Contact support@scootsign.com.

Aram by ScootSign docs.scootsign.com