API Rate Limits
Every request to https://api.primecal.eu/api is rate limited. Limits depend on who is
calling (your tier) and what you're calling (the endpoint category).
Tiers
| Tier | Who gets it |
|---|---|
guest | Unauthenticated requests |
user | Signed-in users and most API keys |
premium | System administrators, and users on the Enterprise or Store usage plan |
Your tier is resolved automatically from your auth context — there's nothing to configure. An API key can also carry its own tier independent of the calling user's plan.
Categories and limits
Every endpoint falls into one category based on its path. Limits are requests per 60-second window unless noted.
| Category | Matches | guest | user | premium |
|---|---|---|---|---|
auth | /auth/* (excluding the paths below) | 8 | 20 | 40 |
oauth | /auth/google, /auth/microsoft | 60 | 120 | 240 |
availability | /auth/username-availability, /auth/email-availability, any /availability path | 30 | 80 | 180 |
booking | /reservations/*, /booking/*, /public-booking/* | 20 | 120 | 300 |
admin | /admin/* | 4 | 30 | 120 |
default | everything else | 40 | 180 | 450 |
availability uses a token-bucket algorithm (allows short bursts); every other category uses
a sliding window.
A request's effective limit can be reduced automatically if PrimeCal's abuse-prevention system sees a high risk score for your IP/identity. The table above is the baseline, not a hard guarantee at every moment.
Response headers
Every response — successful or not — includes:
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Your limit for this request's category and tier |
X-RateLimit-Remaining | Requests remaining in the current window |
X-RateLimit-Reset | Unix timestamp (seconds) when the window resets |
X-RateLimit-Policy | <algorithm>;w=<windowSeconds>;tier=<tier>;category=<category> |
When you're rate limited
A request over the limit returns HTTP 429 with a Retry-After header (seconds) and a JSON
body:
{
"statusCode": 429,
"message": "Too many requests",
"details": {
"tier": "user",
"category": "default",
"retryAfterSeconds": 12
}
}
Wait at least retryAfterSeconds before retrying. Don't retry in a tight loop — that keeps you
inside the same window.
Practical guidance
- Batch and cache where you can, especially against the
admincategory — its limits are intentionally low. - Authenticate — the
guesttier is the most restrictive across every category. Signing in or using an API key roughly doubles your budget on most categories. - A 429 does not mean something is broken — it means you're calling faster than your tier
allows. Check
X-RateLimit-Remainingbefore you hit zero rather than reacting after a 429. - If your integration genuinely needs a higher limit, higher usage plans (Enterprise, Store) get
the
premiumtier automatically — see Plans and Pricing.