Errors

Every error uses the same envelope:

{ "error": { "code": "…", "message": "…" } }

code is a stable machine-readable string; message is a human-readable explanation. Some errors add fields (e.g. 429 adds retryAfterSec and scope). Guardian Logs never reveals whether another org, app, token, or resource exists.

Status codes

StatusWhenTypical code
200Success (read endpoints).
202Ingest accepted — inspect results[] for per-event outcome.
400Invalid input or filter value.malformed_json, empty, invalid_request
401Missing / malformed / unknown / revoked / expired credential, or wrong credential type. Uniform.unauthorized
403Ingest: source disabled. Read: valid key missing the required scope.source_disabled, forbidden
404Resource not found (a cross-tenant id is indistinguishable from a nonexistent one).not_found
413Ingest payload too large (body > 1 MB, or > 500 events).payload_too_large, batch_too_large
429Rate limit exceeded.rate_limited
500Unexpected server error.

503 is returned only by the public GET /api/health probe when the database is unreachable.

By surface

Read API (gl_api_…)

StatusMeaning
400Bad filter — e.g. an unknown status/severity on /issuesinvalid_request.
401Bad/missing API key (uniform).
403Key valid but missing the endpoint's scope.
404Resource not in your organization, or nonexistent.
429Per-key or per-org request budget exceeded.

Ingest (gl_live_…)

StatusMeaning
400Body not valid JSON (malformed_json) or no events (empty).
401Bad/missing ingest token (uniform).
403The token's log source is disabled (source_disabled).
413Body > 1 MB (payload_too_large) or > 500 events (batch_too_large).
429Per-token or per-org event budget exceeded (rate_limited).

Note: within a 202, an individual malformed event is reported as rejected in results[] rather than failing the whole request — see ingest.md.

Examples

Uniform auth failure (401):

{ "error": { "code": "unauthorized", "message": "Invalid or expired API key." } }

Missing scope (403):

{ "error": { "code": "forbidden", "message": "This API key is missing the required scope: issues:read." } }

Not found (404):

{ "error": { "code": "not_found", "message": "Issue not found." } }

Invalid filter (400):

{ "error": { "code": "invalid_request", "message": "Invalid severity. One of: CRITICAL, HIGH, MEDIUM, LOW." } }

Rate limited (429):

{ "error": { "code": "rate_limited", "message": "Rate limit exceeded.", "retryAfterSec": 12, "scope": "org" } }

Retry guidance

Retry on network errors, timeouts, 429, and 5xx (with backoff + jitter). Do not retry 400, 401, 403, 404, or 413 — fix the request or credential first. For ingest, reuse idempotency keys on retry.

See also: authentication.md · scopes.md · rate-limits.md.