🚀 VaultsPay API v1 is live. See what's new →
Errors

Errors

VaultsPay uses conventional HTTP status codes and returns a predictable JSON body for every error.

Error shape

{
  "error": {
    "code": "validation_failed",
    "message": "email: must be a valid email address",
    "type": "invalid_request",
    "param": "email",
    "request_id": "req_01HX7ABCDEFG..."
  }
}

Always log the request_id — it’s the fastest way for our support team to trace a specific call.

Status codes

StatusMeaning
200OK — request succeeded.
201Created — new resource was created.
202Accepted — async operation queued.
204No Content — success, no body.
400Bad Request — malformed or invalid request body.
401Unauthorized — missing or invalid API key.
403Forbidden — authenticated but not allowed to do this.
404Not Found — resource does not exist or doesn’t belong to you.
409Conflict — resource state prevents the action.
422Unprocessable Entity — validation failed.
429Too Many Requests — rate limit hit.
500Server Error — we had a bad day. Retry with backoff.
503Service Unavailable — maintenance / degraded mode.

Error types

TypeWhen used
authenticationAPI key, signature, or credential problems.
authorizationYou are authenticated but not allowed to do this.
invalid_requestRequest is malformed or fails validation.
resource_conflictThe current state of a resource blocks the requested action.
rate_limitToo many requests within the window.
api_errorSomething went wrong on our end.

Common error codes

CodeTypeTypical fix
invalid_api_keyauthenticationRotate your key and re-send.
unauthorized_ipauthenticationAdd source IP to allow-list.
validation_failedinvalid_requestInspect param and fix the field.
duplicate_emailresource_conflictRetrieve the existing user instead.
kyc_incompleteresource_conflictComplete KYC before issuing cards.
non_zero_balanceresource_conflictSweep remaining funds before closing account.
rate_limit_exceededrate_limitBack off with exponential delay.
idempotency_key_in_useinvalid_requestSame key replayed with a different body.
server_errorapi_errorSafe to retry with backoff.

Handling errors

try {
  const user = await vp.users.create(input)
} catch (err) {
  switch (err.code) {
    case 'duplicate_email':
      return existingUserByEmail(input.email)
    case 'validation_failed':
      return showFieldError(err.param, err.message)
    case 'rate_limit_exceeded':
      return retryWithBackoff(() => vp.users.create(input))
    default:
      throw err
  }
}