Skip to main content

Errors

All error responses share a common JSON envelope:

{ "message": "Human-readable, localized message.", "code": "optional_code" }

message is localized per the active locale (see Localization). code is an optional machine-readable identifier.

Validation errors (422)​

Validation failures add a field-keyed errors map (Laravel-compatible):

{
"message": "The given data was invalid.",
"errors": {
"email": ["The email field is required."],
"password": ["The password field must be at least 8 characters."]
}
}

Status codes​

StatusMeaning
400Malformed request
401Not authenticated
403Authenticated but not permitted (RBAC / policy / cross-tenant)
404Not found, or not visible to the current tenant
419CSRF token missing/expired (SPA flow) — refetch /sanctum/csrf-cookie
422Validation failed (see above)
429Rate limit exceeded (see Rate limiting)
5xxServer error (reported to Sentry)

Tenant isolation and 404​

Cross-tenant access does not leak existence: a resource that belongs to another tenant is invisible under Row Level Security and returns 404, not 403.

Request id (debugging)​

Every API response carries an X-Request-Id header. The value is also attached to every structured log line for that request (request_id), so quoting it lets support correlate your request with the server logs.

You may supply your own correlation id by sending an X-Request-Id request header (alphanumerics, dot, underscore and hyphen; capped at 128 characters); otherwise the server generates one. When reporting a problem, include the X-Request-Id from the failing response.

Security headers​

API responses include baseline security headers (X-Content-Type-Options, X-Frame-Options, Referrer-Policy, a conservative Content-Security-Policy, and Strict-Transport-Security over HTTPS). These are defensive and do not affect normal client usage.