VeztaVezta

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.

Response Format

{
  "statusCode": 400,
  "code": "VALIDATION_ERROR",
  "message": "Field 'amount' must be a positive number"
}
FieldTypeDescription
statusCodenumberHTTP status code (400, 401, 403, 404, 429, 500)
codestringMachine-readable error code for programmatic handling
messagestringHuman-readable description of the error

Error Codes by Status

400 Bad Request

CodeDescriptionExample
VALIDATION_ERRORRequest body failed DTO validationMissing required field, invalid type, value out of range
NONCE_EXPIREDAuth nonce expired or not foundWallet verification took too long, nonce was consumed
ORDER_FAILEDOrder could not be placedInsufficient balance, market closed, invalid order parameters
ORDER_REJECTEDOrder rejected by the exchangePolymarket CLOB rejected the order with a reason
ORDER_NOT_FILLEDCannot perform operation on unfilled orderAttempting to set TP/SL on an order that hasn't filled
MARKET_NOT_ACTIVEMarket is not available for tradingMarket is closed, resolved, or paused
PREPARE_NOT_SUPPORTEDOrder type doesn't support preparePrepare is supported for Polymarket market orders only
SELF_REFERRALUser tried to use their own access keyReferral code belongs to the authenticated user
INVALID_CODE_FORMATAccess key format is invalidCode must be 4-12 alphanumeric characters
INSUFFICIENT_BALANCENot enough funds for the operationPaper trading balance too low, merge/split insufficient shares
INSUFFICIENT_SHARESNot enough shares for the operationTrying to sell more shares than held in a position
INVALID_SHARESShare count must be positivePartial sell with a non-positive share count
FILTER_REQUIREDFilter criteria is requiredCreating a dynamic wallet list without filter criteria
FILTER_NOT_ALLOWEDCannot set filter on this list typeSetting filter criteria on a static wallet list
CANNOT_MODIFY_DYNAMICCannot manually modify a dynamic listAdding or removing wallets from a dynamic wallet list
GROUP_CODE_INACTIVEGroup code has been deactivatedAttempting to send a deactivated group code
TELEGRAM_LINK_INVALIDTelegram link token is invalid or expiredBad or expired link-account token
MISSION_NOT_COMPLETEDMission is not yet completedAttempting to claim a mission before completing it

401 Unauthorized

CodeDescriptionExample
UNAUTHORIZEDMissing or invalid JWT tokenNo Bearer token, expired access token
INVALID_SIGNATUREWallet signature verification failedSignature does not match the expected message
INVALID_REFRESH_TOKENRefresh token is invalid or expiredToken was revoked, rotated, or past its 7-day TTL
INVALID_GOOGLE_TOKENGoogle token verification failedGoogle OAuth token is invalid, expired, or user info missing

403 Forbidden

CodeDescriptionExample
FORBIDDENUser does not have permissionAccessing another user's resource, insufficient tier
NOT_ELIGIBLEUser is not eligible for the actionCannot generate access key, mission requirements not met
ACCOUNT_DISABLEDUser account has been disabledAccount was disabled by admin
BETA_ACCESS_REQUIREDAn active access key is requiredUser logged in but hasn't activated a beta access key

404 Not Found

CodeDescriptionExample
NOT_FOUNDResource does not existGeneric 404 for all untyped resources
USER_NOT_FOUNDUser account not foundWallet address has no associated account
MARKET_NOT_FOUNDMarket does not existInvalid market slug or ID
ORDER_NOT_FOUNDOrder does not existAttempting to cancel a nonexistent order
POSITION_NOT_FOUNDPosition does not existNo open position found for the given market
ALERT_NOT_FOUNDPrice alert not foundAttempting to update or delete a nonexistent alert
MISSION_NOT_FOUNDMission does not existInvalid mission ID
LIST_NOT_FOUNDWallet list not foundInvalid list ID
KEY_NOT_FOUNDAccess key not foundInvalid key ID
GROUP_CODE_NOT_FOUNDGroup code not foundInvalid group code ID
RULE_NOT_FOUNDCommission rule not foundInvalid commission rule ID

409 Conflict

CodeDescriptionExample
ALREADY_REFERREDUser already has a referralCannot apply a second referral code
ALREADY_ACTIVATEDUser already has an access key activatedCannot activate a second access key
ALREADY_CLAIMEDPosition already claimedTrying to claim a resolved position twice
CODE_TAKENAccess key code already in useAnother user has claimed this custom code
KEY_EXISTSCustom key already existsDuplicate key code in the system
LIST_NAME_EXISTSWallet list name already existsDuplicate list name for the same user
POSITION_NOT_OPENPosition is not openAttempting to sell shares from a closed/claimed position
MISSION_ALREADY_CLAIMEDMission rewards already claimedAttempting to claim a mission that was already claimed
TELEGRAM_ALREADY_LINKEDTelegram account already connectedThis Telegram account is linked to a different Vezta account

429 Too Many Requests

CodeDescriptionExample
RATE_LIMITEDRequest rate limit exceededMore than the configured requests per minute from the same IP

500 Internal Server Error

CodeDescriptionExample
INTERNAL_ERRORUnexpected server errorUnhandled exception, database connection failure
CODE_GENERATION_FAILEDFailed to generate a unique codeRandom code generation exhausted all retries

Validation Errors

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).

How Errors Are Generated

Domain Errors

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,
);

Default Code Mapping

When an error does not include an explicit code (e.g., a raw HttpException), the GlobalExceptionFilter maps the HTTP status to a default code:

StatusDefault Code
400VALIDATION_ERROR
401UNAUTHORIZED
403FORBIDDEN
404NOT_FOUND
429RATE_LIMITED
OtherINTERNAL_ERROR

Client-Side Handling

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.

On this page