MENU navbar-image

Introduction

The YAAMS REST API (v1) for virtual airline management - airlines, fleet and PIREPs. All endpoints live under /api/v1 and return JSON.

This documentation covers the YAAMS REST API v1. Every endpoint is served under `/api/v1` and returns JSON.

Except for the public `GET /api/v1/info` endpoint, requests must be authenticated with a personal Sanctum bearer token (see the Authenticating section below).

<aside>As you scroll, you'll see code examples for working with the API in different programming languages in the dark area to the right (or as part of the content on mobile).
You can switch the language used with the tabs at the top right (or from the nav menu at the top left on mobile).</aside>

Authenticating requests

To authenticate requests, include an Authorization header with the value "Bearer {YOUR_AUTH_KEY}".

All authenticated endpoints are marked with a requires authentication badge in the documentation below.

Create a personal API token from your account settings (Settings → API tokens) in the web UI, then send it as a bearer token: Authorization: Bearer {YOUR_TOKEN}. Tokens are managed with Laravel Sanctum.

Account

The token owner's own account.

Current user

requires authentication

"Who am I" - returns the account the API token belongs to, with its airline memberships. Useful as a token sanity check for API clients.

Example request:
curl --request GET \
    --get "http://192.168.1.95:8001/api/v1/user" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "http://192.168.1.95:8001/api/v1/user"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'http://192.168.1.95:8001/api/v1/user';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "data": {
        "id": 1,
        "name": "Homer Simpson",
        "email": "homer@test.com",
        "airlines": [
            {
                "id": 1,
                "name": "Example Virtual Airlines",
                "prefix": "EV",
                "icaoCallsign": "EVA",
                "atcCallsign": "EXAMPLE",
                "unitIsLbs": false,
                "requirePirepReview": true,
                "locationContinuity": false,
                "createdAt": "2026-01-01T00:00:00.000000Z",
                "updatedAt": "2026-01-01T00:00:00.000000Z"
            }
        ]
    }
}
 

Request      

GET api/v1/user

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

Aircraft

An airline's fleet. Aircraft are scoped to their airline - an aircraft that does not belong to {airline} resolves as a 404.

List fleet

requires authentication

List the airline's aircraft.

Example request:
curl --request GET \
    --get "http://192.168.1.95:8001/api/v1/airlines/16/aircraft" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "http://192.168.1.95:8001/api/v1/airlines/16/aircraft"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'http://192.168.1.95:8001/api/v1/airlines/16/aircraft';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "data": [
        {
            "id": 7,
            "registration": "D-EXAM",
            "manufacturer": "Airbus",
            "model": "A320-200",
            "currentLoc": "EDDF",
            "engineType": "CFM56",
            "satcom": false,
            "winglets": true,
            "selcal": "AB-CD",
            "hexCode": "3C6444",
            "msn": "1234",
            "mtow": 78000,
            "mzfw": 62500,
            "mlw": 66000,
            "remarks": null,
            "status": "active",
            "active": true,
            "retiredAt": null,
            "retiredReason": null,
            "inServiceSince": "2020-01-01",
            "firstFlight": "2019-11-15",
            "createdAt": "2026-01-01T00:00:00.000000Z",
            "updatedAt": "2026-01-01T00:00:00.000000Z"
        }
    ]
}
 

Example response (403):


{
    "message": "You are not a member of this airline."
}
 

Request      

GET api/v1/airlines/{airline_id}/aircraft

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

airline_id   integer     

The ID of the airline. Example: 16

airline   integer     

The airline ID. Example: 1

Add an aircraft

requires authentication

Add an aircraft to the airline's fleet. Requires the "add aircraft" permission and membership of the airline. Permission, membership, normalization and the duplicate-registration rule are enforced by StoreAircraftRequest.

Example request:
curl --request POST \
    "http://192.168.1.95:8001/api/v1/airlines/16/aircraft" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"registration\": \"D-EXAM\",
    \"manufacturer\": \"Airbus\",
    \"model\": \"A320-200\",
    \"engine_type\": \"CFM56\",
    \"satcom\": false,
    \"winglets\": true,
    \"selcal\": \"AB-CD\",
    \"hex_code\": \"3C6444\",
    \"msn\": \"1234\",
    \"mtow\": 78000,
    \"mzfw\": 62500,
    \"mlw\": 66000,
    \"service_ceiling\": 41000,
    \"remarks\": \"Delivered new.\",
    \"current_loc\": \"EDDF\"
}"
const url = new URL(
    "http://192.168.1.95:8001/api/v1/airlines/16/aircraft"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "registration": "D-EXAM",
    "manufacturer": "Airbus",
    "model": "A320-200",
    "engine_type": "CFM56",
    "satcom": false,
    "winglets": true,
    "selcal": "AB-CD",
    "hex_code": "3C6444",
    "msn": "1234",
    "mtow": 78000,
    "mzfw": 62500,
    "mlw": 66000,
    "service_ceiling": 41000,
    "remarks": "Delivered new.",
    "current_loc": "EDDF"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'http://192.168.1.95:8001/api/v1/airlines/16/aircraft';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'registration' => 'D-EXAM',
            'manufacturer' => 'Airbus',
            'model' => 'A320-200',
            'engine_type' => 'CFM56',
            'satcom' => false,
            'winglets' => true,
            'selcal' => 'AB-CD',
            'hex_code' => '3C6444',
            'msn' => '1234',
            'mtow' => 78000,
            'mzfw' => 62500,
            'mlw' => 66000,
            'service_ceiling' => 41000,
            'remarks' => 'Delivered new.',
            'current_loc' => 'EDDF',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (201):


{
    "data": {
        "id": 7,
        "registration": "D-EXAM",
        "manufacturer": "Airbus",
        "model": "A320-200",
        "currentLoc": "EDDF",
        "engineType": "CFM56",
        "satcom": false,
        "winglets": true,
        "selcal": "AB-CD",
        "hexCode": "3C6444",
        "msn": "1234",
        "mtow": 78000,
        "mzfw": 62500,
        "mlw": 66000,
        "remarks": null,
        "status": "active",
        "active": true,
        "retiredAt": null,
        "retiredReason": null,
        "inServiceSince": null,
        "firstFlight": null,
        "createdAt": "2026-07-11T12:00:00.000000Z",
        "updatedAt": "2026-07-11T12:00:00.000000Z"
    }
}
 

Example response (403):


{
    "message": "This action is unauthorized."
}
 

Example response (422):


{
    "message": "The registration field is required.",
    "errors": {
        "registration": [
            "The registration field is required."
        ]
    }
}
 

Request      

POST api/v1/airlines/{airline_id}/aircraft

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

airline_id   integer     

The ID of the airline. Example: 16

airline   integer     

The airline ID. Example: 1

Body Parameters

registration   string     

Tail number, e.g. D-EXAM (max 9 chars, uppercased). Example: D-EXAM

manufacturer   string     

Airframe manufacturer, max 100 chars. Example: Airbus

model   string     

Aircraft model, max 100 chars. Example: A320-200

engine_type   string  optional    

Engine type, max 100 chars. Example: CFM56

satcom   boolean  optional    

Whether the aircraft has SATCOM. Example: false

winglets   boolean  optional    

Whether the aircraft has winglets. Example: true

selcal   string  optional    

SELCAL code, format XX-XX. Example: AB-CD

hex_code   string  optional    

Mode-S hex code, 6 hex chars. Example: 3C6444

msn   string  optional    

Manufacturer serial number, 1-6 digits. Example: 1234

mtow   integer  optional    

Max take-off weight (kg), 0-1000000. Example: 78000

mzfw   integer  optional    

Max zero-fuel weight (kg), 0-1000000. Example: 62500

mlw   integer  optional    

Max landing weight (kg), 0-1000000. Example: 66000

service_ceiling   integer  optional    

Service ceiling (ft), 1000-60000; PIREPs with a higher cruise altitude are rejected. Example: 41000

remarks   string  optional    

Free-text remarks, max 1000 chars. Example: Delivered new.

current_loc   string     

ICAO code of the aircraft's current location (must exist in airports). Example: EDDF

Show an aircraft

requires authentication

The scoped route binding 404s any aircraft that does not belong to {airline}.

Example request:
curl --request GET \
    --get "http://192.168.1.95:8001/api/v1/airlines/16/aircraft/16" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "http://192.168.1.95:8001/api/v1/airlines/16/aircraft/16"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'http://192.168.1.95:8001/api/v1/airlines/16/aircraft/16';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "data": {
        "id": 7,
        "registration": "D-EXAM",
        "manufacturer": "Airbus",
        "model": "A320-200",
        "currentLoc": "EDDF",
        "engineType": "CFM56",
        "satcom": false,
        "winglets": true,
        "selcal": "AB-CD",
        "hexCode": "3C6444",
        "msn": "1234",
        "mtow": 78000,
        "mzfw": 62500,
        "mlw": 66000,
        "remarks": null,
        "status": "active",
        "active": true,
        "retiredAt": null,
        "retiredReason": null,
        "inServiceSince": "2020-01-01",
        "firstFlight": "2019-11-15",
        "createdAt": "2026-01-01T00:00:00.000000Z",
        "updatedAt": "2026-01-01T00:00:00.000000Z"
    }
}
 

Example response (403):


{
    "message": "You are not a member of this airline."
}
 

Example response (404):


{
    "message": "No query results for model [App\\Models\\Aircraft] 999"
}
 

Request      

GET api/v1/airlines/{airline_id}/aircraft/{id}

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

airline_id   integer     

The ID of the airline. Example: 16

id   integer     

The ID of the aircraft. Example: 16

airline   integer     

The airline ID. Example: 1

aircraft   integer     

The aircraft ID (must belong to the airline). Example: 7

Airlines

Virtual airlines. Aircraft and flights are nested resources of an airline.

List airlines

requires authentication

Example request:
curl --request GET \
    --get "http://192.168.1.95:8001/api/v1/airlines?members_only=1" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "http://192.168.1.95:8001/api/v1/airlines"
);

const params = {
    "members_only": "1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'http://192.168.1.95:8001/api/v1/airlines';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'members_only' => '1',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "data": [
        {
            "id": 1,
            "name": "Example Virtual Airlines",
            "prefix": "EV",
            "icaoCallsign": "EVA",
            "atcCallsign": "EXAMPLE",
            "unitIsLbs": false,
            "requirePirepReview": true,
            "locationContinuity": false,
            "createdAt": "2026-01-01T00:00:00.000000Z",
            "updatedAt": "2026-01-01T00:00:00.000000Z"
        }
    ]
}
 

Request      

GET api/v1/airlines

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

Query Parameters

members_only   boolean  optional    

Only return airlines the token owner belongs to. Defaults to all airlines. Example: true

Found a new airline

requires authentication

Requires the "add airlines" permission (enforced by StoreAirlineRequest).

Example request:
curl --request POST \
    "http://192.168.1.95:8001/api/v1/airlines" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"Example Virtual Airlines\",
    \"prefix\": \"EV\",
    \"icao_callsign\": \"EVA\",
    \"atc_callsign\": \"EXAMPLE\"
}"
const url = new URL(
    "http://192.168.1.95:8001/api/v1/airlines"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "Example Virtual Airlines",
    "prefix": "EV",
    "icao_callsign": "EVA",
    "atc_callsign": "EXAMPLE"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'http://192.168.1.95:8001/api/v1/airlines';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'name' => 'Example Virtual Airlines',
            'prefix' => 'EV',
            'icao_callsign' => 'EVA',
            'atc_callsign' => 'EXAMPLE',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (201):


{
    "data": {
        "id": 2,
        "name": "Example Virtual Airlines",
        "prefix": "EV",
        "icaoCallsign": "EVA",
        "atcCallsign": "EXAMPLE",
        "unitIsLbs": false,
        "requirePirepReview": true,
        "locationContinuity": false,
        "createdAt": "2026-01-01T00:00:00.000000Z",
        "updatedAt": "2026-01-01T00:00:00.000000Z"
    }
}
 

Example response (403):


{
    "message": "This action is unauthorized."
}
 

Example response (422):


{
    "message": "The prefix has already been taken.",
    "errors": {
        "prefix": [
            "The prefix has already been taken."
        ]
    }
}
 

Request      

POST api/v1/airlines

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

Body Parameters

name   string     

Display name, max 50 chars, unique. Example: Example Virtual Airlines

prefix   string     

Two-letter IATA-style prefix, unique, uppercased. Example: EV

icao_callsign   string     

Three-letter ICAO callsign, unique, uppercased. Example: EVA

atc_callsign   string     

Spoken ATC callsign, max 25 chars, unique. Example: EXAMPLE

Show an airline

requires authentication

Example request:
curl --request GET \
    --get "http://192.168.1.95:8001/api/v1/airlines/16" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "http://192.168.1.95:8001/api/v1/airlines/16"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'http://192.168.1.95:8001/api/v1/airlines/16';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "data": {
        "id": 1,
        "name": "Example Virtual Airlines",
        "prefix": "EV",
        "icaoCallsign": "EVA",
        "atcCallsign": "EXAMPLE",
        "unitIsLbs": false,
        "requirePirepReview": true,
        "locationContinuity": false,
        "createdAt": "2026-01-01T00:00:00.000000Z",
        "updatedAt": "2026-01-01T00:00:00.000000Z"
    }
}
 

Example response (404):


{
    "message": "No query results for model [App\\Models\\Airline] 999"
}
 

Request      

GET api/v1/airlines/{id}

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

id   integer     

The ID of the airline. Example: 16

airline   integer     

The airline ID. Example: 1

Endpoints

POST api/v1/airlines/{airline_id}/live-position

requires authentication

Example request:
curl --request POST \
    "http://192.168.1.95:8001/api/v1/airlines/16/live-position" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"lat\": -89,
    \"lon\": -179,
    \"heading_deg\": 4326.41688,
    \"altitude_ft\": 4326.41688,
    \"ground_speed_kt\": 4326.41688
}"
const url = new URL(
    "http://192.168.1.95:8001/api/v1/airlines/16/live-position"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "lat": -89,
    "lon": -179,
    "heading_deg": 4326.41688,
    "altitude_ft": 4326.41688,
    "ground_speed_kt": 4326.41688
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'http://192.168.1.95:8001/api/v1/airlines/16/live-position';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'lat' => -89,
            'lon' => -179,
            'heading_deg' => 4326.41688,
            'altitude_ft' => 4326.41688,
            'ground_speed_kt' => 4326.41688,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/v1/airlines/{airline_id}/live-position

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

airline_id   integer     

The ID of the airline. Example: 16

Body Parameters

lat   number     

Must be between -90 and 90. Example: -89

lon   number     

Must be between -180 and 180. Example: -179

heading_deg   number  optional    

Example: 4326.41688

altitude_ft   number  optional    

Example: 4326.41688

ground_speed_kt   number  optional    

Example: 4326.41688

Flights

PIREPs (pilot reports / flight logs) for an airline. Filing, listing, and - for reviewers - the review queue plus accept/reject.

List my flights

requires authentication

List the authenticated pilot's own flights for a specific airline.

Example request:
curl --request GET \
    --get "http://192.168.1.95:8001/api/v1/airlines/16/flights?status_id=2" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "http://192.168.1.95:8001/api/v1/airlines/16/flights"
);

const params = {
    "status_id": "2",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'http://192.168.1.95:8001/api/v1/airlines/16/flights';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'status_id' => '2',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "data": [
        {
            "id": 42,
            "callsign": "421",
            "flightNumber": "421",
            "fullFlightNumber": "EV421",
            "fullIcaoCallsign": "EVA421",
            "departureIcao": "EDDF",
            "arrivalIcao": "EGLL",
            "cruiseAltitude": 36000,
            "blockOff": "2026-07-11 10:00:00",
            "blockOn": "2026-07-11 11:30:00",
            "duration": "01:30",
            "burnedFuel": 4200,
            "route": "SOVAT UL610 KONAN",
            "onlineNetwork": 1,
            "status": {
                "id": 2,
                "name": "Accepted"
            },
            "remarks": null,
            "rejectionRemarks": null,
            "createdAt": "2026-07-11T11:35:00.000000Z",
            "updatedAt": "2026-07-11T11:40:00.000000Z"
        }
    ]
}
 

Example response (403):


{
    "message": "You are not a member of this airline."
}
 

Request      

GET api/v1/airlines/{airline_id}/flights

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

airline_id   integer     

The ID of the airline. Example: 16

airline   integer     

The airline ID. Example: 1

Query Parameters

status_id   integer  optional    

Filter by flight status: 1 = Pending, 2 = Accepted, 3 = Rejected. Example: 2

File a PIREP

requires authentication

Submit a new PIREP for the airline. Membership, airport/aircraft existence and the location-continuity rule are enforced by StoreFlightRequest. If the airline requires review the flight is created Pending (status 1) and reviewers are notified; otherwise it is Accepted (status 2) immediately.

Example request:
curl --request POST \
    "http://192.168.1.95:8001/api/v1/airlines/16/flights" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"flightnumber\": 421,
    \"departure_icao\": \"EDDF\",
    \"arrival_icao\": \"EGLL\",
    \"aircraft_id\": 7,
    \"callsign\": \"421\",
    \"crzalt\": 36000,
    \"blockoff\": \"2026-07-11 10:00:00\",
    \"blockon\": \"2026-07-11 11:30:00\",
    \"burned_fuel\": 4200,
    \"route\": \"SOVAT UL610 KONAN\",
    \"online_network_id\": 1,
    \"remarks\": \"Smooth flight.\"
}"
const url = new URL(
    "http://192.168.1.95:8001/api/v1/airlines/16/flights"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "flightnumber": 421,
    "departure_icao": "EDDF",
    "arrival_icao": "EGLL",
    "aircraft_id": 7,
    "callsign": "421",
    "crzalt": 36000,
    "blockoff": "2026-07-11 10:00:00",
    "blockon": "2026-07-11 11:30:00",
    "burned_fuel": 4200,
    "route": "SOVAT UL610 KONAN",
    "online_network_id": 1,
    "remarks": "Smooth flight."
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'http://192.168.1.95:8001/api/v1/airlines/16/flights';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'flightnumber' => 421,
            'departure_icao' => 'EDDF',
            'arrival_icao' => 'EGLL',
            'aircraft_id' => 7,
            'callsign' => '421',
            'crzalt' => 36000,
            'blockoff' => '2026-07-11 10:00:00',
            'blockon' => '2026-07-11 11:30:00',
            'burned_fuel' => 4200,
            'route' => 'SOVAT UL610 KONAN',
            'online_network_id' => 1,
            'remarks' => 'Smooth flight.',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (201):


{
    "data": {
        "id": 42,
        "callsign": "421",
        "flightNumber": "421",
        "fullFlightNumber": "EV421",
        "fullIcaoCallsign": "EVA421",
        "departureIcao": "EDDF",
        "arrivalIcao": "EGLL",
        "cruiseAltitude": 36000,
        "blockOff": "2026-07-11 10:00:00",
        "blockOn": "2026-07-11 11:30:00",
        "duration": "01:30",
        "burnedFuel": 4200,
        "route": "SOVAT UL610 KONAN",
        "onlineNetwork": 1,
        "status": {
            "id": 1,
            "name": "Pending"
        },
        "remarks": null,
        "rejectionRemarks": null,
        "createdAt": "2026-07-11T11:35:00.000000Z",
        "updatedAt": "2026-07-11T11:35:00.000000Z"
    }
}
 

Example response (403):


{
    "message": "This action is unauthorized."
}
 

Example response (422):


{
    "message": "The departure icao field is required.",
    "errors": {
        "departure_icao": [
            "The departure icao field is required."
        ]
    }
}
 

Request      

POST api/v1/airlines/{airline_id}/flights

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

airline_id   integer     

The ID of the airline. Example: 16

airline   integer     

The airline ID. Example: 1

Body Parameters

flightnumber   integer     

Numeric flight number, 1-4 digits. Example: 421

departure_icao   string     

Departure airport ICAO (must exist; uppercased). Example: EDDF

arrival_icao   string     

Arrival airport ICAO (must exist; uppercased). Example: EGLL

aircraft_id   integer     

ID of an active aircraft owned by the airline. Example: 7

callsign   string     

Radio callsign, 1-4 digits optionally followed by up to 2 letters. Example: 421

crzalt   integer     

Cruise altitude in feet, max 50000. Example: 36000

blockoff   string     

Block-off time (UTC), format Y-m-d H:i:s. Example: 2026-07-11 10:00:00

blockon   string     

Block-on time (UTC), format Y-m-d H:i:s. Must be after blockoff; flight duration may not exceed 26 hours. Example: 2026-07-11 11:30:00

burned_fuel   integer     

Fuel burned, in the airline's unit (min 1, max 600000). Example: 4200

route   string     

Filed route string. Example: SOVAT UL610 KONAN

online_network_id   integer     

Online network ID (must exist in online_networks). Example: 1

remarks   string  optional    

Optional remarks (letters, digits, spaces, . , -). Example: Smooth flight.

List the review queue

requires authentication

List pending PIREPs (status 1) for an airline. Requires the per-airline Dispatcher or Manager role.

Example request:
curl --request GET \
    --get "http://192.168.1.95:8001/api/v1/airlines/16/flights/review" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "http://192.168.1.95:8001/api/v1/airlines/16/flights/review"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'http://192.168.1.95:8001/api/v1/airlines/16/flights/review';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "data": [
        {
            "id": 43,
            "callsign": "422",
            "flightNumber": "422",
            "fullFlightNumber": "EV422",
            "fullIcaoCallsign": "EVA422",
            "departureIcao": "EGLL",
            "arrivalIcao": "EDDF",
            "cruiseAltitude": 37000,
            "blockOff": "2026-07-11 13:00:00",
            "blockOn": "2026-07-11 14:25:00",
            "duration": "01:25",
            "burnedFuel": 4100,
            "route": "DET L6 KONAN",
            "onlineNetwork": 1,
            "status": {
                "id": 1,
                "name": "Pending"
            },
            "remarks": null,
            "rejectionRemarks": null,
            "createdAt": "2026-07-11T14:30:00.000000Z",
            "updatedAt": "2026-07-11T14:30:00.000000Z"
        }
    ]
}
 

Example response (403):


{
    "message": "You do not have permission to review flights for this airline."
}
 

Request      

GET api/v1/airlines/{airline_id}/flights/review

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

airline_id   integer     

The ID of the airline. Example: 16

airline   integer     

The airline ID. Example: 1

Accept a PIREP

requires authentication

Mark a pending PIREP as Accepted (status 2) and notify the pilot. Requires the "review flight" permission for the flight's airline.

Example request:
curl --request POST \
    "http://192.168.1.95:8001/api/v1/flights/16/accept" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "http://192.168.1.95:8001/api/v1/flights/16/accept"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'http://192.168.1.95:8001/api/v1/flights/16/accept';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "data": {
        "id": 43,
        "callsign": "422",
        "flightNumber": "422",
        "fullFlightNumber": "EV422",
        "departureIcao": "EGLL",
        "arrivalIcao": "EDDF",
        "status": {
            "id": 2,
            "name": "Accepted"
        },
        "rejectionRemarks": null
    }
}
 

Example response (403):


{
    "message": "This action is unauthorized."
}
 

Request      

POST api/v1/flights/{flight_id}/accept

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

flight_id   integer     

The ID of the flight. Example: 16

flight   integer     

The flight ID. Example: 43

Reject a PIREP

requires authentication

Mark a PIREP as Rejected (status 3) and notify the pilot. If location continuity is on and the flight was still pending, the aircraft is moved back to the flight's departure. Requires the "review flight" permission.

Example request:
curl --request POST \
    "http://192.168.1.95:8001/api/v1/flights/16/reject" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"rejection_remarks\": \"Cruise altitude above aircraft ceiling.\"
}"
const url = new URL(
    "http://192.168.1.95:8001/api/v1/flights/16/reject"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "rejection_remarks": "Cruise altitude above aircraft ceiling."
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'http://192.168.1.95:8001/api/v1/flights/16/reject';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'rejection_remarks' => 'Cruise altitude above aircraft ceiling.',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "data": {
        "id": 43,
        "callsign": "422",
        "flightNumber": "422",
        "fullFlightNumber": "EV422",
        "departureIcao": "EGLL",
        "arrivalIcao": "EDDF",
        "status": {
            "id": 3,
            "name": "Rejected"
        },
        "rejectionRemarks": "Cruise altitude above aircraft ceiling."
    }
}
 

Example response (403):


{
    "message": "This action is unauthorized."
}
 

Request      

POST api/v1/flights/{flight_id}/reject

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

flight_id   integer     

The ID of the flight. Example: 16

flight   integer     

The flight ID. Example: 43

Body Parameters

rejection_remarks   string  optional    

Reason shown to the pilot. Example: Cruise altitude above aircraft ceiling.

Instance

Public metadata about this YAAMS instance.

Instance info

Public instance metadata for API clients (e.g. ACARS "connect to your VA" setup screens). Unauthenticated by design - exposes only what the public landing page already shows.

Example request:
curl --request GET \
    --get "http://192.168.1.95:8001/api/v1/info" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "http://192.168.1.95:8001/api/v1/info"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'http://192.168.1.95:8001/api/v1/info';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "data": {
        "name": "Example Virtual Airlines",
        "version": "1.1.0",
        "apiVersion": "v1",
        "supportEmail": "ops@example.com",
        "features": {
            "registration": true,
            "userAirlineCreation": false
        }
    }
}
 

Request      

GET api/v1/info

Headers

Content-Type        

Example: application/json

Accept        

Example: application/json