Fleet Management API

Manage custom aircraft fleet profiles — both user-specific and virtual-airline-wide. Every profile inherits from a parent (a base aircraft or another registration), and the server cleanly separates the untouched master from the user's overrides, making one-click "reset to default" straightforward to implement on the client.

Overview

A fleet profile (fleet_user row) links a registration (tail number) to a custom JSON file that extends a base aircraft profile. The JSON is merged server-side using deep inheritance: parent values are kept unless the child explicitly overrides them.

There are three kinds of fleet entries:

Kind Owner Editable by
User Individual user (user_id) That user via fleetSave / fleetDelete
VA Virtual airline (virtual_airline, user_id = null) VA admin with matching VA scope only
Community Any user with shareCommunity = true Read-only by everyone; edited only by the profile owner

Concepts & Data Model

Profile fields

Field Type Description
registration string Aircraft tail number (unique per user or per VA). Letters, digits, hyphens; max 30 chars.
basedOnProfile string Registration or aircraft variant_id that this profile inherits from. Can point to another fleet_user registration (user-defined parent) or to a standard aircraft file (community master). A user may use their own registration as a base, creating a self-referential chain capped at depth 5.
file string Filename of the stored JSON. Auto-generated: User_{userId}_{reg}.json for users; {reg}.json for VA.
flight_sim string|null Flight simulator identifier (e.g. "MSFS", "XP12"). Max 15 chars.
addon string|null Add-on / livery pack identifier (e.g. "PMDG"). Max 15 chars.
variant string|null Aircraft variant name resolved from the base aircraft profile (e.g. "A330-243F"). Populated automatically at fleetSave time — no need to send it explicitly.
engines string|null Engine type resolved from the base profile (e.g. "TRENT 772B").
engine_time_limit integer|null Engine thrust time limit in seconds resolved from the base profile (e.g. 10).
share_community boolean When true the profile appears in the community fleet returned by fleetList.
isBasedOnUserProfile boolean Computed. true when basedOnProfile resolves to another fleet_user row (not a base aircraft file).

Master / Override / Reset Model

fleetGet always returns three views of the same profile:

Key Contents Use case
master The parent chain merged without the current row's data. null when basedOnProfile points to a base aircraft file (no custom parent row exists). Show the user "what you inherited". Dropping overrides and falling back to master = reset to default.
overrides The raw JSON stored in this row's own file only, no merging applied. Populate the "your customisations" diff panel in the UI.
merged Deep merge of master + overrides (child wins). This is the value actually used for performance calculations. Read-only display; pass to the performance engine.
Implementing "Reset to default"

Call fleetGet to obtain master. Display it as a preview, then call fleetSave with profileData = master. The server overwrites the override file; subsequent fleetGet calls return overrides == master and merged == master.

Alternatively, call fleetDelete to remove the row entirely, which means the performance engine will use the standard community aircraft profile going forward.

VA Fleet & Admin Rules

VA fleet writes (fleetSave / fleetDelete with isVA: true) require the caller to be an active admin with VA fleet access:

  • VA-scoped admin (va_scope = VA_ONLY): can only manage the fleet for their own virtual airline. The vaName field in the request is optional; it must match their VA if provided.
  • Full-scope admin / superadmin (va_scope = FULL): can manage any VA's fleet. Must pass vaName explicitly so the server knows which VA to target.

Regular users attempting isVA: true receive 403 FORBIDDEN.

fleetList

Return the authenticated user's custom fleet, their active virtual airline's fleet, and all community-shared profiles. Use this to populate the fleet selector on the main screen.

POST /api

Request Body

Parameter Type Required Description
query string Required Must be "fleetList"

Example

cURL
curl -X POST "https://api.virtualperformancetool.com/api" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "query": "fleetList" }'

Response

JSON
{
  "success": true,
  "data": {
    "userFleet": [
      {
        "id": 42,
        "user_id": 9416,
        "api_key": "abc123",
        "registration": "D-ABIB",
        "basedOnProfile": "737-800",
        "virtual_airline": null,
        "file": "User_9416_D-ABIB.json",
        "flight_sim": "MSFS",
        "addon": "PMDG",
        "variant": "B737-800",
        "engines": "CFM56-7B27",
        "engine_time_limit": 10,
        "share_community": 0,
        "recommended": 0,
        "isBasedOnUserProfile": 0
      }
    ],
    "vaFleet": [
      {
        "id": 100,
        "user_id": null,
        "api_key": "VA",
        "registration": "EI-ESV",
        "basedOnProfile": "737-800",
        "virtual_airline": "vRYR",
        "file": "EI-ESV.json",
        "flight_sim": null,
        "addon": null,
        "variant": "B737-800",
        "engines": "CFM56-7B27",
        "engine_time_limit": 10,
        "share_community": 0,
        "recommended": 0,
        "isBasedOnUserProfile": 0
      }
    ],
    "communityFleet": []
  }
}

fleetGet

Fetch a single fleet profile by registration. Returns the master, overrides, and merged views so the UI can display the inheritance chain and offer a reset button.

POST /api

Request Body

Parameter Type Required Description
query string Required Must be "fleetGet"
data.registration string Required Aircraft registration to fetch (e.g. "D-ABIB")
data.isVA boolean Optional Set to true to fetch a VA-owned profile. Requires VA admin privileges.
data.vaName string Optional Target VA name. Required when isVA = true and the caller has full-scope admin access.

Example

cURL
curl -X POST "https://api.virtualperformancetool.com/api" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "fleetGet",
    "data": { "registration": "D-ABIB" }
  }'

Response

JSON
{
  "success": true,
  "data": {
    "fleetRow": {
      "id": 42,
      "user_id": 9416,
      "registration": "D-ABIB",
      "basedOnProfile": "737-800",
      "file": "User_9416_D-ABIB.json",
      "isBasedOnUserProfile": 0
    },
    "master": null,
    "overrides": {
      "profile": {
        "user_registration": "D-ABIB",
        "basedOnProfile": "737-800"
      },
      "limits": {
        "maxTOW": 79016
      }
    },
    "merged": {
      "profile": {
        "user_registration": "D-ABIB",
        "basedOnProfile": "737-800"
      },
      "limits": {
        "maxTOW": 79016
      }
    }
  }
}
When master is null

master is null when basedOnProfile points to a standard aircraft variant file rather than another fleet_user registration. In that case overrides and merged are identical — there is no intermediate custom parent.

fleetSave

Add or update a custom fleet profile. Writes both the JSON file on disk and the fleet_user database row. Use isVA: true to manage the VA fleet (requires VA admin privileges).

POST /api

Request Body

Parameter Type Required Description
query string Required Must be "fleetSave"
data.registration string Required Aircraft tail number. Letters, digits, hyphens only; max 30 chars.
data.basedOnProfile string Required Aircraft variant or another registration this profile inherits from (e.g. "737-800" or "G-GDFV"). A user may reference their own registration.
data.profileData object Required The complete profile JSON to store. Only send the fields that differ from the parent — the server deep-merges with the parent on read. The server will inject profile.user_registration and profile.basedOnProfile automatically.
data.isVA boolean Optional true to save a VA-owned profile. Requires VA admin privileges.
data.vaName string Optional Target VA name; required for full-scope admins when isVA = true.
data.flightSim string Optional Flight simulator (e.g. "MSFS", "XP12", "P3D"). Max 15 chars.
data.addon string Optional Aircraft add-on identifier (e.g. "PMDG"). Max 15 chars.
data.shareCommunity boolean Optional When true, this profile is included in the community fleet returned by fleetList for all users.
data.variant string Optional Aircraft variant name override (e.g. "A330-243F"). If omitted the server resolves it automatically from the base aircraft profile by walking the basedOnProfile chain.
data.engines string Optional Engine type override (e.g. "TRENT 772B"). Auto-resolved when omitted.
data.engineTimeLimit integer Optional Engine thrust time limit in seconds override (e.g. 10). Auto-resolved when omitted.

Example

cURL
curl -X POST "https://api.virtualperformancetool.com/api" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "fleetSave",
    "data": {
      "registration": "D-ABIB",
      "basedOnProfile": "737-800",
      "profileData": {
        "limits": { "maxTOW": 79016 }
      },
      "flightSim": "MSFS",
      "addon": "PMDG",
      "shareCommunity": false
    }
  }'

VA fleet example

cURL
curl -X POST "https://api.virtualperformancetool.com/api" \
  -H "Authorization: Bearer VA_ADMIN_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "fleetSave",
    "data": {
      "isVA": true,
      "registration": "EI-ESV",
      "basedOnProfile": "737-800",
      "profileData": {
        "limits": { "maxTOW": 78500 }
      }
    }
  }'

Response

JSON
{
  "success": true,
  "data": {
    "registration": "D-ABIB",
    "file": "User_9416_D-ABIB.json",
    "variant": "B737-800",
    "engines": "CFM56-7B27",
    "engineTimeLimit": 10,
    "saved": true
  }
}

fleetDelete

Remove a custom fleet profile. Deletes both the JSON file on disk and the fleet_user database row. This action is irreversible — consider offering the user a "reset to default" option (via fleetSave with master data) before deleting.

POST /api

Request Body

Parameter Type Required Description
query string Required Must be "fleetDelete"
data.registration string Required Registration of the profile to delete.
data.isVA boolean Optional true to delete a VA-owned profile. Requires VA admin privileges.
data.vaName string Optional Target VA name; required for full-scope admins when isVA = true.

Example

cURL
curl -X POST "https://api.virtualperformancetool.com/api" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "fleetDelete",
    "data": { "registration": "D-ABIB" }
  }'

Response

JSON
{
  "success": true,
  "data": {
    "registration": "D-ABIB",
    "deleted": true
  }
}

Error Codes

Code HTTP Description
AUTH_REQUIRED 401 No valid JWT token provided.
INVALID_REGISTRATION 400 Registration is empty, too long, or contains invalid characters.
MISSING_BASED_ON 400 basedOnProfile is required for fleetSave.
INVALID_PROFILE_DATA 400 profileData must be a non-empty JSON object.
FORBIDDEN 403 VA fleet write attempted without admin privileges, or a VA-scoped admin attempted to manage a different VA's fleet.
MISSING_VA_NAME 400 vaName must be provided when the caller is a full-scope VA admin.
NO_VA_ASSIGNED 403 The VA-scoped admin account has no virtual airline assigned in the database.
NOT_FOUND 404 No fleet profile matching the given registration exists for the caller.
FILE_NOT_FOUND 500 Profile row exists in the database but the JSON file is missing on disk.
FS_ERROR 500 Could not create the storage directory on the server.
FS_WRITE_ERROR 500 Failed to write the profile JSON to disk.
DB_ERROR 500 Database insert / delete failed. The file write is automatically rolled back for fleetSave.