Error Codes Standardized error response format and codes
All API errors return a consistent JSON structure. The GlobalExceptionFilter normalizes every error -- including validation errors, domain exceptions, and unhandled crashes -- into this format.
{
"statusCode" : 400 ,
"code" : "VALIDATION_ERROR" ,
"message" : "Field 'amount' must be a positive number"
}
Field Type Description statusCodenumberHTTP status code (400, 401, 403, 404, 429, 500) codestringMachine-readable error code for programmatic handling messagestringHuman-readable description of the error
Code Description Example VALIDATION_ERRORRequest body failed DTO validation Missing required field, invalid type, value out of range NONCE_EXPIREDAuth nonce expired or not found Wallet verification took too long, nonce was consumed ORDER_FAILEDOrder could not be placed Insufficient balance, market closed, invalid order parameters ORDER_REJECTEDOrder rejected by the exchange Polymarket CLOB rejected the order with a reason ORDER_NOT_FILLEDCannot perform operation on unfilled order Attempting to set TP/SL on an order that hasn't filled MARKET_NOT_ACTIVEMarket is not available for trading Market is closed, resolved, or paused PREPARE_NOT_SUPPORTEDOrder type doesn't support prepare Prepare is supported for Polymarket market orders only SELF_REFERRALUser tried to use their own access key Referral code belongs to the authenticated user INVALID_CODE_FORMATAccess key format is invalid Code must be 4-12 alphanumeric characters INSUFFICIENT_BALANCENot enough funds for the operation Paper trading balance too low, merge/split insufficient shares INSUFFICIENT_SHARESNot enough shares for the operation Trying to sell more shares than held in a position INVALID_SHARESShare count must be positive Partial sell with a non-positive share count FILTER_REQUIREDFilter criteria is required Creating a dynamic wallet list without filter criteria FILTER_NOT_ALLOWEDCannot set filter on this list type Setting filter criteria on a static wallet list CANNOT_MODIFY_DYNAMICCannot manually modify a dynamic list Adding or removing wallets from a dynamic wallet list GROUP_CODE_INACTIVEGroup code has been deactivated Attempting to send a deactivated group code TELEGRAM_LINK_INVALIDTelegram link token is invalid or expired Bad or expired link-account token MISSION_NOT_COMPLETEDMission is not yet completed Attempting to claim a mission before completing it
Code Description Example UNAUTHORIZEDMissing or invalid JWT token No Bearer token, expired access token INVALID_SIGNATUREWallet signature verification failed Signature does not match the expected message INVALID_REFRESH_TOKENRefresh token is invalid or expired Token was revoked, rotated, or past its 7-day TTL INVALID_GOOGLE_TOKENGoogle token verification failed Google OAuth token is invalid, expired, or user info missing
Code Description Example FORBIDDENUser does not have permission Accessing another user's resource, insufficient tier NOT_ELIGIBLEUser is not eligible for the action Cannot generate access key, mission requirements not met ACCOUNT_DISABLEDUser account has been disabled Account was disabled by admin BETA_ACCESS_REQUIREDAn active access key is required User logged in but hasn't activated a beta access key
Code Description Example NOT_FOUNDResource does not exist Generic 404 for all untyped resources USER_NOT_FOUNDUser account not found Wallet address has no associated account MARKET_NOT_FOUNDMarket does not exist Invalid market slug or ID ORDER_NOT_FOUNDOrder does not exist Attempting to cancel a nonexistent order POSITION_NOT_FOUNDPosition does not exist No open position found for the given market ALERT_NOT_FOUNDPrice alert not found Attempting to update or delete a nonexistent alert MISSION_NOT_FOUNDMission does not exist Invalid mission ID LIST_NOT_FOUNDWallet list not found Invalid list ID KEY_NOT_FOUNDAccess key not found Invalid key ID GROUP_CODE_NOT_FOUNDGroup code not found Invalid group code ID RULE_NOT_FOUNDCommission rule not found Invalid commission rule ID
Code Description Example ALREADY_REFERREDUser already has a referral Cannot apply a second referral code ALREADY_ACTIVATEDUser already has an access key activated Cannot activate a second access key ALREADY_CLAIMEDPosition already claimed Trying to claim a resolved position twice CODE_TAKENAccess key code already in use Another user has claimed this custom code KEY_EXISTSCustom key already exists Duplicate key code in the system LIST_NAME_EXISTSWallet list name already exists Duplicate list name for the same user POSITION_NOT_OPENPosition is not open Attempting to sell shares from a closed/claimed position MISSION_ALREADY_CLAIMEDMission rewards already claimed Attempting to claim a mission that was already claimed TELEGRAM_ALREADY_LINKEDTelegram account already connected This Telegram account is linked to a different Vezta account
Code Description Example RATE_LIMITEDRequest rate limit exceeded More than the configured requests per minute from the same IP
Code Description Example INTERNAL_ERRORUnexpected server error Unhandled exception, database connection failure CODE_GENERATION_FAILEDFailed to generate a unique code Random code generation exhausted all retries
When request body validation fails via class-validator, the GlobalExceptionFilter joins all validation messages into a single comma-separated string and forces the code to VALIDATION_ERROR:
{
"statusCode" : 400 ,
"code" : "VALIDATION_ERROR" ,
"message" : "amount must be a positive number, side must be one of: YES, NO"
}
The validation pipe is configured with whitelist: true (strips unknown properties), transform: true (auto-coerces types), and forbidNonWhitelisted: true (rejects unknown fields).
Backend services throw ApiException for business logic errors with a specific code:
throw new ApiException (
'ORDER_FAILED' ,
'Insufficient balance to place this order' ,
HttpStatus. BAD_REQUEST ,
);
When an error does not include an explicit code (e.g., a raw HttpException), the GlobalExceptionFilter maps the HTTP status to a default code:
Status Default Code 400 VALIDATION_ERROR401 UNAUTHORIZED403 FORBIDDEN404 NOT_FOUND429 RATE_LIMITEDOther INTERNAL_ERROR
The frontend API client (lib/api/client.ts) throws an ApiClientError with the full error body. Handle errors by checking the code field:
try {
await placeOrder (orderData);
} catch (error) {
if (error instanceof ApiClientError ) {
switch (error.body.code) {
case 'ORDER_FAILED' :
showToast ( 'Order failed: ' + error.body.message);
break ;
case 'UNAUTHORIZED' :
// 401 retry is handled automatically by the client
break ;
default :
showToast ( 'Something went wrong' );
}
}
}
The API client automatically handles 401 errors by refreshing the access token and retrying the request. You do not need to handle UNAUTHORIZED errors manually in most cases.