Error Format
All API errors return JSON with this structure:
{
"error": "Short error description",
"detail": "Extended description (optional)"
}
Some endpoints (Django REST Framework defaults) may also return:
{
"detail": "Error message"
}
HTTP Status Codes
| Status | Meaning | When |
|---|---|---|
| 200 | OK | Request succeeded |
| 400 | Bad Request | Missing or invalid parameters |
| 401 | Unauthorized | Missing, expired, or invalid auth token |
| 403 | Forbidden | Token lacks required scope or workspace access |
| 404 | Not Found | Resource doesn't exist or workspace has no synced data |
| 405 | Method Not Allowed | Wrong HTTP method for endpoint |
| 422 | Unprocessable Entity | Request body validation failed |
| 429 | Too Many Requests | Rate limit exceeded |
| 500 | Internal Server Error | Unexpected server error |
| 503 | Service Unavailable | Elasticsearch or other dependency down |
Rate Limits
V1 API (Service Tokens)
| Tier | Limit | Scope |
|---|---|---|
| Burst | 20 requests / 10 seconds | Per token |
| Window | 600 requests / 15 minutes | Per token |
User API (JWT)
| Tier | Limit | Scope |
|---|---|---|
| Authenticated | 100 requests / minute | Per user |
| Anonymous | 20 requests / minute | Per IP |
Rate Limit Headers
When rate limited, the response includes:
HTTP/1.1 429 Too Many Requests
Retry-After: 30
Handling rate limits: Wait for the Retry-After duration (in seconds) before retrying. Implement exponential backoff for repeated 429 responses.
Common Error Scenarios
Authentication Errors
// Missing Authorization header
{"detail": "Authentication credentials were not provided."}
// Invalid or expired JWT
{"detail": "Given token not valid for any token type", "code": "token_not_valid"}
// Invalid service token
{"error": "Invalid or revoked service token."}
// Expired service token
{"error": "Token has expired."}
Permission Errors
// Token missing required scope
{"error": "Token does not have the required scope: graph:search"}
// Workspace not in token's allowed list
{"error": "Workspace not allowed for this token."}
Validation Errors
// Missing required parameter
{"error": "workspace_id is required."}
// Invalid UUID format
{"error": "Invalid node_id format."}
// Query too long (V1 API)
{"error": "Query too long (max 256 characters)."}
// Disallowed characters in query
{"error": "Query contains disallowed characters."}
Resource Errors
// Workspace not synced
{"error": "No synced data found for this workspace."}
// Node not found
{"error": "Node not found."}
// Elasticsearch unavailable
{"error": "Search service unavailable."}