Sonny Labs Docs
Error codes

Error codes

Stable dot-namespaced identifiers returned in the RFC 9457 Problem envelope's `code` field. Branch on these in your SDK exception handlers.

Every error response from the Sonny Labs API is an RFC 9457 application/problem+json envelope with a stable, dot-namespaced code field. The type URL on the envelope points back to one of the pages below — branch on code in your SDK exception handlers, not on title or detail.

CodeHTTPSummary
auth.api_key.expired401The API key authenticated correctly but its expires_at is in the past.
auth.forbidden403The principal is authenticated but is not allowed to perform this operation.
auth.forbidden_scope403The credential is valid but does not carry the scope this operation requires.
auth.no_org_context400The request authenticated but no org_id was bound to the session — typically a misconfigured caller.
auth.scope.insufficient403Variant of auth.forbidden_scope returned by the API's scope check.
auth.scope.missing403Alias of auth.scope.insufficient retained for SDK dispatch compatibility.
auth.token.invalid401A credential was supplied but failed signature, format, or expiry validation.
auth.unauthenticated401The request reached an authenticated endpoint without a credential the server could verify.
http.403403Generic 403 returned when the server forbids the request without a more specific code.
idempotency.key_reuse_mismatch409The same Idempotency-Key was reused with a different request body.
invites.already_member409The accepting user is already a member of the target organisation.
invites.email_mismatch403The accepting user's email does not match the email the invite was issued for.
invites.expired410The invite token is past its expires_at and is no longer valid.
invites.not_found404The invite token is unknown to the server, or has been revoked.
invites.principal_email_unavailable403The accepting user's identity provider did not release an email claim, so the invite-email match check cannot run.
onboarding.already_in_org409The signed-in user attempted to create a new org while already belonging to one.
onboarding.unsupported_in_self_hosted501Org-creation is disabled in self-hosted deployments — the operator provisions orgs out of band.
org.not_provisioned409The principal is authenticated but their organisation has not finished provisioning yet.
resource.not_found404The path matched no route or the requested entity does not exist (or is not visible to this principal).
scans.invalid_param400A query parameter on the scans endpoints failed validation.
scans.not_found404The scan id did not resolve in the principal's org.
service.not-ready503The backend received a request before its readiness probe transitioned to ready.
tenant.quota_exceeded429The organisation has exceeded a billing or fair-use quota for the requested operation.
upstream.unavailable502, 503A downstream dependency the dashboard or backend relies on is unreachable.
users.invalid_cursor400The opaque pagination cursor on /v1/users could not be decoded.
users.invalid_param400A query parameter on the users endpoints failed validation.
validation.body_invalid400Request body parsed as JSON but failed bean-validation rules.
validation.body_unparseable400Request body could not be parsed as JSON at all.
validation.error400Generic 400 surfaced when a request fails ad-hoc validation that is not bucketed into a more specific code.
validation.invalid_json400Variant of validation.body_unparseable returned by the dashboard when a proxied request body is not valid JSON.
validation.parameter_invalid400A query or path parameter failed bean-validation rules.
validation.parameter_missing400A required query or path parameter was not supplied.
validation.parameter_type_mismatch400A query or path parameter could not be converted to the expected type.

Namespaces

  • auth.* — credential rejected, scope missing, session expired.
  • validation.* — request body / parameter failed validation.
  • resource.* — path or entity not found in the principal's org.
  • idempotency.*Idempotency-Key collision.
  • scans.* — scan-specific 4xx on the scans endpoints.
  • upstream.* — downstream dependency unreachable; safe to retry.
  • tenant.* — billing / quota exhaustion.
  • invites.*, onboarding.*, org.*, users.* — auth-domain 4xx not covered by the broad auth.* namespace.
  • service.* — readiness / liveness probe failures during boot.
  • http.* — fallback shape used when the server forbids or rejects the request without a more specific typed code.

SDK exception mapping

The SDKs dispatch on code first, then fall back to HTTP status:

NamespacePython SDKTypeScript SDK
auth.*AuthenticationErrorAuthenticationError
validation.*ValidationErrorValidationError
idempotency.*IdempotencyConflictErrorIdempotencyConflictError
403 (any)ScopeMissingErrorScopeMissingError
404 (any)NotFoundErrorNotFoundError
429 (any)RateLimitErrorRateLimitError
5xx (any)ServerErrorServerError

See the Python SDK quickstart and TypeScript SDK quickstart for the full dispatch tables.

On this page