Skip to main content
The v2 API surfaces every error as an RFC 7807 ProblemDetails document, served as application/problem+json. Switch on the code extension — it’s part of the contract and won’t move under your feet. The title and detail strings are human-readable and may be reworded between releases.

Response shape

Validation responses

When binding fails or a FluentValidation rule rejects, the response includes an errors map:
Keys are JSON property paths; the empty key carries object-level errors that aren’t tied to a specific field. A route or query value that names an enum member is matched without regard to case. One that matches no member is rejected the same way, keyed by the parameter name and listing what is accepted:
A JSON body the API cannot read is rejected before any handler runs. The empty key in errors says what was wrong: the missing required properties, the JSON path of a value with the wrong type, or the line and position of malformed JSON.
A request with no body at all on an endpoint that needs one returns the same code with detail set to A JSON request body is required. and target naming the parameter. A value that cannot be read from the route or query string returns detail A route or query value could not be read. A wrong Content-Type returns 415 UNSUPPORTED_MEDIA_TYPE, and a wrong verb 405 METHOD_NOT_ALLOWED, each with this envelope.

Error code catalogue


Mapping behavior

A few specific cases are worth calling out because they affect how you should design retries and surface failures to your own users.
When a downstream SIEM rejects a request with a 4xx (404 for an unknown ID, 400 for an unparseable filter, 409 for a conflict, 429 for rate-limit, 408/504 for timeout), the v2 API surfaces that as the matching 4xx — NOT_FOUND, VALIDATION_ERROR, CONFLICT, RATE_LIMITED, TIMEOUT — rather than collapsing onto an opaque 502. That way your retry logic can act on what’s actually wrong.Only opaque or 5xx upstream failures stay as UPSTREAM_ERROR. Upstream 401/403 also stay opaque (they mean our credential to the upstream is broken; that’s not something you can fix).
When the caller disconnects mid-request, the response is an empty 499 and no ProblemDetails body is written. Treat 499 as “request was cancelled before we could respond” — your client probably already knows.
Some development-mode payloads previously carried a traceId extension from ASP.NET. The v2 contract is requestId only. Quote the requestId value when contacting support — we can correlate it to backend logs without you needing to share anything else.

Correlating with our logs

Every requestId is also recorded in our backend logs. Including it in support requests dramatically shortens triage:
Hello, I’m seeing intermittent 502 UPSTREAM_ERROR on POST /api/v2/incidents/across-workspaces. Example requestId: 0HNLBAGCRD4RN:00000003 at 2026-04-15T20:00:00Z.
We can pull the full backend trace and pinpoint the failure without needing the request body or your credentials.