Errors and Status Codes

The HTTP and validation error patterns clients should expect and translate into UX or retries.

PixService uses standard HTTP status codes and returns JSON problem details for public request failures, including controller validation and empty authorization responses. Treat the stable code and typed extension fields as the machine-readable contract; titles and human-readable detail may become more specific over time.

Common status codes

  • 400 Bad Request: malformed input, missing required fields, or an invalid field value.
  • 401 Unauthorized: no valid session or bearer credential, or a credential that is invalid, expired, or revoked before authorization can run.
  • 403 Forbidden: a visible target is known, but the current operation is not authorized.
  • 404 Not Found: the target does not exist or is intentionally opaque to the current caller. Clients must not try to distinguish those cases.
  • 409 Conflict: an idempotency, optimistic-concurrency, duplicate-name, or current-state conflict. Refresh authoritative state before retrying.
  • 422 Unprocessable Entity: a permission or entitlement policy mutation is structurally valid JSON but violates catalog or governance rules.
  • 429 Too Many Requests: a request-rate boundary was reached. Honor the response retry guidance.
  • 503 Service Unavailable: a required dependency or bounded authorization plan is temporarily unavailable. Retry only idempotent operations with backoff.

Problem envelope

Errors use application/problem+json. Every response includes status, title, type, code, retryable, and traceId. detail is display text and may change without changing the error's meaning. Additional fields are feature-specific; ignore unknown fields and show a general failure for an unknown code.

{
  "status": 409,
  "title": "Conflict",
  "type": "urn:pixservice:errors:upload_state_conflict",
  "detail": "Upload session is not accepting transfer operations.",
  "code": "upload_state_conflict",
  "retryable": false,
  "traceId": "request-trace-id"
}

Common codes include request_validation_failed, authentication_required, authentication_failed, invalid_personal_access_token, account_unavailable, access_denied, resource_not_found, resource_conflict, resource_gone, payload_too_large, rate_limited, dependency_unavailable, and internal_error. Upload state and concurrent finalization conflicts use upload_state_conflict and upload_finalization_conflict. Spatial edit conflicts use resource_revision_conflict with currentRevision and conflictingFields. Existing permission, billing, volume and idempotency codes remain feature-specific.

Internal failures return a sanitized 500 and internal_error; they are not reported as invalid user input. retryable: true describes a potentially transient condition, not permission to replay a write. It does not override the endpoint's idempotency rules. Invalid login credentials return 401 without directing an already signed-in browser to refresh its session.

Permission denials for known resources

When the caller may safely know a protected target exists, centralized action enforcement returns 403 with code: "permission_action_denied". Its arrays keep repair paths separate:

FieldMeaning
missingOrdinaryCapabilitiesThe user's ordinary ACL does not supply the required value.
entitlementCeilingsThe organization's exact entitlement version caps the capability below the required value.
personalAccessTokenCeilingsThe current PAT organization or capability scope narrows the session result.
storageCapacityA Document or Bundle addition exceeds effective storage capacity (storage_capacity_exceeded).
currentResourceCountsCluster or Location creation exceeds current-count capacity (cluster_limit_exceeded or location_limit_exceeded).
monthlyJobAdmissionThe UTC-month logical Job allowance is exhausted (monthly_job_limit_exceeded) and includes its reset boundary.
lifetimeJobAdmissionThe non-resetting organization-lifetime logical Job allowance is exhausted (lifetime_job_limit_exceeded).

One response may contain more than one family. Do not translate an entitlement, PAT, or capacity failure into an instruction to add a user or group assignment. The response omits contributing principals, assignment sources, PAT IDs, and detailed usage ledgers.

If revealing the target would disclose protected metadata, the operation returns a metadata-free 404 with the same resource_not_found code as a missing resource: no permission code, context, or missing requirement arrays are included. Current-user effective-permission lookups use the same opacity rule. External share-link preflight labels safely visible ordinary, entitlement, credential, visibility, and action-prerequisite layers, while collapsing hidden members into one identifier-free opaque group.

Retrying safely

Use a documented idempotency key for supported mutations and reuse it only for the exact same operation. On 409, reload current versions before deciding whether to retry. On 429 or retryable 503, use bounded exponential backoff. Never retry a non-idempotent mutation automatically unless its endpoint documents an idempotency contract.

On this page