Caching and rate limits
How long each feed is cached, and how to poll cheaply.
Examples use a fictional festival, summer-fest. Sign in at events.grofomo.com and they switch to your own events.
How long responses live
Most read endpoints are cached at our edge for 60 seconds, with a 5-minute stale-while-revalidate window:
Cache-Control: public, s-maxage=60, stale-while-revalidate=300So a lineup publish can take up to a minute to appear on your site. That is the trade for a feed that survives an on-sale.
Some endpoints differ and say so on their own page — content version is 15 seconds, and anything that changes by the second (merch stock, announcements, any write) is no-store.
The one that surprises people
When an organiser is in key_required mode, their responses are no-store. Not slower — uncached entirely.
The reason is that a shared CDN keys on URL, not on credentials. If a key-holder's 200 were cached, the next anonymous caller would be served that cached copy and the key gate would be worth nothing.
The practical consequence: your own caching does the work. In Next.js, next: { revalidate: 60 }; anywhere else, a small in-process cache or a scheduled build. This is why the quickstart fetches on the server rather than from the browser — one cached server fetch serves every visitor, and a per-visitor browser fetch cannot be cached at all.
Polling without the cost
Do not poll the lineup. Poll the version probe instead — it is tiny, and it moves whenever the event or its lineup is edited:
const { data } = await fetch(
'https://api.grofomo.com/v1/events/summer-fest/version',
).then((r) => r.json());
if (data.scheduleVersion !== lastSeenVersion) {
// Only now pull the heavy feeds.
}Rate limits
Read endpoints allow roughly 60 requests per minute; writes (signups, form submissions) roughly 30. Over the limit you get 429 with a Retry-After header.
Two honest caveats:
- These are guidance, not a contract. The limiter is per-server-instance, so the effective ceiling in production is higher and not exactly predictable. Do not design something that depends on the precise number.
- A key gets its own budget. Without one, you share a bucket with everyone on your IP — which, behind a corporate proxy or a serverless egress pool, may not be only you.
If you cache as described above, you will not come near any of this.