Authentication

Every feeder gets a unique API key. Use it from any IP — your laptop, VPS, phone, scripts.

curl -H "Authorization: Bearer YOUR_API_KEY" https://adsbiq.com/api/v2/all

Your API key is shown on the join page and your feeder dashboard after install.

Alternative: IP-based auth (no key needed from home network)

Requests from your feeder's IP are automatically authenticated — no header needed:

curl https://adsbiq.com/api/v2/all

Not a feeder? Install in 60 seconds to get access.

Access & Rate Limits

All feeds (REST, WebSocket) are exclusively for active feeders. Non-feeders get 403. Become a feeder to get access.

FeedLimit
REST API60 req burst / 10 per minute sustained. Exceeding returns 429.
WebSocketServer-push — no request rate limit. One connection per feeder.

REST API

Request/response — poll for aircraft data on demand

Endpoints

GET
/api/v2/all

Full aircraft snapshot — all currently tracked aircraft.

GET
/api/v2/hex/{hex}

Single aircraft by ICAO 24-bit hex (e.g., ad5d5c).

GET
/api/v2/reg/{reg}

Aircraft by registration (e.g., N960NK).

GET
/api/v2/type/{type}

Aircraft by ICAO type designator (e.g., B738, A20N).

GET
/api/v2/callsign/{callsign}

Aircraft by callsign (e.g., NKS3205).

GET
/api/v2/lat/{lat}/lon/{lon}/dist/{nm}

Aircraft within radius (nautical miles). Example: /api/v2/lat/26.68/lon/-80.10/dist/50

GET
/api/v2/squawk/{code}

Aircraft by squawk code (e.g., 7700).

GET
/api/v2/signal

Real-time RSSI signal stats (no auth required). Returns avg, median, p10, p90, aircraft count.

GET
/api/v2/signal/history

Last 5 minutes of signal readings (2s intervals, ~150 points). For chart priming.

GET
/api/v2/stats

Lightweight network stats (no auth). Returns aircraft_count and messages.

Response Format

{
  "now": 1774187176.0,
  "messages": 6505606,
  "total": 51,
  "ctime": 1774187176.3,
  "ptime": 1774187175.9,
  "ac": [
    {
      "hex": "ad5d5c",
      "type": "adsb_icao",
      "flight": "NKS3205 ",
      "category": "A3",
      "squawk": "1770",
      "emergency": "none",

      "lat": 26.224091,
      "lon": -80.960739,
      "alt_baro": 33350,
      "alt_geom": 34725,
      "baro_rate": 1472,
      "geom_rate": 1504,

      "gs": 457.4,
      "ias": 277,
      "tas": 458,
      "mach": 0.776,
      "track": 2.26,
      "track_rate": 0.0,
      "roll": -0.7,
      "mag_heading": 5.27,
      "true_heading": 358.36,

      "nav_qnh": 1012.8,
      "nav_altitude_mcp": 35008,

      "oat": -44,
      "tat": -16,

      "rssi": -23.1,
      "messages": 1140,
      "seen": 0.3,
      "seen_pos": 0.98,

      "r": "N960NK",
      "t": "A20N",
      "route_origin": "FLL",
      "route_dest": "MCI"
    }
  ]
}

Envelope

FieldDescription
nowUnix epoch (UTC, 1dp) when readsb wrote this snapshot (feeder Pi clock)
messagesTotal ADS-B messages received since receiver start
totalNumber of aircraft in this response
ctimeUnix epoch (UTC, 1dp) when the API server generated this response
ptimeUnix epoch (UTC, 1dp) when the cache daemon last processed the data

ADS-B Position & Flight Data

FieldTypeDescription
hexstringICAO 24-bit address (lowercase hex)
typestringSource: adsb_icao, mlat, tisb, adsr
flightstringCallsign (8 chars, space-padded)
rstringRegistration (e.g., N960NK)
lat/lonfloatPosition (WGS84 decimal degrees)
alt_baroint | "ground"Barometric altitude (feet) or the string "ground"
alt_geomintGeometric (GPS) altitude (feet)
gsfloatGround speed (knots)
iasintIndicated airspeed (knots)
tasintTrue airspeed (knots)
machfloatMach number
trackfloatTrack angle (degrees, 0=north)
track_ratefloatRate of turn (degrees/second)
calc_trackfloatCalculated track from position history
rollfloatRoll angle (degrees, negative=left)
mag_headingfloatMagnetic heading (degrees)
true_headingfloatTrue heading (degrees)
baro_rateintBarometric vertical rate (ft/min)
geom_rateintGeometric vertical rate (ft/min)
seenfloatSeconds since last message from this aircraft
seen_posfloatSeconds since last position update
rssifloatSignal strength (dBFS, typically -1 to -35)
messagesintTotal messages received from this aircraft

Navigation & Avionics

FieldTypeDescription
squawkstringTransponder squawk code
emergencystringEmergency status (none, general, downed, etc.)
categorystringEmitter category (A1-A7, B1-B7, C1-C3)
nav_qnhfloatAltimeter setting (hPa/mbar)
nav_altitude_mcpintSelected altitude — MCP/FCU (feet)
nav_altitude_fmsintSelected altitude — FMS (feet)
nav_headingfloatSelected heading (degrees)
nav_modesarrayActive nav modes: autopilot, vnav, lnav, tcas, althold, approach
alertintAlert flag (0 or 1)
spiintSpecial Position Identification (0 or 1)
nicintNavigation Integrity Category (0-11)
rcintContainment radius (meters)
nic_barointNIC supplement for baro altitude
nac_pintNavigation Accuracy — Position
nac_vintNavigation Accuracy — Velocity
silintSource Integrity Level
sil_typestringSIL supplement: perhour or persample
gvaintGeometric Vertical Accuracy
sdaintSystem Design Assurance
versionintADS-B version (0, 1, or 2)
dbFlagsintBitmask: 1=military, 2=interesting, 4=PIA, 8=LADD
mlatarrayFields derived from multilateration
tisbarrayFields derived from TIS-B

Meteorological (from aircraft avionics — BDS 4,4 / 4,5)

FieldTypeDescription
oatfloatOutside air temperature (°C)
tatfloatTotal air temperature (°C)
wdintWind direction (degrees)
wsintWind speed (knots)

Route (from TFMS flight plans)

FieldTypeDescription
route_originstringOrigin airport IATA code
route_deststringDestination airport IATA code

Compression

Send Accept-Encoding: gzip for ~80% smaller payloads.

curl -H "Accept-Encoding: gzip" --compressed https://adsbiq.com/api/v2/all

WebSocket Feed

Real-time push-based aircraft data — no polling needed

Connection

Endpointwss://adsbiq.com/ws/
AuthIP-based (same as REST API) or Bearer token via query: wss://adsbiq.com/ws/?token=YOUR_API_KEY
Compressionpermessage-deflate (negotiated automatically)
Ping/PongServer sends ping every 30s, timeout 10s
Max message size512 bytes (client → server)

Channels

The WebSocket supports two channels on the same endpoint. Choose based on your use case:

ChannelIntervalCoverageHow to connect
Global (default) Every 10 seconds All aircraft worldwide wss://adsbiq.com/ws/
Zone Every 1 second Aircraft within 250 nm of your location wss://adsbiq.com/ws/?lat=40.7&lon=-74.0

Breaking change: The default (global) channel now updates every 10s instead of 1s. If you need 1-second updates, switch to zone mode by adding ?lat=X&lon=Y to your connection URL.

Client Messages

Clients can switch channels mid-session by sending JSON messages:

ActionPayloadEffect
set_zone {"action": "set_zone", "lat": 40.7, "lon": -74.0} Switch to zone channel centered on (lat, lon). Triggers immediate full snapshot.
set_global {"action": "set_global"} Switch back to global channel. Triggers full snapshot on next 10s tick.

Message Types

The first message after connect is a full snapshot. Subsequent messages are deltas containing only changes. Every message includes a channel field ("global" or "zone").

Full Snapshot

{
  "type": "full",
  "channel": "zone",
  "seq": 42,
  "now": 1774187176.0,
  "messages": 6505606,
  "total": 51,
  "ctime": 1774187176.3,
  "ptime": 1774187175.9,
  "ac": [ ... ]
}

Delta Update

{
  "type": "delta",
  "channel": "zone",
  "seq": 43,
  "now": 1774187177.0,
  "messages": 6505620,
  "total": 52,
  "ctime": 1774187177.3,
  "ptime": 1774187176.9,
  "new": [
    {"hex": "c99aab", "flight": "SWA789  ", "lat": 42.0, "lon": -72.0, "alt_baro": 30000, ...}
  ],
  "update": [
    {"hex": "ad5d5c", "lat": 26.3, "alt_baro": 34000}
  ],
  "remove": ["a1b2c3"]
}

Delta Fields

FieldDescription
type"full" or "delta"
channel"global" or "zone"
seqMonotonic sequence number (increments by 1 per message, per channel). If your client sees a gap, reconnect to get a fresh full snapshot.
totalCurrent aircraft count (zone = nearby count, global = worldwide). Clients SHOULD verify Object.keys(aircraft).length === msg.total after applying each delta — mismatch means state drift, reconnect.
newFull aircraft objects appearing for the first time (omitted if empty)
updateSparse objects: hex + only the fields that changed (omitted if empty)
removeArray of hex codes no longer tracked (omitted if empty)

Client-Side Merge Pattern

update objects are sparse — they contain only hex plus fields that actually differ from the previous message. Merge them into your local state, do not replace:

// JavaScript — global channel (10s updates, all aircraft)
const ws = new WebSocket("wss://adsbiq.com/ws/");

// JavaScript — zone channel (1s updates, 250nm radius)
// const ws = new WebSocket("wss://adsbiq.com/ws/?lat=40.7&lon=-74.0");

const aircraft = {};
let lastSeq = 0;

ws.onmessage = (e) => {
  const msg = JSON.parse(e.data);

  // Sequence gap detection — reconnect if we missed a frame
  if (msg.type === "delta" && msg.seq !== lastSeq + 1) {
    ws.close(); // reconnect logic will get a fresh full
    return;
  }
  lastSeq = msg.seq;

  if (msg.type === "full") {
    for (const k in aircraft) delete aircraft[k];
    for (const ac of msg.ac) aircraft[ac.hex] = ac;
  } else {
    for (const ac of msg.new    || []) aircraft[ac.hex] = ac;
    for (const ac of msg.update || []) Object.assign(aircraft[ac.hex], ac);
    for (const hex of msg.remove || []) delete aircraft[hex];
  }

  // Consistency check — total must match local state
  if (Object.keys(aircraft).length !== msg.total) {
    ws.close(); // state drift — reconnect for fresh full
  }
};

// Switch to zone mid-session:
// ws.send(JSON.stringify({action: "set_zone", lat: 40.7, lon: -74.0}));

// Switch back to global:
// ws.send(JSON.stringify({action: "set_global"}));

Trigger Fields

Deltas are triggered by changes to: lat, lon, alt_baro, alt_geom, gs, ias, tas, mach, track, track_rate, roll, mag_heading, true_heading, baro_rate, geom_rate, squawk, emergency, flight, nav_qnh, nav_altitude_mcp, nav_altitude_fms, nav_heading, category, r, t, route_origin, route_dest.

Volatile fields (rssi, seen, seen_pos, messages) alone do not trigger an update, but are included in the sparse object if they changed alongside a trigger field.

Example Code

Get started quickly with a working Flask demo that queries every endpoint:

git clone https://github.com/adsbiq/adsbiq-api-demo.git
cd adsbiq-api-demo
pip install -r requirements.txt
python app.py

View on GitHub — includes REST and WebSocket examples.