B2B API
Error Handling
API error format, error codes, and how to handle failures.
Error Handling
VanityPass API responses use a tagged ApiResponse<T> envelope. A normal success response has status: "success"; a client-safe failure has status: "fail" and an error object.
Response envelope
{
"status": "success",
"message": "Request completed",
"data": { }
}
or
{
"status": "fail",
"error": {
"code": "INPUT_VALIDATION",
"message": "Destination is required"
}
}
Error codes
| Code | HTTP Status | Meaning |
|---|---|---|
INPUT_VALIDATION | 400 | Invalid input, such as a missing field, wrong type, or out-of-range value. |
UNAUTHORIZED | 401 | Missing or invalid API key or JWT. |
FORBIDDEN | 403 | Authenticated but not authorized for this resource. |
RESOURCE_NOT_FOUND | 404 | The resource does not exist. |
CONFLICT | 409 | State conflict, such as a booking already being confirmed. |
RATE_LIMIT_EXCEEDED | 429 | Too many requests. Honor the Retry-After header. |
INTERNAL_ERROR | 500 | Unexpected server error. |
Handling errors
- Check the HTTP status to categorize the failure.
- For
status: "fail", readerror.codeanderror.message. - For
429, wait at least the number of seconds inRetry-Afterand add jitter. - Retry transient 5xx responses with capped exponential backoff.
- Show
error.messageto users only when appropriate for your product.
const response = await fetch('https://cloud.vanitypass.com/v1/fx/rates', {
headers: { 'X-Api-Key': 'vp_test_...' }
});
const body = await response.json();
if (!response.ok && body.status === 'fail') {
console.error(`Error [${body.error.code}]: ${body.error.message}`);
}