Rate limits
Every API key has an independent hourly request budget. When you exhaust it, the API returns 429 Too Many Requests until the rolling window resets.
Per-key hourly budget
Section titled “Per-key hourly budget”The default budget is 1000 requests per rolling hour per API key. Each key carries its own counter — keys are not pooled, and there is no tenant-wide cap on top of the per-key limit.
If 1000/hour is too tight for your integration, ask the operator who issued the key to raise the limit. Operators can set the limit when the key is created. To change the limit on an existing key, the operator revokes it and issues a new one with the desired limit. Don’t assume the limit is 1000 — read it from the operator if you need to reason about exact pacing.
What counts toward the limit
Section titled “What counts toward the limit”Every authenticated request is counted, regardless of outcome:
200 OKand201 Created— counted400,403,404,429— counted (the request reached the API key’s quota before failing)
The single exception is 401 Unauthorized — failed authentication doesn’t count, because the call cannot be attributed to a specific key.
This means you cannot evade the limit by sending broken requests. Validate inputs client-side where possible.
429 response
Section titled “429 response”When a key crosses its budget, the API returns:
HTTP/1.1 429 Too Many RequestsRetry-After: 600Content-Type: application/json
{ "detail": "Request was throttled. Expected available in 600 seconds." }The 600 above is illustrative — the actual value varies (anywhere from 1 to roughly 3600) depending on how much of the rolling window remains.
The Retry-After header is the number of seconds until the next request should succeed (not an HTTP date). Wait at least that long before retrying. Doing anything else — retrying immediately, polling tightly — just keeps the counter pinned.
Audit log
Section titled “Audit log”Every authenticated call is recorded in a per-tenant audit log, regardless of whether it succeeded or hit a 4xx. Each row captures:
- Tenant
- Which API key was used
- HTTP method and request path
- Response status code
- Latency in milliseconds
- Timestamp
The log does not capture request or response bodies — it’s a flat operational trail, not a payload archive.
The operator can review this log in the admin console under Settings → API → Audit. If you suspect a key has leaked or want to debug an integration’s traffic shape, this is the source of truth on what actually hit the API.
Best practices
Section titled “Best practices”A few patterns will keep most integrations comfortably under the limit:
- Cache aggressively. Sites and customer lists change slowly. Pull them once, cache locally, refresh on a schedule (e.g. once an hour) rather than on every user-facing request.
- Page in larger chunks. Use
page_size=200for bulk reads — one 200-record page costs one request, the same as one 50-record page. - Filter on the server. Use the date-range filters on bookings instead of pulling the full list and filtering client-side.
- Back off exponentially on 429. Respect
Retry-After, then on the next failure double the wait, and so on. Capping at a reasonable maximum (e.g. an hour) keeps your integration polite. - Don’t poll. If you need near-real-time bookings, ask your CampOne representative about webhooks — they’re on the roadmap and will replace polling for change feeds.
- Use a separate key per environment. Don’t share one key between production and staging deployments — you’ll lose the ability to attribute traffic in the audit log.