Errors
The Sphere API uses standard HTTP status codes to indicate the success or failure of a request. When something goes wrong, the response body includes a structured error message to help you diagnose the issue.
You can identify whether a request succeeded by checking the HTTP status code. Codes in the 2xx range indicate success, 4xx codes indicate a client error (something in your request is wrong), and 5xx codes indicate a server-side issue.
Every error response includes an X-Correlation-Id header. Include this ID when reporting issues — it allows us to trace the exact request through all services.
Status codes
Here is a complete list of HTTP status codes returned by the Sphere API, grouped by category.
Success codes
- Name
200 OK- Description
The request succeeded and the response body contains the requested data.
- Name
201 Created- Description
A new resource was created successfully. The response body contains the created resource.
- Name
204 No Content- Description
The request succeeded but there is no response body. Commonly returned by DELETE operations.
Client error codes
- Name
400 Bad Request- Description
The request is malformed — invalid JSON, missing required headers, or unrecognized parameters.
- Name
401 Unauthorized- Description
Authentication failed. The token is missing, expired, or invalid.
- Name
403 Forbidden- Description
The authenticated user does not have permission to perform this action. Check workspace role and scopes.
- Name
404 Not Found- Description
The requested resource does not exist, or you do not have access to it in the current tenant context.
- Name
409 Conflict- Description
The request conflicts with the current state of the resource. For example, creating a tenant with a slug that already exists.
- Name
422 Unprocessable Entity- Description
Validation failed. The request body contains invalid data. See the
errorsobject for field-level details.
- Name
429 Too Many Requests- Description
Rate limit exceeded. Wait for the duration specified in the
Retry-Afterheader before retrying.
Server error codes
- Name
500 Internal Server Error- Description
An unexpected error occurred on the server. If this persists, report it with the
X-Correlation-Id.
- Name
502 Bad Gateway- Description
The gateway received an invalid response from an upstream service. This can occur during engine orchestration if a dependent service is down.
- Name
503 Service Unavailable- Description
The service is temporarily unavailable, usually during maintenance or deployment. Retry after a short delay.
Status code summary
2xx Success
├── 200 OK
├── 201 Created
└── 204 No Content
4xx Client Error
├── 400 Bad Request
├── 401 Unauthorized
├── 403 Forbidden
├── 404 Not Found
├── 409 Conflict
├── 422 Unprocessable Entity
└── 429 Too Many Requests
5xx Server Error
├── 500 Internal Server Error
├── 502 Bad Gateway
└── 503 Service Unavailable
Error response format
All error responses follow a consistent JSON structure. The exact shape depends on the type of error.
General errors (4xx/5xx)
Most errors return a simple message field describing what went wrong.
Validation errors (422)
Validation errors include an additional errors object that maps field names to arrays of error messages. This allows you to display field-level errors in forms.
General error (401)
{
"message": "Unauthenticated."
}
Validation error (422)
{
"message": "The given data was invalid.",
"errors": {
"login": [
"The login field is required."
],
"password": [
"The password must be at least 8 characters."
]
}
}
Conflict error (409)
{
"message": "A tenant with slug 'acme' already exists."
}
Validation errors (422)
When you submit a request with invalid data, the API returns a 422 status code with detailed field-level errors. Each field that failed validation is listed in the errors object with an array of human-readable error messages.
Common validation rules include:
- Name
required- Description
The field must be present and non-empty.
- Name
email- Description
The field must be a valid email address.
- Name
min:N- Description
The field must have at least N characters (strings) or be at least N (numbers).
- Name
max:N- Description
The field must not exceed N characters or value.
- Name
unique- Description
The value must not already exist in the database (e.g., duplicate email).
curl -X POST https://your-sphere.example.com/auth/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"login": "", "password": "short"}'
Authentication errors (401)
A 401 response means the request could not be authenticated. This happens in three cases:
- Name
Missing token- Description
No
Authorizationheader was provided. AddAuthorization: Bearer {access_token}to your request.
- Name
Expired token- Description
The
access_tokenhas expired (after 60 minutes). Use therefresh_tokento obtain a new one via/auth/api/v1/auth/refresh.
- Name
Invalid token- Description
The token is malformed, has been tampered with, or was signed with a different key. Obtain a fresh token by logging in again.
Token expired
{
"message": "Unauthenticated."
}
JavaScript — auto-refresh on 401
async function apiCall(url, token, refreshToken) {
let response = await fetch(url, {
headers: { Authorization: `Bearer ${token}` },
})
if (response.status === 401) {
// Token expired — refresh it
const refreshResponse = await fetch(
'https://your-sphere.example.com/auth/api/v1/auth/refresh',
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ refresh_token: refreshToken }),
},
)
const tokens = await refreshResponse.json()
// Retry with new token
response = await fetch(url, {
headers: { Authorization: `Bearer ${tokens.access_token}` },
})
}
return response
}
Authorization errors (403)
A 403 response means the user is authenticated but does not have sufficient permissions for the requested action. This is different from 401 — the token is valid, but the user's role or scope does not allow the operation.
Common causes:
- Name
Workspace role- Description
The user has a
viewerrole in the workspace but attempted a write operation. Upgrade toeditororowner.
- Name
Token scope- Description
The token was issued with limited scopes (e.g.,
guesttoken type) that do not include the requested permission.
- Name
Resource ownership- Description
The user is trying to access or modify a resource owned by another user without the appropriate admin privileges.
Insufficient permissions
{
"message": "This action is unauthorized."
}
Rate limiting (429)
All Sphere API endpoints enforce rate limiting to protect against abuse. When you exceed the allowed number of requests, the API returns a 429 status with a Retry-After header indicating how many seconds to wait before retrying.
- Name
Retry-After- Type
- response header
- Description
The number of seconds to wait before making another request.
- Name
X-RateLimit-Limit- Type
- response header
- Description
The maximum number of requests allowed in the current window.
- Name
X-RateLimit-Remaining- Type
- response header
- Description
The number of requests remaining in the current window.
Rate limits vary by endpoint. Authentication endpoints have stricter limits to prevent brute-force attacks. Read endpoints generally allow more requests than write endpoints.
Rate limit exceeded (429)
{
"message": "Too Many Attempts."
}
Response headers
HTTP/1.1 429 Too Many Requests
Retry-After: 60
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-Correlation-Id: a1b2c3d4-e5f6-7890-abcd-ef0123456789
JavaScript — respect rate limits
async function fetchWithRetry(url, options, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const response = await fetch(url, options)
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After') || '60'
const waitMs = parseInt(retryAfter, 10) * 1000
await new Promise((resolve) => setTimeout(resolve, waitMs))
continue
}
return response
}
throw new Error('Rate limit exceeded after max retries')
}
Correlation ID
Every response from the Sphere API includes an X-Correlation-Id header. This is a unique identifier that traces the request through all services in the platform — from the Traefik gateway through sphere-auth, sphere-core, and any downstream engines.
When reporting errors or unexpected behavior, always include the correlation ID. It allows the platform team to find the exact request in logs across all services.
Extracting the correlation ID
curl -v https://your-sphere.example.com/core/api/v1/families \
-H "Authorization: Bearer {token}" 2>&1 | grep X-Correlation-Id
# < X-Correlation-Id: a1b2c3d4-e5f6-7890-abcd-ef0123456789