An aviation schema for every flight

Contrail is a simple set of lexicons for the AT Protocol to describe flights. It provides a common structure to support building compelling aviation-centric experiences on the ATmosphere.

To get started, browse the definitions below, read the documentation, or try the Flighty importer demo.

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: tid

An 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:datetimerequired

When this record was written, not when the flight happened. Explicit UTC offset, no fractional seconds.

datestring
maxLength: 10

Calendar 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#place

Where the flight departed. May equal 'destination'; local flights are ordinary.

destinationcom.airplaneian.contrail.temp.defs#place

Where 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.

routestring
maxLength: 1000

The 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.

sourcestring
maxLength: 64

Short identifier for the tool or dataset that wrote this record, for example 'flighty', 'manual', or 'adsb'.

sourceIdstring
maxLength: 512

That 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'.

callsignstring
maxLength: 16

The flight identification the aircraft transmitted, uppercase, verbatim. Never decompose it: populate 'operator' and 'flightNumber' as well only when the split is unambiguous.

operatorstring
maxLength: 8

ICAO designator of the agency that operated the flight, three letters, uppercase. Not airlines only: 'UAL', 'FDX', 'RCH'. Use 'operatorName' where no designator exists.

operatorNamestring
maxLength: 128

Free-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.

flightNumberstring
maxLength: 16

The operating agency's flight number, as a string. Digits only, without the operator prefix.

marketingAirlinestring
maxLength: 8

ICAO designator of the airline that sold the flight, when it differs from 'operator'. Codeshares only.

marketingFlightNumberstring
maxLength: 16

Flight number under which the flight was sold, when it differs from 'flightNumber'.

registrationstring
maxLength: 16

Registration 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.

registeredOwnerstring
maxLength: 128

Free-text name of the party the airframe is registered to. Often a trust or holding company, and frequently not the operator.

aircraftTypestring
maxLength: 128

Free-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.

icaoTypeDesignatorstring
maxLength: 8

ICAO aircraft type designator, for example 'B77W'. Write it only when the source supplies a designator.

icao24string
maxLength: 8

The 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:datetime

Scheduled 'out' time, leaving the gate or parking position. Explicit UTC offset, no fractional seconds.

actualGateDeparturestring:datetime

Actual 'out' time, leaving the gate or parking position. Explicit UTC offset, no fractional seconds.

scheduledTakeoffstring:datetime

Scheduled 'off' time, wheels off. Explicit UTC offset, no fractional seconds.

actualTakeoffstring:datetime

Actual 'off' time, wheels off. Explicit UTC offset, no fractional seconds.

scheduledLandingstring:datetime

Scheduled 'on' time, wheels on. Explicit UTC offset, no fractional seconds.

actualLandingstring:datetime

Actual 'on' time, wheels on. Explicit UTC offset, no fractional seconds.

scheduledGateArrivalstring:datetime

Scheduled 'in' time, reaching the gate or parking position. Explicit UTC offset, no fractional seconds.

actualGateArrivalstring:datetime

Actual 'in' time, reaching the gate or parking position. Explicit UTC offset, no fractional seconds.

relationshipstring
maxLength: 64
known valuespassengerpicsicstudentinstructorcrewobserver

The 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.

seatstring
maxLength: 16

Seat occupied, as a string, for example '14C'.

cabinstring
maxLength: 64
known valueseconomypremiumEconomybusinessfirst

Cabin or class of service. Open string, lower camel case; readers must tolerate values outside the known list.

statusstring
maxLength: 32
known valuesnormalcancelleddiverted

How the flight concluded. Absent means unknown, so write 'normal' explicitly when the flight operated as planned.

diversionAirportcom.airplaneian.contrail.temp.defs#place

Where the flight actually landed, when that was not 'destination'. Present only when 'status' is 'diverted'.

notesstring
maxLength: 10000 maxGraphemes: 1000

Free-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: tid

An 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:datetimerequired

When this record was written, not when the trip happened. Explicit UTC offset, no fractional seconds.

namestring
maxLength: 640 maxGraphemes: 64

Free-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>
maxLength: 200

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.

sourcestring
maxLength: 64

Short identifier for the tool that wrote this record.

sourceIdstring
maxLength: 512

That 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#placeobject

An 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

icaostring
maxLength: 8

ICAO location indicator, four characters, uppercase, for example 'KOAK'. Preferred for matching. Many small airfields have none.

iatastring
maxLength: 8

IATA location code, three characters, uppercase, for example 'OAK'. Reassigned between airports over time, so pair it with 'icao' or 'geo' where possible.

faaLidstring
maxLength: 8

FAA Location Identifier, for United States airfields that have one, for example '1G5'. Many US fields have this and no ICAO indicator.

namestring
maxLength: 256

Free-text name, for landing sites that no identifier system covers. Carries no matching guarantees.

geocommunity.lexicon.location.geo

Coordinates, for landing sites that no identifier system covers. Do not write coordinates looked up from an identifier already in this object.

terminalstring
maxLength: 32

Terminal used by this flight at this place, as free text. A fact about the flight, not about the place.

gatestring
maxLength: 32

Gate 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.