~4 min read
Rate limiting
Use project settings from the dashboard (mode, window, caps) or override them per check. Counters bucket by IP; optional metadata ties a limit to your user id and still requires the same IP.
Dashboard settings
In project settings, configure website rate limits: adaptive vs fixed mode, base/max caps, window length, and strike decay. Those values apply to every check unless you pass settingsOverride.
Server helper
import { qyzar } from "@/lib/qyzar";
export async function POST(req: Request) {
const ip = req.headers.get("x-forwarded-for")?.split(",")[0]?.trim() ?? "0.0.0.0";
const userAgent = req.headers.get("user-agent") ?? "unknown";
const userId = "…"; // from your session
const rl = await qyzar.checkRateLimit(process.env.QYZAR_PROJECT_ID!, {
ip,
userAgent,
metadata: userId, // same user on another IP gets a separate bucket
sessionId: null,
analytics: {
path: "/api/checkout",
method: "POST",
baseUrl: "https://shop.example.com",
body: { cartId: "…" },
headers: { "content-type": "application/json" },
},
});
if (!rl.allowed) {
return Response.json(
{ error: "Too many requests", retryAfter: rl.retryAfter },
{ status: 429, headers: { "Retry-After": String(rl.retryAfter ?? 60) } }
);
}
// … your handler
}See also Server helper for all QyzarServer methods.
IP and metadata
- Every check requires
ip— counters are always scoped to that address. - Optional
metadata(e.g. account id) adds a second dimension: the same metadata on a different IP does not share the limit. - Omit
metadatato rate-limit by IP only for that project.
Override settings
await qyzar.checkRateLimit(projectId, {
ip,
userAgent,
settingsOverride: {
rateLimitMode: "default",
rateLimitBaseMax: 200,
rateLimitWindowSeconds: 120,
},
});Overrides apply only to that request; dashboard defaults are unchanged.
Denied-request analytics
When a check is denied by the adaptive/fixed cap (not a traffic rule block or challenge), Qyzar stores a request-log row with rateLimitHit: true and source rate_limit_denied. Pass analytics to attach optional request body, headers, and response snapshot (status, body, response headers) for investigation in the dashboard request log.
HTTP API
POST /projects/client/rate-limit-check— project secret (used byQyzarServer.checkRateLimit)POST /projects/rate-limit/check— signed-in project owner (dashboard tooling)
These routes are excluded from platform HTTP abuse limiting so the checker cannot block itself. Full route list: HTTP routes.
