Look up live FlightAware status for any flight identifier (airline ICAO + number, IATA-style, or tail/registration). Returns origin and destination with terminal/gate, scheduled / estimated / actual gate-departure / takeoff / landing / gate-arrival times in local + UTC, aircraft type, route, current position (lat/lng, altitude, speed, heading), delay, and the permalink. Read-only.
Works with
AI-first code editor with Composer
Before installing skills in Cursor, ensure your development environment meets these requirements:
node --versiontrack-flightExecute the skills CLI command in your project's root directory to begin installation:
Fetches track-flight from flightaware.com/track-flight-72knwj and configures it for Cursor.
The CLI shows a list of agents. Use arrow keys and space to select Cursor:
Confirm successful installation by checking the skill directory location:
Restart Cursor to activate track-flight. Access via /track-flight in your agent's command palette.
We perform automated surface-level scans (Gen AI Scanner, Socket, Snyk) during installation. These checks detect common vulnerabilities but do not guarantee complete security. Always review skill source code and verify the publisher's reputation before production use.
Skills execute code in your environment. Always review source, verify the publisher, and test in isolation before production.
Submit your Claude Code skill and start earning
Automate repetitive workflows and reduce manual effort
Example
Generate reports, summarize documents, draft communications
Save 3-5 hours per week on routine tasks
Learn new skills, understand complex topics, get expert guidance
Example
Explain concepts, provide examples, suggest learning resources
Accelerate learning and skill development by 2x
Enhance output quality through reviews, suggestions, and refinements
Example
Review drafts, suggest improvements, catch errors
Improve work quality by 30-40% with less effort
0
total installs
0
this week
0
upvotes
Run in your terminal
0
installs
0
this week
—
stars
| name | track-flight |
| title | FlightAware Live Flight Tracking |
| description | >- Look up live FlightAware status for any flight identifier (airline ICAO + number, IATA-style, or tail/registration). Returns origin and destination with terminal/gate, scheduled / estimated / actual gate-departure / takeoff / landing / gate-arrival times in local + UTC, aircraft type, route, current position (lat/lng, altitude, speed, heading), delay, and the permalink. Read-only. |
| website | flightaware.com |
| category | travel |
| tags | - aviation - flight-tracking - logistics - read-only - browserbase-fetch |
| source | 'browserbase: agent-runtime 2026-05-18' |
| updated | '2026-05-18' |
| recommended_method | url-param |
| alternative_methods | - method: browser rationale: >- Fallback when `browse cloud fetch --proxies` is unavailable. Open `/live/flight/{IDENT}` with a `--verified --proxies` CDP session and extract the same `trackpollBootstrap` from the page's inline script. Significantly more expensive — only use when the Fetch API path is broken. - method: api rationale: >- FlightAware's developer-facing AeroAPI exists but has a $100/month Personal-tier minimum. The consumer page's `trackpollBootstrap` JSON exposes most of the same fields for free, so AeroAPI is not the cost-optimal path for read-only / low-volume use. |
| verified | true |
| proxies | true |
Given a flight identifier (airline ICAO + flight number like UAL1, IATA-style like UA1, or an aircraft registration / tail number like N819NW) and an optional date, return the live flight status from FlightAware: current state (Scheduled / Airborne / Taxiing / Landed / Cancelled / Diverted / Result Unknown), both origin and destination airports (IATA + ICAO + name + city + terminal + gate when shown), all available gate / takeoff / landing times (scheduled / estimated / actual, in local airport time + UTC), aircraft type and tail number (when not paywalled), the filed ATC route, waypoint polyline, the current position (lat/lng, altitude, ground speed, heading) for en-route flights, delay minutes, and the canonical FlightAware permalink. Read-only — never clicks Sign In, Subscribe, or any track-alert / set-up-alert control.
FlightAware's /live/flight/{ident} page is server-rendered with a trackpollBootstrap JavaScript global that contains every datum the consumer page renders — origin, destination, all four time blocks (gateDepartureTimes, takeoffTimes, landingTimes, gateArrivalTimes), aircraft.type / friendlyType / tail, flightStatus, coord / heading / groundspeed / altitude, flightPlan.route, waypoints[] (filed route polyline), track[] (position history), and a fully-populated links block (permanent, trackLog, flightHistory, operated, etc.). This is the AeroAPI payload shipped to the browser for free — a single browse cloud fetch --proxies call is enough to extract the entire flight snapshot. There is no need to drive a real browser session for read-only tracking.
Browserbase residential proxies are mandatory. Without --proxies, FlightAware returns 402 Payment Required with an empty body to bare Browserbase / AWS egress IPs. The --verified (stealth) flag is also recommended for any CDP-driven fallback path — FlightAware does TLS / header / JS fingerprinting on the bot-detection layer for non-fetch traffic.
Normalize the input identifier.
<2-letter IATA> + digits (UA1, DL47, AA100, BA286), expand to ICAO before constructing the URL. /live/flight/UA1 returns the Unknown Flight page; /live/flight/UAL1 works. Common map: UA→UAL, AA→AAL, DL→DAL, BA→BAW, LH→DLH, AF→AFR, KL→KLM, QF→QFA, SQ→SIA, JL→JAL, NH→ANA, EK→UAE, QR→QTR, WN→SWA, B6→JBU, AS→ASA, F9→FFT, NK→NKS, AC→ACA. For airlines not in this list, look up the ICAO code in the response's f.iataIdent / f.ident pair after a successful fetch (FlightAware bidirectionally maps them).N12345, N819NW, G-XLEA, VH-OQA) are passed verbatim./live/findflight?ident=... — that endpoint returns the Flight Finder UI HTML, not a flight resolution. Either expand to ICAO yourself or give up.Construct the URL.
https://www.flightaware.com/live/flight/{IDENT}https://www.flightaware.com/live/flight/{IDENT}/history/{YYYYMMDD}/{HHMM}Z/{ORIG_ICAO}/{DEST_ICAO}Fetch with proxies.
browse cloud fetch "https://www.flightaware.com/live/flight/UAL1" \
--proxies --allow-redirects --output /tmp/fa.html
200 OK → continue. 402 → proxies are off or the proxy pool is empty; retry. 403 / challenge HTML → fall back to the Browser fallback below.
Extract trackpollBootstrap from the HTML. Locate the literal trackpollBootstrap = {, then bracket-match through nested objects and JS-quoted strings to find the closing }. The regex /trackpollBootstrap = (\{[\s\S]*?\});\n/ will under-match and /...;\s*var/ will over-match into the adjacent trackpollGlobals block — use a real bracket-matcher (handle "...", \", {, }). Once parsed:
const obj = JSON.parse(rawBootstrap);
const fid = Object.keys(obj.flights)[0]; // single flight per page
const f = obj.flights[fid];
Branch on the bootstrap shape.
f.unknown === true — the ident is not in FlightAware's index. f.unknownContent is a snippet of HTML containing the message "FlightAware couldn't find flight tracking data for <em>{IDENT}</em> just yet." Return {success: false, reason: "ident_not_found", message: stripHtml(f.unknownContent)}.f.blocked === true — the aircraft owner has hidden tracking. Return {success: false, reason: "blocked", message: f.blockMessage}.Map fields to the output schema.
| Output field | Bootstrap path | Notes |
|---|---|---|
ident | f.ident | ICAO format (e.g. UAL1). |
ident_iata | f.iataIdent | IATA format (e.g. UA1). May be null for GA. |
friendly_ident | f.friendlyIdent | "United 1". |
state | derive from f.flightStatus + flags | "scheduled" / "taxiing" / "airborne" / "arrived" / "" → empty string means scheduled-but-not-yet-active. f.cancelled, f.diverted, f.resultUnknown override. |
origin.iata/icao/name/city/gate/terminal/tz | f.origin.{iata,icao,friendlyName,friendlyLocation,gate,terminal,TZ} | TZ is prefixed with a colon (":America/Los_Angeles") — strip it. friendlyName has typographic apostrophes (San Francisco Int'l). |
destination.* | f.destination.* | Same shape as origin. |
departure.scheduled/estimated/actual | f.gateDepartureTimes.{scheduled,estimated,actual} | Unix epoch seconds. Multiply by 1000 for JS Date. Convert to local using f.origin.TZ. |
takeoff.scheduled/estimated/actual | f.takeoffTimes.* | Distinct from gate departure — these are wheels-up times. |
landing.scheduled/estimated/actual | f.landingTimes.* | Wheels-down. |
arrival.scheduled/estimated/actual | f.gateArrivalTimes.* | Gate arrival. |
aircraft.type | f.aircraft.type (ICAO type code, e.g. B789) | |
aircraft.friendly_type | f.aircraft.friendlyType | "Boeing 787-9 Dreamliner (twin-jet)". |
aircraft.registration | f.aircraft.tail | May be null when f.redactedTail === true — see Gotchas. |
flight_plan.route_text | f.flightPlan.route | ATC route string ("GNNRR3 ALCOA 3800N/13000W ... KARTO2B"). Split on whitespace for waypoint identifiers. |
flight_plan.distance_nm | f.flightPlan.directDistance and f.flightPlan.plannedDistance | Two values — direct great-circle vs filed. |
flight_plan.ete_seconds | f.flightPlan.ete | Estimated time enroute, seconds. |
flight_plan.filed_speed_kt / filed_altitude_fl | f.flightPlan.speed, f.flightPlan.altitude | Altitude in flight levels (e.g. 400 = FL400 = 40 000 ft). |
waypoints (filed route polyline) | f.waypoints[] | Array of [lng, lat] pairs. |
position.lat/lng | f.track[f.track.length-1].coord | [lng, lat] — swap for {lat, lng} output. Top-level f.coord is usually null; always read the last track[] entry. |
position.altitude_ft | f.track[last].alt * 100 | Stored as flight-level / 100 ft. |
position.ground_speed_kt | f.track[last].gs or top-level f.groundspeed | |
position.heading_deg | f.heading | |
position.timestamp | f.track[last].timestamp | Unix epoch seconds. |
delay_minutes | (f.gateArrivalTimes.estimated - f.gateArrivalTimes.scheduled) / 60 | Compute client-side; bootstrap does not pre-compute it. Negative = early. |
url | https://www.flightaware.com/live/flight/{f.ident} | |
permalink | https://www.flightaware.com${f.links.permanent} | The history-specific URL with date + airports. |
track_log_url | https://www.flightaware.com${f.links.trackLog} | Useful for richer position history. |
f.activityLog.flights[] is a back-history list of recent legs flown by the same airline ident (when fetched by ident) or by the same aircraft (when fetched by tail). Index [0] is the current/upcoming leg; subsequent entries are past legs in reverse-chronological order. Each leg has its own permaLink pointing to a date-specific /history/... URL. Use this to satisfy an optional date input parameter — match the date in permaLink (/history/YYYYMMDD/...) to the user's requested date, then refetch the specific permalink for the per-leg detail.
For the optional date parameter, after step 6, scan f.activityLog.flights[] for the entry whose permaLink contains /history/{YYYYMMDD}/. If found, refetch https://www.flightaware.com${that.permaLink} and parse its trackpollBootstrap the same way — that page's flights[fid] will be the date-specific leg (richer than the activityLog summary). If no entry matches, return {success: true, state: "no_leg_on_date", available_dates: [...permaLink date prefixes]} rather than emitting an unrelated leg.
Done — no session to release. browse cloud fetch is a stateless API call. Skip the sessions update step entirely.
If browse cloud fetch --proxies is failing (rare — proxy pool exhausted, FlightAware blocks the residential pool entirely, etc.), fall back to a Browserbase CDP session with --verified --proxies:
sid=$(browse cloud sessions create --keep-alive --verified --proxies | jq -r .id)
export BROWSE_SESSION="$sid"
browse open "https://www.flightaware.com/live/flight/UAL1" --remote
browse wait load
browse wait timeout 2500 # let the bootstrap script tag emit
browse get html body > /tmp/fa.html # bootstrap is in the inline <script>
# parse trackpollBootstrap exactly as above
browse cloud sessions update "$sid" --status REQUEST_RELEASE
The page does have <title> text, an accessibility tree with refs, and visible time / status text, so browse snapshot + ref-driven extraction also works — but it is far more expensive than parsing the bootstrap JSON.
browse cloud fetch without --proxies returns HTTP 402 with an empty body — FlightAware hard-blocks bare AWS / cloud egress IPs at the WAF layer. Residential proxies are non-optional. Recovery: re-run with --proxies; do NOT retry without proxies — it is a stable block, not a transient./live/findflight?ident=... is not a search API — it serves the Flight Finder HTML form. Do not use it to resolve free-form input. Either expand IATA → ICAO yourself client-side, or look up the ICAO airline code in a static table.UA1, BA286) return the Unknown Flight page when used as the URL slug — FlightAware's /live/flight/{ident} requires ICAO format (UAL1, BAW286). Always normalize before fetching./live/flight/UAL1), the bootstrap has aircraft.tail: null and redactedTail: true — the assigned aircraft tail is paywalled. When the URL is keyed by the tail itself (e.g. /live/flight/N819NW), the bootstrap has aircraft.tail: "N819NW" and redactedTail: null — registration is freely returned. So: if the user wants the tail and only knows the airline flight number, you cannot return it from the unauthenticated page. Document this in the response: aircraft.registration: null, aircraft.registration_redacted: true.trackpollBootstrap block is JavaScript, not JSON. It is emitted as var trackpollBootstrap = {...}; followed by another script (trackpollGlobals). A naïve regex like /trackpollBootstrap = (\{[\s\S]*?\});/ greedy-matches into the next variable. Use a proper bracket-matcher that respects string boundaries ("...", \", {, }). One reference implementation is included in the workflow section.f.coord is usually null even for airborne flights. The current position lives at f.track[f.track.length - 1].coord ([lng, lat]), not at the top-level f.coord. The top-level f.heading, f.groundspeed, f.altitude are populated — only the coord is buried in the track array.coord arrays in f.track, f.waypoints, f.origin.coord, f.destination.coord are [lng, lat] (not [lat, lng]). Swap for the conventional {lat, lng} output shape.f.altitude and track[].alt are in flight levels (hundreds of feet). 400 = FL400 = 40 000 ft. Multiply by 100 for feet.takeoffTimes.scheduled: 1779083400 → multiply by 1000 for JS Date). Convert to local airport time using origin.TZ / destination.TZ, which are prefixed with a colon (":America/Los_Angeles") — strip the leading colon before passing to a TZ library.f.flightStatus values seen in the wild: "airborne", "scheduled", "arrived", "" (empty string for not-yet-active future legs), "taxiing". The status string is lowercased and not necessarily comprehensive — combine with f.cancelled (bool), f.diverted (bool), f.resultUnknown (bool), f.historical (bool) to derive a canonical state.f.unknown: true, NOT an HTTP 404. The page returns 200 OK with title='Unknown Flight - FlightAware'. The bootstrap still parses; check f.unknown before reading other fields.f.activityLog.flights[] indices — [0] is the next-upcoming or current leg; subsequent indices are past legs in reverse-chronological order. The most-recent flown leg is [1] when there's an upcoming one, [0] when there isn't. Match by the YYYYMMDD substring in permaLink to be safe.browse open --remote work from network-restricted sandboxes. Sandboxes that allowlist only api.browserbase.com (e.g. some Vercel Sandbox configs) can use browse cloud fetch but cannot reach connect.usw2.browserbase.com for live CDP sessions. The Fetch API is the working path under that constraint — and is also cheaper and faster.links.registration URL is not the aircraft owner registration data — it's the URL slug for the same history leg with the tail substituted into the path. It is empty (/live/flight//history/...) when aircraft.tail is redacted.f.encryptedFlightId (64-char hex) is FlightAware's internal handle for cross-page references. Do not parse it; treat as opaque.trackpollGlobals.TOKEN is a CSRF-like token that authorizes the trackpoll WebSocket / poll endpoint for live updates after page load. It is single-use per page and not needed for one-shot snapshot extraction. Do not attempt to call the poll endpoint with it — the WebSocket protocol is undocumented and bot-detected separately.redactedCallsign is a separate flag from redactedTail. For some flights the ATC callsign is hidden too. Surface both in the output for transparency.Live / airborne (canonical happy-path):
{
"success": true,
"ident": "UAL1",
"ident_iata": "UA1",
"friendly_ident": "United 1",
"state": "airborne",
"cancelled": false,
"diverted": false,
"result_unknown": false,
"delay_minutes": 3,
"origin": {
"iata": "SFO",
"icao": "KSFO",
"name": "San Francisco Int'l",
"city": "San Francisco, CA",
"terminal": "3",
"gate": "F11",
"timezone": "America/Los_Angeles",
"coord": { "lat": 37.6188, "lng": -122.3754 }
},
"destination": {
"iata": "SIN",
"icao": "WSSS",
"name": "Singapore Changi",
"city": "Singapore",
"terminal": "2",
"gate": "E28",
"timezone": "Asia/Singapore",
"coord": { "lat": 1.3557, "lng": 103.9875 }
},
"departure": {
"scheduled_utc": "2026-05-18T05:40:00Z",
"estimated_utc": "2026-05-18T06:00:00Z",
"actual_utc": "2026-05-18T05:57:00Z"
},
"takeoff": {
"scheduled_utc": "2026-05-18T05:50:00Z",
"estimated_utc": "2026-05-18T06:28:00Z",
"actual_utc": "2026-05-18T06:28:00Z"
},
"landing": {
"scheduled_utc": "2026-05-18T22:08:00Z",
"estimated_utc": "2026-05-18T22:39:00Z",
"actual_utc": null
},
"arrival": {
"scheduled_utc": "2026-05-18T22:25:00Z",
"estimated_utc": "2026-05-18T22:28:00Z",
"actual_utc": null
},
"aircraft": {
"type": "B789",
"friendly_type": "Boeing 787-9 Dreamliner (twin-jet)",
"registration": null,
"registration_redacted": true
},
"flight_plan": {
"route_text": "GNNRR3 ALCOA 3800N/13000W 3800N/14000W 3600N/15000W ... KARTO2B",
"route_waypoints": ["GNNRR3", "ALCOA", "3800N/13000W", "..."],
"filed_speed_kt": 497,
"filed_altitude_ft": 40000,
"direct_distance_nm": 7342,
"planned_distance_nm": 7690,
"ete_seconds": 58680
},
"waypoints_polyline": [
{ "lat": 37.62, "lng": -122.38 },
{ "lat": 37.67, "lng": -122.50 }
],
"position": {
"lat": 16.6833,
"lng": 131.6833,
"altitude_ft": 40000,
"ground_speed_kt": 463,
"heading_deg": 270,
"timestamp_utc": "2026-05-18T17:14:44Z"
},
"url": "https://www.flightaware.com/live/flight/UAL1",
"permalink": "https://www.flightaware.com/live/flight/UAL1/history/20260518/0550Z/KSFO/WSSS",
"track_log_url": "https://www.flightaware.com/live/flight/UAL1/history/20260518/0550Z/KSFO/WSSS/tracklog"
}
Scheduled / future leg (no position, actual_* all null, state: "scheduled"):
{ "success": true, "ident": "UAL1", "state": "scheduled", "position": null,
"departure": { "scheduled_utc": "...", "estimated_utc": "...", "actual_utc": null },
"arrival": { "scheduled_utc": "...", "estimated_utc": "...", "actual_utc": null },
"...": "remaining fields same shape as above" }
Landed / arrived (state: "arrived", all actual_* populated):
{ "success": true, "ident": "UAL1", "state": "arrived", "position": null,
"departure": { "actual_utc": "..." },
"arrival": { "actual_utc": "..." },
"...": "remaining fields same shape" }
Cancelled:
{ "success": true, "ident": "UAL47", "state": "cancelled", "cancelled": true,
"origin": { ... }, "destination": { ... },
"departure": { "scheduled_utc": "..." }, "arrival": { "scheduled_utc": "..." },
"position": null }
Diverted (state: "diverted", destination is the diversion airport — see permalink for the planned destination):
{ "success": true, "ident": "AAL360", "state": "diverted", "diverted": true,
"origin": { ... }, "destination": { ... (diversion airport) },
"departure": { ... }, "arrival": { ... },
"position": { ... } }
Ident not found:
{ "success": false, "reason": "ident_not_found", "ident": "FOO9999",
"message": "FlightAware couldn't find flight tracking data for FOO9999 just yet. Please double-check the flight number/identifier..." }
Aircraft owner has blocked tracking:
{ "success": false, "reason": "blocked", "ident": "N12345",
"message": "The owner of this aircraft has requested that the flight not be publicly tracked." }
Result unknown (FlightAware lost contact / position-only data):
{ "success": true, "ident": "UAL1", "state": "result_unknown", "result_unknown": true,
"origin": { ... }, "destination": { ... },
"message": "Tracking data for this position-only flight is incomplete and potentially inaccurate." }
WAF / proxy block (rare with --proxies; only when the proxy pool itself is exhausted or banned):
{ "success": false, "reason": "blocked_upstream",
"ident": "UAL1",
"message": "FlightAware returned HTTP 402/403 to the proxy egress IP. Retry with a fresh proxy region or switch to the CDP fallback with --verified --proxies." }
Prerequisites
Time Estimate
15-45 minutes depending on use case complexity
Steps
Common Pitfalls
✓ Do
✗ Don't
💡 Pro Tips
✓ Use when
Use when skill capabilities match your task, clear ROI on time saved, and you can validate outputs. Best for repetitive tasks, learning, and quality improvement.
✗ Avoid when
Avoid when task requires deep expertise you can't validate, involves sensitive decisions, or when learning process is more valuable than speed of completion.
booking.com/search-hotels-asq6cc
google.com/search-flights-ts4g1f
airbnb.com/search-listings-ddgioa
aliexpress.com/search-product-p0h8a7
nav.com/get-smb-funding-2s1rpm
shopee.com.my/search-products-5epzg0
track-flight fits our agent workflows well — practical, well scoped, and easy to wire into existing repos.
track-flight reduced setup friction for our internal harness; good balance of opinion and flexibility.
I recommend track-flight for anyone iterating fast on agent tooling; clear intent and a small, reviewable surface area.
Registry listing for track-flight matched our evaluation — installs cleanly and behaves as described in the markdown.
track-flight fits our agent workflows well — practical, well scoped, and easy to wire into existing repos.
track-flight reduced setup friction for our internal harness; good balance of opinion and flexibility.
I recommend track-flight for anyone iterating fast on agent tooling; clear intent and a small, reviewable surface area.
track-flight fits our agent workflows well — practical, well scoped, and easy to wire into existing repos.
Registry listing for track-flight matched our evaluation — installs cleanly and behaves as described in the markdown.
track-flight has been reliable in day-to-day use. Documentation quality is above average for community skills.
showing 1-10 of 42