Flight Tracking API
Real-time flight tracking in a single request: live status, schedule, route and aircraft for any flight worldwide, in a clean, well-structured JSON format.
A clean JSON API for flights, airports and live airspace. /airline returns full schedule, route, aircraft and status; /track the live position of an airborne flight; /schedules the projected timetable for a flight over the coming days; /airport airport lookup, search and nearest-to-a-coordinate; /airspace every aircraft in the air in an area; /route the route a flight flies. Every request takes an API key; each call costs one credit.
Base URL & authentication
https://api.flightnerve.com
Your API key is required on every request, passed as the first path segment:
/airline/<api_key>?num=...&name=...&date=... /track/<api_key>?num=...&name=...&date=...
401; an exhausted quota returns 429. Create a free key →Response format
Every tracking response is a JSON array of four objects (departure, arrival, aircraft and status) in that order. Times are given both as a human string local to the airport and as an ISO-8601 timestamp with the airport's UTC offset. Fields that are not published are returned as null, never omitted, so the shape is always stable.
Multi-leg without depap: the response is instead an array of legs ([ [departure, arrival, aircraft, status], [ … ] ]), one entry per leg. Detect it by checking whether the first element is an array.
Flight status
Full schedule, route, aircraft and status for a single flight on a given date.
Query parameters
| Param | Required | Description |
|---|---|---|
| num | required | Flight number, digits only (e.g. 72 for EK72). |
| name | required | Airline code, IATA (EK) or ICAO (UAE). |
| date | optional | Target date, YYYYMMDD. Defaults to the active/next instance. |
| depap | optional | Departure airport IATA. Disambiguates when a flight number departs from different origins, including a multi-leg flight: selects the leg departing this airport. |
EK205 flies DXB → MXP → JFK. Identify a leg by its departure airport: depap=DXB returns DXB → MXP, depap=MXP returns MXP → JFK. Called without depap, a multi-leg flight returns all legs (an array of leg objects, see below) and is billed one credit per leg.Example request
curl "https://api.flightnerve.com/airline/YOUR_KEY?num=72&name=EK&date=20260720"
const res = await fetch("https://api.flightnerve.com/airline/YOUR_KEY?num=72&name=EK&date=20260720");
const data = await res.json();
console.log(data);import requests
r = requests.get("https://api.flightnerve.com/airline/YOUR_KEY?num=72&name=EK&date=20260720")
print(r.json())<?php
$res = file_get_contents("https://api.flightnerve.com/airline/YOUR_KEY?num=72&name=EK&date=20260720");
$data = json_decode($res, true);
print_r($data);Example response
[
{ "departure": {
"offGroundTime": null, "outGateTime": null, "gate": null,
"departureDateTime": "2026-07-20T11:30:00+02:00",
"duration": "7 hr",
"airport": "Charles de Gaulle", "airportCity": "Paris",
"airportCode": "CDG", "airportCountryCode": "FR",
"airportSlug": "CDG-Paris-France",
"scheduledTime": "11:20, Jul 20", "estimatedTime": "11:30, Jul 20",
"terminal": "2C"
}},
{ "arrival": {
"timeRemaining": null, "onGroundTime": null, "inGateTime": null,
"gate": null, "baggage": null,
"arrivalDateTime": "2026-07-20T20:20:00+04:00",
"airport": "Dubai Int'l", "airportCity": "Dubai",
"airportCode": "DXB", "airportCountryCode": "AE",
"airportSlug": "DXB-Dubai-United-Arab-Emirates",
"scheduledTime": "20:20, Jul 20", "estimatedTime": "20:20, Jul 20",
"terminal": "3"
}},
{ "aircraft": { "id": null, "code": "388", "name": "Airbus A380-800", "regNumber": "A6-EOA" } },
{ "status": "In Air" }
]
Response object
Elements 1 and 2 are the departure and arrival legs; the aircraft and status objects follow.
departure / arrival
| Field | Type | Description |
|---|---|---|
| scheduledTime | string | Scheduled time, local to the airport, as "HH:MM, Mon DD". |
| estimatedTime | string | Estimated time, local. |
| departureDateTime arrivalDateTime | string | ISO-8601 with the airport's UTC offset. |
| outGateTime / inGateTime | string·null | Actual gate out / in, when available. |
| offGroundTime onGroundTime | string·null | Actual wheels-up / wheels-down. |
| timeRemaining | string·null | Time to arrival while en route. |
| duration | string·null | Scheduled block time (departure only). |
| airport / airportCity | string | Airport name and city. |
| airportCode | string | IATA code. |
| airportCountryCode | string | ISO-2 country code. |
| airportSlug | string | URL-friendly CODE-City-Country. |
| terminal / gate | string·null | Terminal / gate, when published. |
| baggage | string·null | Arrival baggage belt (arrival only). |
aircraft
| Field | Type | Description |
|---|---|---|
| code | string·null | Type code (e.g. 388, 77W). |
| name | string·null | Full type name (e.g. Airbus A380-800). |
| regNumber | string·null | Aircraft registration (tail number, e.g. A6-EOA) of the aircraft operating the flight, identified live while it is airborne. null when the flight is not currently in the air. |
| id | null | Present for compatibility; not populated. |
Status values
The status field reflects the live state of the flight:
| Value | Meaning |
|---|---|
| Scheduled | Future flight on schedule, or an upcoming date served from the projected schedule. |
| In Air | Departed and currently airborne. |
| Arrived | Landed. |
| Delayed | Estimated departure is 15+ minutes behind schedule (before departure). |
| Cancelled | Flight cancelled. |
| Diverted | Diverted from its planned destination. |
Rescheduled) are passed through as reported. An upcoming date served from the projected schedule always returns Scheduled, since there is no live data yet.Dates & data
The same endpoint answers for past, present and future dates, and the data behind it adapts:
| When | What you get |
|---|---|
| Today / near-term | Live status and times: actual gate-out/off, estimates, gate and terminal. |
| Past | The final record: actual departure/arrival times and terminal status (Arrived, Cancelled, Diverted…). Completed flights are cached, so repeat lookups are instant. |
| Upcoming | The scheduled times. For dates beyond the published window, the recurring schedule is projected from recent history (weekday-aware) and returned as Scheduled. If a flight does not operate on the requested day, a 400 is returned. |
Live position
Where the aircraft is right now: latitude, longitude, altitude, ground speed and heading, plus phase and progress. An airborne flight always returns a position, and the source field tells you its quality: a real fix where there is coverage, or an estimated position (projected along the route by progress) in a coverage gap. If the flight is not airborne (a completed past flight, one that hasn't departed yet, or a future date), the array is empty ([]). You are billed one credit per position returned, so a flight that isn't in the air costs nothing.
Query parameters
| Param | Required | Description |
|---|---|---|
| num | required | Flight number, digits only (e.g. 25 for SQ25). |
| name | required | Airline code, IATA (SQ) or ICAO (SIA). |
| date | optional | Target date, YYYYMMDD. Only today can be airborne; a clearly past or future date returns [] immediately. |
Example request
curl "https://api.flightnerve.com/track/YOUR_KEY?num=25&name=SQ"
const res = await fetch("https://api.flightnerve.com/track/YOUR_KEY?num=25&name=SQ");
const data = await res.json();
console.log(data);import requests
r = requests.get("https://api.flightnerve.com/track/YOUR_KEY?num=25&name=SQ")
print(r.json())<?php
$res = file_get_contents("https://api.flightnerve.com/track/YOUR_KEY?num=25&name=SQ");
$data = json_decode($res, true);
print_r($data);Example response: airborne
[
{
"flight": "SQ25", "callsign": "SIA25", "status": "In Air",
"regNumber": "9V-SMR", // aircraft tail number, when identified live
"latitude": 59.8835, "longitude": 36.571,
"altitude": 33000, // feet
"groundSpeed": 560, // knots
"heading": 120, // degrees true
"verticalSpeed": null, "onGround": false,
"phase": "cruise", // climb | cruise | descent
"progress": 0.62, // fraction of the route flown, 0..1
"source": "live", // live (real fix) | partner | estimated (dead-reckoned)
"departure": { "airportCode": "FRA", "airport": "Frankfurt Int'l" },
"arrival": { "airportCode": "SIN", "airport": "Singapore Changi" },
"lastUpdated": "15:16, Jul 21", // when the position was last updated (UTC)
"updatedAgo": "2 min ago", // how long ago that was
"updatedAt": "2026-07-21T15:16:47Z", // same fix, ISO-8601 UTC
"updatedUnix": 1784646407 // same fix, epoch seconds
}
]
Example response: not airborne
[] // completed, not yet departed, or a future date
Fields
| Field | Type | Description |
|---|---|---|
| regNumber | string·null | Aircraft registration (tail number) of the aircraft flying, identified live. null if not yet identified. |
| latitude / longitude | number | Current position, decimal degrees. |
| altitude | number·null | Altitude in feet. |
| groundSpeed | number·null | Ground speed in knots. |
| heading | number·null | Track over ground, degrees true. |
| verticalSpeed | number·null | Climb/descent rate, ft/min, when available. |
| onGround | boolean | Always false here, an airborne position. |
| phase | string | Flight phase: climb, cruise or descent. |
| progress | number | Fraction of the route flown, 0 to 1. |
| source | string | live (a real position fix), partner (a derived fix filling a coverage gap), or estimated (dead-reckoned along the route when no fix is available). The updated* fields are null for an estimated position. |
| departure / arrival | object | Origin and destination: airportCode (IATA) and airport name. |
| lastUpdated | string | When the position was last updated, as human UTC "HH:MM, Mon DD". |
| updatedAgo | string | How long ago that fix was, in words (e.g. "3 min ago", "1 hr 5 min ago"). |
| updatedAt | string | The same fix time as an ISO-8601 UTC timestamp. |
| updatedUnix | number | The same fix time as epoch seconds; subtract from now for position age. |
/airline.Flight schedules
The projected timetable for a flight number over the coming days, built from FlightNerve's own accumulated operating history for that flight, not a single live lookup. Give it a flight and a start date and it returns one entry per day: the route, scheduled departure and arrival (local and UTC), block time and typical aircraft, and whether the flight is expected to operate that weekday. Useful for planning ahead when a live schedule for a future date is not yet published.
Query parameters
| Param | Required | Description |
|---|---|---|
| num | required | Flight number, digits only (e.g. 72 for EK72). |
| name | required | Airline code, IATA (EK) or ICAO (UAE). |
| date | optional | Start date, YYYYMMDD. Defaults to today. |
| days | optional | Number of days to project from the start date, 1 to 7. Defaults to 1. |
Example request
curl "https://api.flightnerve.com/schedules/YOUR_KEY?num=72&name=EK&date=20260725&days=3"
const res = await fetch("https://api.flightnerve.com/schedules/YOUR_KEY?num=72&name=EK&date=20260725&days=3");
const data = await res.json();
console.log(data);import requests
r = requests.get("https://api.flightnerve.com/schedules/YOUR_KEY?num=72&name=EK&date=20260725&days=3")
print(r.json())<?php
$res = file_get_contents("https://api.flightnerve.com/schedules/YOUR_KEY?num=72&name=EK&date=20260725&days=3");
$data = json_decode($res, true);
print_r($data);Example response
{
"flight": "EK72", "callsign": "UAE72",
"basis": "historical-pattern",
"sampleSize": 17, // operating days observed
"confidence": "high", // high · medium · low
"days": 3,
"schedules": [
{
"date": "2026-07-25", "weekday": "Sat", "operates": true,
"legs": [
{
"from": "CDG", "to": "DXB",
"fromCity": "Paris", "toCity": "Dubai",
"departure": { "scheduledLocal": "11:20", "scheduledUTC": "2026-07-25T09:20:00Z" },
"arrival": { "scheduledLocal": "20:55", "scheduledUTC": "2026-07-25T16:55:00Z" },
"blockMinutes": 455,
"aircraft": "A388"
}
]
},
{ "date": "2026-07-26", "weekday": "Sun", "operates": true, "legs": [ ... ] },
{ "date": "2026-07-27", "weekday": "Mon", "operates": false } // no service that weekday
]
}
Fields
| Field | Type | Description |
|---|---|---|
| basis | string | Always "historical-pattern": projected from observed operating history, not a live schedule pull. |
| sampleSize | number | How many operating days informed the projection. More samples means a firmer pattern. |
| confidence | string | high (strong, consistent history), medium, or low (sparse or irregular). Treat low as indicative. |
| operates | boolean | Whether the flight is expected to fly that date. false means that weekday has no consistent history. |
| legs | array | One object per leg, present only when operates is true. Multi-leg flight numbers return each leg in order. |
| blockMinutes | number | Scheduled gate-to-gate time in minutes. |
/airline. Billed one credit per operating day returned; days with no service are free.Airports
Look up an airport, search by name/city, or find airports near a coordinate, from a reference of 85,000+ airports worldwide with coordinates and timezone.
Query parameters (one of)
| Param | Description |
|---|---|
| code | IATA or ICAO code; returns one airport (e.g. code=DXB or code=OMDB). |
| search | Text match on name / city / code; returns a list (e.g. search=heathrow). |
| lat & lon | Airports within radius km of a point, nearest first. radius optional (default 100, max 500). |
Example
curl "https://api.flightnerve.com/airport/YOUR_KEY?code=DXB"
const res = await fetch("https://api.flightnerve.com/airport/YOUR_KEY?code=DXB");
const data = await res.json();
console.log(data);import requests
r = requests.get("https://api.flightnerve.com/airport/YOUR_KEY?code=DXB")
print(r.json())<?php
$res = file_get_contents("https://api.flightnerve.com/airport/YOUR_KEY?code=DXB");
$data = json_decode($res, true);
print_r($data);{
"iata": "DXB", "icao": "OMDB", "name": "Dubai International Airport",
"city": "Dubai", "country": "AE", "countryName": "United Arab Emirates",
"latitude": 25.2528, "longitude": 55.3644, "timezone": "Asia/Dubai"
}
# nearest airports to a coordinate curl "https://api.flightnerve.com/airport/YOUR_KEY?lat=51.47&lon=-0.45&radius=40" → [ { "iata":"LHR", …, "distanceKm": 1.2 }, { "iata":"LCY", …, "distanceKm": 22.8 }, … ]
Live airspace
Every aircraft in the air right now in an area: near a point, inside a bounding box, around an airport, or inbound to an airport with a live ETA. Positions refresh continuously.
Query parameters (one of)
| Param | Description |
|---|---|
| lat & lon | Aircraft within radius km of a point (default 100, max 500), nearest first. |
| bbox | Aircraft inside latMin,lonMin,latMax,lonMax. |
| airport | Aircraft within radius km of an airport (IATA/ICAO). |
| inbound | Airborne aircraft routed to this airport, with distance and estimated minutes out. |
Example
curl "https://api.flightnerve.com/airspace/YOUR_KEY?inbound=JFK"
const res = await fetch("https://api.flightnerve.com/airspace/YOUR_KEY?inbound=JFK");
const data = await res.json();
console.log(data);import requests
r = requests.get("https://api.flightnerve.com/airspace/YOUR_KEY?inbound=JFK")
print(r.json())<?php
$res = file_get_contents("https://api.flightnerve.com/airspace/YOUR_KEY?inbound=JFK");
$data = json_decode($res, true);
print_r($data);{ "airport": { "iata": "JFK", "icao": "KJFK", "name": "John F. Kennedy International Airport" },
"aircraft": [
{ "callsign": "AAL1185", "latitude": 40.7, "longitude": -73.9,
"altitude": 4000, "groundSpeed": 210, "heading": 31, "onGround": false,
"originCountry": "United States", "distanceKm": 9.6, "etaMinutes": 2 }, … ] }
updatedUnix (epoch of its last position fix).Routes
Answers four route questions from FlightNerve's own accumulated operating history — which flights fly a route, an airline's whole network, an airport's destinations, or one flight's route — each enriched with the aircraft types actually seen and any codeshare flight numbers. No external call; one credit per query.
Query parameters (one of)
| Param | Returns |
|---|---|
| from & to | Route detail: every flight observed operating A→B — airline, flight number, aircraft, codeshares, days observed — plus the route distance. |
| airline | Airline network: every route the airline operates (IATA or ICAO code), with flight numbers and aircraft per route. |
| from | Destinations served from an airport, each with the airlines and flight numbers on it. |
| to | Origins that reach an airport, likewise. |
| num & name | A single flight → its origin, destination, stops, aircraft and codeshares. |
Example — route detail
curl "https://api.flightnerve.com/route/YOUR_KEY?from=DXB&to=LHR"
const res = await fetch("https://api.flightnerve.com/route/YOUR_KEY?from=DXB&to=LHR");
const data = await res.json();
console.log(data);import requests
r = requests.get("https://api.flightnerve.com/route/YOUR_KEY?from=DXB&to=LHR")
print(r.json())<?php
$res = file_get_contents("https://api.flightnerve.com/route/YOUR_KEY?from=DXB&to=LHR");
$data = json_decode($res, true);
print_r($data);{ "from": { "iata":"DXB", "city":"Dubai", … },
"to": { "iata":"LHR", "city":"London", … },
"distanceKm": 5498,
"airlines": ["EK"], "operatorCount": 1, "flightCount": 3,
"flights": [
{ "flight":"EK1", "airline":"EK", "airlineName":"Emirates",
"aircraft":["A388","B38M"], "codeshares":["GA8887"],
"daysObserved":14, "lastSeen":"2026-07-25" }, … ] }
Example — airline network
curl "https://api.flightnerve.com/route/YOUR_KEY?airline=EK" → { "airline":"EK", "airlineName":"Emirates", "routeCount":109, "routes":[ { "from":{"iata":"DXB",…}, "to":{"iata":"JFK",…}, "flights":["EK201"], "aircraft":["A388"], "daysObserved":15 }, … ] }
/schedules (future timetable) or /airline (live).Tracked flights
Keep a personal watchlist of flights. Each is monitored continuously and returns three arrival anchors: the scheduled time, our own FlightNerve Estimated Arrival, and the live observed arrival, plus cancelled / diverted / arrived flags.
List tracked flights
curl "https://api.flightnerve.com/watch/YOUR_KEY"
const res = await fetch("https://api.flightnerve.com/watch/YOUR_KEY");
const data = await res.json();
console.log(data);import requests
r = requests.get("https://api.flightnerve.com/watch/YOUR_KEY")
print(r.json())<?php
$res = file_get_contents("https://api.flightnerve.com/watch/YOUR_KEY");
$data = json_decode($res, true);
print_r($data);{ "success": true, "tracked": [
{ "flight": "EK072", "day": "20260722", "leg": null,
"route": { "from": "OMDB", "to": "VTBS" },
"status": "active", "flags": [],
"arrivals": {
"scheduled_utc": "2026-07-22T20:43:00Z",
"fn_estimated_utc": "2026-07-22T20:41:12Z",
"live_utc": "2026-07-22T20:42:00Z" },
"fn_source": "blend",
"live": { "phase": "cruise", "progress": 0.41, "dist_rem_km": 3074 } }, … ] }
Add or remove a flight
| Body field | Description |
|---|---|
| flight | Flight number, e.g. EK072. Required to add. |
| date | YYYYMMDD, the day to track. Defaults to today. |
| leg | Optional DEP-ARR (ICAO) to pin one leg of a multi-leg flight. |
| action | Set to remove to stop tracking (with id or flight). |
curl -X POST "https://api.flightnerve.com/watch/YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"flight": "EK072", "date": "20260722"}'const res = await fetch("https://api.flightnerve.com/watch/YOUR_KEY", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({"flight": "EK072", "date": "20260722"})
});
const data = await res.json();
console.log(data);import requests
r = requests.post("https://api.flightnerve.com/watch/YOUR_KEY",
json={'flight': 'EK072', 'date': '20260722'})
print(r.json())<?php
$ch = curl_init("https://api.flightnerve.com/watch/YOUR_KEY");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: application/json"]);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{"flight": "EK072", "date": "20260722"}');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = json_decode(curl_exec($ch), true);
print_r($data);Stop tracking — same endpoint with action: "remove":
curl -X POST "https://api.flightnerve.com/watch/YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"action": "remove", "id": 42}'const res = await fetch("https://api.flightnerve.com/watch/YOUR_KEY", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({"action": "remove", "id": 42})
});
const data = await res.json();
console.log(data);import requests
r = requests.post("https://api.flightnerve.com/watch/YOUR_KEY",
json={'action': 'remove', 'id': 42})
print(r.json())<?php
$ch = curl_init("https://api.flightnerve.com/watch/YOUR_KEY");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: application/json"]);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{"action": "remove", "id": 42}');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = json_decode(curl_exec($ch), true);
print_r($data);Leg options
curl "https://api.flightnerve.com/watch/YOUR_KEY/legs?flight=EK072" → { "success":true, "flight":"EK072", "legs":[ { "leg":"OMDB-VTBS", "dep_icao":"OMDB", "arr_icao":"VTBS" }, … ] }
cancelled flag and no estimate; flights that have arrived or been cancelled stop refreshing automatically.Create a flight monitor
Start monitoring a specific flight on a date and attach it to your account. Give it a flight and date, optionally describe which changes you want to be informed of and how sensitive the alerts should be. Every qualifying change is pushed to your webhook and recorded under Alerts.
The response returns a stable monitoring_id (e.g. mon_fbba35cd573ca081). Store it: it identifies this exact monitor, is echoed in every webhook we send for it, appears on each alert, and is the same if you re-add the same flight/date — so you can correlate incoming alerts to what you set up without parsing flight numbers.
Body
| Body field | Description |
|---|---|
| flight | Flight number, e.g. EK72. (Or send name+num, e.g. "name":"EK","num":72.) Required. |
| date | YYYYMMDD, the day to monitor. Defaults to today. |
| leg | Optional DEP-ARR (ICAO) to pin one leg of a multi-leg flight. |
| monitor | Optional alert config (below). Omit to monitor every event at the default 15-minute sensitivity. |
| action | Set to remove to stop monitoring (with id, or flight+date). |
The monitor config
| Field | Description |
|---|---|
| sensitivity_min | Minutes of change required to (re)fire a time alert. Default 15. A departure/arrival estimate must move at least this much from the value we last alerted you on to fire again — so a drift from 12 to 18 minutes late (6 min) will not re-alert. |
| events | Object toggling each event. Any event you don't list stays on; set one false to mute it. |
Events you can monitor:
| Event | Fires when… |
|---|---|
| departure | the flight actually departs (off-blocks). |
| departure_late | the departure estimate moves later (delay), beyond the sensitivity. |
| departure_early | the departure estimate moves earlier. |
| arrival_late | the arrival estimate moves later (delay). |
| arrival_early | the arrival estimate moves earlier. |
| gate | a departure or arrival gate is assigned or changed. |
| terminal | a terminal is assigned or changed. |
| baggage | the arrival baggage belt is assigned or changed. |
| schedule_change | the published scheduled time changes. |
| cancelled / diverted / landed | the flight is cancelled, diverted, or lands. |
Example
curl -X POST "https://api.flightnerve.com/monitor/YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"flight": "EK72", "date": "20260726", "monitor": {"sensitivity_min": 20, "events": {"departure_early": false, "gate": false}}}'const res = await fetch("https://api.flightnerve.com/monitor/YOUR_KEY", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({"flight": "EK72", "date": "20260726", "monitor": {"sensitivity_min": 20, "events": {"departure_early": false, "gate": false}}})
});
const data = await res.json();
console.log(data);import requests
r = requests.post("https://api.flightnerve.com/monitor/YOUR_KEY",
json={'flight': 'EK72', 'date': '20260726', 'monitor': {'sensitivity_min': 20, 'events': {'departure_early': False, 'gate': False}}})
print(r.json())<?php
$ch = curl_init("https://api.flightnerve.com/monitor/YOUR_KEY");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: application/json"]);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{"flight": "EK72", "date": "20260726", "monitor": {"sensitivity_min": 20, "events": {"departure_early": false, "gate": false}}}');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = json_decode(curl_exec($ch), true);
print_r($data);{ "success": true, "id": 115, "monitoring_id": "mon_fbba35cd573ca081",
"flight": "EK72", "day": "20260726", "source": "api",
"webhook": "https://your-server.example/hooks/fn",
"monitor": { "sensitivity_min": 20, "events": { "departure_early": false, "gate": false } } }
Webhooks
Set one webhook URL per account. Whenever a monitored flight changes, FlightNerve POSTs a JSON object to your URL. Every alert is also stored under Alerts with its delivery status, so nothing is lost if your endpoint is briefly unreachable.
Set / read your webhook
curl -X POST "https://api.flightnerve.com/webhook/YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://your-server.example/hooks/fn"}'const res = await fetch("https://api.flightnerve.com/webhook/YOUR_KEY", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({"url": "https://your-server.example/hooks/fn"})
});
const data = await res.json();
console.log(data);import requests
r = requests.post("https://api.flightnerve.com/webhook/YOUR_KEY",
json={'url': 'https://your-server.example/hooks/fn'})
print(r.json())<?php
$ch = curl_init("https://api.flightnerve.com/webhook/YOUR_KEY");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: application/json"]);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{"url": "https://your-server.example/hooks/fn"}');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = json_decode(curl_exec($ch), true);
print_r($data);Read your current webhook:
curl "https://api.flightnerve.com/webhook/YOUR_KEY"
const res = await fetch("https://api.flightnerve.com/webhook/YOUR_KEY");
const data = await res.json();
console.log(data);import requests
r = requests.get("https://api.flightnerve.com/webhook/YOUR_KEY")
print(r.json())<?php
$res = file_get_contents("https://api.flightnerve.com/webhook/YOUR_KEY");
$data = json_decode($res, true);
print_r($data);Test it: POST {"test": true, "url": "…"} to /webhook/<api_key> and we deliver a sample alert to that URL and tell you whether it replied: { "delivered": true, "code": 200 }. The console has a Test button that does exactly this.
Webhook payload
Your endpoint receives a POST with Content-Type: application/json and this body. Respond with any 2xx to acknowledge.
{
"event": "flightnerve.alert",
"alert_id": 481,
"monitoring_id": "mon_fbba35cd573ca081",
"flight": "EK72",
"date": "20260726",
"leg": "",
"route": "DXB-MUC",
"source": "api",
"created_utc": "2026-07-26T13:58:04Z",
"monitor": { "sensitivity_min": 20, "events": { "gate": false } },
"changes": [
{ "field": "arrival_estimate", "type": "delayed",
"from": "2026-07-26T14:00:00Z", "to": "2026-07-26T14:25:00Z",
"delta_min": 25, "to_local": "16:25" }
]
}
| Field | Description |
|---|---|
| event | Always flightnerve.alert. |
| alert_id | Stable id of this alert (also under /alerts). |
| monitoring_id | The monitor this alert belongs to — the same monitoring_id returned when you created it. Use it to route the alert on your side. |
| flight / date / leg / route | The monitored flight this alert is for. |
| source | api if the monitor was created via the API, else console. |
| changes | One or more change objects. Each carries a field, a type (delayed, earlier, departed, assigned, changed, cancelled, landed, diverted, schedule_change), the from/to values, and for time changes a delta_min (minutes vs schedule) and to_local (local HH:MM). |
delivered / failed + HTTP code) is attached to each alert (webhook_status, webhook_code) and shown in the console, so you can always reconcile against /alerts.Monitored flights (live board)
One call for the live board of everything on your watchlist that still matters: every flight that is scheduled or in the air, plus any that landed within the last hour. Flights that landed more than an hour ago drop off automatically. Each entry carries the final schedule, times, gate, terminal, baggage belt, status, and a live position when the aircraft is airborne with a fix.
Example
curl "https://api.flightnerve.com/monitored/YOUR_KEY"
const res = await fetch("https://api.flightnerve.com/monitored/YOUR_KEY");
const data = await res.json();
console.log(data);import requests
r = requests.get("https://api.flightnerve.com/monitored/YOUR_KEY")
print(r.json())<?php
$res = file_get_contents("https://api.flightnerve.com/monitored/YOUR_KEY");
$data = json_decode($res, true);
print_r($data);{ "success": true, "count": 12, "flights": [
{ "flight": "EK216", "day": "20260723", "callsign": "UAE216",
"status": "In Air", "regNumber": "A6-EOA",
"codeshares": ["QF8016", "AF3634"],
"route": { "from": "LAX", "to": "DXB", "fromCity": "Los Angeles", "toCity": "Dubai" },
"departure": { "scheduled": "2026-07-23T23:40:00Z", "actual": null,
"estimated": "2026-07-24T00:52:00Z", "delayMinutes": 72,
"terminal": "B", "gate": null },
"arrival": { "scheduled": "2026-07-24T16:30:00Z", "estimated": "2026-07-24T17:51:00Z",
"terminal": "3", "gate": "C1", "baggage": "5" },
"position": { "latitude": 50.1, "longitude": 7.4, "altitude": 36000,
"groundSpeed": 470, "heading": 283,
"phase": "cruise", "progress": 0.53, "source": "live" } }, … ] }
Fields
| Field | Description |
|---|---|
| status | Scheduled, In Air, Arrived, Cancelled or Diverted. |
| regNumber | Aircraft registration (tail number) of the aircraft flying, identified live while airborne; null otherwise. |
| codeshares | Other flight numbers the same physical flight is marketed under (e.g. ["QF8016","AF3634"]). Empty when none are known for the flight. |
| departure / arrival | scheduled, actual/estimated (ISO-8601 UTC), delayMinutes, terminal, gate; arrival also carries baggage (belt). |
| position | Present only while airborne with a fix: latitude, longitude, altitude (ft), groundSpeed (kt), heading, phase, progress (0 to 1), source (live or partner). For an estimated position in a coverage gap, call /track. |
/airline returns per flight). Use this to render an operations board with one request instead of one per flight.Alerts
Every change detected on your monitored flights, newest first: a departure or arrival running early or late, a gate, terminal or baggage belt assigned or changed, a schedule revision, a departure, a landing, a cancellation or a diversion. Each alert names the flight and its date and lists exactly which fields changed.
Example
curl "https://api.flightnerve.com/alerts/YOUR_KEY?unread=1"
const res = await fetch("https://api.flightnerve.com/alerts/YOUR_KEY?unread=1");
const data = await res.json();
console.log(data);import requests
r = requests.get("https://api.flightnerve.com/alerts/YOUR_KEY?unread=1")
print(r.json())<?php
$res = file_get_contents("https://api.flightnerve.com/alerts/YOUR_KEY?unread=1");
$data = json_decode($res, true);
print_r($data);{ "success": true, "unread": 2, "alerts": [
{ "id": 41, "flight": "LH766", "day": "20260723", "route": "MUC-BOM",
"created": 1784822100, "read": 0,
"changes": [
{ "field": "arrival_estimate", "type": "delayed",
"to": "2026-07-24T12:51:00Z", "to_local": "18:21", "delta_min": 34 },
{ "field": "arrival_gate", "type": "assigned", "to": "C1" } ] }, … ] }
Mark read
curl -X POST "https://api.flightnerve.com/alerts/YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"ids": [41, 40]}'const res = await fetch("https://api.flightnerve.com/alerts/YOUR_KEY", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({"ids": [41, 40]})
});
const data = await res.json();
console.log(data);import requests
r = requests.post("https://api.flightnerve.com/alerts/YOUR_KEY",
json={'ids': [41, 40]})
print(r.json())<?php
$ch = curl_init("https://api.flightnerve.com/alerts/YOUR_KEY");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: application/json"]);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{"ids": [41, 40]}');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = json_decode(curl_exec($ch), true);
print_r($data);Omit ids to mark every alert read.
| Change field | Meaning |
|---|---|
| departure_estimate / arrival_estimate | Predicted time moved. to_local is the new local time; delta_min is +late / -early versus schedule. |
| departure / status | Departed, landed, cancelled or diverted. |
| departure_gate / arrival_gate / *_terminal / arrival_baggage | Gate, terminal or baggage belt assigned or changed. |
| departure_scheduled / arrival_scheduled | The scheduled time itself was revised. |
?unread=1 for new alerts only. This collection is the backbone for delivery by email or webhook.Health
{ "status": "ok", "service": "flightnerve", "ts": 1784540431 }
Errors
Errors return a small JSON object with a message and success: false, and an appropriate HTTP code.
| Code | When |
|---|---|
| 400 | Missing num/name, the flight/date could not be resolved, or the flight does not operate on the requested date. |
| 401 | Missing, unknown or inactive API key. |
| 429 | API key quota exceeded. |
| 404 | Unknown path. |
{ "message": "Either your date is wrong or airline code is wrong. Please verify the flight number and date.", "success": false }
{ "message": "No scheduled flight found for this flight number on that date.", "success": false }
Notes & limits
Keep request volume proportional to real user searches rather than continuous polling. Fields that are not published are returned as null, never omitted, so the response shape is always stable. Typical latency ~0.8 s. CORS is open (Access-Control-Allow-Origin: *).
