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 " ,
The HTTP status code is on the response itself (e.g., 404). The body carries:
Field Type Description codestringMachine-readable error code — use this for programmatic handling messagestringHuman-readable description of what went wrong metaobjectAdditional context (optional, varies by error)
Status Name Description 400Bad Request The request body or parameters are invalid 401Unauthorized Missing or invalid authentication credentials 403Forbidden Valid credentials but insufficient permissions 404Not Found The requested resource does not exist 409Conflict The request conflicts with the current state of a resource 422Unprocessable Entity The request is well-formed but semantically invalid 429Too Many Requests Rate limit exceeded 500Internal Server Error Unexpected server error
Error Code Status Description INVALID_CREDENTIALS401Email or password is incorrect AUTHENTICATION_REQUIRED401No valid session or API key provided SESSION_EXPIRED401Session has expired, re-authenticate UNAUTHORIZED401General authentication failure INVALID_OR_EXPIRED_TOKEN401Token (reset, verification) is invalid or expired API_KEY_INVALID401API key is malformed or does not exist API_KEY_DISABLED401API key has been deactivated API_KEY_EXPIRED401API key has passed its expiration date
Error Code Status Description FORBIDDEN403Generic access denied INSUFFICIENT_PERMISSION403User lacks the required permission for this action NO_PROJECT_ACCESS403User does not have access to this project NOT_ORGANIZATION_MEMBER403User is not a member of the organization PERMISSION_DENIED403Permission check failed GRANULAR_RESTRICTION403Blocked by language or namespace restrictions ROLE_HIERARCHY_VIOLATION403Cannot assign a role higher than your own API_KEY_PERMISSIONS_REVOKED403API key’s permissions have been revoked
Error Code Status Description NOT_FOUND404Generic resource not found USER_NOT_FOUND404User does not exist ORGANIZATION_NOT_FOUND404Organization does not exist PROJECT_NOT_FOUND404Project does not exist API_KEY_NOT_FOUND404API key does not exist LOCALE_NOT_FOUND404Locale does not exist TRANSLATION_KEY_NOT_FOUND404Translation key does not exist NAMESPACE_NOT_FOUND404Namespace does not exist WEBHOOK_NOT_FOUND404Webhook does not exist WEBHOOK_DELIVERY_NOT_FOUND404Webhook delivery does not exist INVITATION_NOT_FOUND404Invitation does not exist HISTORY_NOT_FOUND404History entry does not exist
Error Code Status Description EMAIL_ALREADY_USED409An account with this email already exists USER_ALREADY_IN_ORGANIZATION409User is already a member of this organization LOCALE_ALREADY_EXISTS409This locale is already added to the project TRANSLATION_KEY_ALREADY_EXISTS409A key with this name already exists in the namespace NAMESPACE_ALREADY_EXISTS409A namespace with this name already exists UNIQUE_CONSTRAINT409A unique constraint was violated INVITATION_ALREADY_SENT409An invitation has already been sent to this email PASSWORD_ALREADY_SET409Password has already been set for this account
Error Code Status Description VALIDATION_ERROR400General validation failure INVALID_INPUT400Input data is invalid FIELD_REQUIRED400A required field is missing FIELD_TOO_SHORT400Field value is below the minimum length FIELD_TOO_LONG400Field value exceeds the maximum length MISSING_PARAMS400Required URL parameters are missing SYNTAX_ERROR400Request body has a syntax error (invalid JSON) INVALID_ROLE400The specified role is not valid
Error Code Status Description FILE_TOO_LARGE400Uploaded file exceeds the size limit FILE_TYPE_NOT_ALLOWED400File format is not supported INVALID_FILE_STRUCTURE400File content does not match the expected structure TOO_MANY_KEYS400Import exceeds the maximum number of translation keys ZIP_BOMB_DETECTED400Compressed file detected as potentially malicious JSON_BOMB_DETECTED400JSON file detected as potentially malicious COMPRESSION_RATIO_EXCEEDED400File compression ratio exceeds the safety threshold IMPORT_SESSION_EXPIRED400The import session has timed out IMPORT_SESSION_MISMATCH400Import confirmation does not match the started session
Error Code Status Description RATE_LIMIT_EXCEEDED429Too many requests, retry after the Retry-After header value TOO_MANY_REQUESTS429General rate limiting
Error Code Status Description LIMIT_EXCEEDED403Plan limit reached (e.g., max projects, max keys) FEATURE_NOT_AVAILABLE403Feature not available on your current plan READ_ONLY_MODE403Organization is in read-only mode (subscription expired) SUBSCRIPTION_NOT_FOUND404No active subscription found PLAN_NOT_FOUND404The referenced billing plan does not exist INSUFFICIENT_CREDITS402Not enough credits for this operation ACTIVE_SUBSCRIPTION_REQUIRED403An active subscription is required for this action CANNOT_CANCEL_FREE_PLAN400Cannot cancel a free plan
Error Code Status Description CANNOT_REMOVE_LAST_OWNER400Cannot remove or demote the last owner INVITATION_EXPIRED400The invitation link has expired INVALID_INVITATION400The invitation is invalid or has already been used CANNOT_DELETE_LAST_PROVIDER400Cannot remove the only authentication provider
Error Code Status Description FAILED_TO_CREATE_PROJECT500Internal error during project creation CANNOT_REMOVE_DEFAULT_LOCALE400Cannot remove the source language from a project LOCALE_NOT_ENABLED400The locale is not enabled for this project
Error Code Status Description WEBHOOK_NOT_FOUND404Webhook does not exist WEBHOOK_DELIVERY_NOT_FOUND404Delivery record does not exist WEBHOOK_RETRY_NOT_ALLOWED400Can only retry deliveries with failed status
Error Code Status Description INTERNAL_ERROR500Unexpected internal error INTERNAL_SERVER_ERROR500General server error UNKNOWN500An unknown error occurred
const response = await fetch ( ' https://api.comvi.io/api/v1/projects ' , {
headers : { ' X-API-Key ' : apiKey },
const error = await response . json ();
case ' AUTHENTICATION_REQUIRED ' :
// Redirect to login or refresh API key
case ' INSUFFICIENT_PERMISSION ' :
// Show permission denied message
console . error ( ` Access denied: ${ error . message } ` );
case ' RATE_LIMIT_EXCEEDED ' :
// Retry after the specified delay
const retryAfter = response . headers . get ( ' Retry-After ' );
console . log ( ` Rate limited. Retry after ${ retryAfter } seconds ` );
// Display validation errors to the user
console . error ( ` Validation failed: ${ error . message } ` , error . meta );
console . error ( ` API error: ${ error . code } - ${ error . message } ` );
const data = await response . json ();
// Process successful response
// Handle network errors (DNS failure, timeout, etc.)
console . error ( ' Network error: ' , networkError );
Check the HTTP status code and parse the JSON error body:
response =$( curl -s -w " \n%{http_code} " \
-H " X-API-Key: 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 "
When your request is rate-limited (429), the response includes headers to help you retry:
Header Description Retry-AfterSeconds to wait before retrying X-RateLimit-LimitMaximum requests allowed in the window X-RateLimit-RemainingRequests remaining in the current window