Developer HubRate, Size & Time Limits
On this page0

Reference

Not a developer? The step-by-step guides begin at Start Here, and a problem on your screen is in When something goes wrong.

Rate, Size & Time Limits

What It Does

A rate limit is a cap on how many times something may be tried in a short time. Zonitix uses them to slow down password and code guessing. An administrator has nothing to switch on: the limits are built in and cannot be changed from the app. You meet them in two ways. A person who mistypes their password or code many times is told to wait and try again later. A script that calls the API too quickly is refused until it slows down. Separately from these limits, 5 wrong passwords in a row lock that one account for 15 minutes.

The plain explanation is above. This part is for IT and developers: the exact settings, permission names, API addresses and data fields behind it.

Your gateway rate-limits the sensitive routes. Limits are backed by Redis, so they hold across restarts and replicas. This page also lists the fixed request-size limits and the fixed lifetimes of links, keys and lockouts.

Configured Limiters

These are the limiters configured on the gateway. Paths are shown without the /api/v1 prefix; both forms share one budget. Ordinary authenticated read/write traffic is not globally throttled — because your instance serves only your company, the limiters exist to blunt credential guessing and abuse of high-impact routes, not to ration capacity between tenants.

RoutesLimitWhy
/auth/login, /auth/password/change, /auth/magic-link/verify, /auth/accept-terms, /auth/invite/inspect, /auth/invite/accept, /auth/sso/login, /auth/sso/saml/login, /auth/sso/saml/acs, /auth/sso/saml/metadata, /auth/sso/callback20 failed / 15 minBrute-force protection, per client IP. Only failed requests count; a successful one does not use the budget.
/auth/magic-link/request30 / 15 minAsking for an emailed sign-in link. Per client IP, and every request counts, successful or not.
/auth/mfa/setup/init, /auth/mfa/setup/confirm, /auth/mfa/verify, /auth/mfa/verify-recovery, /auth/webauthn/register/*, /auth/webauthn/authenticate/*, /auth/webauthn/login/*, DELETE /auth/webauthn/credentials/:id20 failed / 5 minSecond-factor routes, per client IP, failed requests only. The per-account limits on the MFA Enforcement page (5 wrong codes per challenge) apply on top.
POST /auth/sudo, POST /auth/webauthn/sudo/verify5 failed / 15 minStep-up re-authentication guards the most damaging actions. Counted per client IP and signed-in user; a successful step-up does not use the budget.
GET /auth/webauthn/sudo/options30 / 15 minFetching a passkey step-up challenge. Same IP-and-user key as the row above, counted separately.
GET /auth/setup/status3,000 / 15 minPer client IP. A read-only status check that the app polls, so it has a wide budget.
Every other /auth/setup/* route30 / 15 minBlocks guessing of the one-time setup key during first-run setup.
Personal API tokens (any route)300 / minCounted per token, not per IP.
/scim/v2/*600 / minPer client IP. Sized for an identity provider pushing a large directory. A refusal uses the SCIM error format.
/agent/*300 / minPer client IP, for device agents checking in. Redeeming an enrolment code (POST /agent/mdm-enroll-redeem) has its own budget of 30 / 15 min.
/ai/*30 / minPer signed-in user. The assistant runs on your own server and is CPU-bound.
/security-lab/* (writes)20 / minPer signed-in user. GET requests are not counted; scans and probes are heavy.
/signature/sign/*80 / 15 minPer client IP, for the public document-signing pages.
/recruitment/public/*, /recruitment/webhooks/*, /shared/*, /public/phishing/*, GET /auth/sso/pending240 / minPer client IP, for pages that need no sign-in. Blunts link guessing and webhook spam. Like every limit in this table, it is applied by the gateway.
GET /public/phishing/l/:token120 / minPer client IP, on top of the 240 / min public limit above.
/training-content/*6,000 / minPer client IP. Only GET and HEAD requests are accepted on this path.
/recruitment/public/*, /shared/* (non-GET)30 / 15 minPer client IP. A tighter budget for public form submissions such as a job application.
GET /shared/verify/:runId20 / 10 minPer client IP, for the public report-verification page.

A refused request gets 429 with a JSON error message. If the gateway cannot reach Redis, most limiters fail closed: the request is refused with 503 and Retry-After: 5 instead of being let through uncounted. The exceptions let requests through while Redis is down: the 240-per-minute public-page limiter, the phishing landing-page limiter, the training-content limiter, the SCIM limiter, the personal API token limiter and the report-verification limiter.

How The Client Address Is Determined

In plain words: the “client IP” is the public address the request came from, as reported by the network edge in front of your server. Everyone in one office usually shares one such address, so they share one allowance and one rule.

Wherever these docs say client IP or address for a rate limit, a country or IP rule, or an audit entry, this is the value the gateway uses, in this order.

Used forValue, in orderNotes
Country and IP rules, and the auto-block detectorsThe CF-Connecting-IP request header. If it is absent, the address of the peer on the connection itself.X-Forwarded-For and X-Real-IP are not read for these rules.
Rate limits described as "per client IP"The CF-Connecting-IP request header. If it is absent, the gateway’s own request address, worked out with one proxy hop trusted.Three limiters read only the gateway’s own request address and not the header: device agent check-ins, the public document-signing pages, and the 30-per-15-minutes limit on first-run setup.
The address written on an audit entryThe CF-Connecting-IP header, then the first address in X-Forwarded-For, then X-Real-IP, then the peer on the connection.The gateway passes these headers on to the service that writes the entry. The later choices apply only when the first header is absent.
  • What is trusted. The gateway expects the network edge to set CF-Connecting-IP on every request it passes into the tunnel. The gateway publishes no port on the server, so a request from outside reaches it only through that tunnel; the path is drawn under Request Path And TLS.
  • One form of the address. For the country and IP rules, the auto-block detectors, the rate limits that read the header, and the audit entry, the prefix ::ffff: on an IPv4 address written in IPv6 form is removed, so the same client is the same key either way. The three limiters that read only the gateway’s own request address are not part of that statement. A rate-limit key passes through the limiter library’s address function, which counts an IPv6 network as one client, not each address in it.
  • Private addresses. An address in a private or loopback range is never subject to a country or IP rule, as listed under Evaluation Order & Safety.
  • What follows for you. People behind one office or VPN address count as one client for a per-IP limit and match one IP rule. A limit counted per signed-in user or per token is not affected by the address at all.

Request Size Limits

Every limit below is fixed in the product. A JSON body over its limit is refused with 413; the rows say where an upload answers differently. Paths are shown without the /api/v1 prefix. Separately from size, the gateway allows 5 minutes for a whole request.

RequestLimitNotes
Any /auth/* JSON body100 KBGateway, before authentication. 413.
POST /auth/settings/branding, /auth/settings/security/access-control10 MB at the gateway, then 1 MBThe gateway accepts up to 10 MB once the caller is authenticated; the identity service behind it accepts 1 MB. 413.
POST /auth/audits/active, /auth/audits/history, /auth/security-lab/sbom-scan, /auth/security-lab/intel-import10 MBGateway, after authentication; the service behind accepts the same. 413.
POST /auth/sso/saml/acs100 KB form, at most 5 fieldsGateway. The limit is on the URL-encoded form, so the usable SAMLResponse is somewhat smaller.
/scim/v2/*1 MBJSON or SCIM JSON. 413.
Résumé upload by a signed-in user (parse, screen, referral)5 MB, one file413.
Public job application (POST /recruitment/public/apply/:jobId, /recruitment/public/apply-general)5 MB, one file400 with "The résumé must be a single file under 5 MB."
Offer supporting document (POST /recruitment/offer-documents)10 MB, one file400 with "File is too large (max 10 MB)."
Compliance evidence upload25 MB, one fileUp to 20 other form fields of 64 KB each. 413.
User import (preview and commit), training-completions import2 MBJSON. 413.
Employee document content10 MBSent as the raw request body. 413 with "The file is larger than 10 MB."
Training SCORM package50 MB zippedAt most 150 MB and 2,000 files once unpacked.
Training video95 MBRead as it arrives and stored in sealed 1 MB chunks.
Device agent installer upload150 MBSent as application/octet-stream.
POST /agent/mdm-enroll-redeem4 KBJSON.
Any other JSON body100 KB, 2 MB, 10 MB or 25 MBOutside /auth the gateway streams the body through and the service that receives it applies its own limit: 100 KB for identity, user management, workflows, recruitment and the assistant; 2 MB for devices; 10 MB for compliance, integrations, Security Lab and logging; 25 MB for e-signature.

Caps On What Comes Out

OutputCap
Audit log export50,000 rows per export
Log forwarding, one event64 KB. A larger event is sent with its payload replaced by a marker, never cut off part-way.
Log forwarding, one batch200 events or 1 MB

Uploaded Files: What Is Checked

Besides its size, an uploaded file is checked for its type, and in some routes for its name and its content. Which check runs depends on the route. Where a row says first bytes, the product compares the start of the file with the signature of the format it claims to be. For PDF, PNG and JPEG that means a file renamed to one of those endings is refused. A Word or Excel file is checked for the zip container signature the two formats share.

UploadWhat is checkedWhen it fails, or what is recorded
Résumé read by the product (parse, AI screen, referral, public application)The document parser reads it. The file name must end in pdf, png, jpg, jpeg, docx, xlsx, txt or csv. For pdf, png and jpg the file’s first bytes must be that format’s signature; a docx or xlsx must start with the zip container signature; a txt or csv must decode as UTF-8 text.Reading a résumé to pre-fill the candidate form: 200 with empty fields and a warning to enter the details by hand. A résumé screened after it was submitted: the check runs in a background job after the request has been answered, so the file is refused there and no error status is returned to the person who sent it.
Public job applicationBefore anything else, the file name must end in .pdf, .docx or .txt. The stored copy and the screening then pass the résumé checks in the rows above and below.400 with "The résumé must be a PDF, Word (.docx), or plain text file…".
Any file kept by the shared file store: résumés, offer supporting documents, compliance evidenceThe file name must end in .pdf, .png, .jpg, .jpeg, .docx, .txt, .xlsx or .csv. The name the uploader gave is not used on disk: the file is stored under a random identifier with that ending, and it is encrypted before it is written.Offer documents: 400 with "Unsupported file type…".
Offer supporting documentAs the row above. The label and the original file name kept for display have angle brackets removed and are cut to 120 and 200 characters.Written to the audit log as OFFER_DOCUMENT_UPLOADED.
Compliance evidenceAs the shared file store. The server computes the SHA-256 of the bytes it received and returns it with the stored file’s address. A download request whose file name contains "..", "/" or "\" is refused.The hash, size and control are written to the audit log as COMPLIANCE_EVIDENCE_UPLOADED.
Finance document and invoice importThe document parser’s check on the file name and the start of the file, as in the first row, with its own 10 MB ceiling on the content.400 naming the mismatch or the size.
Employee documentPDF, PNG and JPEG are recognised by their first bytes. A Word or Excel file must start with the zip container signature and is told apart by the parts listed inside the container; when that list does not settle it, the ending of the document’s name (.docx or .xlsx) is used. The document’s title has path and quote characters and line breaks replaced with spaces and is cut to 180 characters.415 when none of those matches; 400 for an empty file.
Training SCORM packageThe zip’s file list is read before anything is unpacked. Refused: a zip64 or multi-part archive, more than 2,000 entries, more than 150 MB unpacked, and any entry whose name is empty, longer than 400 characters, holds control characters or a backslash, is an absolute path, or has a "." or ".." segment. imsmanifest.xml must be at the top level and the start file it names must be in the package.400 with the reason in plain words.
Training videoThe first 12 bytes must be an MP4 or a WebM file. The file name and the type the browser declares are not used.415 for anything else; 400 for an empty file.

Lifetimes And Lockouts

These windows are fixed in the product and are not rate limits: each one belongs to a single link, key, account or grant. The session lifetime is the one an administrator can change; it is on API Authentication.

WhatLimitWhat happens
Invitation link72 hours, single useSending a new invitation replaces the old link. A used, replaced or expired link answers 410.
First-run setup key72 hours from when the server is builtAfter that the key answers 410 with "This setup key has expired. Contact your provider for a new one."
Wrong setup keys10 from one address in 15 minutesSetup then pauses for that address for 15 minutes and answers 429 with "Too many attempts. Please wait, then try again." 200 wrong keys from all addresses together pause setup for everyone for 15 minutes. The counters are held in memory and start again when the identity service restarts.
Wrong passwords5 in a rowThat account is locked for 15 minutes.
Step-up (confirming a sensitive action)15 minutesA step-up counts for 15 minutes. The server reads the window from a stored setting, sudoTimeoutMinutes, and holds any value between 1 and 60 minutes, but no screen and no API route writes that setting, so every instance uses 15 minutes. A missing or expired step-up is refused with "error": "SUDO_REQUIRED" in the response body. The status beside it is 400 on most routes, because the gateway turns a 401 from a service behind it into 400. It stays 401 on the routes the gateway passes through unchanged: removing a passkey, the diagnostics bundle, and in Security Lab starting an aggressive scan, changing a scan scope and archiving findings. Key on the error string, not the status.
Interim sign-in token5 minutesIssued while a second factor or a forced password change is still owed.
Emailed sign-in link15 minutes
SAML sign-in request10 minutesThe response must arrive within that time, in the same browser.
Support access window1 to 72 whole hoursChosen by the administrator who grants it. See below.
Internal service token60 secondsBetween the gateway and the services behind it; a new one is made per request.

Database Limits

Two limits sit between a service and the database, and a very large list or report is what reaches them. A single SQL statement may run for 60 seconds; after that the database cancels it and the request fails. A service holds at most 5 database connections at once (12 for the identity service, 10 for user management), and a request that finds them all busy waits up to 30 seconds for one. Narrow the request with a filter or a smaller page and send it again. The connection settings are on Transport & Service Trust.

Support Access

Zonitix support has no sign-in to your instance until an administrator grants one. The steps are in Give Zonitix support temporary access. A grant lasts a whole number of hours from 1 to 72 and cannot be extended: a second grant while one is live answers 409, so revoke first. Every rule the server enforces, the endpoints and what is audited are in Support Access Reference.

On Key Rotation

Session tokens are signed with HMAC-SHA-256 (HS256) using one symmetric secret held on your instance; it reaches each service as a file-based secret. Replacing that secret is a change on the server, and every token issued before the change stops verifying. Which keys exist, which can be replaced and what replacing one does is on Data Isolation, under Keys and rotation.

Standard Headers

Limiters are configured to emit the standard RateLimit-* headers, so a client can back off before it is refused, and not the legacy X-RateLimit-* set. The second-factor limiter (/auth/mfa/* and the /auth/webauthn/* sign-in and enrolment routes) is the exception: it does not set either option, so do not rely on RateLimit-* headers on those routes.

Keyed By IP

Auth limiters key on client IP; which value that is, and in what order it is read, is under How The Client Address Is Determined above. If your integration egresses through one NAT address, budget for the whole office sharing that allowance. The step-up limiter keys on client IP plus the signed-in user, and the AI, Security Lab and personal API token limiters count per user or per token.

Related reference