Error Codes
Complete reference for 4Quays API error codes and handling
All API errors follow a consistent format with error codes for programmatic handling.
Error Response Format
{
"error": {
"code": "ERROR_CODE",
"message": "Human-readable description"
},
"requestId": "req_abc123"
}
HTTP Status Codes
| Status | Meaning |
|---|---|
| 400 | Bad Request — Invalid input |
| 401 | Unauthorized — Authentication failed |
| 403 | Forbidden — Not permitted |
| 404 | Not Found — Resource doesn't exist |
| 429 | Too Many Requests — Rate limited |
| 500 | Internal Server Error — Something went wrong |
Authentication Errors (401)
AUTHENTICATION_FAILED
{
"error": {
"code": "AUTHENTICATION_FAILED",
"message": "Invalid or expired API key"
}
}
Causes:
- API key is invalid
- API key has been revoked
- Authorization header is missing
Resolution:
- Verify the API key is correct
- Check if the key has been revoked in the dashboard
- Ensure the Authorization header is properly formatted
API_KEY_REVOKED
{
"error": {
"code": "API_KEY_REVOKED",
"message": "This API key has been revoked"
}
}
Causes:
- API key was explicitly revoked in the dashboard
Resolution:
- Generate a new API key in the dashboard
Validation Errors (400)
INVALID_PAYLOAD
{
"error": {
"code": "INVALID_PAYLOAD",
"message": "Payload must be a valid JSON value"
}
}
Causes:
- Payload is not valid JSON
- Payload is missing
- Payload is too large
Resolution:
- Verify JSON syntax
- Ensure Content-Type is
application/json
INVALID_PROTECTED_PAYLOAD
{
"error": {
"code": "INVALID_PROTECTED_PAYLOAD",
"message": "Payload is not a valid protected format"
}
}
Causes:
- Protected payload is malformed
- Payload was modified after protection
- Wrong payload passed to unprotect
Resolution:
- Ensure protected payload is passed unchanged
- Verify you're using the correct protected payload
INVALID_POLICY_NUMBER
{
"error": {
"code": "INVALID_POLICY_NUMBER",
"message": "Policy number format is invalid"
}
}
Causes:
- Policy number contains invalid characters
- Policy number is empty
Resolution:
- Check policy number format
Resource Errors (404)
POLICY_NOT_FOUND
{
"error": {
"code": "POLICY_NOT_FOUND",
"message": "Policy 'INVALID-POLICY' does not exist"
}
}
Causes:
- Policy number doesn't exist
- Policy belongs to a different organization
- Policy has been deleted
Resolution:
- Verify policy number in the dashboard
- Check organization context
KEY_NOT_FOUND
{
"error": {
"code": "KEY_NOT_FOUND",
"message": "Key 'key_abc123' not found"
}
}
Causes:
- Key ID doesn't exist
- Key has been retired
- Key belongs to a different organization
Resolution:
- Verify key exists in the dashboard
- Check if key has been rotated
SERVICE_NOT_FOUND
{
"error": {
"code": "SERVICE_NOT_FOUND",
"message": "Service 'svc_xyz' not found"
}
}
Causes:
- Service ID doesn't exist
- Service has been deleted
Cryptographic Errors (400)
DECRYPTION_FAILED
{
"error": {
"code": "DECRYPTION_FAILED",
"message": "Unable to decrypt payload with the configured key"
}
}
Causes:
- Payload was encrypted with a different key
- Payload is corrupted
- Wrong policy used for unprotect
Resolution:
- Verify the correct policy is used
- Check if key has been rotated since encryption
SIGNATURE_INVALID
{
"error": {
"code": "SIGNATURE_INVALID",
"message": "Signature verification failed"
}
}
Causes:
- Payload was modified after signing
- Wrong key used for verification
- Signature is corrupted
Resolution:
- This may indicate tampering — investigate
- Verify correct policy is used
KEY_EXPIRED
{
"error": {
"code": "KEY_EXPIRED",
"message": "Key 'key_abc123' has expired"
}
}
Causes:
- Key's validity period has ended
Resolution:
- Rotate to a new key
- Update key validity in dashboard
ALGORITHM_NOT_SUPPORTED
{
"error": {
"code": "ALGORITHM_NOT_SUPPORTED",
"message": "Algorithm 'XYZ' is not supported"
}
}
Causes:
- Requested algorithm is not available
Resolution:
- Use a supported algorithm
- Check documentation for supported algorithms
Rate Limiting (429)
RATE_LIMIT_EXCEEDED
{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Retry after 60 seconds."
}
}
Headers included:
Retry-After: 60 X-RateLimit-Limit: 100 X-RateLimit-Remaining: 0 X-RateLimit-Reset: 1707473460
Resolution:
- Wait for the specified retry period
- Implement exponential backoff
- Consider upgrading your rate limit tier
Server Errors (500)
INTERNAL_ERROR
{
"error": {
"code": "INTERNAL_ERROR",
"message": "An unexpected error occurred"
}
}
Causes:
- Server-side issue
Resolution:
- Retry with exponential backoff
- Contact support if persistent
SERVICE_UNAVAILABLE
{
"error": {
"code": "SERVICE_UNAVAILABLE",
"message": "Service temporarily unavailable"
}
}
Causes:
- System maintenance
- Temporary outage
Resolution:
- Retry after a short delay
- Check status page
Error Handling Best Practices
JavaScript/TypeScript
try {
const result = await fourq.protect(payload, 'POLICY-123');
} catch (error) {
switch (error.code) {
case 'AUTHENTICATION_FAILED':
// Re-authenticate or check API key
break;
case 'POLICY_NOT_FOUND':
// Check policy configuration
break;
case 'RATE_LIMIT_EXCEEDED':
// Wait and retry
await sleep(error.retryAfter * 1000);
break;
case 'INTERNAL_ERROR':
// Retry with backoff
break;
default:
// Log and re-throw
console.error('Unexpected error:', error);
throw error;
}
}
Retry Logic
async function protectWithRetry(payload, policy, maxRetries = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await fourq.protect(payload, policy);
} catch (error) {
if (error.code === 'RATE_LIMIT_EXCEEDED') {
await sleep(error.retryAfter * 1000);
continue;
}
if (error.code === 'INTERNAL_ERROR' && attempt < maxRetries) {
await sleep(Math.pow(2, attempt) * 1000);
continue;
}
throw error;
}
}
}
Request IDs
Always log the requestId from error responses:
try {
await fourq.protect(payload, 'POLICY');
} catch (error) {
console.error(`Error ${error.code} [${error.requestId}]: ${error.message}`);
// Use requestId when contacting support
}
Related
- API Reference — API overview
- Audit Logs — Debug with audit logs