Northlight Weather API

Error codes

Every error response has the same shape: an error object with a code from the table below, a human-readable message that may change between releases, the requestId of the failed request and, for validation errors, a details object naming the parameter. Branch on the code, never on the message.

{
  "error": {
    "code": "parameter_invalid",
    "message": "hours must be an integer between 1 and 48",
    "requestId": "req_7f3a9c2e",
    "details": { "parameter": "hours", "received": "0" }
  }
}
Field Type Description
code string One of the codes below. Stable; treat unknown codes as errors.
message string For humans and logs. Not stable.
requestId string Quote it to support. Also sent as the X-Request-Id header.
details object Present on 400 errors; names the parameter and the value seen.

All codes

Code HTTP Meaning Retry
parameter_missing 400 A required parameter is absent. No
parameter_invalid 400 A parameter has the wrong type or is out of range. No
range_too_wide 400 A history range is too long for its step or starts before the retention. No
key_invalid 401 The Authorization header is missing or malformed. No
key_revoked 401 The key was revoked or rotated. No
key_scope 403 The key's project does not cover the station. No
plan_required 403 The endpoint or the horizon needs a higher plan. No
station_unknown 404 No station has that code. No
not_acceptable 406 Accept names a representation other than JSON. No
station_retired 410 The station stopped reporting permanently. No
rate_limited 429 The window is exhausted. After Retry-After
upstream_delayed 503 The station has not reported in time. With backoff
maintenance 503 The API is being upgraded; announced in the release notes. After Retry-After

Request errors

A 400 describes a request that can be corrected before it is sent again. The details object names the parameter and repeats the value the server saw, so nothing has to be parsed out of the message. Validate ranges before sending: hours is 1 to 48, days 1 to 7, limit 1 to 1,000 for history and 1 to 200 for the directory, and step is one of 10m, 1h and 1d.

range_too_wide is the one 400 that depends on the plan. It is returned when from is earlier than the plan's history retention allows, and when a range at the 10m step spans more than 31 days. The details object carries earliest, the first instant the plan can serve, so a client can clamp its range and retry once.

Authorization errors

A 401 means the key itself was not accepted. key_invalid is almost always a formatting problem: a missing Bearer prefix, a key pasted with a trailing newline from a secrets file, or a test key sent to a live station. key_revoked follows a rotation or a revocation and is permanent for that key; deploy the new key everywhere before revoking the old one.

A 403 means the key is fine but the request is not. key_scope says the station is not in the key's project; add it in the console rather than creating a second project. plan_required says the endpoint or the horizon is not in the plan, and its details.plan names the lowest plan that allows it.

Availability errors

A 503 is temporary by definition. upstream_delayed means the station has been silent for more than six hours; the station directory shows the same in lastObservedAt, and the station usually returns within a day. maintenance is rare and announced in the release notes beforehand, and it always carries Retry-After.

A client that sorts codes into three groups covers every case:

switch (body.error?.code) {
  case "rate_limited":
  case "upstream_delayed":
  case "maintenance":
    return retryLater(response)
  case "station_retired":
    return removeStation(station)
  case "key_revoked":
    return alertOperators("Northlight key revoked")
  default:
    throw new Error(`${body.error.code}: ${body.error.message}`)
}
Northlight Weather API