Public API
The AvioADSB ADS-B API: endpoints, anonymous and contributor limits, API keys, rate-limit headers and code examples. Free for personal and research use, CC BY-NC 4.0.
The AvioADSB API serves live ADS-B aircraft positions from our own community receiver network. It's free for personal projects, education and research. No key is needed to start.
- Base URL:
https://avioadsb.org/v1 - Interactive reference: avioadsb.org/v1/docs (OpenAPI at
/v1/openapi.json) - Playground: avioadsb.org/#playground
Paths and response shapes follow adsb.lol's v2 API and readsb's aircraft.json, so most existing clients work after a base-URL change.
Limits
| Tier | Who | Rate | Quota | Extras |
|---|---|---|---|---|
| Anonymous | Anyone, no key | 1 request / 10 s | 100 / day (UTC) | Point radius ≤ 100 nm |
| Contributor | A key whose account has a receiver that shared data in the last 7 days | 1 request / s (burst 2) | 10,000 / month (UTC) | Radius ≤ 250 nm, /v1/aircraft |
| Commercial | By agreement | Custom | Custom | Contact us |
Anonymous limits are counted per network, not per address: an IPv4 /24 or an IPv6 /64. Contributor limits are counted per account. A key whose stations have stopped feeding keeps working at anonymous limits (the inactive_key tier) until one feeds again.
Getting a key
- Create an account and verify your email.
- Add a receiver on the dashboard and run the feeder script (setup guide).
- Click Create API key. Copy it: it's shown once, and we only store a hash.
The key moves to the contributor tier once your station reports aircraft (within about a minute of it starting to feed).
Send it in a header. Never put it in a URL:
curl -H "X-API-Key: avio_…" https://avioadsb.org/v1/me
# or
curl -H "Authorization: Bearer avio_…" https://avioadsb.org/v1/meAn unknown or revoked key gets 401. It is never silently treated as anonymous.
Endpoints
| Endpoint | Returns |
|---|---|
GET /v1/point/{lat}/{lon}/{radius} | Aircraft within radius nm, nearest first, with dst (nm) and dir (°) |
GET /v1/closest/{lat}/{lon}/{radius} | The single nearest aircraft |
GET /v1/hex/{icao} | By ICAO 24-bit address; up to 20 comma-separated (alias /v1/icao/) |
GET /v1/extended/{icao} | Like /v1/hex, plus the extended fields below (airspeed, heading, wind…) |
GET /v1/callsign/{callsign} | By callsign (case-insensitive) |
GET /v1/reg/{registration} | By registration (hyphens optional) |
GET /v1/type/{type} | By ICAO type designator, e.g. A320 |
GET /v1/squawk/{code} | By Mode A code, e.g. 7700 |
GET /v1/mil | Military aircraft, by ICAO address block |
GET /v1/aircraft?bbox=minLat,minLon,maxLat,maxLon | Every live aircraft, optionally in a box. Contributors only |
GET /v1/stats | Live aircraft and receiver counts |
GET /v1/me | Your tier, limits and remaining quota. Free, doesn't count |
Response
Aircraft endpoints return:
{
"ac": [
{
"hex": "4ca2d5",
"type": "adsb_icao",
"flight": "EIN53X",
"r": "EI-DEO",
"t": "A320",
"desc": "AIRBUS A-320",
"ownOp": "Aer Lingus",
"alt_baro": 38000,
"gs": 453.2,
"track": 91.5,
"baro_rate": 0,
"squawk": "1000",
"lat": 53.4213,
"lon": -6.2701,
"seen": 0.4,
"seen_pos": 0.9,
"mlat": []
}
],
"msg": "No error",
"now": 1790000000000,
"total": 1,
"ctime": 1789999999600,
"ptime": 1
}Fields appear only when known. alt_baro is feet or "ground"; gs knots; track degrees; baro_rate ft/min; seen/seen_pos are seconds since any message and since the last position. type is mlat when the position came from multilateration, and mlat then lists the derived fields. r, t, desc come from the aircraft database and ownOp from the callsign's airline prefix. dbFlags bit 1 marks military. Aircraft not heard from for 60 seconds are dropped.
GET /v1/extended/{icao} also returns extended fields, using readsb's names; the other endpoints leave them out. They are decoded from Beast feeds (ADS-B airspeed, target-state and status messages, and Mode S Comm-B replies to radar interrogations) or sent by SBS feeders that read their decoder's aircraft.json. Wind, temperature and true heading are computed from true airspeed, heading and ground velocity. The fields are tas, ias (knots), mach, mag_heading, true_heading, roll, track_rate, geom_rate, alt_geom, nav_altitude_mcp, nav_altitude_fms, nav_heading, nav_qnh, nav_modes, ws and wd (wind speed in knots and the direction it blows from), oat, tat, category, emergency, the ADS-B version, and the integrity fields nic, nac_p, nac_v, sil, gva, sda. They are present only for some aircraft and only while fresh (30 seconds).
Headers
| Header | Meaning |
|---|---|
X-AvioADSB-Tier | anonymous, contributor or inactive_key |
X-RateLimit-Limit | Your quota for the period (100/day or 10,000/month) |
X-RateLimit-Remaining | Requests left in the period |
X-RateLimit-Reset | Seconds until the quota resets |
X-RateLimit-Policy | The full policy, e.g. 1;w=10, 100;w=86400 |
Retry-After | On 429: seconds to wait |
X-AvioADSB-Notice | Why a valid key is on anonymous limits |
X-AvioADSB-Upgrade | On an anonymous 429: the hardware guide for running a receiver |
Errors
| Status | When |
|---|---|
401 | Invalid or revoked key, or /v1/aircraft without a key |
403 | /v1/aircraft with an inactive key, or a blocked network |
422 | Invalid parameter, or radius above your tier's limit |
429 | Rate limit, daily/monthly quota, or more than 4 concurrent requests from your network |
503 | Live data briefly unavailable |
Errors are JSON: {"detail": "…"}. An anonymous (or inactive-key) 429 also carries a feeder object you can show your
users. It says what running a receiver unlocks:
{
"detail": "Daily limit of 100 anonymous requests reached for your network. …",
"feeder": {
"from": "100 requests/day",
"to": "10,000 requests/month",
"hardware_guide": "https://avioadsb.org/docs/hardware",
"feed_line": "adsb,feed.avioadsb.org,30004,beast_reduce_plus_out,uuid=<your-uuid>",
"claim": "https://avioadsb.org/dashboard#claim"
}
}Examples
import os, time, requests
KEY = os.environ.get("AVIOADSB_KEY") # optional
headers = {"X-API-Key": KEY} if KEY else {}
while True:
r = requests.get("https://avioadsb.org/v1/point/51.47/-0.45/40", headers=headers, timeout=10)
if r.status_code == 429:
time.sleep(int(r.headers.get("Retry-After", "10")))
continue
r.raise_for_status()
for ac in r.json()["ac"]:
print(ac.get("flight", ac["hex"]), ac.get("alt_baro"), ac["dst"], "nm")
time.sleep(10 if not KEY else 5)const res = await fetch("https://avioadsb.org/v1/squawk/7700", {
headers: process.env.AVIOADSB_KEY ? { "X-API-Key": process.env.AVIOADSB_KEY } : {},
});
if (!res.ok) throw new Error(`${res.status} ${(await res.json()).detail}`);
const { ac } = await res.json();Fair use
- Respect
Retry-After. Poll no faster than you need; aircraft positions change about once a second at most. - Don't rotate addresses, pool or publish keys, or scrape the live map instead of using the API. Networks and keys involved get blocked.
- Keys belong in server-side code or environment variables, not in public front-end code.
Attribution
Data is licensed CC BY-NC 4.0. A visible "Data: AvioADSB (CC BY-NC 4.0)" with a link to https://avioadsb.org satisfies attribution.
Not for safety-critical aviation use. This is a best-effort community feed, not a certified aviation data source. The free API service is for personal and research use; see the terms.
What is AvioADSB?
AvioADSB is a free real-time ADS-B API for research and personal projects, powered by a community-built receiver network. No key needed to start; share data for 10,000 requests a month.
Getting Started — Feed ADS-B and Get an API Key
From zero to a feeding AvioADSB station and a contributor API key: add one connector line to readsb or ultrafeeder, claim your station, create your key.