Error Handling
Understanding error responses and implementing proper error handling in your VPT API integration.
Overview
The VPT API uses structured error responses for clear debugging. All errors follow a consistent format, making it easy to handle errors programmatically.
Error Response Format
{
"success": false,
"error": {
"message": "Human-readable error description",
"code": "ERROR_CODE",
"status": 401
}
}
Authentication Error Codes
These errors occur during login or when validating JWT tokens.
| Code | HTTP Status | Description |
|---|---|---|
AUTH_REQUIRED |
401 | No authentication token provided |
AUTH_MISSING_CREDENTIALS |
400 | Email or password missing in login request |
AUTH_MISSING_DEV_KEY |
400 | Developer key not provided in login request |
AUTH_INVALID_CREDENTIALS |
401 | Invalid email or password |
AUTH_TOKEN_EXPIRED |
401 | JWT token has expired |
AUTH_TOKEN_REVOKED |
401 | Token was revoked (password changed) |
AUTH_TOKEN_INVALID |
401 | Malformed or tampered JWT token |
API Error Codes
These errors occur when making API requests after authentication.
| Code | HTTP Status | Description |
|---|---|---|
INVALID_REQUEST |
400 | Request body is malformed or missing required fields |
INVALID_QUERY |
400 | The query parameter is invalid or unsupported |
MISSING_PARAMETERS |
400 | Required parameters are missing from the request |
RATE_LIMIT_EXCEEDED |
429 | Too many requests - rate limit exceeded |
SERVER_ERROR |
500 | Internal server error - please try again later |
OFP & Flight Data Error Codes
These errors are returned by the OFP storage endpoints
(ofpImport, ofpList, ofpGet,
ofpDelete, ofpAsset) and the Flight Data
endpoints (flightDataList, flightDataGet,
flightDataSave, flightDataDelete).
| Code | HTTP Status | Description |
|---|---|---|
OFP_NOT_FOUND |
404 | No OFP with that id belongs to the caller |
OFP_PAYLOAD_MISSING |
404 |
OFP row exists but the stored ofp.json is missing
on disk
|
OFP_PAYLOAD_CORRUPT |
500 | Stored ofp.json could not be parsed |
OFP_ASSET_NOT_FOUND |
404 | The requested asset kind does not exist for this OFP |
OFP_PREVIEW_AIRPORT_RESTRICTED |
403 | Preview users can only import OFPs whose origin and destination are in the demo airports list |
OFP_IMPORT_FAILED |
400 | Generic Simbrief import failure (network, quota, or upstream error) |
INVALID_OFP_ID |
400 | OFP id missing or contains forbidden characters |
INVALID_DATA_KEY |
400 |
Flight Data dataKey missing or invalid (max 64
chars, A-Z a-z 0-9 . _ -)
|
FLIGHT_DATA_NOT_FOUND |
404 |
No saved Flight Data row exists for
(ofpId, dataKey)
|
MISSING_PAYLOAD |
400 |
flightDataSave body had no
payload field
|
INVALID_PAYLOAD |
400 | Payload is not an object, array or JSON string |
INVALID_TIMESTAMP |
400 |
lastDownloadedAt could not be parsed as ISO 8601
|
PAYLOAD_TOO_LARGE |
413 | Flight Data payload exceeds the 4 MB hard cap |
VERSION_CONFLICT |
409 |
The client's expectedVersion or
lastDownloadedAt does not match the server. The
response body's current field contains the
server's up-to-date copy so the client can present a Cancel /
Download latest / Override dialog.
|
OFP Sharing Error Codes
Returned by the cross-account sharing endpoints
(ofpShare, ofpShareList,
ofpShareAccept, ofpShareRevoke) and by any
OFP / Flight Data endpoint when the caller is a shared user with
insufficient permission.
| Code | HTTP Status | Description |
|---|---|---|
INVALID_PERMISSION |
400 |
permission must be "view" or
"edit"
|
INVALID_EMAIL |
400 |
sharedWithEmail is not a valid email address
|
INVALID_EXPIRY |
400 | expiresInDays must be between 1 and 365 |
INVALID_SHARE_TARGET |
400 | You cannot share an OFP with yourself / accept your own share |
SHARE_NOT_FOUND |
404 | No share matches the supplied token / code / id |
SHARE_REVOKED |
410 | This share has been revoked and can no longer be redeemed |
SHARE_EXPIRED |
410 | This share has passed its expiresAt |
SHARE_FORBIDDEN |
403 | This share is bound to a different account, or the caller cannot revoke it |
INSUFFICIENT_PERMISSION |
403 |
Caller has view access to the OFP but tried a
Flight Data write (flightDataSave,
flightDataDelete).
|
Handling Errors
Here's how to properly handle errors in your application:
async function apiRequest(endpoint, data) {
try {
const response = await fetch(endpoint, {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
});
const result = await response.json();
if (!result.success) {
// Handle specific error codes
switch (result.error.code) {
case 'AUTH_TOKEN_EXPIRED':
case 'AUTH_TOKEN_REVOKED':
// Redirect to login
localStorage.removeItem('vpt_token');
window.location.href = '/login';
break;
case 'RATE_LIMIT_EXCEEDED':
// Wait and retry
await delay(5000);
return apiRequest(endpoint, data);
default:
// Display error message to user
showError(result.error.message);
}
return null;
}
return result;
} catch (error) {
console.error('Network error:', error);
showError('Network error. Please check your connection.');
return null;
}
}
- Always check the
successfield in responses - Use the
error.codefor programmatic handling - Display
error.messagefor user-facing errors - Implement retry logic for transient errors (5xx, rate limits)