Error Codes Reference
Complete reference of all error codes in the Essence Platform API, including descriptions, causes, and resolution steps.
Error Response Format
All API errors follow this consistent structure:
{
"error": {
"code": "ERROR_CODE",
"message": "Human-readable error message",
"details": {
"field": "additionalInfo"
},
"requestId": "req_1234567890abcdef",
"timestamp": "2025-11-06T10:00:00Z",
"documentation": "https://docs.essence.digital/api/error-codes#ERROR_CODE"
}
}HTTP Status Codes
| Status Code | Meaning | When Used |
|---|---|---|
| 200 | OK | Request successful |
| 201 | Created | Resource created successfully |
| 204 | No Content | Successful deletion |
| 400 | Bad Request | Invalid request format or validation error |
| 401 | Unauthorized | Authentication required or failed |
| 403 | Forbidden | Authenticated but lacks permissions |
| 404 | Not Found | Resource doesn't exist |
| 409 | Conflict | Resource state conflict |
| 422 | Unprocessable Entity | Valid format but semantic errors |
| 429 | Too Many Requests | Rate limit exceeded |
| 500 | Internal Server Error | Server-side error |
| 502 | Bad Gateway | Upstream service error |
| 503 | Service Unavailable | Temporary unavailability |
| 504 | Gateway Timeout | Upstream service timeout |
Authentication Errors (401)
INVALID_API_KEY
Message: "API key is invalid or malformed"
Cause:
- API key format is incorrect
- API key doesn't exist in the system
- API key has been revoked
Resolution:
// Check API key format
const apiKey = process.env.ESSENCE_API_KEY;
if (!apiKey || !apiKey.startsWith('essence_sk_')) {
console.error('Invalid API key format');
}
// Regenerate API key if necessary
// Visit: https://app.essence.digital/settings/api-keysEXPIRED_TOKEN
Message: "JWT token has expired"
Cause:
- Access token lifetime exceeded (1 hour)
- Token was issued too long ago
Resolution:
import { AuthenticationError } from '@essence-platform/sdk';
try {
const vaults = await client.vaults.list();
} catch (error) {
if (error instanceof AuthenticationError && error.code === 'EXPIRED_TOKEN') {
// Refresh the access token
const newToken = await refreshAccessToken(refreshToken);
client.setBearerToken(newToken);
// Retry the request
const vaults = await client.vaults.list();
}
}INVALID_TOKEN
Message: "JWT token is invalid or malformed"
Cause:
- Token signature is invalid
- Token structure is malformed
- Token issuer doesn't match
Resolution:
// User must re-authenticate
await redirectToLogin();MISSING_AUTH
Message: "No authentication credentials provided"
Cause:
- Request missing both
X-Api-KeyandAuthorizationheaders
Resolution:
// Add authentication header
const client = new EssenceClient({
apiKey: process.env.ESSENCE_API_KEY
});REVOKED_TOKEN
Message: "Token has been revoked"
Cause:
- User logged out
- Token manually revoked
- Security event triggered revocation
Resolution:
// User must re-authenticate
await redirectToLogin();Authorization Errors (403)
INSUFFICIENT_PERMISSIONS
Message: "API key lacks required scope"
Cause:
- API key missing required scope for operation
- User doesn't have permission for resource
Details:
{
"code": "INSUFFICIENT_PERMISSIONS",
"message": "API key lacks required scope",
"details": {
"requiredScopes": ["documents:share"],
"providedScopes": ["documents:read", "documents:write"]
}
}Resolution:
// Regenerate API key with correct scopes
// Visit: https://app.essence.digital/settings/api-keys
// Or check permissions before operation
const info = await client.auth.getInfo();
if (info.scopes.includes('documents:share')) {
await client.documents.share(documentId, options);
} else {
console.error('Missing documents:share scope');
}RESOURCE_FORBIDDEN
Message: "You don't have permission to access this resource"
Cause:
- Resource belongs to different user
- Resource requires higher permission level
Resolution:
// Verify resource ownership
const vault = await client.vaults.get(vaultId);
if (vault.userId !== currentUserId) {
console.error('Cannot access vault owned by different user');
}ACCOUNT_SUSPENDED
Message: "Your account has been suspended"
Cause:
- Account suspended due to policy violation
- Payment failure
- Administrative action
Resolution:
- Contact support at support@essence.digital
- Check email for suspension notice
IP_BLOCKED
Message: "Your IP address has been blocked"
Cause:
- Too many failed authentication attempts
- Suspicious activity detected
- Geographic restrictions
Resolution:
- Wait 1 hour for automatic unblock
- Contact support if legitimate traffic
Validation Errors (400)
VALIDATION_ERROR
Message: "Request validation failed"
Cause:
- Missing required fields
- Invalid field values
- Type mismatches
Details:
{
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"details": {
"errors": [
{
"field": "name",
"message": "Name is required",
"code": "REQUIRED"
},
{
"field": "email",
"message": "Invalid email format",
"code": "INVALID_FORMAT"
},
{
"field": "age",
"message": "Must be at least 18",
"code": "MIN_VALUE"
}
]
}
}Resolution:
try {
await client.vaults.create({ name: '' }); // Invalid
} catch (error) {
if (error instanceof ValidationError) {
error.fields.forEach(field => {
console.error(`${field.field}: ${field.message}`);
});
}
}INVALID_REQUEST_FORMAT
Message: "Request body is not valid JSON"
Cause:
- Malformed JSON
- Wrong Content-Type header
Resolution:
// Ensure correct Content-Type
fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data) // Ensure valid JSON
});MISSING_REQUIRED_FIELD
Message: "Required field is missing"
Details:
{
"code": "MISSING_REQUIRED_FIELD",
"details": {
"field": "name",
"location": "body"
}
}Resolution:
// Include all required fields
await client.vaults.create({
name: 'My Vault', // Required
description: 'Optional description'
});INVALID_FIELD_VALUE
Message: "Field value is invalid"
Details:
{
"code": "INVALID_FIELD_VALUE",
"details": {
"field": "category",
"value": "invalid_category",
"allowedValues": ["personal", "health", "financial", "legal", "work", "education"]
}
}Resolution:
// Use valid enum values
await client.vaults.create({
name: 'My Vault',
category: 'health' // Must be valid category
});Resource Errors (404)
NOT_FOUND
Message: "Resource not found"
Cause:
- Resource ID doesn't exist
- Resource was deleted
- Wrong resource ID format
Details:
{
"code": "NOT_FOUND",
"details": {
"resourceType": "vault",
"resourceId": "vault-123"
}
}Resolution:
try {
const vault = await client.vaults.get(vaultId);
} catch (error) {
if (error instanceof NotFoundError) {
console.error('Vault not found:', error.details.resourceId);
// Handle missing resource (create new, show error, etc.)
}
}VAULT_NOT_FOUND
Message: "Vault not found"
Resolution: Verify vault ID and ownership
DOCUMENT_NOT_FOUND
Message: "Document not found"
Resolution: Verify document ID and vault ownership
USER_NOT_FOUND
Message: "User not found"
Resolution: Verify user ID
INSTANCE_NOT_FOUND
Message: "Instance not found"
Resolution: Verify instance ID
Conflict Errors (409)
RESOURCE_ALREADY_EXISTS
Message: "Resource with this identifier already exists"
Cause:
- Duplicate unique field (e.g., email, name)
- Resource creation race condition
Details:
{
"code": "RESOURCE_ALREADY_EXISTS",
"details": {
"resourceType": "webhook",
"conflictingField": "url",
"existingResourceId": "webhook-123"
}
}Resolution:
try {
await client.webhooks.create({ url: 'https://example.com/webhook' });
} catch (error) {
if (error.code === 'RESOURCE_ALREADY_EXISTS') {
// Update existing resource instead
const existingId = error.details.existingResourceId;
await client.webhooks.update(existingId, { events: newEvents });
}
}VAULT_QUOTA_EXCEEDED
Message: "Vault storage quota exceeded"
Cause:
- Vault reached maximum storage limit
- Document upload would exceed quota
Details:
{
"code": "VAULT_QUOTA_EXCEEDED",
"details": {
"vaultId": "vault-123",
"currentSize": 10737418240,
"maxSize": 10737418240,
"additionalSize": 1048576
}
}Resolution:
// Check quota before upload
const vault = await client.vaults.get(vaultId);
const availableSpace = vault.maxStorageBytes - vault.totalSize;
if (fileSize > availableSpace) {
console.error('Insufficient storage space');
// Delete old documents or upgrade plan
} else {
await client.documents.upload(file);
}DOCUMENT_COUNT_EXCEEDED
Message: "Maximum document count exceeded"
Cause:
- Vault reached maximum document limit
Resolution:
// Check document count
const vault = await client.vaults.get(vaultId);
if (vault.documentCount >= vault.maxDocuments) {
console.error('Maximum documents reached');
// Delete old documents or create new vault
}Rate Limiting Errors (429)
RATE_LIMIT_EXCEEDED
Message: "Rate limit exceeded"
Cause:
- Too many requests in time window
- Exceeded hourly/burst limits
- GraphQL complexity limit exceeded
Details:
{
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded",
"details": {
"limit": 1000,
"remaining": 0,
"resetAt": "2025-11-06T11:00:00Z",
"retryAfter": 120
}
}Headers:
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1699564800
Retry-After: 120Resolution:
import { RateLimitError } from '@essence-platform/sdk';
async function makeRequestWithRetry() {
try {
return await client.vaults.list();
} catch (error) {
if (error instanceof RateLimitError) {
const retryAfter = error.retryAfter * 1000;
console.log(`Rate limited. Retrying after ${retryAfter}ms`);
// Wait and retry
await new Promise(resolve => setTimeout(resolve, retryAfter));
return makeRequestWithRetry();
}
throw error;
}
}GRAPHQL_COMPLEXITY_EXCEEDED
Message: "GraphQL query complexity exceeded"
Cause:
- Query requests too many nested fields
- Too many items in list queries
Details:
{
"code": "GRAPHQL_COMPLEXITY_EXCEEDED",
"details": {
"complexity": 150,
"maxComplexity": 100
}
}Resolution:
# ❌ Too complex
query {
vaults {
documents {
shares {
accessLogs {
user {
vaults {
documents # Too nested!
}
}
}
}
}
}
}
# ✅ Simplified
query {
vaults {
id
name
documentCount
}
}Server Errors (500)
INTERNAL_ERROR
Message: "Internal server error"
Cause:
- Unexpected server-side error
- Database connection failure
- Third-party service failure
Resolution:
- Retry the request
- Check status page: https://status.essence.digital
- Contact support if persistent
Example:
async function makeRobustRequest(fn: () => Promise<any>, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await fn();
} catch (error) {
if (error.code === 'INTERNAL_ERROR' && i < maxRetries - 1) {
// Exponential backoff
const delay = Math.pow(2, i) * 1000;
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
throw error;
}
}
}DATABASE_ERROR
Message: "Database operation failed"
Cause:
- Database connection issues
- Query timeout
- Data consistency issues
Resolution:
- Retry the request
- Contact support if persistent
ENCRYPTION_ERROR
Message: "Encryption operation failed"
Cause:
- Invalid encryption metadata
- Corrupted encrypted data
- Unsupported encryption algorithm
Resolution:
// Verify encryption metadata
const metadata = {
algorithm: 'AES-256-GCM', // Must be supported
keyDerivation: 'PBKDF2',
iterations: 100000,
iv: validIV,
authTag: validAuthTag
};Service Unavailable (503)
SERVICE_UNAVAILABLE
Message: "Service temporarily unavailable"
Cause:
- Planned maintenance
- System overload
- Deployment in progress
Resolution:
- Retry with exponential backoff
- Check status page
- Subscribe to status updates
Example:
async function makeRequestWithBackoff() {
const maxRetries = 5;
let retryCount = 0;
while (retryCount < maxRetries) {
try {
return await client.vaults.list();
} catch (error) {
if (error.code === 'SERVICE_UNAVAILABLE') {
retryCount++;
const delay = Math.min(1000 * Math.pow(2, retryCount), 30000);
console.log(`Retrying in ${delay}ms (attempt ${retryCount}/${maxRetries})`);
await new Promise(resolve => setTimeout(resolve, delay));
} else {
throw error;
}
}
}
throw new Error('Max retries exceeded');
}Encryption Errors
INVALID_ENCRYPTION_METADATA
Message: "Encryption metadata is invalid"
Cause:
- Missing required encryption fields
- Invalid IV or auth tag format
- Unsupported algorithm
Resolution:
// Ensure complete metadata
const metadata = {
algorithm: 'AES-256-GCM',
keyDerivation: 'PBKDF2',
iterations: 100000,
iv: Buffer.from(iv).toString('base64'),
authTag: Buffer.from(authTag).toString('base64'),
salt: Buffer.from(salt).toString('base64')
};DECRYPTION_FAILED
Message: "Failed to decrypt data"
Cause:
- Wrong decryption key
- Corrupted encrypted data
- Invalid auth tag (data tampering)
Resolution:
// Verify key and metadata
try {
const decrypted = await decryptData(encryptedData, key, metadata);
} catch (error) {
if (error.code === 'DECRYPTION_FAILED') {
console.error('Decryption failed - wrong key or corrupted data');
// Prompt user for correct key
}
}Webhook Errors
WEBHOOK_DELIVERY_FAILED
Message: "Webhook delivery failed"
Cause:
- Endpoint not responding
- Invalid HTTPS certificate
- Endpoint returned error status
Details:
{
"code": "WEBHOOK_DELIVERY_FAILED",
"details": {
"webhookId": "webhook-123",
"url": "https://your-app.com/webhooks",
"statusCode": 500,
"error": "Connection timeout",
"attemptNumber": 3,
"nextRetry": "2025-11-06T10:15:00Z"
}
}Resolution:
- Verify endpoint is accessible
- Check HTTPS certificate
- Review endpoint logs
- Ensure endpoint responds within 10 seconds
INVALID_WEBHOOK_SIGNATURE
Message: "Webhook signature verification failed"
Cause:
- Wrong webhook secret
- Request body modified
- Signature header missing
Resolution:
// Verify you're using correct secret
const secret = process.env.WEBHOOK_SECRET; // From webhook configuration
// Use raw body for verification
app.post('/webhooks', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['x-essence-signature'];
if (!verifyWebhookSignature(req.body, signature, secret)) {
return res.status(401).send('Invalid signature');
}
// Process event...
});Error Handling Best Practices
1. Use Typed Errors
import {
EssenceError,
AuthenticationError,
AuthorizationError,
NotFoundError,
ValidationError,
RateLimitError
} from '@essence-platform/sdk';
try {
await operation();
} catch (error) {
if (error instanceof ValidationError) {
// Handle validation
} else if (error instanceof RateLimitError) {
// Handle rate limiting
} else if (error instanceof NotFoundError) {
// Handle not found
}
}2. Implement Retry Logic
async function withRetry<T>(
fn: () => Promise<T>,
maxRetries = 3,
retryableErrors = ['INTERNAL_ERROR', 'SERVICE_UNAVAILABLE', 'DATABASE_ERROR']
): Promise<T> {
for (let i = 0; i < maxRetries; i++) {
try {
return await fn();
} catch (error) {
if (retryableErrors.includes(error.code) && i < maxRetries - 1) {
const delay = Math.pow(2, i) * 1000;
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
throw error;
}
}
}3. Log Errors with Context
try {
await client.vaults.create({ name: vaultName });
} catch (error) {
logger.error('Failed to create vault', {
error: error.code,
message: error.message,
vaultName,
userId,
requestId: error.requestId,
timestamp: error.timestamp
});
}4. Handle User-Facing Errors
function getUser FriendlyErrorMessage(error: EssenceError): string {
const messages = {
'INVALID_API_KEY': 'Authentication failed. Please try logging in again.',
'INSUFFICIENT_PERMISSIONS': 'You don\'t have permission to perform this action.',
'NOT_FOUND': 'The requested resource was not found.',
'VALIDATION_ERROR': 'Please check your input and try again.',
'RATE_LIMIT_EXCEEDED': 'Too many requests. Please wait a moment and try again.',
'INTERNAL_ERROR': 'Something went wrong. Please try again later.'
};
return messages[error.code] || 'An unexpected error occurred.';
}Getting Help
If you encounter an error not listed here:
- Check the Request ID in the error response
- Check the Status Page
- Search the Discord Community
- Contact Support with the request ID