Skip to content
Alpha — Headcode is currently in alpha. APIs and data may change without notice.

Error handling

Headcode uses RFC 9457 Problem Details for all error responses. Errors are returned with content type application/problem+json.

Every error response includes these fields:

FieldDescription
typeA URI pointing to the documentation page for this error
titleA short, human-readable summary of the problem type
statusThe HTTP status code
codeA machine-readable Headcode error code
detailA human-readable explanation specific to this occurrence

Some errors also include:

FieldDescription
instanceA URI identifying this specific occurrence
errorsAn array of detailed error objects for validation failures
{
"type": "https://docs.headcode.dev/errors/stations/not-found",
"title": "Station Not Found",
"status": 404,
"code": "HEADCODE.STATIONS.NOT_FOUND",
"detail": "No station found for identifier 'XYZ'."
}

The code field follows a dotted namespace convention: HEADCODE.{DOMAIN}.{ERROR}. Use this field for programmatic error handling rather than parsing the detail message.

CodeStatusMeaning
HEADCODE.GENERAL.BAD_REQUEST400The request is invalid — check the detail and errors fields
HEADCODE.GENERAL.UNAUTHORIZED401Authentication is missing or invalid
HEADCODE.GENERAL.FORBIDDEN403The API key does not have the required scope
HEADCODE.GENERAL.INTERNAL_SERVER_ERROR500An unexpected internal error occurred
HEADCODE.SERVICE.TEMPORARILY_UNAVAILABLE503The service is temporarily unavailable
CodeStatusMeaning
HEADCODE.STATIONS.NOT_FOUND404No station matches the supplied identifier
HEADCODE.SERVICES.NOT_FOUND404No service matches the supplied identifier
HEADCODE.TRAIN_ORDERS.NOT_FOUND404No train order found for the station and filter
HEADCODE.LOCATIONS.NOT_FOUND404No location matches the supplied TIPLOC
HEADCODE.DISRUPTIONS.NOT_FOUND404No disruption matches the supplied identifier
HEADCODE.OPERATIONS.HEARTBEAT_NOT_FOUND404No heartbeat data available
HEADCODE.OPERATORS.NOT_FOUND404No operator matches the supplied code

When a request has multiple validation problems, the errors array provides details for each:

{
"type": "https://docs.headcode.dev/errors/general/bad-request",
"title": "Bad Request",
"status": 400,
"code": "HEADCODE.GENERAL.BAD_REQUEST",
"detail": "Both 'lat' and 'lng' must be provided together.",
"errors": [
{
"detail": "Both 'lat' and 'lng' must be provided together.",
"parameter": "lat"
}
]
}

Each error object may include detail, pointer (for request body fields), parameter (for query or path parameters), or header.

The type field in every error response is a working URL that links to the corresponding page in the Errors section of this documentation.

  • Use the code field for branching logic, not the HTTP status code alone — multiple error types can share the same status.
  • Display the detail field to users when appropriate — it is written in plain British English.
  • For 401 and 403 errors, check that your API key is valid and has the required scopes.
  • For 503 errors, retry with backoff.
  • For 500 errors, retry once. If the error persists, the instance field (when present) is useful for support requests.