https://api.grantiva.io
Rate limiting
Two layers of rate limiting apply:- Per-IP — DoS protection on the challenge and validate endpoints. Applied before the tenant limit.
- Per-tenant — a Redis sliding 60-second window, scoped per organization and endpoint bucket, with limits set by your plan tier.
Headers
Rate-limited endpoints attach these headers to every response:
A 429 body looks like:
Per-tier limits
Requests per minute, per organization, by endpoint bucket:
Flag limits are 4x attestation limits to accommodate SDK polling. API key limits are lower than SDK limits because calls originate from a server, not individual devices.
Rate limiting fails open: if the limiter backend is unavailable, requests are allowed through. Treat limits as a ceiling, not a guarantee of throttling behavior.
402 vs 429
These are different signals — don’t handle them the same way:
The 402 body includes the details you need:
Request IDs
Every response carries anX-Request-ID header. If you send X-Request-ID on the request, your value is echoed back; otherwise the server generates a UUID. The same ID appears as requestId in error bodies and in server logs — include it in support requests.
Deployment version
Every response carries anX-Grantiva-Commit header with the deployed commit SHA. Useful for verifying which version you’re talking to.
Error envelope
API errors return a JSON envelope with a stable machine-readablecode, a developer-readable message in error, and (where useful) a hint:
Attestation endpoints use domain-specific codes (see validate errors). Generic failures map to codes derived from the HTTP status:
bad_request, unauthorized, forbidden, not_found, conflict, unprocessable_entity, rate_limited, internal_error.