Documentation Index
Fetch the complete documentation index at: https://docs.unleeshed.ai/llms.txt
Use this file to discover all available pages before exploring further.
All errors follow a consistent format:
{
"success": false,
"error": {
"code": "error_code",
"message": "Human-readable description",
"details": {} // Optional additional context
}
}
HTTP Status Codes
| Status | Meaning | Action |
|---|
400 | Bad Request | Check request body/parameters |
401 | Unauthorized | Check API key |
403 | Forbidden | Check permissions/licenses |
404 | Not Found | Check resource ID |
429 | Rate Limited | Wait and retry |
500 | Server Error | Retry with backoff |
Common Errors
Authentication Errors (401)
{
"success": false,
"error": {
"code": "unauthorized",
"message": "Invalid or missing API key"
}
}
Solutions:
- Ensure
X-Api-Key header is present
- Check the key hasn’t been revoked
- Verify the key format (
pk_live_...)
License Errors (403)
{
"success": false,
"error": {
"code": "not_licensed",
"message": "No active license for persona",
"details": {
"persona_id": "persona-abc..."
}
}
}
Solutions:
- Check your licensed personas with
GET /personas
- Contact support to license additional personas
Validation Errors (400)
{
"success": false,
"error": {
"code": "invalid_request",
"message": "Content must be between 10 and 500 characters",
"details": {
"field": "content",
"constraint": "length"
}
}
}
Solutions:
- Check request body matches schema
- Ensure required fields are present
- Validate content length limits
Rate Limit Errors (429)
{
"success": false,
"error": {
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded",
"details": {
"retry_after": 3600,
"limit": 1000,
"remaining": 0
}
}
}
Solutions:
- Wait for
retry_after seconds
- Implement request queuing
- Contact support for higher limits
Error Handling Patterns
Basic Error Handler
async function apiRequest(path, options = {}) {
const response = await fetch(`${BASE_URL}${path}`, {
...options,
headers: {
'X-Api-Key': API_KEY,
'Content-Type': 'application/json',
...options.headers
}
});
const data = await response.json();
if (!response.ok) {
throw new UnleeshedError(
data.error.code,
data.error.message,
response.status,
data.error.details
);
}
return data;
}
class UnleeshedError extends Error {
constructor(code, message, status, details = {}) {
super(message);
this.code = code;
this.status = status;
this.details = details;
}
}
Retry with Exponential Backoff
async function requestWithRetry(path, options = {}, maxRetries = 3) {
let lastError;
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await apiRequest(path, options);
} catch (error) {
lastError = error;
// Don't retry client errors (except rate limits)
if (error.status >= 400 && error.status < 500 && error.status !== 429) {
throw error;
}
// Calculate backoff delay
const delay = error.status === 429
? (error.details.retry_after || 60) * 1000
: Math.min(1000 * Math.pow(2, attempt), 30000);
console.log(`Retry ${attempt + 1}/${maxRetries} in ${delay}ms`);
await new Promise(r => setTimeout(r, delay));
}
}
throw lastError;
}
Graceful Degradation
async function getCommentariesSafely(topicId) {
try {
const result = await getTopicWithCommentaries(topicId);
return {
success: true,
data: result.commentaries
};
} catch (error) {
console.error('Failed to fetch commentaries:', error);
// Return partial data or fallback
if (error.code === 'rate_limit_exceeded') {
return {
success: false,
error: 'Please try again in a few minutes',
retryAfter: error.details.retry_after
};
}
if (error.code === 'not_found') {
return {
success: false,
error: 'Commentary not found'
};
}
// Generic fallback
return {
success: false,
error: 'Unable to load commentary. Please try again.'
};
}
}
User-Facing Error Messages
Map error codes to user-friendly messages:
const ERROR_MESSAGES = {
unauthorized: 'Authentication failed. Please contact support.',
not_licensed: 'This content is not available.',
rate_limit_exceeded: 'Too many requests. Please wait a moment.',
invalid_request: 'Invalid request. Please check your input.',
not_found: 'Content not found.',
internal_error: 'Something went wrong. Please try again.',
};
function getUserMessage(error) {
return ERROR_MESSAGES[error.code] || ERROR_MESSAGES.internal_error;
}
Monitoring & Alerting
Track errors in your integration:
async function trackError(error, context = {}) {
// Log to your monitoring service (e.g., Sentry, DataDog)
console.error({
service: 'unleeshed',
code: error.code,
message: error.message,
status: error.status,
...context
});
// Alert on critical errors
if (error.status >= 500 || error.code === 'unauthorized') {
await alertTeam({
severity: 'high',
message: `Unleeshed API Error: ${error.code}`,
details: error
});
}
}
Next Steps
Rate Limits
Understand API rate limits.
API Reference
Complete API documentation.