Skip to content
Documentation · Endpoints

Endpoints

Every FlyItalyADSB REST API v2 endpoint: aircraft by hex, callsign or registration (flight numbers too, up to 50 in one request), within a radius or a box, by squawk or type, military, PIA, LADD, tracks, profile, overflights, flight history and today's flights, watched aircraft, the runway in use; list options; differences from ADSBx v2.

Updated

Base URL: https://api.flyitalyadsb.com/v2. Every endpoint is a GET, answers in JSON and needs the X-Api-Key header; the few POSTs, to manage webhooks and watched aircraft, are in Alerts. The full machine-readable spec is openapi.json. Code written for ADS-B Exchange v2 can use its format at https://api.flyitalyadsb.com/api/aircraft/v2 instead.

EndpointReturns
/icao/{hex} (also /hex/{hex})one aircraft by 24-bit ICAO address
/callsign/{callsign}one aircraft by callsign; a flight number is tried too (how)
/reg/{reg}one aircraft by registration, with or without dashes
/find/{text}one aircraft by callsign, registration or ICAO address, when you don’t know which one you have
/icao/{a,b,c} (also /hex, /reg, /callsign)up to 50 aircraft in one request (how)
/lat/{lat}/lon/{lon}/dist/{km}every aircraft within km kilometres of a point
/box/{lat_south}/{lat_north}/{lon_west}/{lon_east}every aircraft in a box (how)
/milthe military traffic seen now
/piaaircraft with a privacy ICAO address (PIA)
/laddaircraft in the FAA LADD programme
/sqk/{squawk} (also /squawk/{squawk})the aircraft squawking that code, e.g. 7700
/type/{type}the aircraft of an ICAO type designator, e.g. A320
/airport/{code}/runwaysthe runway an airport is using now, estimated from the aircraft near it (runway in use)
/history/{icao}the dates with a track for one aircraft
/history/{icao}/{date}one aircraft’s track on one day
/profile/{icao}what we know about one aircraft: identity, live status, history summary
/overflights?lat=&lon=&dist=&from=&to=the aircraft that flew within dist km of a point between two times
/events?lat=…&lon=…&dist=…notable traffic (emergencies, military) within a radius, over the last hours
/flights/callsign/{callsign}the flights of a callsign the network observed in the last days, and its usual routes (flight history)
/flights/icao/{hex}, /flights/reg/{reg}one aircraft’s flight history between two days: departure, arrival, duration; on Fleet also today’s flights
/flights/airport/{code}the departures or arrivals observed at an airport on one day
/flights/route/{from}/{to}the callsigns observed flying from one airport to another, with their usual departure time (find my flight)
/watchthe aircraft your account watches for takeoff and landing alerts, on Fleet; added and removed with POST (your aircraft)

The lists of aircraft take options: only the fields you need, each aircraft’s route, and more.

One aircraft

/icao/{hex}, /callsign/{callsign} and /reg/{reg} return the aircraft’s record if it is seen right now, otherwise 404 with "error": "not found" and a few fields that say why (below). The hex is 6 characters, either case, with or without 0x; callsign and registration ignore case and spaces, the registration dashes and dots too. /hex/{hex} is the same as /icao/{hex}. To follow several aircraft, ask for up to 50 in one request.

curl -H "X-Api-Key: YOUR_KEY" https://api.flyitalyadsb.com/v2/reg/I-ABCD

Callsign and flight number

The callsign is what the aircraft transmits, e.g. BAW185 or RYR55NU. It is often, not always, the flight number on the ticket. /callsign takes both and tries, in order:

  • the callsign as written;
  • without the zeros after the airline prefix: CPA0289 finds CPA289;
  • the ICAO form of the airline’s IATA code: FR5518 finds RYR5518, BA0185 finds BAW185, 5X1219 finds UPS1219.

When the aircraft was found under another form, the answer has two headers, X-Matched-As: callsign and X-Matched-Value: RYR5518, readable from a browser too. /reg compares registrations without dashes, spaces and dots: SP-GPM, S-PGPM and SPGPM find the same aircraft.

Some airlines seldom use the flight number as their callsign. Ryanair, easyJet and Wizz Air mostly fly alphanumeric callsigns (RYR55NU), and nothing in the radio signal links them to the flight number. For them, ask by registration, or look at the route in the flight history.

/find/{text} is for when you don’t know what you have: it tries the text as a callsign (with the forms above), a registration and an ICAO address, and says how each aircraft matched, at most one per kind:

{
  "query": "FR5518",
  "count": 1,
  "results": [
    {"matched_as": "callsign", "value": "RYR5518",
     "aircraft": {"hex": "4d2247", "flight": "RYR5518 ", "r": "9H-QDF"}}
  ]
}

These lookups answer only for aircraft in the air and seen by the network now. Otherwise the 404 says why:

  • tried: the forms tried (in /find, one list per kind);
  • hint: a short explanation, e.g. that a flight number is not always the callsign;
  • found_as: when the text is another identifier of an aircraft in the air, e.g. an ICAO address sent to /callsign, where to ask for it: {"matched_as": "icao", "value": "4d2247", "path": "/v2/icao/4d2247"}. We never answer with another aircraft in place of the one you asked for;
  • last_seen: when there is one, the last flight the network observed for it in the past 7 days, in the flight history format.

Aircraft within a radius

/lat/{lat}/lon/{lon}/dist/{km}:

  • coordinates in decimal degrees;
  • the radius in kilometres, not the nautical miles some other ADS-B APIs use;
  • it works anywhere on Earth, across the 180° meridian too.

The maximum radius depends on the plan (see Limits and errors). Above it, the answer is 403 with max_radius_km. Pro and Fleet have no maximum and can ask for the whole world in one request: /lat/0/lon/0/dist/20040.

The answer is {"now", "count", "total", "ac": [...]}, with the same fields for every aircraft (total is the same number as count).

For a rectangle instead of a circle, use /box. To get a smaller answer, or each aircraft’s route, see the list options.

Military, PIA, LADD

/mil, /pia and /ladd return the network-wide list, in the same format as a radius. They are the aircraft with the matching dbFlags bits (see Fields and units). The data is unfiltered: PIA and LADD aircraft are flagged, not hidden.

By squawk or type

/sqk/{squawk} (or /squawk/{squawk}) returns the aircraft squawking that code: 4 octal digits, e.g. 7700, 7600, 7500. /type/{type} returns the aircraft of an ICAO type designator, either case, e.g. A320, B738, C172. Both cover the whole network, in the same format as a radius. An invalid value answers 400 and is not counted.

curl -H "X-Api-Key: YOUR_KEY" https://api.flyitalyadsb.com/v2/sqk/7700

Tracks and overflights

/history/{icao} lists the dates available for one aircraft, and /history/{icao}/{YYYY-MM-DD} returns that day’s track; with ?since= only the points after a time. Coverage and format are in History.

/overflights answers “what flew over this place between these two times”: one entry per aircraft, with the time and distance of its closest point. Parameters, coverage and limits are in History.

Flight history

The flights the network observed, built every night from its own tracks: departure and arrival airport, the times and the duration. They are what our receivers saw, not airline schedules: an end that wasn’t seen is null.

EndpointReturns
/flights/callsign/{callsign}?days=7the flights of a callsign in the last days (1 to 14, default 7), newest first, and its usual routes in usual, with how many times each was flown
/flights/icao/{hex}?from=&to=one aircraft’s flights between two days, YYYY-MM-DD (default the last 7 days, at most 31): its flight log
/flights/reg/{reg}?from=&to=the same, by registration
/flights/airport/{code}?type=departures&date=the departures (default) or arrivals observed at an airport on one day; ICAO or IATA code, default the latest day available
/flights/route/{from}/{to}?around=HH:MMthe callsigns observed flying from one airport to the other, with their usual departure time and, if they are flying now, where they are (find my flight)

A flight:

{
  "icao": "4d2247", "r": "9H-QDF", "t": "B738", "callsign": "RYR791K",
  "from": {"airport": "EGGD", "iata": "BRS", "name": "Bristol Airport", "country": "GB",
           "time": 1793882940, "seen": "ground"},
  "to":   {"airport": "EPKK", "iata": "KRK", "name": "Kraków John Paul II International Airport",
           "country": "PL", "time": 1793891880, "seen": "low"},
  "first_seen": 1793882940, "last_seen": 1793891880, "duration_min": 149, "day": "2026-11-05"
}
  • from and to: the airport, time (Unix seconds) when the network saw the aircraft there, and seen, how the airport was recognised. With ground and low the time is close to take-off or landing; with approach it can be a few minutes away:
    • ground: on the ground within 6 km;
    • low: at most 2,500 ft above the airport within 15 km;
    • approach: at most 6,000 ft within 30 km, heading towards or away from it.
  • duration_min: the minutes from the first to the last point observed.
  • day: the UTC day the flight started. Flights across midnight UTC are joined.

The callsign route takes the same forms as /callsign, so a flight number works too. The aircraft routes also return a summary (flights, minutes, airports), handy for flight hours. Every answer has coverage, the days searched. A callsign or an aircraft with no flights in the period answers 200 with count 0, and so does an airport with no flights observed that day; an IATA code we don’t know answers 404.

The days are built after midnight UTC, around 02:45: yesterday and the days before are there, today not yet. On every plan, one request each; how far back you can ask depends on the plan (below). Where receivers are few, over oceans for example, one end of a flight can be missing.

How far back, by plan

How many days back from today (UTC) you can ask:

PlanFlight history
Free7 days
Starter14 days
Pro30 days
Fleet90 days

A Free key with the feeder perk gets Pro’s 30 days.

The limit applies to the oldest day you ask for: from for an aircraft, date for an airport, days for a callsign or a route. The limits of each request stay the same on every plan: up to 14 days for a callsign or a route, up to 31 days per request for an aircraft (for a longer period, ask for it in parts).

If you don’t give days, from or date, the default window never goes past the plan’s depth: right after midnight UTC, before the night’s day is built, it is simply one day shorter. Asking explicitly beyond the plan’s depth answers 403, and it is not counted:

{
  "error": "flight history older than 7 days is not in this plan",
  "code": "flights-depth", "max_days": 7, "requested_days": 14,
  "docs": "https://flyitalyadsb.com/data/api/docs/endpoints/#observed-flights",
  "plans": "https://flyitalyadsb.com/data/api/?…#piani"
}

max_days is the plan’s depth, requested_days how far back you asked, plans the link to the plans.

The flight history starts on 23 October 2026 and grows by one day every night, so the longer depths fill up as the days go by. coverage.missing lists the days of your period that are not there.

Today’s flights (Fleet)

The nightly flights stop at yesterday. On Fleet, /flights/icao/{hex}, /flights/reg/{reg} and /flights/callsign/{callsign} also carry today: the flights of the day so far, built from the takeoffs and landings our receivers detect in real time, the same ones the takeoff and landing alerts send. You don’t need to watch the aircraft to see them here.

"today": {
  "available": true, "since": "2026-11-07", "source": "live", "count": 2,
  "flights": [
    {"icao": "4d2247", "callsign": "RYR5518",
     "from": {"airport": "EGSS", "time": "2026-11-07T08:58:20Z", "seen": "ground", "runway": "22", "place": "airport", "near": false},
     "to":   {"airport": "EIDW", "time": "2026-11-07T09:57:45Z", "seen": "low", "runway": "28L", "place": "airport", "near": false},
     "status": "landed", "duration_min": 59},
    {"icao": "4d2247", "callsign": "RYR5519",
     "from": {"airport": "EIDW", "time": "2026-11-07T10:41:05Z", "seen": "ground", "runway": "28L", "place": "airport", "near": false},
     "to": null, "status": "in_flight",
     "position": {"lat": 53.2, "lon": -4.95, "alt_ft": 24000, "gs_kt": 410.0, "track": 112.0},
     "eta": {"airport": "EGSS", "airport_iata": "STN", "time": "2026-11-07T11:19:30Z", "minutes": 30,
             "distance_km": 380, "estimate": true,
             "basis": "the usual destination of this callsign in the flight history, and distance / ground speed now"}}
  ],
  "note": "today's flights come from takeoffs and landings detected in real time from our receivers; …"
}
  • since: the first UTC day that is not in the nightly flights yet: today, or yesterday right after midnight UTC, until the night’s day is built.
  • from and to: the airport (ICAO code where there is one), time (ISO 8601, UTC: not Unix seconds as in the nightly flights), seen (ground, low or approach, as above), runway when known, place (airport or heliport) and near, true when the aircraft was more than 2 km from it: say “near” that airport. from is null for a landing with no takeoff seen since since.
  • status: landed, with duration_min (takeoff to landing); in_flight, with position (lat, lon, alt_ft, gs_kt, track) when the aircraft is flying now; unknown when a takeoff was seen but no landing, and the aircraft isn’t flying now (or it took off again without a landing seen).
  • eta, only for an aircraft in flight and only an estimate: if the callsign’s usual route in the flight history leaves from today’s takeoff airport, its destination, and the time it would take in a straight line at the ground speed it has now. No eta without a usual route or under 80 knots. While the aircraft is still climbing the speed is low and the estimate comes out late; it knows nothing of the route, the wind or the approach. It is never a schedule.
  • Flights are oldest first. Repeated takeoffs and landings, such as circuits, are each a flight here.

It is real-time detection, so it has the limits of what our receivers see: a takeoff or landing the network does not see is missing (the flight stays unknown, or has from null). A landing deduced from the aircraft disappearing near a field appears about 2.5 minutes after its last signal, and goes away again if the aircraft is seen flying within 10 minutes. The next night the day is rebuilt from the full tracks in the flight history.

On the other plans, today is {"available": false, "error": "…", "plans": "…"} and the rest of the answer is the same. These answers can change every minute: they are cached for at most 15 seconds, privately (Cache-Control: private, max-age=15). ?format=csv has only the nightly flights. Still one request.

Find my flight, by route

/flights/route/{from}/{to} is for when you know the route and roughly the time, but not the callsign. Ryanair, easyJet and Wizz Air, for example, mostly fly callsigns that are not the flight number. It lists the callsigns the network observed flying from one airport to the other, the most frequent first:

curl -H "X-Api-Key: YOUR_KEY" "https://api.flyitalyadsb.com/v2/flights/route/STN/DUB?around=09:30"
  • from and to: ICAO or IATA codes.
  • around=HH:MM, in UTC: only the callsigns that usually leave within window minutes of that time (default 90, from 15 to 720).
  • days: how many days back to look, from 1 to 14, default 7.

A candidate:

{
  "callsign": "RYR5518", "flights": 3,
  "usual_departure_utc": "09:00", "usual_duration_min": 60, "last_day": "2026-11-05",
  "aircraft": [{"r": "9H-QDF", "t": "B738"}],
  "live": {"hex": "4d2247", "flight": "RYR5518 ", "lat": 52.0, "lon": -3.0, "alt_baro": 31000}
}
  • flights: how many times it was observed on this route in the period.
  • usual_departure_utc and usual_duration_min: the median departure time (UTC) and duration of those flights.
  • last_day: the last day it was observed on this route.
  • aircraft: up to three aircraft that flew it most, with registration (r, the ICAO address when the registration is unknown) and type (t).
  • live: only when an aircraft with that callsign is flying now, its live record, the same as /callsign returns.

The answer also has from and to (code, IATA, name, country), days, coverage, count and up to 50 candidates. A route with no flights in the period answers 200 with count 0; an IATA code we don’t know answers 404. These are the callsigns our receivers saw on the route, not airline schedules: a callsign is what the aircraft transmits.

Flight log as CSV

Add ?format=csv to /flights/icao/{hex} or /flights/reg/{reg} to get the same flights as a CSV file (text/csv), one row per flight, oldest first, for a spreadsheet or a logbook:

day,callsign,icao,r,t,from,from_iata,from_time_utc,from_seen,to,to_iata,to_time_utc,to_seen,duration_min
2026-11-03,RYR5518,4d2247,9H-QDF,B738,EGSS,STN,2026-11-03 09:00:00,ground,EIDW,DUB,2026-11-03 10:00:00,low,60

Times are UTC. An end that wasn’t observed leaves its columns empty. The period, the limits and the depth are the same as for the JSON; one request.

Runway in use

/airport/{code}/runways estimates the runway an airport is using right now, from the aircraft our receivers see near it. The code is ICAO or IATA:

The runway in use starts from Starter; on Free the answer is 403 with code plan-feature.

curl -H "X-Api-Key: YOUR_KEY" https://api.flyitalyadsb.com/v2/airport/MXP/runways
{
  "airport": {"code": "LIMC", "iata": "MXP", "name": "Milan Malpensa International Airport", "country": "IT"},
  "now": 1794038400.5,
  "in_use": ["35R"],
  "runways": [{"runway": "35R", "heading": 350, "arrivals": 3, "departures": 1,
               "aircraft": [{"hex": "4d2247", "flight": "RYR5518", "kind": "arrival"}]}],
  "aircraft_nearby": 14,
  "known_runways": ["17L", "17R", "35L", "35R"],
  "note": "estimate from the aircraft our receivers see now near the airport; a quiet airport can show no runway"
}
  • in_use: the runways with traffic now, the busiest first. Empty when no aircraft fits.
  • runways: for each one, heading (the direction of travel on it, degrees true), the arrivals and departures counted now, and the aircraft behind them (kind: arrival or departure).
  • aircraft_nearby: the aircraft with a position within 25 km of the airport.
  • known_runways: the airport’s open runways.

An aircraft counts for a runway when it is within 25 km of the airport, less than 5,000 ft above it, lined up with the runway (within 20°) and at most 1 km from its extended centreline. Then:

  • arrival: not climbing, up to 18 km before the threshold;
  • departure: climbing, over the runway or up to 12 km after its end;
  • on the ground: rolling on the runway at 40 knots or more.

With parallel runways, the nearest centreline wins.

It is an estimate of what is happening now, not an official source. A quiet airport, or one with few receivers around it, can show no runway: then in_use is empty. For flight planning, use the ATIS and the official sources.

The runways come from OurAirports (public domain), refreshed every night. An airport we don’t know answers 404 (unknown airport code), and so does an airport without runway data (no runway data for this airport). 503 with runway data is not available yet means the runway list is not loaded yet: try again later. One request, on every plan; the answer can be cached for 15 seconds.

List options

Options for the answers that are lists of aircraft, in our /v2 format (the ADS-B Exchange v2 format does not change). They are checked first: an invalid option answers 400, with error and a docs link here, and is not counted.

Only the fields you need: fields

?fields=a,b,c keeps only those fields of each aircraft. It works on /lat/…/lon/…/dist/…, /box, /mil, /pia, /ladd, /sqk, /squawk, /type and the lookups of several aircraft.

curl -H "X-Api-Key: YOUR_KEY" "https://api.flyitalyadsb.com/v2/lat/45.46/lon/9.19/dist/250?fields=light"
  • hex is always there, first.
  • A field the aircraft doesn’t have is missing, as in the full record.
  • fields=light is a fixed set for maps and displays: hex, flight, r, t, lat, lon, alt_baro, gs, track, squawk, seen_pos, category. It never changes, so the same URL always gives the same shape.
  • Presets and names can be mixed: fields=light,rssi.
  • An unknown name answers 400 with allowed, every field you can ask for, and presets.
  • The answer keeps its shape: {"now", "count", "total", "ac"}.

Each aircraft’s route: with=route

?with=route, on the same lists, adds to each aircraft the route its callsign flew most often in the latest 7 days of flight history:

"route": {"from": "EGSS", "from_iata": "STN", "to": "EIDW", "to_iata": "DUB",
          "count": 12, "last_day": "2026-11-05", "source": "observed"}
  • from and to are the airports’ ICAO codes, count how many times the callsign flew the route in those days, last_day the last time.
  • It is the same route as the first one in usual of /flights/callsign/{callsign}.
  • source: "observed": it comes from what our receivers saw, not from airline schedules. A callsign that flies different routes can be on another one today.
  • When no route is known, there is no route field.
  • with takes only route: any other value answers 400. It can be combined with fields.

Aircraft in a box: /box

/box/{lat_south}/{lat_north}/{lon_west}/{lon_east} returns every aircraft in a latitude/longitude rectangle, in the same format as a radius:

curl -H "X-Api-Key: YOUR_KEY" https://api.flyitalyadsb.com/v2/box/44/46/8/10
  • The edges are included. lat_south must be lower than lat_north, both between -90 and 90; the longitudes are between -180 and 180.
  • A lon_west greater than lon_east crosses the 180° meridian: /box/50/60/170/-170 goes from 170° E to 170° W.
  • The plan’s maximum radius applies to the half-diagonal, the distance from the centre of the box to its farthest point (about 137 km for /box/44/46/8/10). So a box never costs more than a circle the plan allows. Above it, the answer is the same 403 as for a radius, with max_radius_km.
  • One request, like a radius.

Several aircraft in one request

/icao/, /hex/, /reg/ and /callsign/ take up to 50 values separated by commas, and count as one request:

curl -H "X-Api-Key: YOUR_KEY" https://api.flyitalyadsb.com/v2/callsign/FR5518,CPA0289,EZY12AB
{
  "now": 1794038400.5, "count": 2, "total": 2, "ac": [{"hex": "4d2247", "flight": "RYR5518 "}, {"hex": "780a3c", "flight": "CPA289  "}],
  "not_found": ["EZY12AB"],
  "matched": {"FR5518": "RYR5518", "CPA0289": "CPA289"}
}
  • Each value takes the same forms as a single lookup: flight numbers and zeros for callsigns, dashes for registrations, case and 0x for ICAO addresses.
  • ac: the aircraft in the air now. One found by two values appears once.
  • not_found: the values with no aircraft in the air now, as you wrote them.
  • matched: the value you wrote and the form that was found, only when they differ (the X-Matched-Value header of a single lookup).
  • One comma is enough, at the end too: /icao/4d2247,.
  • More than 50 values, or none, answers 400 and is not counted.
  • Without a comma, the route answers as always: the aircraft, or the 404 that says why.

Only the new points of a track: since

/history/{icao}/{date}?since={unix seconds} returns the track with only the points after that time (the track’s timestamp plus the point’s offset greater than since), for today and for past days. To follow an aircraft during the day, ask with the time of the last point you have instead of reading the whole day again.

  • The rest of the file is unchanged, and the answer has the header X-Since-Applied: 1. Without that header the file came whole.
  • since is in seconds, e.g. since=1794038400. Milliseconds, a negative value or something that is not a number answers 400 and is not counted.
  • An empty since= is the same as no since.

Aircraft profile

/profile/{icao} puts together, in one request, what the other endpoints say about one aircraft:

  • identity: registration, ICAO type (icao_type), type_description, year when the aircraft database has it, and the dbFlags bits already decoded (military, interesting, pia, ladd);
  • live: seen_now, and if it is being received now its callsign, position, altitude, speed and source, the source of the position (adsb_icao, mlat, tisb_icao…), with seen_pos in seconds;
  • history: first_day and last_day with a track, days_last_30 (today and the 29 days before, UTC) and total_days, from the same dates as /history/{icao};
  • links: map, the public map on this aircraft (live, or its last track the map can show), and history;
  • photos: page, a link to the aircraft’s photos on Planespotters.net.

It answers 404 if the aircraft is not received now and has no history.

curl -H "X-Api-Key: YOUR_KEY" https://api.flyitalyadsb.com/v2/profile/3c66a3

The profile is about the aircraft: it never returns the names of owners or operators. It has no photo, because Planespotters.net’s terms do not allow their photos to be served through another API: photos.page is a link to their public page, where every photo credits its photographer, and the aircraft panel of the map shows one the same way. For PIA and LADD aircraft photos.page is null and withheld says why. Their data is still in the profile, flagged, as everywhere in the API.

Emergencies, notable aircraft and alerts

/events lists the emergencies, military and other notable aircraft the network recorded in an area, and paid plans can receive them as signed webhooks (POST /v2/webhooks). Both are in Alerts and notable traffic.

Coming from ADSBx v2 or airplanes.live

To keep code written for ADS-B Exchange v2 unchanged, use the ADS-B Exchange v2 format at https://api.flyitalyadsb.com/api/aircraft/v2: same paths, key headers and JSON, only the host and the key change. The list below is about our own /v2.

The aircraft records have the same fields (readsb’s), and the route names are the same for /callsign, /icao, /reg, /lat/…/lon/…/dist/…, /mil, /pia, /ladd, /sqk, /squawk and /type. What changes:

  • Key: here always the X-Api-Key header; ADSBx uses its provider’s header.
  • Radius in /lat/…/lon/…/dist/…: here kilometres, there nautical miles.
  • /icao, /callsign, /reg: here the aircraft object (404 if not seen), there a list {"ac": [...]}.
  • now: here Unix seconds, there milliseconds.
  • List size: here count and total, there total.
  • /hex: here an alias of /icao.
  • Not available in /v2: /registration, /point, /closest. Use /reg and /lat/…/lon/…/dist/…, or the ADS-B Exchange v2 format, which has /registration, /point and /closest.

Errors

Errors are JSON with a plain-English error field. Codes and fixes are in Limits and errors.