Caching
Cache aggressively. We do, and we expect you to. Most endpoints stay fresh enough at ten-minute TTLs that a single client-side or CDN cache layer eliminates ~90% of duplicate requests against your quota.
Per-endpoint defaults
| Endpoint | s-maxage | stale-while-revalidate |
|---|---|---|
| GET /saints (list) | 300s | 60s |
| GET /saints/{slug} | 300s | 60s |
| GET /saints/{slug}/hymnography | 600s | 120s |
| GET /countries | 600s | 120s |
| GET /countries/{slug} | 600s | 120s |
| GET /calendar/today | 60s | 30s |
| GET /calendar/{date} | 600s | 120s |
| GET /search | 120s | 30s |
| GET /openapi.json | 3600s | 86400s |
Cache-Control header
Every successful response sets a public Cache-Control header. Errors and authenticated-only failures set private, no-store.
HTTP/1.1 200 OK
Cache-Control: public, s-maxage=300, stale-while-revalidate=60
X-RateLimit-Tier: starter
X-RateLimit-Remaining-Minute: 287
X-RateLimit-Remaining-Month: 49823Client-side caching tips
A 30-second in-memory map keyed by URL + endpoint is the cheapest possible win. Next.js users get this for free with fetch() and { next: { revalidate: 300 } }. For long-running services running behind Cloudflare or Vercel, set up an asset-rule to honor our Cache-Controlheaders and you're done.
Bypassing the cache
We don't expose a no-cache toggle. If you need fresher data than the TTL, that's a signal you should be using webhooks (planned for v2) or filing a feature request.