Error Codes Reference
Last Updated: 2026-02-16
This document provides a complete reference of all error codes, HTTP status codes, and error responses returned by the cloak.business API.
Table of Contents#
- Error Response Format
- HTTP Status Codes
- Error Codes by Category
- Handling Errors
- Troubleshooting Guide
Error Response Format#
All API errors return a consistent JSON structure:
{
"error": "Error type (short)",
"message": "Human-readable description",
"code": "MACHINE_READABLE_CODE",
"details": {
"field": "Additional context"
}
}
| Field | Type | Description |
|---|---|---|
error | string | Short error type identifier |
message | string | Human-readable explanation |
code | string | Machine-readable error code (optional) |
details | object | Additional context (optional) |
HTTP Status Codes#
Success Codes#
| Code | Name | Description |
|---|---|---|
| 200 | OK | Request succeeded |
| 201 | Created | Resource created successfully |
| 204 | No Content | Request succeeded, no response body |
Client Error Codes#
| Code | Name | Description |
|---|---|---|
| 400 | Bad Request | Invalid request parameters |
| 401 | Unauthorized | Invalid or missing authentication |
| 402 | Payment Required | Insufficient tokens |
| 403 | Forbidden | Feature not available on plan |
| 404 | Not Found | Resource does not exist |
| 409 | Conflict | Resource conflict (duplicate) |
| 413 | Payload Too Large | Request body exceeds limits |
| 422 | Unprocessable Entity | Validation failed |
| 429 | Too Many Requests | Rate limit exceeded |
Server Error Codes#
| Code | Name | Description |
|---|---|---|
| 500 | Internal Server Error | Unexpected server error |
| 502 | Bad Gateway | Backend service unavailable |
| 503 | Service Unavailable | Service temporarily unavailable |
| 504 | Gateway Timeout | Backend request timed out |
Error Codes by Category#
Authentication Errors (401)#
| Code | Message | Cause | Solution |
|---|---|---|---|
AUTH_MISSING | Authorization header missing | No Authorization header | Add Authorization: Bearer YOUR_KEY |
AUTH_INVALID | Invalid API key | API key is malformed or revoked | Check key format, regenerate if needed |
AUTH_EXPIRED | Token expired | Session or API token expired | Re-authenticate or refresh token |
AUTH_SCHEME | Invalid authorization scheme | Not using Bearer scheme | Use Bearer prefix |
Example:
{
"error": "Unauthorized",
"message": "Invalid API key",
"code": "AUTH_INVALID"
}
Fix:
# Verify your API key format
curl -H "Authorization: Bearer cb_your_key_here" ...
Token/Billing Errors (402)#
| Code | Message | Cause | Solution |
|---|---|---|---|
INSUFFICIENT_TOKENS | Insufficient tokens | Not enough tokens for operation | Purchase more tokens |
TOKENS_EXHAUSTED | Monthly allocation exhausted | Monthly limit reached | Wait for reset or upgrade |
PAYMENT_REQUIRED | Payment required | Account has unpaid balance | Update payment method |
Example:
{
"error": "Insufficient tokens",
"message": "Operation requires 50 tokens, you have 23",
"code": "INSUFFICIENT_TOKENS",
"details": {
"required": 50,
"available": 23
}
}
Fix:
Check your balance and purchase tokens if needed:
curl https://cloak.business/api/user/tokens \
-H "Authorization: Bearer YOUR_KEY"
Plan/Feature Errors (403)#
| Code | Message | Cause | Solution |
|---|---|---|---|
FEATURE_NOT_AVAILABLE | Feature not available | Feature requires higher plan | Upgrade your plan |
PLAN_LIMIT_EXCEEDED | Plan limit exceeded | Exceeded plan-specific limit | Upgrade or wait for reset |
IMAGE_NOT_AVAILABLE | Image redaction not available | Image features require Basic+ | Upgrade to Basic plan |
BATCH_NOT_AVAILABLE | Batch processing not available | Batch requires Basic+ | Upgrade to Basic plan |
Example:
{
"error": "Feature not available",
"message": "Image redaction is not available on the Free plan. Please upgrade.",
"code": "FEATURE_NOT_AVAILABLE",
"details": {
"feature": "image_redaction",
"required_plan": "basic",
"current_plan": "free"
}
}
Validation Errors (400)#
| Code | Message | Cause | Solution |
|---|---|---|---|
INVALID_REQUEST | Invalid request | Malformed JSON or missing fields | Check request body |
INVALID_LANGUAGE | Invalid language | Language code not supported | Use ISO 639-1 code |
INVALID_ENTITIES | Invalid entities | Unknown entity type | Check entity names |
INVALID_OPERATOR | Invalid operator | Unknown operator type | Use valid operator |
INVALID_HASH_TYPE | Invalid hash type | Hash type not supported | Use sha256 or sha512 |
MISSING_FIELD | Required field missing | Required parameter not provided | Include required field |
Example:
{
"error": "Invalid request",
"message": "Language must be a valid 2-letter ISO 639-1 code",
"code": "INVALID_LANGUAGE",
"details": {
"provided": "english",
"expected": "2-letter code (e.g., 'en', 'de')"
}
}
Fix:
{
"text": "Hello world",
"language": "en"
}
Size Limit Errors (413)#
| Code | Message | Cause | Solution |
|---|---|---|---|
TEXT_TOO_LONG | Text size limit exceeded | Text exceeds plan limit | Split into smaller chunks |
FILE_TOO_LARGE | File too large | File exceeds 10 MB limit | Reduce file size |
TOO_MANY_ENTITIES | Too many entities | >50 entities in request | Reduce entity list |
TOO_MANY_RECOGNIZERS | Too many ad-hoc recognizers | >50 recognizers | Reduce recognizer count |
TOO_MANY_PATTERNS | Too many patterns | >200 total patterns | Reduce pattern count |
Example:
{
"error": "Text size limit exceeded",
"message": "Text length 600000 exceeds plan limit of 500000 characters",
"code": "TEXT_TOO_LONG",
"details": {
"provided": 600000,
"limit": 500000,
"plan": "basic"
}
}
Plan Limits:
| Plan | Max Text Length | Max File Size |
|---|---|---|
| Free | 100,000 chars | N/A |
| Basic | 500,000 chars | 10 MB |
| Professional | 1,000,000 chars | 10 MB |
| Enterprise | Unlimited | 50 MB |
Rate Limit Errors (429)#
| Code | Message | Cause | Solution |
|---|---|---|---|
RATE_LIMITED | Rate limit exceeded | Too many requests | Wait and retry |
DAILY_LIMIT_EXCEEDED | Daily upload limit reached | Daily file limit hit | Wait until tomorrow |
MONTHLY_LIMIT_EXCEEDED | Monthly upload limit reached | Monthly limit hit | Upgrade or wait |
Example:
{
"error": "Rate limit exceeded",
"message": "Too many requests. Please wait before retrying.",
"code": "RATE_LIMITED",
"retryAfter": 60
}
Response Headers:
Retry-After: 60
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1708099200
Fix:
Implement exponential backoff:
import time
def call_api_with_retry(func, max_retries=3):
for attempt in range(max_retries):
response = func()
if response.status_code == 429:
retry_after = int(response.headers.get("Retry-After", 60))
time.sleep(retry_after)
continue
return response
raise Exception("Max retries exceeded")
Service Errors (5xx)#
| Code | Message | Cause | Solution |
|---|---|---|---|
MODEL_LOADING | Language model loading | Model being loaded | Retry after delay |
SERVICE_UNAVAILABLE | Service unavailable | Backend down | Retry later |
INTERNAL_ERROR | Internal server error | Unexpected error | Contact support |
TIMEOUT | Request timeout | Processing took too long | Reduce input size |
Example - Model Loading:
{
"error": "MODEL_LOADING",
"message": "Language model for 'ja' is being loaded. Please retry.",
"retry_after": 30,
"language": "ja"
}
Fix:
Large language models (Japanese, Chinese, Korean) may take 30-90 seconds to load on first use. Retry after the suggested delay:
import time
response = analyze(text, language="ja")
if response.status_code == 503 and response.json().get("error") == "MODEL_LOADING":
retry_after = response.json().get("retry_after", 30)
time.sleep(retry_after)
response = analyze(text, language="ja")
Handling Errors#
Python Example#
import requests
from typing import Optional
class CloakAPIError(Exception):
def __init__(self, status_code: int, error: str, message: str, code: Optional[str] = None):
self.status_code = status_code
self.error = error
self.message = message
self.code = code
super().__init__(f"{status_code} {error}: {message}")
def call_api(endpoint: str, payload: dict) -> dict:
response = requests.post(
f"https://cloak.business/api{endpoint}",
headers={"Authorization": f"Bearer {API_KEY}"},
json=payload
)
if response.status_code >= 400:
data = response.json()
raise CloakAPIError(
status_code=response.status_code,
error=data.get("error", "Unknown"),
message=data.get("message", "Unknown error"),
code=data.get("code")
)
return response.json()
# Usage
try:
result = call_api("/presidio/analyze", {"text": "Hello"})
except CloakAPIError as e:
if e.code == "INSUFFICIENT_TOKENS":
print("Need to purchase more tokens")
elif e.code == "RATE_LIMITED":
print("Rate limited, will retry")
else:
print(f"API error: {e}")
JavaScript Example#
class CloakAPIError extends Error {
constructor(statusCode, error, message, code) {
super(`${statusCode} ${error}: ${message}`);
this.statusCode = statusCode;
this.error = error;
this.code = code;
}
}
async function callAPI(endpoint, payload) {
const response = await fetch(`https://cloak.business/api${endpoint}`, {
method: "POST",
headers: {
"Authorization": `Bearer ${API_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify(payload)
});
const data = await response.json();
if (!response.ok) {
throw new CloakAPIError(
response.status,
data.error || "Unknown",
data.message || "Unknown error",
data.code
);
}
return data;
}
// Usage
try {
const result = await callAPI("/presidio/analyze", { text: "Hello" });
} catch (e) {
if (e instanceof CloakAPIError) {
switch (e.code) {
case "INSUFFICIENT_TOKENS":
console.log("Need more tokens");
break;
case "RATE_LIMITED":
console.log("Will retry later");
break;
default:
console.error(`API error: ${e.message}`);
}
}
}
Troubleshooting Guide#
"Unauthorized" (401)#
- Check API key format: Must start with
cb_ - Check header: Must be
Authorization: Bearer YOUR_KEY - Verify key is active: Check Dashboard > API Keys
- Regenerate if needed: Create a new key
"Insufficient tokens" (402)#
- Check balance: GET
/api/user/tokens - Estimate cost: Analyze ~1 token/1000 chars + entities
- Purchase tokens: Dashboard > Billing > Buy Tokens
"Rate limit exceeded" (429)#
- Wait: Check
Retry-Afterheader - Reduce frequency: Add delays between requests
- Batch requests: Use
/batchfor multiple texts - Upgrade: Higher plans have higher limits
"Text too long" (413)#
- Check limit: See plan limits above
- Split text: Process in chunks
- Upgrade: Higher plans have higher limits
"Model loading" (503)#
- Wait: Models load on first use
- Retry: After
retry_afterseconds - Pre-warm: Send a test request at startup
"Invalid language" (400)#
- Use ISO 639-1: 2-letter codes only
- Supported:
en,de,fr,es,it,pt,nl,pl,ru,ja,zh,ko, etc. - Check spelling:
"en"not"english"
Support#
If you encounter an error not listed here or need assistance:
- Email: support@cloak.business
- Documentation: cloak.business/docs
- Status: status.cloak.business
Include the following in support requests:
- Error response (full JSON)
- Request endpoint and parameters (without sensitive data)
- Timestamp of the error
- Your plan type
Document maintained by cloak.business