HFU Digital Docs
StarPlan APIGuides

Errors

Wire format and conventional status codes

The StarPlan API uses standard HTTP status codes plus a wrapped JSON body for any non-2xx response.

Envelope

{
  "error": {
    "code": "ERROR_CODE",
    "message": "Human-readable message",
    "details": {}
  }
}

The envelope is produced by the global HttpExceptionFilter in the backend — it is the same shape used by every endpoint on api.hfu.digital, so a single error handler in your client handles StarPlan responses uniformly with the rest of the platform.

details may be {}, an object describing the validation failure, or a small structured payload. Do not depend on its shape changing — only code and message are stable contract.

Conventional status codes

StatusWhen you see it
400 Bad RequestBody validation failed (e.g. webhook URL is not a URL, secret too short, invalid eventTypes). The handler also returns { data: [], error: 'Invalid since timestamp' } from GET /v1/starplan/changes when since is unparseable — this is one of the few endpoints where the error rides inside the data envelope.
401 UnauthorizedMissing or invalid X-API-Key on an authenticated route. Messages are Missing X-API-Key header or Invalid or revoked API key.
403 ForbiddenYou authenticated successfully but the resource is not yours (e.g. fetching another developer's webhook by id).
404 Not FoundUnknown id (program, semester, course, room, instructor, change, webhook), or no upstream URL exists for the requested semester yet.
409 ConflictPOST /v1/starplan/developers/register with an email already in use.
429 Too Many RequestsRate-limit window exceeded. Standard Retry-After header. See Rate limits.
500 Internal Server ErrorUnhandled error. Logged centrally; if it persists across retries, please report it on the linked GitHub repo.

204 No Content

The platform's TransformInterceptor converts handlers that return null or undefined into a 204 No Content response with an empty body. In the StarPlan namespace this happens for:

  • DELETE /v1/starplan/webhooks/:id
  • POST /v1/starplan/developers/deactivate
  • POST /v1/starplan/webhooks/:id/test

(Both delete and the deactivate route also include a confirmation message in their JSON body, so you'll typically see a 200 with that body. The 204 path is reserved for the rare case where a handler explicitly returns nothing.)

Examples

$ curl -i https://api.hfu.digital/v1/starplan/programs/not-a-real-id
HTTP/1.1 404 Not Found
content-type: application/json

{"error":{"code":"NOT_FOUND","message":"Program not-a-real-id not found"}}
$ curl -i -X POST https://api.hfu.digital/v1/starplan/developers/regenerate-key
HTTP/1.1 401 Unauthorized
content-type: application/json

{"error":{"code":"UNAUTHORIZED","message":"Missing X-API-Key header"}}

On this page