Skip to main content

Aircraft

The aircraft.proto contract defines how to start the stream (the StartStream RPC) and the JsonAircraftBatch messages it delivers. Copy it into your project; your gRPC tooling generates a client from it.

aircraft.proto
syntax = "proto3";
package jetnet.aircraft;

message StartStreamRequest {
string subscription_id = 1;
}

message JsonAircraftBatch {
bytes json_data = 1;
}

service AircraftStreamingService {
rpc StartStream(StartStreamRequest) returns (stream JsonAircraftBatch);
}

Response payload

The json_data field of each JsonAircraftBatch is a UTF-8 JSON array of records. Every record carries an event_type discriminator telling you which kind of data it is.

event_typeDescription
"position"An Aircraft State update — the current known state of one aircraft.

Today only "position" is emitted; the fields below describe that record shape.

Field presence — absent, never null

Every field is optional except the ones listed below. When a value isn't available the key is omitted entirely — the stream does not send null, 0, or an empty string as a placeholder. So an absent key means only "not currently known for this aircraft."

Emitted on every record:

  • event_type, hex, type — identity (always a value)
  • messages, seen, rssi — reception metadata (always a value)
  • mlat, tisb — source-field arrays (present, but [] when empty)
  • now — the per-record server timestamp

Every other field below is optional — build your client to null-check before use. Two typing edge cases follow from this: records with no lat/lon (see Position) and alt_baro arriving as either a number or the string "ground" (see Altitude). The full typed contract is the Record model at the bottom of this page.

Sample response payload

A single batch typically looks like this:

[
{
"event_type": "position",
"hex": "a1b2c3",
"type": "adsb_icao",
"flight": "AAL123",
"r": "N123AA",
"t": "B738",
"squawk": "1234",
"category": "A3",
"lat": 37.7749,
"lon": -122.4194,
"alt_baro": 35000,
"alt_geom": 35225,
"gs": 450.2,
"track": 270.5,
"baro_rate": 0,
"nav_qnh": 1013.2,
"nav_altitude_mcp": 35008,
"nav_heading": 271,
"mach": 0.78,
"ias": 280,
"tas": 470,
"wd": 270,
"ws": 25,
"oat": -52,
"nic": 8,
"rc": 186,
"nac_p": 9,
"nac_v": 2,
"sil": 3,
"sil_type": "perhour",
"version": 2,
"messages": 12345,
"seen": 0.1,
"seen_pos": 0.5,
"rssi": -2.5
},
{
"event_type": "position",
"hex": "d4e5f6",
"type": "mlat",
"flight": "DAL456",
"lat": 33.9416,
"lon": -118.4085,
"alt_baro": 12025,
"gs": 320.1,
"track": 95.0,
"seen": 0.3,
"seen_pos": 1.2
}
]

The first aircraft is a fully-populated ADS-B target. The second is a sparser MLAT target — most fields are absent because the underlying source provided less. Both forms are valid; client code should treat every field except hex, type, and event_type as optional.

Identity

FieldTypeDescription
event_typestringDiscriminator for future event kinds. Currently always "position".
hexstringICAO 24-bit address (e.g. "a1b2c3"). Prefixed with ~ for a non-ICAO address.
typestringHow this aircraft's data was obtained — see Source types below.
flightstringCallsign or flight number. Fixed 8-character field, space-padded (e.g. "BMA551 ") — trim trailing whitespace before use.
rstringRegistration / tail number.
tstringAircraft type code (e.g. B38M, A320).
dbFlagsnumberDatabase flags bitfield.
squawkstringTransponder squawk code (e.g. "1200").
emergencystringEmergency status: none, general, lifeguard, minfuel, nordo, unlawful, downed, reserved.
categorystringAircraft category based on ADS-B emitter category (e.g. "A1" light, "A5" heavy).

Source types

The type field tells you how each aircraft's data was obtained, which is your best cue to its accuracy. The most common — and most precise — is adsb_icao: the position is broadcast directly by the aircraft. Other types are derived from ground stations, other receivers, or radar, and vary in accuracy and update rate.

A quick naming guide: a _icao suffix means the aircraft is identified by its real 24-bit ICAO address; an _other suffix means a non-ICAO address (often anonymised or temporary).

typeWhat it means
adsb_icaoPosition broadcast directly by the aircraft's ADS-B transponder. The most common and most accurate source.
adsb_icao_ntADS-B from a non-transponder emitter (e.g. a ground vehicle), real ICAO address.
adsb_otherADS-B from a transponder using a non-ICAO (e.g. anonymised) address.
adsr_icaoADS-R: an ADS-B report originally sent on another link (e.g. UAT) and rebroadcast by a ground station; real ICAO address.
adsr_otherSame as adsr_icao but with a non-ICAO address.
tisb_icaoTIS-B: a ground station relaying traffic info about a non-ADS-B aircraft (e.g. one seen by radar); real ICAO address.
tisb_otherTIS-B about a non-ADS-B target using a non-ICAO address.
tisb_trackfileTIS-B about a target identified only by a radar track/file number (typically primary or Mode A/C radar).
adscADS-C: position reported over a long-range satellite link, typically over oceans; updates are infrequent (minutes apart).
mlatMultilateration: position computed from the timing differences of a Mode S signal across several ground receivers.
mode_sMode S transponder data only (identity, altitude, etc.) — this source carries no position.
otherMiscellaneous data; source and quality unknown.

Position

lat and lon are the aircraft's current position; the other fields tell you how accurate that position is and what to fall back on when it isn't available.

FieldTypeDescription
latnumberCurrent latitude, in decimal degrees.
lonnumberCurrent longitude, in decimal degrees.
nicnumberNavigation Integrity Category — how trustworthy the position is, on a 0–11 scale; higher is better.
rcnumberRadius of Containment, in metres — the aircraft is within this distance of the reported point; smaller is more precise.
seen_posnumberHow many seconds ago this position was measured (relative to now — see Timestamps).
rr_latnumberRough fallback latitude, estimated from which ground receivers heard the aircraft — low precision; use only when nothing better is available.
rr_lonnumberRough fallback longitude (see rr_lat).
lastPositionobjectThe last known precise position, used when no current one is available. Contains lat, lon, nic, rc, seen_pos — its seen_pos is the age, which can be up to 14 days.

When lat/lon are absent

A record is emitted as soon as any message is heard from an aircraft — even before a valid position is available — so it is normal to receive records with no lat/lon. This happens when the aircraft is tracked via Mode S only, or when its last fix has aged out (current lat/lon are dropped once the position is older than ~60 seconds). When this happens you may still have:

  • lastPosition — the last precise fix, with its own seen_pos giving the age (can be up to 14 days old). Use it when a stale position is acceptable, and always check the age.
  • rr_lat / rr_lon — a rough position derived from receiver geometry (low precision), present when no ADS-B/MLAT fix is available.

If your pipeline only wants live positions, dropping records that lack lat/lon is a reasonable and expected choice. A typical "best available position" helper:

function pickPosition(r: AircraftRecord) {
if (r.lat != null && r.lon != null) return { lat: r.lat, lon: r.lon, stale: false };
if (r.lastPosition) return { lat: r.lastPosition.lat, lon: r.lastPosition.lon, stale: true };
return null; // no usable position — drop, or use rr_lat/rr_lon as a rough fallback
}

Altitude

FieldTypeDescription
alt_baronumber | "ground"Barometric altitude in feet, or the string "ground" when the aircraft reports it is on the surface.
alt_geomnumberGeometric (GNSS) altitude in feet.
Altitude is a number or "ground"

alt_baro is the one field whose JSON type varies, so handle it as a union:

  • A number (feet) — e.g. 35000 — when a reliable barometric altitude is available.
  • The string "ground" when the aircraft's transponder reports an on-surface (air/ground) state. This is not the same as "altitude is 0" — it is a distinct surface indicator. Barometric altitude near the ground is unreliable, so the surface state is reported as this sentinel rather than a misleading number.
  • Absent when no reliable barometric altitude is available and the aircraft is not reporting on-ground — there is no null placeholder, the key is simply omitted.

A typical way to collapse it to a numeric altitude plus an on-ground flag:

function altitude(altBaro: number | "ground" | undefined) {
if (altBaro === "ground") return { altFt: 0, onGround: true };
if (typeof altBaro === "number") return { altFt: altBaro, onGround: false };
return { altFt: null, onGround: false }; // absent — unknown
}

Movement

FieldTypeDescription
gsnumberGround speed in knots.
iasnumberIndicated airspeed in knots.
tasnumberTrue airspeed in knots.
machnumberMach number.
tracknumberTrack angle over ground in degrees (0-360).
calc_tracknumberCalculated track (present when track is unavailable).
track_ratenumberRate of change of track in degrees/second.
rollnumberRoll angle in degrees (negative = left roll).
mag_headingnumberMagnetic heading in degrees.
true_headingnumberTrue heading in degrees.
baro_ratenumberBarometric vertical rate in feet/minute.
geom_ratenumberGeometric vertical rate in feet/minute.
FieldTypeDescription
nav_qnhnumberAltimeter setting (QNH/QFE) in hPa.
nav_altitude_mcpnumberAltitude selected on the Mode Control Panel / FCU, in feet.
nav_altitude_fmsnumberAltitude selected by the Flight Management System, in feet.
nav_headingnumberSelected heading from the autopilot, in degrees.
nav_modesstring[]Engaged automation modes (e.g. ["autopilot","vnav","lnav"]).

Atmospheric (derived)

FieldTypeDescription
wdnumberWind direction in degrees.
wsnumberWind speed in knots.
oatnumberOutside (static) air temperature in Celsius. Derived from Mach and true airspeed — unreliable at low speed (the calculation is inhibited below ~Mach 0.4), so occasional out-of-range values appear; sanity-filter before use.
tatnumberTotal air temperature in Celsius. Same derived-value caveat as oat.

GPS Integrity

FieldTypeDescription
gpsOkBeforenumberUnix timestamp (seconds) of last reliable ADS-B position before GPS degradation was detected.
gpsOkLatnumberLast known latitude before GPS was lost.
gpsOkLonnumberLast known longitude before GPS was lost.

Data Quality & Integrity

FieldTypeDescription
versionnumberADS-B version (0, 1, or 2).
nic_baronumberNavigation Integrity Category for barometric altitude.
nac_pnumberNavigation Accuracy Category for position.
nac_vnumberNavigation Accuracy Category for velocity.
silnumberSource Integrity Level.
sil_typestringSIL interpretation: unknown, perhour, persample.
gvanumberGeometric Vertical Accuracy.
sdanumberSystem Design Assurance.
alertnumberTransponder alert flag.
spinumberSpecial Position Identification flag.

Source Indicators

FieldTypeDescription
mlatstring[]Names of the fields whose values were derived from MLAT. Entries are source labels, which differ slightly from the JSON keys (e.g. altitudealt_baro, callsignflight). Always present; [] when none.
tisbstring[]Names of the fields whose values were derived from TIS-B (same label convention as mlat). Always present; [] when none.

Timing & Metadata

FieldTypeDescription
nownumberUnix timestamp in seconds (millisecond precision, e.g. 1743600000.123) marking when this record was generated on the server. Carried on every record — see Timestamps.
seennumberSeconds since last message of any type, relative to now.
seen_posnumberSeconds since last position update, relative to now.
messagesnumberTotal Mode S messages received from this aircraft.
rssinumberSignal strength in dBFS.

ACAS / TCAS

FieldTypeDescription
acas_raobjectACAS Resolution Advisory data (experimental, subject to change). Contains: utc, unix_timestamp, bytes, ara, rat, mte, rac, advisory_complement, advisory, tti, threat_id_hex.

Record model (TypeScript)

The complete record contract, ready to copy into a client. Fields without ? are emitted on every record; everything with ? is omitted when unavailable (never null). alt_baro is the one union type. This is the full payload — there are no other fields in this feed.

interface AircraftRecord {
// ---- always present ----
event_type: "position"; // discriminator for future event kinds
hex: string; // ICAO 24-bit address; "~" prefix = non-ICAO address
type: string; // source type, e.g. "adsb_icao", "mlat", "mode_s"
now: number; // server timestamp for this record (Unix seconds, ms precision)
messages: number; // total messages received from this aircraft
seen: number; // seconds since last message of any type
rssi: number; // signal strength (dBFS)
mlat: string[]; // field names sourced from MLAT ([] when none)
tisb: string[]; // field names sourced from TIS-B ([] when none)

// ---- identity (optional) ----
flight?: string; // callsign / flight number (8-char, space-padded)
r?: string; // registration / tail number
t?: string; // aircraft type code, e.g. "B738"
dbFlags?: number; // database flags bitfield
squawk?: string; // transponder code, e.g. "1200"
emergency?: string; // none|general|lifeguard|minfuel|nordo|unlawful|downed|reserved
category?: string; // emitter category, e.g. "A3"

// ---- position (optional) ----
lat?: number;
lon?: number;
nic?: number; // navigation integrity category (0-11, higher = better)
rc?: number; // radius of containment (metres, smaller = better)
seen_pos?: number; // seconds since last position update
rr_lat?: number; // rough receiver-derived latitude (low precision)
rr_lon?: number; // rough receiver-derived longitude (low precision)
lastPosition?: LastPosition; // last precise fix when no current position

// ---- altitude (optional) ----
alt_baro?: number | "ground"; // feet, or "ground" on the surface
alt_geom?: number; // geometric (GNSS) altitude, feet

// ---- movement (optional) ----
gs?: number; // ground speed (knots)
ias?: number; // indicated airspeed (knots)
tas?: number; // true airspeed (knots)
mach?: number;
track?: number; // track over ground (degrees, 0-360)
calc_track?: number; // calculated track when `track` unavailable
track_rate?: number; // degrees/second
roll?: number; // degrees (negative = left)
mag_heading?: number;
true_heading?: number;
baro_rate?: number; // barometric vertical rate (ft/min)
geom_rate?: number; // geometric vertical rate (ft/min)

// ---- navigation & autopilot (optional) ----
nav_qnh?: number; // altimeter setting (hPa)
nav_altitude_mcp?: number;
nav_altitude_fms?: number;
nav_heading?: number;
nav_modes?: string[]; // autopilot|vnav|althold|approach|lnav|tcas

// ---- atmospheric, derived (optional) ----
wd?: number; // wind direction (degrees)
ws?: number; // wind speed (knots)
oat?: number; // outside air temp (C)
tat?: number; // total air temp (C)

// ---- GPS integrity (optional) ----
gpsOkBefore?: number;
gpsOkLat?: number;
gpsOkLon?: number;

// ---- data quality (optional) ----
version?: number; // ADS-B version (0,1,2)
nic_baro?: number;
nac_p?: number;
nac_v?: number;
sil?: number;
sil_type?: string; // unknown|perhour|persample
gva?: number;
sda?: number;
alert?: number;
spi?: number;

// ---- ACAS / TCAS (optional, experimental) ----
acas_ra?: AcasRa;
}

interface LastPosition {
lat: number;
lon: number;
nic?: number;
rc?: number;
seen_pos: number; // age of this fix in seconds — can be up to 14 days
}

interface AcasRa {
utc?: string;
unix_timestamp?: number;
bytes?: string;
ARA?: string;
RAT?: string;
MTE?: string;
RAC?: string;
advisory_complement?: string;
advisory?: string;
TTI?: string;
threat_id_hex?: string;
}