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
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
const response = await fetch ( ' https://api.comvi.io/api/v1/projects ' , {
headers : { Authorization : ` Bearer ${ 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 " 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 "
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