Error catalogue
Published verbatim from Gungner’s Brayns partner interface pack, version 1.6.0 (
errors.md). This page is not edited here.
Every error code the API can emit, with its fix. 401 = no valid token; 403 = valid token, wrong tenant, scope or missing legal basis; 404 only when the resource is provably absent for that tenant — see semantics.md §10. Surface the code, not the message, in your own logs.
| Code | Status | Fix |
|---|---|---|
bad_request |
400 | The request body or query did not validate against the route schema. Check the field named in message against reference.md. |
budget_exceeded |
429 | The tenant’s daily paid-API call budget is exhausted. Wait for the next window, or ask the tenant to raise its budget. Cached data (stale: true) may still be available. |
country_not_granted |
403 | The identifier names a country (the xx: prefix; none means se:) outside the countries this grant carries. Ask the tenant to add that country to the grant, then mint a new token. |
country_not_provisioned |
403 | The identifier names a country the tenant is not provisioned for. Countries are provisioned by Gungner on signed terms; ask the tenant to contact Gungner. |
country_not_supported |
501 | The country is granted and provisioned, but Gungner does not serve this resource there yet, and nothing was looked up. Lithuanian company and person data, and monitoring or screening of a subject identified only in Lithuania, are unlocked by the Lithuanian connectors (SPEC-003f, SPEC-003g); until they land these answer 501. A subject that also holds a Swedish identifier is served as Swedish. The coverage matrix in reference.md lists what each country serves today. |
forbidden |
403 | The token is valid but lacks the scope the route requires. Ask the tenant to grant the consumer that scope; the message names it. |
grant_countries_invalid |
400 | A grant’s countries must be a non-empty subset of the tenant’s provisioned countries; there is no wildcard. Pick countries the tenant is provisioned for, or ask Gungner to provision the country first. A change that would leave an existing grant outside the tenant’s countries — narrowing the tenant’s provisioned set under an active grant, or emptying a grant — is refused whole, and grants names each grant in the way: revoke or re-scope those first. |
identifier_in_argument |
422 | Not returned by any route. The assistant refused one of its own tool calls because the arguments the model wrote contained a raw personnummer or samordningsnummer rather than the opaque handle it was given. Nothing was looked up and the value was not stored. Ask the question again. |
internal_error |
500 | An unexpected server error occurred. Retry; if it persists, report it with the request time — no further detail is returned to the client (hard rule 5). |
invalid_client |
401 | The client_id/client_secret pair presented to POST /oauth/token is not valid. Check the consumer credentials issued in the portal. |
invalid_cursor |
400 | The cursor is malformed: not 0 or the exact decimal spelling next_cursor returned. Restart from cursor 0 — delivery is at-least-once with idempotency keys, so this is safe. A well-formed cursor beyond the newest event you can see is not an error: it returns an empty page and the same cursor back. |
invalid_identifier |
400 | The organisationsnummer or other identifier — in the path, or in the request body on POST /v1/screening/checks — is not well-formed. Check the check digit and format against reference.md. |
invalid_link |
401 | The magic-link token could not be parsed. Request a new sign-in link. |
legal_basis_invalid |
400 | legal_basis must be one of aml_cdd, contract, legal_obligation, consent, legitimate_interest (ADR-011 §2). legal_basis_ref beside it is free text and is never parsed. |
link_expired |
401 | The magic-link token has expired. Request a new sign-in link. |
link_invalid |
401 | The magic-link token does not match any issued link. Request a new sign-in link. |
link_used |
401 | The magic-link token has already been consumed. Request a new sign-in link. |
name_is_identifier |
400 | The name of an ad-hoc screening check carries a number shaped like a personal identity number (a personnummer, samordningsnummer or Lithuanian asmens kodas — judged by shape, so a ten-digit number with a date-shaped middle counts). A name is stored with the check and a name-only check is visible to every grant of the tenant, so an identifier is never accepted there. Resolve the person with POST /v1/subjects/resolve and screen by subject_id. Nothing was looked up or stored, and the value is not repeated in the response. |
not_found |
404 | The resource does not exist for this tenant. Confirm the id and that it belongs to the tenant the token is scoped to. |
provisioned_countries_invalid |
400 | Not returned to a consumer; answered on Gungner’s ops routes. A tenant’s own country must be one of the countries it is provisioned for: provision it with its own country included, and do not remove that country from its provisioned set. |
ref_conflict |
409 | The customer reference is already attached to a different subject. References are immutable once set; use the existing subject or a new reference. |
screening_unavailable |
503 | The screening matcher is unavailable, or no screening policy version is active, so no check was performed and nothing was stored. Retry; a screening check is never served from cache, so there is no stale result to accept in the meantime. If it persists, report it with the request time. |
spar_permit_required |
403 | Person data and person monitoring both run under the tenant’s own SPAR permit, and this tenant has no active one — it is missing, not yet valid, or past its validity. No upstream call was made and no subscription was created. Ask the tenant to complete its SPAR permit (SKV 1537); Gungner activates it once the permit document is in hand. |
spar_permit_suspended |
403 | The tenant’s SPAR permit has been suspended, so person data cannot be read under it. No upstream call was made. Suspension is not reversible in place: a reinstated permit is activated as a new permit. |
subscription_ended |
409 | The subscription has already ended. Ending is one-way: create a new subscription to resume monitoring, which starts a fresh legal basis and a fresh retention clock. |
subscription_exists |
409 | An active subscription already covers this subject and kind for this tenant. Read it with GET /v1/subscriptions, or end it before creating another — monitoring is one subscription per subject, so a merge never doubles it or its cost. |
tenant_pending |
403 | The tenant this token belongs to has not been activated yet. Ask the tenant’s admin to complete onboarding. |
unauthorized |
401 | No valid bearer token (or portal session) was presented, or it failed to verify. Mint a new token at POST /oauth/token, or sign in again. |
upstream_unavailable |
503 | The upstream source is unavailable and no fresh cached value exists for this request. Retry later, or accept stale: true on a subsequent call once the cache is populated — except on GET /v1/persons/{ref}, which never serves a stale profile and returns this instead (see semantics.md §8). |