Introduction
Contrail is a proposal to provide lexicons to describe flight segments. A contrail record
merely asserts that a particular flight existed, additional optional fields exist to
provide context. For instance, a user's connection to a particular flight (i.e. as a
passenger or pilot) is entirely optional. In fact, the only mandatory field required is
createdAt. This is the most important property of the schema and everything
else follows from it.
An absent field means the value is unknown or does not apply. It never means zero, empty, or none, and the schema defines no placeholder values. A record describing a flight where only the date and the tail number are known is as valid as one with every field populated. Tools that require complete data should enforce that requirement themselves, since the schema cannot do so without excluding general aviation, where most of the commercial fields have no meaning.
The relationship field is the one exception to this rule. When it is absent,
no claim is being made about the author's involvement, rather than the claim being
unknown. A record created from ADS-B data about another operator's aircraft simply omits
it.
Contrail is in alpha. The lexicons are published under a temp namespace while
the shape settles, so field names and constraints can still change. Feedback is welcome,
and the best place for it is Bluesky at
@airplaneian.com.
Definitions
The following schemas are published to did:plc:5jsivedaksbcc4n2epiegflk and resolve by NSID.
com.airplaneian.contrail.temp.flightrecord, key: tidAn assertion that a particular flight existed, rather than a personal log entry about the author. Only 'createdAt' is required. Every other field is optional, and absent means unknown or not applicable rather than empty or zero.
The exception is 'relationship', where absent means no claim is being made. Records of the same flight written by different people are expected, so write the identifying fields consistently. Any kind of flying is in scope, and origin may equal destination.
32 fields, 1 required
createdAtstring:datetimerequiredWhen this record was written, not when the flight happened. Explicit UTC offset, no fractional seconds.
datestringCalendar date of departure at the origin, as 'YYYY-MM-DD'. Part of the identity key with 'operator' and 'flightNumber'. Must agree with any departure timestamp.
origincom.airplaneian.contrail.temp.defs#placeWhere the flight departed. May equal 'destination'; local flights are ordinary.
destinationcom.airplaneian.contrail.temp.defs#placeWhere the flight arrived, or was intended to arrive if it was cancelled. If it diverted, this stays the intended destination and 'diversionAirport' holds where it landed.
routestringThe route as filed, written as the flight plan expressed it, for example 'SSTIK2 SSTIK Q90 AVOSE'. Free text, not normalised and not reliable for matching.
This is the planned route, not the flown track: a track belongs in a surveillance archive, which 'icao24' and a departure time are enough to query.
sourcestringShort identifier for the tool or dataset that wrote this record, for example 'flighty', 'manual', or 'adsb'.
sourceIdstringThat tool's own identifier for this flight. Kept in the record body rather than the record key, so a record can be corrected without becoming a new one. Meaningful only with 'source'.
callsignstringThe flight identification the aircraft transmitted, uppercase, verbatim. Never decompose it: populate 'operator' and 'flightNumber' as well only when the split is unambiguous.
operatorstringICAO designator of the agency that operated the flight, three letters, uppercase. Not airlines only: 'UAL', 'FDX', 'RCH'. Use 'operatorName' where no designator exists.
operatorNamestringFree-text name of the operating agency, for operators with no ICAO designator. Not reliable for matching. This is who flew the aircraft, which is often not who owns it.
flightNumberstringThe operating agency's flight number, as a string. Digits only, without the operator prefix.
marketingAirlinestringICAO designator of the airline that sold the flight, when it differs from 'operator'. Codeshares only.
marketingFlightNumberstringFlight number under which the flight was sold, when it differs from 'flightNumber'.
registrationstringRegistration or tail number, uppercase with no hyphens or spaces, so that 'G-VBOW' and 'GVBOW' are one aircraft. Military and state identifiers go here too.
registeredOwnerstringFree-text name of the party the airframe is registered to. Often a trust or holding company, and frequently not the operator.
aircraftTypestringFree-text aircraft type as the source expressed it, for example 'Boeing 737-800'. Not reliable for matching. Do not derive it from 'icaoTypeDesignator' or the reverse.
icaoTypeDesignatorstringICAO aircraft type designator, for example 'B77W'. Write it only when the source supplies a designator.
icao24stringThe airframe's 24-bit ICAO address, six lowercase hexadecimal characters. With an actual departure time this is the identity key for flights with no flight number.
scheduledGateDeparturestring:datetimeScheduled 'out' time, leaving the gate or parking position. Explicit UTC offset, no fractional seconds.
actualGateDeparturestring:datetimeActual 'out' time, leaving the gate or parking position. Explicit UTC offset, no fractional seconds.
scheduledTakeoffstring:datetimeScheduled 'off' time, wheels off. Explicit UTC offset, no fractional seconds.
actualTakeoffstring:datetimeActual 'off' time, wheels off. Explicit UTC offset, no fractional seconds.
scheduledLandingstring:datetimeScheduled 'on' time, wheels on. Explicit UTC offset, no fractional seconds.
actualLandingstring:datetimeActual 'on' time, wheels on. Explicit UTC offset, no fractional seconds.
scheduledGateArrivalstring:datetimeScheduled 'in' time, reaching the gate or parking position. Explicit UTC offset, no fractional seconds.
actualGateArrivalstring:datetimeActual 'in' time, reaching the gate or parking position. Explicit UTC offset, no fractional seconds.
relationshipstringpassengerpicsicstudentinstructorcrewobserverThe author's connection to this flight. Absent means no claim is being made, unlike every other field where absent means unknown. Open string: readers must tolerate values outside the known list.
seatstringSeat occupied, as a string, for example '14C'.
cabinstringeconomypremiumEconomybusinessfirstCabin or class of service. Open string, lower camel case; readers must tolerate values outside the known list.
statusstringnormalcancelleddivertedHow the flight concluded. Absent means unknown, so write 'normal' explicitly when the flight operated as planned.
diversionAirportcom.airplaneian.contrail.temp.defs#placeWhere the flight actually landed, when that was not 'destination'. Present only when 'status' is 'diverted'.
notesstringFree-text note. Public as soon as the record is written, and copies may persist after the record is deleted. Do not put booking references or other credentials here.
com.airplaneian.contrail.temp.triprecord, key: tidAn assertion that a set of flights belonged to one journey. Only 'createdAt' is required, and absent means unknown or not applicable. The reference points one way only, from trip to flight, and a trip references only flight records the author wrote.
5 fields, 1 required
createdAtstring:datetimerequiredWhen this record was written, not when the trip happened. Explicit UTC offset, no fractional seconds.
namestringFree-text name for the trip. Public as soon as the record is written, and copies may persist after the record is deleted.
flightsarray<string:at-uri>The flights in this trip, in the order flown, as AT-URIs to flight records. Plain AT-URIs rather than strong references, since flight records are corrected in place. References may dangle; readers must tolerate that.
sourcestringShort identifier for the tool that wrote this record.
sourceIdstringThat tool's own identifier for this trip. A grouping key may be sensitive even when the grouping is not: never write a booking reference here.
com.airplaneian.contrail.temp.defs#placeobjectAn airport, airfield, or landing site referenced by a flight record. Every field is optional, and absent means unknown or not applicable. Write the identifier fields wherever they are known, since readers match on them, and prefer 'icao' where a place has one.
Never invent or derive an identifier the source did not supply.
7 fields, 0 required
icaostringICAO location indicator, four characters, uppercase, for example 'KOAK'. Preferred for matching. Many small airfields have none.
iatastringIATA location code, three characters, uppercase, for example 'OAK'. Reassigned between airports over time, so pair it with 'icao' or 'geo' where possible.
faaLidstringFAA Location Identifier, for United States airfields that have one, for example '1G5'. Many US fields have this and no ICAO indicator.
namestringFree-text name, for landing sites that no identifier system covers. Carries no matching guarantees.
geocommunity.lexicon.location.geoCoordinates, for landing sites that no identifier system covers. Do not write coordinates looked up from an identifier already in this object.
terminalstringTerminal used by this flight at this place, as free text. A fact about the flight, not about the place.
gatestringGate or stand used by this flight at this place, as free text.
These are currently published under a temp namespace while the shape
settles. Published lexicon constraints can never be loosened afterwards, so the stable
names will not be claimed until real data has been through them.