Flights
Role names and
user_group_idvalues are listed in User groups.
Flight status
Section titled “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
Section titled “List Flights”GET /flights/index/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. With no filters, GET /flights/index.json returns page 1.
Path Parameters
Section titled “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
Section titled “Example”GET /flights/index/page:1/from:2025-01-01/to:2025-03-31/aircraft:/pilot:/base:/flight_type:/.jsonResponse
Section titled “Response”{ "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
Section titled “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
Section titled “Time Fields”Flight times (block_time, flight_time, night_flight_time, ifr_flight_time) are returned in seconds.
Timezone
Section titled “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. 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
Section titled “View Flight”GET /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
Section titled “Path Parameters”| Parameter | Type | Description |
|---|---|---|
| id | string | Flight ID |
Response
Section titled “Response”{ "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" } }}Aircraft log row
Section titled “Aircraft log row”flight.AircraftLog is this flight’s row in the aircraft logbook, with total_time, meter and time. The fields are null until the flight is confirmed. meter is the flight’s Hobbs end reading on an aircraft counted on Hobbs time, and null otherwise. If total_time is above meter, the reading was below the recorded hours and was not used: the flight added time instead. See Aircraft logbook.
Flight legs
Section titled “Flight legs”flight.FlightLeg lists the flight’s legs (sorties such as skydiving lifts or tows), ordered by sequence. It is an empty array when the flight has none. Legs are read and written through their own endpoints, never through Create or Update Flight: see Flight legs.
Permission Flags
Section titled “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
Section titled “Create or Update Flight”POST /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 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
Section titled “Request Body”Send a JSON body with a top-level Flight object:
{ "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. |
| 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. |
| 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. The end cannot be lower than the start. |
| hobbs_start, hobbs_end | number | Conditional | Hobbs readings. Required to confirm when the aircraft counts its airframe hours on the Hobbs meter. The end cannot be lower than the start. |
| fuel | number | No | Fuel uplifted with the flight (before or after it), in the uplift unit (CompanySetting.fuel_uplift_unit, else the aircraft’s fuel_tracking). Seeds the flight’s refuelling, see Refuelings. |
| fuel_start, fuel_end | number | No | Fuel on board at engine start / shutdown, in the aircraft’s gauge unit (Aircraft.fuel_tracking). Fuel used is worked out from them and the legs’ uplifts, never stored: see Flight legs → Fuel. |
| 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
Section titled “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
Section titled “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 a confirmed flight, the caller must be one of:
- Company Administrator, Operations Manager or Compliance & Safety Manager (
user_group_id <= 110): always. - A holder of the Flight.edit permission: any confirmed flight, at any time.
- The flight’s PIC or its creator: only within 12 hours of its off-blocks time.
Anyone else gets
400(“not authorized to edit a flight”). Other crew members (SIC, supervisor) without Flight.edit cannot edit a confirmed flight. The error body carries"error": "FLIGHT_EDIT_NOT_ALLOWED","self_edit_window_hours": 12and areason:reasonMeaning NOT_PIC_OR_CREATORThe caller is neither the PIC nor the creator, and has no Flight.edit. SELF_EDIT_WINDOW_EXPIREDThe caller is the PIC or creator, but more than 12 hours have passed since off-blocks. NO_OFFBLOCKS_TIMEThe caller is the PIC or creator, but the flight has no off-blocks time, so the 12-hour window cannot apply. Branch on
errorandreason, never onmessage. - Company Administrator, Operations Manager or Compliance & Safety Manager (
-
To update an unconfirmed flight (draft, scheduled, dispatched), the caller needs the Flight.create permission.
-
Only flights in the caller’s own company can be updated. Cancelled or deleted flights cannot.
Response
Section titled “Response”On success the API returns the saved flight with its aircraft and crew:
{ "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.
Type rating warning
Section titled “Type rating warning”Logging a flight is never refused for a missing type rating: the flight has happened, and refusing it would lose the logbook record. When the aircraft requires a type rating and a crew seat is not covered (see Type rating requirement), the saved flight carries type_rating_warning, with the same fields as the compliance type_rating block plus a message:
{ "Flight": { "id": "bcc2…", "status": "DRAFT" }, "type_rating_warning": { "required": true, "ok": false, "uncovered": ["pic"], "message": "This aircraft requires a type rating. No valid type rating for CESSNA 172 Skyhawk: Antonio Oreilly (PIC)." }}It is checked on a new flight, and on an update only when the aircraft, a crew seat or the date changes. Offline-synced flights get the same answer.
Safe retries with client_id
Section titled “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_idand noFlight.idupdates that flight instead of creating another one, with the same rules as an update byFlight.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:
{ "error": true, "validation": { "callsign": ["Callsign can not be empty"], "landing_time": ["Landing time can not be after OBT."] }}An end reading below its start is refused the same way, under validation.hobbs_end or validation.tach_end, for any aircraft that records that meter. A reading left out of the request is compared using the value stored on the flight. Saves that do not mention a reading are not checked.
Updating only some fields
Section titled “Updating only some fields”An update (Flight.id set) keeps any field the request leaves out, including times, durations, night and IFR time, and landings. To clear a time, send it empty. If you send any time and leave out block_time or flight_time, those two are worked out again from the times. Updating a DRAFT or other unconfirmed flight still needs aircraft_id.
| 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
Section titled “Recommended flow for an integration”POST /flights/create.jsonwith the flight data. Check the response forerror.- Let a person review the saved draft (for example with View Flight).
POST /flights/confirm/{id}.jsonwhen 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.
Cancel Flight
Section titled “Cancel Flight”POST /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
Section titled “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). 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
Section titled “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
Section titled “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
Section titled “Confirm Flight”POST /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
Section titled “Confirming by client_id”If you created the flight with a client_id and don’t have its Flight.id yet (for example, the create was queued offline), confirm it with POST /flights/confirm.json and a JSON body {"client_id": "<your id>"} (plus pass when required). An unknown client_id returns 404.
Repeating a confirm
Section titled “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). Confirming never waits for an ADS-B provider; follow the result with 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, or an end reading is below its start, 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
Section titled “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:
{ "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
conflictsfield is additive: clients that don’t read it see the samemessage/codeas before. Up to 20 blocking flights are returned, ordered by off-blocks time.
Dispatch Flight
Section titled “Dispatch Flight”POST /flights/dispatch/{id}.json
Dispatches an existing DRAFT or SCHEDULED flight directly — the direct-dispatch
counterpart to 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
Section titled “Path Parameters”| Parameter | Type | Description |
|---|---|---|
| id | string | Flight UUID to dispatch |
Authorization
Section titled “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
Section titled “MEL/CDL hard block”Exactly the same gate as Dispatch Schedule: an expired MEL or CDL item on the flight’s aircraft rejects the dispatch outright.
{ "result": false, "message": "ATA 32 blocks dispatch — MEL Category C expired."}Grounded aircraft hard block
Section titled “Grounded aircraft hard block”Same gate as Dispatch Schedule: while the aircraft has an open report marked Grounded (see Grounded aircraft), nobody can dispatch it.
{ "result": false, "message": "TF-ABC is grounded (ATA 32 — Left brake soft) and cannot be dispatched until maintenance releases it back to service."}Other preconditions
Section titled “Other preconditions”Checked in order, each returning result: false with its own message when it fails:
| Condition | Message |
|---|---|
The aircraft requires a type rating and a crew seat is not covered (code: TYPE_RATING_REQUIRED, see Type rating hard block). A manager (user_group_id <= 110) proceeds by posting type_rating_override_reason; an override on this flight or on the booking it came from, for the same crew, also counts. |
“This aircraft requires a type rating. No valid type rating for …” |
FRAT required (flight type require_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
Section titled “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 |
Response
Section titled “Response”{ "result": true, "flight": { "Flight": { "id": "...", "status": "DISPATCHED" } }}Flight ADS-B Track
Section titled “Flight ADS-B Track”GET /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
Section titled “Response”{ "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
Section titled “ADS-B Preview”GET /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
Section titled “Remark Check”GET /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
Section titled “Response”{ "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
Section titled “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.
Preflight Signature
Section titled “Preflight Signature”POST /flights/preflight_sign/{id}.json
Technical log (see Technical log): the pilot-in-command
accepts the aircraft after the flight is dispatched. A separate step from
Dispatch Flight. The server stores a snapshot of what was accepted
(open defects and MEL/CDL items, CRS validity, aircraft hours) and a SHA-256 hash of the
flight id, signer, time and snapshot, and records a FlightChange row with action
preflight. Online, the client never sends the snapshot.
Offline replay. NEO stores a signature given without signal and sends it later with
offline: 1, signed (the device’s unix signing time) and device_snapshot (the cached
Technical log status the pilot saw). The signature’s
created is then the device time and the row is marked offline; the snapshot gains an
offline block (signed, received, device, hard_block_on_receipt). An offline replay
is not refused for an expired MEL item or a grounded aircraft (that is recorded in
hard_block_on_receipt instead), and it is accepted on a flight that is LANDED or
CANCELED by then. signed must be no more than 5 minutes ahead of the server and no
older than 7 days. A company with require_flight_password never accepts offline
signatures.
When the technical log is on, View Flight returns flight.PreflightSignature
(user_id, created, hash, offline, name, surname), or null while unsigned. Confirming the
flight is the post-flight signature; Confirm Flight is unchanged.
Path Parameters
Section titled “Path Parameters”| Parameter | Type | Description |
|---|---|---|
| id | string | Flight UUID |
Request Body
Section titled “Request Body”| Parameter | Type | Required | Description |
|---|---|---|---|
| pass | string | conditional | The signer’s password, when the company has Require password to confirm flights (require_flight_password) on |
| offline | bool | no | 1 for a signature given offline and sent now |
| signed | int | with offline |
Unix time the signature was given on the device |
| device_snapshot | object | no | What the device showed the pilot (offline only) |
Access
Section titled “Access”- The company has
CompanySetting.techlogon, otherwise400. - Only the flight’s PIC (
pic_id). Any user group, so a student who is PIC of a solo flight signs it. - Flight company-scoped and live, otherwise
404.
Errors (400)
Section titled “Errors (400)”| Condition | Message |
|---|---|
| Already signed | “This flight already has its preflight signature.” |
Flight not DISPATCHED (offline: not DISPATCHED, LANDED or CANCELED) |
“Only a dispatched flight can be signed. Dispatch it first.” |
Offline: signed missing, in the future or older than 7 days |
“The signing time recorded on the device is not valid.” |
| Offline and the company requires the password | “Your company requires a password, so the preflight signature must be given online.” |
| Caller is not the PIC | “Only the pilot-in-command can give the preflight signature.” |
| Password missing or wrong | “Password is required” / “The entered password was not correct” |
| Expired MEL/CDL item | “ATA 32 blocks the preflight signature — MEL Category C expired.” |
| Grounded aircraft | “TF-ABC is grounded (…) and cannot be signed for until maintenance releases it back to service.” |
Response
Section titled “Response”{ "result": true, "signature": { "user_id": 618, "created": 1794295859, "hash": "12971d89e3631a2c5a2e43b1c96e38b171f187ad1c097428b7cde37d0488eb3e", "snapshot": { "aircraft_hours": 3330.62, "crs": { "job_id": "be6ace9a-…", "name": "50 Hour check", "until_hours": 3335, "until_date": null }, "defects": [] } }}Audit: Edits After Confirmation
Section titled “Audit: Edits After Confirmation”POST /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.
{ "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)
Section titled “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
Section titled “Flight Types”GET /flight_types.json
List all flight types configured for the company.
Response
Section titled “Response”[ { "id": "1", "name": "Training", "color": "#3498db" }, { "id": "2", "name": "Charter", "color": "#e74c3c" }, { "id": "3", "name": "Private", "color": "#2ecc71" }]GET /bases/index.json
List all operational bases.
Response
Section titled “Response”[ { "id": "5", "name": "Madrid Base", "airport_id": "100" }, { "id": "6", "name": "Barcelona Base", "airport_id": "101" }]