> For the complete documentation index, see [llms.txt](https://docs.flylogs.com/fcom/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.flylogs.com/fcom/api-docs/reference/flights.md).

# Flights

> Role names and `user_group_id` values are listed in [User groups](/fcom/api-docs/reference/users.md#user-groups).

## Flight status

Every flight carries a single `status` field describing where it sits in its lifecycle. It is the only lifecycle field on a flight: the legacy `draft` and `deleted` booleans have been removed from both the database and every API response, and are no longer accepted in requests.

| Status       | Meaning                                                                                                           |
| ------------ | ----------------------------------------------------------------------------------------------------------------- |
| `DRAFT`      | Unconfirmed flight created directly, without a schedule. The default for a newly created flight.                  |
| `SCHEDULED`  | Unconfirmed flight created from a schedule booking.                                                               |
| `DELAYED`    | Computed at read time only, never stored: a `SCHEDULED` flight whose scheduled time is more than one hour past.   |
| `DISPATCHED` | Dispatched through the dispatch/FRAT flow, not yet confirmed.                                                     |
| `LANDED`     | Confirmed flight. Only `LANDED` flights count toward logbooks, aircraft hours, duty records, billing and reports. |
| `CANCELED`   | Removed while still unconfirmed (was `draft = 1`, `deleted = 1`).                                                 |
| `DELETED`    | Removed after having been confirmed (was `draft = 0`, `deleted = 1`).                                             |

Mapping from the old booleans, for clients migrating off them:

| Old condition               | Equivalent status filter                            |
| --------------------------- | --------------------------------------------------- |
| `draft = 0 AND deleted = 0` | `status = LANDED`                                   |
| `draft = 1 AND deleted = 0` | `status IN (DRAFT, SCHEDULED, DELAYED, DISPATCHED)` |
| `deleted = 0`               | `status NOT IN (CANCELED, DELETED)`                 |
| `deleted = 1`               | `status IN (CANCELED, DELETED)`                     |

***

## List Flights

<mark style="color:blue;">`GET`</mark> `/flights/load/page:{page}/from:{from}/to:{to}/aircraft:{aircraftId}/pilot:{pilotId}/base:{baseId}/flight_type:{typeId}/.json`

Retrieve a paginated list of flight records with optional filters.

#### Path Parameters

All filter parameters are optional — use empty string to skip a filter.

| Parameter    | Type   | Description                                        |
| ------------ | ------ | -------------------------------------------------- |
| page         | number | Page number (starts at 1)                          |
| from         | string | Start date filter (YYYY-MM-DD)                     |
| to           | string | End date filter (YYYY-MM-DD)                       |
| aircraft     | string | Aircraft ID filter                                 |
| pilot        | string | Pilot user ID filter                               |
| base         | string | Base ID filter                                     |
| flight\_type | string | Flight type ID filter                              |
| limit        | number | Records per page (optional, default 20, max 20000) |

#### Example

```
GET /flights/load/page:1/from:2025-01-01/to:2025-03-31/aircraft:/pilot:/base:/flight_type:/.json
```

#### Response

```json
{
  "flights": [
    {
      "Flight": {
        "id": "5678",
        "date": "2025-03-10",
        "status": "LANDED",
        "callsign": "EC-ABC",
        "departure_airport": "LEMD",
        "landing_airport": "LEBL",
        "offblocks_time": "08:00:00",
        "takeoff_time": "08:15:00",
        "landing_time": "09:15:00",
        "onblocks_time": "09:25:00",
        "block_time": "5100",
        "flight_time": "3600",
        "rules": "VFR",
        "landings": "1",
        "engine_starts": "1",
        "pax": "2",
        "oil": "0.5",
        "fuel": "45",
        "cargo": "0",
        "night_flight_time": "0",
        "ifr_flight_time": "0"
      },
      "Base": {
        "id": "5",
        "name": "Madrid Base"
      },
      "Aircraft": {
        "id": "45",
        "registration": "EC-ABC",
        "multiengine": false,
        "multipilot": false,
        "simulator": false,
        "AircraftModel": {
          "name": "C172",
          "icao": "C172",
          "AircraftManufacturer": { "name": "Cessna" }
        }
      },
      "FlightType": {
        "id": "1",
        "name": "Training",
        "color": "#3498db",
        "pic_flight_time": "pic",
        "sic_flight_time": "none",
        "supervisor_flight_time": "none"
      },
      "Pic": {
        "id": "123",
        "user_group_id": "110",
        "UserDetail": {
          "name": "John",
          "surname": "Doe",
          "id": "123"
        }
      },
      "Sic": null
    }
  ],
  "paginate": {
    "page": 1,
    "current": 1,
    "count": 156,
    "prevPage": false,
    "nextPage": true,
    "pageCount": 7,
    "limit": 25
  },
  "time": "1.23"
}
```

#### Pagination

| Field     | Type    | Description                    |
| --------- | ------- | ------------------------------ |
| page      | number  | Requested page                 |
| current   | number  | Current page                   |
| count     | number  | Total number of records        |
| prevPage  | boolean | Whether a previous page exists |
| nextPage  | boolean | Whether a next page exists     |
| pageCount | number  | Total number of pages          |
| limit     | number  | Records per page               |

#### Time Fields

Flight times (`block_time`, `flight_time`, `night_flight_time`, `ifr_flight_time`) are returned in **seconds**.

#### Timezone

The clock fields `offblocks_time`, `takeoff_time`, `landing_time`, `onblocks_time` and the flight `date` are expressed in the company's **flight timezone**. This is `CompanySetting.flight_timezone_id` when set, otherwise the company timezone (`CompanyDetail.timezone_id`) — see [Company Settings](/fcom/api-docs/reference/company.md). This applies both to the times returned here and to the wall-clock times you submit when creating or editing a flight. Schedules and trainings use the company timezone regardless.

***

## View Flight

<mark style="color:blue;">`GET`</mark> `/flights/view/{id}.json`

Retrieve full details for a single flight, including crew, airports, audit trail, and permissions.

Users with `user_group_id > 170` (Captain and below) may only view flights they are involved in (creator, PIC, SIC, supervisor, or owner of the aircraft). Otherwise returns `403 Forbidden`.

#### Path Parameters

| Parameter | Type   | Description |
| --------- | ------ | ----------- |
| id        | string | Flight ID   |

#### Response

```json
{
  "flight": {
    "Flight": {
      "id": "5678",
      "date": "2025-03-10",
      "status": "LANDED",
      "callsign": "EC-ABC",
      "departure_airport": "LEMD",
      "landing_airport": "LEBL",
      "offblocks_time": "08:00:00",
      "takeoff_time": "08:15:00",
      "landing_time": "09:15:00",
      "onblocks_time": "09:25:00",
      "block_time": "5100",
      "flight_time": "3600",
      "night_flight_time": "0",
      "ifr_flight_time": "0",
      "rules": "VFR",
      "crosscountry": true,
      "multiengine": false,
      "landings": "1",
      "fuel": "45.5",
      "oil": null,
      "pax": "1",
      "cargo": null,
      "route": "LEMD DCT LEBL",
      "remarks": "",
      "pf": "PIC",
      "pic_id": "123",
      "sic_id": null
    },
    "Base": { "id": "5", "name": "Madrid Base", "airport_id": "100" },
    "Aircraft": {
      "id": "45",
      "registration": "EC-ABC",
      "photo": "https://...",
      "adsb": "ABC123",
      "multipilot": false,
      "active": true,
      "AircraftModel": {
        "name": "C172",
        "icao": "C172",
        "AircraftManufacturer": { "name": "Cessna" }
      },
      "hours": "12500",
      "landings": "8900"
    },
    "FlightType": {
      "id": "1",
      "name": "Training",
      "color": "#3498db",
      "description": "Training flights"
    },
    "Pic": {
      "id": "123",
      "active": true,
      "pilot": true,
      "deleted": false,
      "user_group_id": "110",
      "UserGroup": { "role": "pilot", "name": "Pilot" },
      "UserDetail": { "name": "John", "surname": "Doe", "photo": null, "id": "123" }
    },
    "Sic": null,
    "DepartureAirport": {
      "id": "100",
      "name": "Adolfo Suárez Madrid–Barajas",
      "lat": "40.4719",
      "lon": "-3.5626"
    },
    "LandingAirport": {
      "id": "101",
      "name": "Josep Tarradellas Barcelona–El Prat",
      "lat": "41.2971",
      "lon": "2.0785"
    },
    "FlightChange": [
      {
        "id": "890",
        "flight_id": "5678",
        "user_id": "123",
        "action": "created",
        "fields": null,
        "comments": null,
        "created": "2025-03-10 09:30:00",
        "User": {
          "id": "123",
          "UserDetail": { "name": "John", "surname": "Doe", "id": "123" },
          "UserGroup": { "role": "pilot" }
        }
      }
    ],
    "Upload": [],
    "SafetyReport": []
  },
  "distance": 267,
  "canConfirm": true,
  "canEdit": true,
  "canCreate": true,
  "canDelete": true,
  "changeNames": {
    "created": { "icon": "fa-plus", "name": "Created", "class": "text-success" },
    "confirmed": { "icon": "fa-check", "name": "Confirmed", "class": "text-primary" },
    "edited": { "icon": "fa-pencil", "name": "Edited", "class": "text-warning" }
  }
}
```

#### Permission Flags

| Field      | Type    | Description                          |
| ---------- | ------- | ------------------------------------ |
| canConfirm | boolean | User can confirm/approve this flight |
| canEdit    | boolean | User can edit this flight            |
| canCreate  | boolean | User can create new flights          |
| canDelete  | boolean | User can delete this flight          |

***

## Create or Update Flight

<mark style="color:green;">`POST`</mark> `/flights/create.json`

Create a flight record, or update an existing one. A new flight is **always saved as `DRAFT`**, whatever `status` you send. To make it count towards the logbook, aircraft hours, duty records and billing, [confirm it](#confirm-flight) afterwards. Creating and confirming are two separate calls, so a reviewed flight can be entered first and approved afterwards.

The flight is created in the company of the API key, and its creator (`user_id`) is the user the key is bound to.

#### Request Body

Send a JSON body with a top-level `Flight` object:

```json
{
  "Flight": {
    "aircraft_id": 45,
    "flight_type_id": 1,
    "date": "2026-10-07",
    "callsign": "EC-ABC",
    "rules": "VFR",
    "departure_airport": "LEMD",
    "landing_airport": "LEBL",
    "offblocks_time": 1791360000,
    "takeoff_time": 1791360900,
    "landing_time": 1791364500,
    "onblocks_time": 1791365100,
    "landings": 1,
    "pic_id": 123,
    "comments": "Created from approved post-flight sheet"
  }
}
```

| Field                    | Type              | Required                                | Description                                                                                         |
| ------------------------ | ----------------- | --------------------------------------- | --------------------------------------------------------------------------------------------------- |
| aircraft\_id             | integer           | Yes                                     | Aircraft ID. Without it the request is rejected with `400 Missing aircraft`.                        |
| flight\_type\_id         | integer           | Yes (create)                            | Flight type ID, from [`/flight_types.json`](#flight-types).                                         |
| date                     | string            | Yes                                     | Flight date, `YYYY-MM-DD`.                                                                          |
| callsign                 | string            | Yes                                     | Callsign. Must not be empty.                                                                        |
| rules                    | string            | Yes (create)                            | `VFR` or `IFR`.                                                                                     |
| departure\_airport       | string            | Yes                                     | Departure airport, as returned in `Flight.departure_airport` by [View Flight](#view-flight).        |
| landing\_airport         | string            | Yes                                     | Landing airport, same format.                                                                       |
| offblocks\_time          | integer           | No                                      | Off-blocks time, unix seconds.                                                                      |
| takeoff\_time            | integer           | No                                      | Take-off time, unix seconds.                                                                        |
| landing\_time            | integer           | No                                      | Landing time, unix seconds.                                                                         |
| onblocks\_time           | integer           | No                                      | On-blocks time, unix seconds.                                                                       |
| night\_flight\_time      | integer \| string | No                                      | Night time, in seconds or `HH:MM`. Capped to the block time. Defaults to `0`.                       |
| ifr\_flight\_time        | integer \| string | No                                      | IFR time, in seconds or `HH:MM`. Capped to the block time. Defaults to `0`.                         |
| landings                 | integer           | No                                      | Number of landings (cycles). Defaults to `0`.                                                       |
| engine\_starts           | integer           | No                                      | Number of engine starts. Non-numeric values are stored as `null`.                                   |
| pic\_id                  | integer           | No at creation, **required to confirm** | Pilot in command.                                                                                   |
| sic\_id                  | integer           | No                                      | Second in command.                                                                                  |
| supervisor\_id           | integer           | No                                      | Supervisor.                                                                                         |
| tach\_start, tach\_end   | number            | Conditional                             | Tach readings. Required to confirm when the aircraft counts its airframe hours on the tach.         |
| hobbs\_start, hobbs\_end | number            | Conditional                             | Hobbs readings. Required to confirm when the aircraft counts its airframe hours on the Hobbs meter. |
| comments                 | string            | No                                      | Free-text change note, stored in the flight's change history.                                       |
| id                       | string            | No                                      | Include the ID of an existing flight to **update** it instead of creating one.                      |

Fields you send as `HH:MM` strings (`night_flight_time`, `ifr_flight_time`, `flight_time`, `block_time`) are converted to seconds. For the four event times, send unix seconds: this is the form the API returns, and it avoids any time-zone ambiguity. As a convenience the API also accepts the strings `start`, `takeoff`, `landing` and `end` (`HH:MM`), combined with `date` into the off-blocks, take-off, landing and on-blocks times.

#### Calculated fields

When all four event times are present, the API calculates `block_time` (on-blocks minus off-blocks) and `flight_time` (landing minus take-off) unless you send them. If a time falls before the previous event (for example a flight across midnight), it is moved forward one day. When any of the four times is missing, `block_time` and `flight_time` are left empty and the flight cannot be confirmed.

#### Authorization

* To **create** a flight, the caller must hold the **Flight.create** company permission; otherwise the API returns `403 Forbidden` ("not authorized to create a flight draft").
* Users above Company Administrator (`user_group_id > 110`) cannot create flights dated before today minus the company's **logbook block window** (`flights_block_days`), when one is set.
* To **update** an existing flight, the caller needs the **Flight.edit** permission. A crew member or the creator without it can no longer edit a **confirmed** flight once more than 12 hours have passed since its off-blocks time (`400`, "not authorized to edit a flight"). Unconfirmed flights stay editable.
* Only flights in the caller's own company can be updated. Cancelled or deleted flights cannot.

#### Response

On success the API returns the saved flight with its aircraft and crew:

```json
{
  "Flight": {
    "id": "9a1b2c3d-...",
    "status": "DRAFT",
    "date": "2026-10-07",
    "callsign": "EC-ABC",
    "block_time": 5100,
    "flight_time": 3600
  },
  "Aircraft": { "id": "45", "registration": "EC-ABC" },
  "Pic": { "id": "123" },
  "Sic": null,
  "premium_process": true
}
```

Keep `Flight.id`: you need it to confirm, view, update or cancel the flight.

#### Safe retries with `client_id`

If your integration may send the same new flight more than once (it queues requests while offline, or retries after a timeout), add a `client_id` to the `Flight` object: your own id for that flight, up to 64 characters of letters, digits, `_` and `-`, unique within your company.

* The first request creates the flight and stores the `client_id`.
* Any later request with the same `client_id` and **no** `Flight.id` updates that flight instead of creating another one, with the same rules as an update by `Flight.id`.
* If that update is refused because your company doesn't allow editing confirmed flights after 12 hours, the request still succeeds: the response is the stored flight, unchanged, with `"warning": "edit_not_allowed"`.
* If the flight has since been cancelled or deleted, the response is that flight, unchanged, with `"warning": "flight_removed"`. It is never restored.

`client_id` is set once, on create; an update never changes it.

If validation fails the HTTP status is still `200`, but the body is an error object. Always check for `error`:

```json
{
  "error": true,
  "validation": {
    "callsign": ["Callsign can not be empty"],
    "landing_time": ["Landing time can not be after OBT."]
  }
}
```

| Message                                                       | Cause                                                              |
| ------------------------------------------------------------- | ------------------------------------------------------------------ |
| `Missing aircraft`                                            | `aircraft_id` missing (`400`).                                     |
| `Missing flight type`                                         | `flight_type_id` missing on a new flight.                          |
| `Invalid flight rules`                                        | `rules` is not `VFR` or `IFR`.                                     |
| `Missing a valid date`                                        | `date` missing or not `YYYY-MM-DD`.                                |
| `Landing time can not be after OBT.`                          | Landing time later than on-blocks time.                            |
| `Flight date is outside the allowed logbook window (N days).` | Date older than the company's logbook block window (`400`).        |
| `Flight not found`                                            | The `id` does not belong to a live flight in your company (`404`). |

#### Recommended flow for an integration

1. `POST /flights/create.json` with the flight data. Check the response for `error`.
2. Let a person review the saved draft (for example with [View Flight](#view-flight)).
3. `POST /flights/confirm/{id}.json` when approved. Confirmation needs a block time, an aircraft and a PIC. It also needs the flight to have landed already and the tach or Hobbs readings, where the aircraft requires them. It is blocked if the flight overlaps another confirmed flight on the same aircraft.

{% hint style="info" %}
Creating a flight through the API follows the same rules as the NEO flight form. Premium and Unlimited companies also get the training-mission, duty-time and schedule updates described for the NEO app, because the same endpoint serves both.
{% endhint %}

***

## Cancel Flight

<mark style="color:green;">`POST`</mark> `/flights/cancel.json`

Cancel (soft-delete) a flight record. The flight moves to `CANCELED` if it was still unconfirmed, or to `DELETED` if it had already been confirmed (`LANDED`), and a `cancel` entry is added to its change history. There is **no date restriction** — a flight can be cancelled at any time, including flights dated in the past.

#### Request Body

| Field      | Type   | Required | Description                                                                                                                                                                                                                                                                                  |
| ---------- | ------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| id         | string | Yes\*    | Flight ID to cancel                                                                                                                                                                                                                                                                          |
| client\_id | string | No       | Instead of `id`: the `client_id` the flight was created with (see [Safe retries](#safe-retries-with-client_id)). Use it when you can't know whether your create reached the server. Unknown `client_id` returns `404`.                                                                       |
| reason     | string | Yes      | Reason for cancellation                                                                                                                                                                                                                                                                      |
| text       | string | No       | Free-text note stored with the cancellation                                                                                                                                                                                                                                                  |
| notify     | string | No       | `"true"` to notify the other crew: an in-app message (email if urgent alerts are on) for PIC/SIC, plus a push notification to PIC, SIC and supervisor except the caller. WhatsApp (`flightchange` template) is sent only to crew with `User.whatsapp` on whom the push reached on no device. |

\* Send either `id` or `client_id`.

#### Authorization

The caller must satisfy **at least one** of the following, otherwise the request returns `400 Not authorized`:

* Has the **Flight.create**, **Flight.edit**, or **Flight.confirm** company permission, or
* Is a crew member of the flight — the **PIC** (`pic_id`), **SIC** (`sic_id`), or **Supervisor** (`supervisor_id`), or
* Is the user who created the flight (`user_id`).

Company Administrators, Operations Managers, and Compliance & Safety Managers hold these permissions by default. Note that the front-end only surfaces the Cancel action for unconfirmed flights; the endpoint itself does not restrict by status.

Only flights of the API key's company can be cancelled; any other id returns `404 Flight not found`.

#### Repeating a cancel

Cancelling a flight that is already `CANCELED` or `DELETED` is not an error: the response is `{"result": true, "warning": "already_removed"}`, nothing changes and nobody is notified. A client that queues cancellations while offline can therefore safely send one twice.

***

## Confirm Flight

<mark style="color:green;">`POST`</mark> `/flights/confirm/{id}.json`

Confirm an unconfirmed flight (moves it to `status = LANDED`, updates aircraft books, billing, and duty records). The flight must already have a block time, aircraft, and PIC. Requires the **Flight.confirm** company permission; when `require_flight_password` is enabled on the company, a `pass` field with the caller's password is also required.

#### Confirming by `client_id`

If you created the flight with a [`client_id`](#safe-retries-with-client_id) and don't have its `Flight.id` yet (for example, the create was queued offline), confirm it with <mark style="color:green;">`POST`</mark> `/flights/confirm.json` and a JSON body `{"client_id": "<your id>"}` (plus `pass` when required). An unknown `client_id` returns `404`.

#### Repeating a confirm

Confirming a flight that is already confirmed is not an error: the response is the flight's `result` with `status: "LANDED"` and `change: false`, and nothing changes. A cancelled or deleted flight returns `400` with `"This flight was cancelled or deleted, so it cannot be confirmed."`.

On paid plans the response's `adsb` field is the flight's ADS-B lookup (`status` `pending`, or `found` straight away when positions were already stored, e.g. from an [ADS-B Preview](#ads-b-preview)). Confirming never waits for an ADS-B provider; follow the result with [Flight ADS-B Track](#flight-ads-b-track).

Some refusals come back as HTTP `200`: when the aircraft needs a Hobbs or tach reading that the flight is missing, `result` carries a `message` and an `errors` object instead of `status: "LANDED"`. Treat a confirm as successful only when `result.status` is `LANDED`.

#### Overlap check

Confirmation is blocked when the flight's block times overlap another **confirmed** (`status = LANDED`) flight on the **same aircraft**. The response is `400` with the usual `message`, plus a **`conflicts`** array naming the blocking flight(s) so a client can link to them:

```json
{
  "code": 400,
  "message": "The selected date and time are already occupied by another flight for this aircraft.",
  "url": "/flights/confirm/9a1b....json",
  "conflicts": [
    {
      "id": "9c2d3e4f-....",
      "callsign": "IBE123",
      "date": "2026-07-22",
      "offblocks_time": 1753180200,
      "onblocks_time": 1753185600,
      "link": "/flights/view/9c2d3e4f-...."
    }
  ]
}
```

| Field            | Type           | Description                                                                                           |
| ---------------- | -------------- | ----------------------------------------------------------------------------------------------------- |
| `id`             | string         | Blocking flight ID                                                                                    |
| `callsign`       | string \| null | Blocking flight callsign, when set                                                                    |
| `date`           | string         | Flight date (`YYYY-MM-DD`)                                                                            |
| `offblocks_time` | integer        | Off-blocks time, unix seconds                                                                         |
| `onblocks_time`  | integer        | On-blocks time, unix seconds                                                                          |
| `link`           | string \| null | Relative URL to the flight — populated only for flights in the caller's own company; `null` otherwise |

> The `conflicts` field is additive: clients that don't read it see the same `message`/`code` as before. Up to 20 blocking flights are returned, ordered by off-blocks time.

***

## Dispatch Flight

<mark style="color:green;">`POST`</mark> `/flights/dispatch/{id}.json`

Dispatches an existing `DRAFT` or `SCHEDULED` flight directly — the direct-dispatch counterpart to [Dispatch Schedule](/fcom/api-docs/reference/schedules.md#dispatch-schedule), used when the flight record already exists rather than being created from a schedule. On success the flight moves to status `DISPATCHED`, a `FlightChange` history row is recorded, and a linked schedule (if any) has its departure/destination synced to match.

#### Path Parameters

| Parameter | Type   | Description             |
| --------- | ------ | ----------------------- |
| id        | string | Flight UUID to dispatch |

#### Authorization

The caller must satisfy **at least one** of: the **Flight.create** or **Flight.edit** company permission, or be a crew member of the flight (`user_id`, `pic_id`, `sic_id`, or `supervisor_id`) — otherwise `400 Not authorized`. The flight must currently be `DRAFT` or `SCHEDULED`, otherwise the call returns `result: false` with `"Only draft or scheduled flights can be dispatched."`.

#### MEL/CDL hard block

Exactly the same gate as [Dispatch Schedule](/fcom/api-docs/reference/schedules.md#dispatch-schedule): an **expired** MEL or CDL item on the flight's aircraft rejects the dispatch outright.

```json
{
  "result": false,
  "message": "ATA 32 blocks dispatch — MEL Category C expired."
}
```

#### Other preconditions

Checked in order, each returning `result: false` with its own message when it fails:

| Condition                                                                         | Message                                                                          |
| --------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
| FRAT required (`schedule_dispatch_frat` on, dispatcher is crew) and not completed | "A completed Flight Risk Assessment (FRAT) is required to dispatch this flight." |
| Non-school company and no `pax` posted                                            | "Number of passengers (PAX) is required to dispatch this flight."                |
| Departure or destination missing (neither already on the flight nor posted)       | "Departure and destination airports are required to dispatch this flight."       |

#### Request Body

| Parameter                           | Type   | Required    | Description                                                                                      |
| ----------------------------------- | ------ | ----------- | ------------------------------------------------------------------------------------------------ |
| departure\_airport                  | string | conditional | Required if the flight has no departure airport yet                                              |
| landing\_airport                    | string | conditional | Required if the flight has no destination airport yet                                            |
| pax                                 | number | conditional | Required for non-school companies                                                                |
| pob                                 | number | no          | Persons on board                                                                                 |
| endurance                           | string | no          | Fuel endurance                                                                                   |
| alternate\_airport                  | string | no          | Alternate airport                                                                                |
| frat\_score, frat\_band, frat\_data | —      | conditional | Same FRAT fields as [Dispatch Schedule](/fcom/api-docs/reference/schedules.md#dispatch-schedule) |

#### Response

```json
{
  "result": true,
  "flight": { "Flight": { "id": "...", "status": "DISPATCHED" } }
}
```

***

## Flight ADS-B Track

<mark style="color:blue;">`GET`</mark> `/flights/adsb/{id}.json`

The flight's ADS-B track and where its lookup stands. Not available on the Free plan (`400`).

Track lookups for confirmed flights run in the background on the server, usually within 15 minutes of on-blocks: Flylogs first uses positions it already has (live OpenSky feed, Spidertracks/Airbly imports, an earlier preview), then asks Flightradar24. This endpoint never calls a provider itself, so it is safe to poll while `status` is `pending`.

#### Response

```json
{
  "status": "found",
  "source": "fr24",
  "misses": 0,
  "next_attempt": null,
  "checked": 1791632400,
  "legs": [
    {
      "fr24_id": "3a1b2c3d",
      "orig_icao": "LELL",
      "dest_icao": "LELL",
      "takeoff": 1791628500,
      "landed": 1791631620,
      "first_seen": 1791628380,
      "last_seen": 1791631740,
      "ended": true,
      "track": "stored"
    }
  ],
  "positions": [
    { "lat": "41.52080", "lon": "2.10510", "alt": "1500", "speed": "95", "vspeed": "0", "track": "090", "ground": false, "source": "fr24", "created": "1791628500" }
  ]
}
```

| Field         | Type           | Description                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| ------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| status        | string         | `found` · `pending` (lookup queued or a leg still being closed by the provider) · `not_found` (looked up, nothing recorded — final after the retries) · `no_data` (before the provider's history, 2024-04-07) · `invalid` (simulator, missing/implausible block times, unsearchable registration) · `untracked` (plan without ADS-B) · `unconfirmed` (draft/dispatched flight: `positions` are whatever the live feed stored in the block window) |
| source        | string \| null | Where the track came from: `fr24`, `opensky`, `spidertracks`, `airbly`                                                                                                                                                                                                                                                                                                                                                                            |
| misses        | int            | Lookups that found nothing so far. A miss is retried after 1 h and 6 h, then becomes `not_found`. Aircraft without any track in their last 5 resolved flights get one attempt only                                                                                                                                                                                                                                                                |
| next\_attempt | int \| null    | Unix time of the next lookup while `pending`                                                                                                                                                                                                                                                                                                                                                                                                      |
| legs          | array          | Flightradar24 flights matched to this flight (several for circuits with full-stop landings). Unix times in UTC                                                                                                                                                                                                                                                                                                                                    |
| positions     | array          | Track points, oldest first. `alt` in feet, `speed` in knots, `vspeed` in ft/min, `created` Unix time                                                                                                                                                                                                                                                                                                                                              |

Company-scoped (`404 Flight not found` otherwise).

***

## ADS-B Preview

<mark style="color:blue;">`GET`</mark> `/flights/adsb_preview.json?aircraft_id={id}&start={unix}&end={unix}[&tracks=1]`

What ADS-B recorded for an aircraft in a block window, **before** the flight is saved or confirmed — used by the flight form's "Find on ADS-B". Not available on the Free plan (`400`).

| Parameter    | Type | Description                                                                                                          |
| ------------ | ---- | -------------------------------------------------------------------------------------------------------------------- |
| aircraft\_id | int  | Aircraft of the caller's company (`404` otherwise)                                                                   |
| start, end   | int  | Entered off-blocks / on-blocks, Unix seconds. At most 24 h apart (`400` otherwise)                                   |
| tracks       | 0/1  | Also return the track positions. Only send it when the user asks to see the track: it is the expensive provider call |

Response: `status` (`found`, `not_found`, `unavailable` — provider not reachable or pausing after a rate limit, try again in a few minutes — `no_data`, `invalid`, `future` — window has not started), `legs` and `positions` with the same shape as above. When no leg is found, `positions` carries any live-feed points in the window.

Results are stored and reused: the same window is never searched twice, and a track fetched here is linked to the flight with no further lookup when it is confirmed.

***

## Remark Check

<mark style="color:blue;">`GET`</mark> `/flights/remark_check/{id}.json`

Advisory reading of one flight's `remarks`: does it look like an aircraft defect, or a safety-relevant event? Used by the flight page to offer the aircraft/safety report forms. **Nothing is created or stored.**

#### Response

```json
{
  "check": {
    "defect": 0.91,
    "safety": 0.15,
    "suggest": ["defect"]
  }
}
```

| Field         | Type           | Description                                                                                                                                                                                         |
| ------------- | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| check         | object \| null | `null` when there is nothing to read: empty or label-only remark (`5T`, `NIL`…), flight logged more than 7 days ago, `CANCELED`/`DELETED` flight, or the feature is not enabled on the installation |
| check.defect  | number \| null | Probability (0–1) that the remark reports an aircraft fault or damage                                                                                                                               |
| check.safety  | number \| null | Probability (0–1) that it describes a safety-relevant event                                                                                                                                         |
| check.suggest | string\[]      | `defect` and/or `safety` — kinds above 0.7 for which the flight has **no** aircraft/safety report yet                                                                                               |

#### Authorization

Company-scoped (`404 Flight not found` otherwise). The caller must be the flight's **PIC**, **SIC** or **Supervisor**, or a manager (`user_group_id < 111`); anyone else gets `403`.

***

## Audit: Edits After Confirmation

<mark style="color:green;">`POST`</mark> `/manager/flights/audit.json`

Besides `flights` and `totals`, the audit response carries `edits`: for every returned flight that was edited after confirmation, its edits, oldest first.

```json
{
  "edits": {
    "7d2326f8-2074-46bf-98b3-a7f39d7ff4df": [
      { "id": "831880", "created": "1792183239", "user_id": "18196",
        "comments": "Landing time was wrong, corrected from the tech log",
        "reason": "TIMES", "confidence": 1 }
    ]
  }
}
```

| Field      | Description                                                                                                                                                                                                        |
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| comments   | The reason typed by the editor, unchanged                                                                                                                                                                          |
| reason     | What the edit was about: `TIMES`, `CREW`, `AIRCRAFT`, `ROUTE`, `TRAINING`, `TYPE`, `BILLING` or `NOTES`. `null` when it has not been read yet (an hourly job reads new edits) or the reading is unsure (below 0.6) |
| confidence | The stored reading's confidence (0–1), or `null`                                                                                                                                                                   |

`edits` is `{}` when no returned flight was edited. The reading is stored apart from the logged edit, which is never modified.

***

## Export Flights (XLS)

The server-side `xls:1` export has been removed. The logbook Excel file is now generated client-side by the NEO web app: it pulls the flights from the **List Flights** endpoint above (using the `limit` parameter to fetch all matching rows) and builds the XLSX in the browser.

***

## Flight Types

<mark style="color:blue;">`GET`</mark> `/flight_types.json`

List all flight types configured for the company.

#### Response

```json
[
  { "id": "1", "name": "Training", "color": "#3498db" },
  { "id": "2", "name": "Charter", "color": "#e74c3c" },
  { "id": "3", "name": "Private", "color": "#2ecc71" }
]
```

***

## Bases

<mark style="color:blue;">`GET`</mark> `/bases/index.json`

List all operational bases.

#### Response

```json
[
  { "id": "5", "name": "Madrid Base", "airport_id": "100" },
  { "id": "6", "name": "Barcelona Base", "airport_id": "101" }
]
```
