HFU Digital Docs
StarPlan APIGuides

Rate limits

Throttle windows enforced on the public StarPlan endpoints

The public StarPlan endpoints (catalog, week, iCal, changes) sit behind @nestjs/throttler with three rolling windows applied per client IP:

WindowMax requests
1 second10
1 minute60
1 hour1 000

These limits apply to every public read endpoint, regardless of whether you send an X-API-Key. The presence of an API key does not raise the limit — keys exist for webhook subscription and usage telemetry, not throttle exemption.

The developer (/v1/starplan/developers/*) and webhook (/v1/starplan/webhooks*) endpoints are not currently rate-limited at the application layer — only the upstream Cloudflare and platform-level limits apply. Treat them as low-volume management endpoints; do not poll them.

Identification

Rate limits key on the requesting IP address (@nestjs/throttler default). Behind a CDN or reverse proxy, the platform reads the original client IP from the X-Forwarded-For header chain, so a single client cannot bypass the limit by routing through an intermediary.

Exceeding a window

The throttler responds with 429 Too Many Requests and standard Retry-After semantics. The error envelope follows the same shape as other API errors — see Errors.

{
  "error": {
    "code": "TOO_MANY_REQUESTS",
    "message": "ThrottlerException: Too Many Requests",
    "details": {}
  }
}

What to do

  • Cache aggressively. Catalog data (programs, semesters, courses, rooms, instructors) changes at most once per StarPlan sync cycle. Cache it for at least an hour.
  • Use the iCal feed for calendar consumers. It already carries Cache-Control: public, max-age=600, and a 365-day horizon means one fetch covers an entire year.
  • Use webhooks instead of polling for change events. A webhook subscription is cheaper than scraping /changes on a timer — see Webhooks.
  • Batch your reads. Prefer /courses?periodId=… over fetching each course one by one.
  • Backoff on 429. Respect Retry-After; do not hammer.

The previous splan-api documentation referenced separate anonymous and API-key tiers (5/30/200 vs 10/60/1000). That distinction was retired with the migration to /v1/starplan — only the unified 10/60/1000 tier remains.

On this page