Skip to main content

Configured limiters

PrefixLimitKeyed onSurface
rl:auth (Better Auth wrapper)5 / 60 sIP/api/auth/sign-in/*

Coarse per-IP gate on sign-in endpoints

rl:abuse:email5 / 1 hsha256(email)magic-link send + email-OTP send

Email-bombing fix: caps sends per target inbox regardless of source IP

rl:captcha:challenge30 / 60 sIP/api/captcha/challenge

Prevents stockpiling of pre-solved ALTCHA challenges

ratelimit:ai:chat20 / 60 sIP/api/ai/chat

Per-IP rate limit on chat completions (in addition to per-user daily token cap)

rl:feedback:submit3 / 1 hIP/feedback (form action)

Public feedback submission — paired with honeypot for unauthenticated posts

rl:username:check20 / 60 sIP/api/showcases/check-username

Username availability probe — prevents enumeration scraping

All limiters use Upstash Redis sliding-window via @upstash/ratelimit. When Redis is unavailable in production they fail closed (block all requests for that prefix); in dev they fall through with a warning so local development isn't blocked.