Skip to content

Error Reference

When an API request fails, Comvi returns a consistent error response with a machine-readable error code, a human-readable message, and optional metadata for debugging.

All errors follow this structure:

{
"code": "PROJECT_NOT_FOUND",
"message": "Project not found",
"meta": {
"projectId": 123
}
}

The HTTP status code is on the response itself (e.g., 404). The body carries:

Field Type Description
code string Machine-readable error code — use this for programmatic handling
message string Human-readable description of what went wrong
meta object Additional context (optional, varies by error)

Status Name Description
400 Bad Request The request body or parameters are invalid
401 Unauthorized Missing or invalid authentication credentials
403 Forbidden Valid credentials but insufficient permissions
404 Not Found The requested resource does not exist
409 Conflict The request conflicts with the current state of a resource
422 Unprocessable Entity The request is well-formed but semantically invalid
429 Too Many Requests Rate limit exceeded
500 Internal Server Error Unexpected server error

Error Code Status Description
INVALID_CREDENTIALS 401 Email or password is incorrect
AUTHENTICATION_REQUIRED 401 No valid session or API key provided
SESSION_EXPIRED 401 Session has expired, re-authenticate
UNAUTHORIZED 401 General authentication failure
INVALID_OR_EXPIRED_TOKEN 401 Token (reset, verification) is invalid or expired
API_KEY_INVALID 401 API key is malformed or does not exist
API_KEY_DISABLED 401 API key has been deactivated
API_KEY_EXPIRED 401 API key has passed its expiration date
Error Code Status Description
FORBIDDEN 403 Generic access denied
INSUFFICIENT_PERMISSION 403 User lacks the required permission for this action
NO_PROJECT_ACCESS 403 User does not have access to this project
NOT_ORGANIZATION_MEMBER 403 User is not a member of the organization
PERMISSION_DENIED 403 Permission check failed
GRANULAR_RESTRICTION 403 Blocked by language or namespace restrictions
ROLE_HIERARCHY_VIOLATION 403 Cannot assign a role higher than your own
API_KEY_PERMISSIONS_REVOKED 403 API key’s permissions have been revoked
Error Code Status Description
NOT_FOUND 404 Generic resource not found
USER_NOT_FOUND 404 User does not exist
ORGANIZATION_NOT_FOUND 404 Organization does not exist
PROJECT_NOT_FOUND 404 Project does not exist
API_KEY_NOT_FOUND 404 API key does not exist
LOCALE_NOT_FOUND 404 Locale does not exist
TRANSLATION_KEY_NOT_FOUND 404 Translation key does not exist
NAMESPACE_NOT_FOUND 404 Namespace does not exist
WEBHOOK_NOT_FOUND 404 Webhook does not exist
WEBHOOK_DELIVERY_NOT_FOUND 404 Webhook delivery does not exist
INVITATION_NOT_FOUND 404 Invitation does not exist
HISTORY_NOT_FOUND 404 History entry does not exist
Error Code Status Description
EMAIL_ALREADY_USED 409 An account with this email already exists
USER_ALREADY_IN_ORGANIZATION 409 User is already a member of this organization
LOCALE_ALREADY_EXISTS 409 This locale is already added to the project
TRANSLATION_KEY_ALREADY_EXISTS 409 A key with this name already exists in the namespace
NAMESPACE_ALREADY_EXISTS 409 A namespace with this name already exists
UNIQUE_CONSTRAINT 409 A unique constraint was violated
INVITATION_ALREADY_SENT 409 An invitation has already been sent to this email
PASSWORD_ALREADY_SET 409 Password has already been set for this account
Error Code Status Description
VALIDATION_ERROR 400 General validation failure
INVALID_INPUT 400 Input data is invalid
FIELD_REQUIRED 400 A required field is missing
FIELD_TOO_SHORT 400 Field value is below the minimum length
FIELD_TOO_LONG 400 Field value exceeds the maximum length
MISSING_PARAMS 400 Required URL parameters are missing
SYNTAX_ERROR 400 Request body has a syntax error (invalid JSON)
INVALID_ROLE 400 The specified role is not valid
Error Code Status Description
FILE_TOO_LARGE 400 Uploaded file exceeds the size limit
FILE_TYPE_NOT_ALLOWED 400 File format is not supported
INVALID_FILE_STRUCTURE 400 File content does not match the expected structure
TOO_MANY_KEYS 400 Import exceeds the maximum number of translation keys
ZIP_BOMB_DETECTED 400 Compressed file detected as potentially malicious
JSON_BOMB_DETECTED 400 JSON file detected as potentially malicious
COMPRESSION_RATIO_EXCEEDED 400 File compression ratio exceeds the safety threshold
IMPORT_SESSION_EXPIRED 400 The import session has timed out
IMPORT_SESSION_MISMATCH 400 Import confirmation does not match the started session
Error Code Status Description
RATE_LIMIT_EXCEEDED 429 Too many requests, retry after the Retry-After header value
TOO_MANY_REQUESTS 429 General rate limiting
Error Code Status Description
LIMIT_EXCEEDED 403 Plan limit reached (e.g., max projects, max keys)
FEATURE_NOT_AVAILABLE 403 Feature not available on your current plan
READ_ONLY_MODE 403 Organization is in read-only mode (subscription expired)
SUBSCRIPTION_NOT_FOUND 404 No active subscription found
PLAN_NOT_FOUND 404 The referenced billing plan does not exist
INSUFFICIENT_CREDITS 402 Not enough credits for this operation
ACTIVE_SUBSCRIPTION_REQUIRED 403 An active subscription is required for this action
CANNOT_CANCEL_FREE_PLAN 400 Cannot cancel a free plan
Error Code Status Description
CANNOT_REMOVE_LAST_OWNER 400 Cannot remove or demote the last owner
INVITATION_EXPIRED 400 The invitation link has expired
INVALID_INVITATION 400 The invitation is invalid or has already been used
CANNOT_DELETE_LAST_PROVIDER 400 Cannot remove the only authentication provider
Error Code Status Description
FAILED_TO_CREATE_PROJECT 500 Internal error during project creation
CANNOT_REMOVE_DEFAULT_LOCALE 400 Cannot remove the source language from a project
LOCALE_NOT_ENABLED 400 The locale is not enabled for this project
Error Code Status Description
WEBHOOK_NOT_FOUND 404 Webhook does not exist
WEBHOOK_DELIVERY_NOT_FOUND 404 Delivery record does not exist
WEBHOOK_RETRY_NOT_ALLOWED 400 Can only retry deliveries with failed status
Error Code Status Description
INTERNAL_ERROR 500 Unexpected internal error
INTERNAL_SERVER_ERROR 500 General server error
UNKNOWN 500 An unknown error occurred

try {
const response = await fetch('https://api.comvi.io/api/v1/projects', {
headers: { Authorization: `Bearer ${apiKey}` },
});
if (!response.ok) {
const error = await response.json();
switch (error.code) {
case 'AUTHENTICATION_REQUIRED':
// Redirect to login or refresh API key
break;
case 'INSUFFICIENT_PERMISSION':
// Show permission denied message
console.error(`Access denied: ${error.message}`);
break;
case 'RATE_LIMIT_EXCEEDED':
// Retry after the specified delay
const retryAfter = response.headers.get('Retry-After');
console.log(`Rate limited. Retry after ${retryAfter} seconds`);
break;
case 'VALIDATION_ERROR':
// Display validation errors to the user
console.error(`Validation failed: ${error.message}`, error.meta);
break;
default:
console.error(`API error: ${error.code} - ${error.message}`);
}
return;
}
const data = await response.json();
// Process successful response
} catch (networkError) {
// Handle network errors (DNS failure, timeout, etc.)
console.error('Network error:', networkError);
}

Check the HTTP status code and parse the JSON error body:

Terminal window
response=$(curl -s -w "\n%{http_code}" \
-H "Authorization: Bearer comvi_your_api_key" \
https://api.comvi.io/api/v1/projects/999)
http_code=$(echo "$response" | tail -1)
body=$(echo "$response" | head -1)
if [ "$http_code" -ne 200 ]; then
echo "Error $http_code: $body"
fi

When your request is rate-limited (429), the response includes headers to help you retry:

Header Description
Retry-After Seconds to wait before retrying
X-RateLimit-Limit Maximum requests allowed in the window
X-RateLimit-Remaining Requests remaining in the current window