Flight data APIs (AirLabs / Aviationstack / AeroDataBox / OpenSky)
When you log a flight, TravStats can fill in fields you didn’t type yourself — aircraft type, scheduled times, real distance flown, codeshare resolution — by querying flight-data providers. None of this is required. Manual entry works fine. But the auto-fill is the single feature most users enable first.
Four providers are supported. They overlap in scope but each has a sweet spot.
Quick decision
Section titled “Quick decision”| You want… | Use |
|---|---|
| Just the basics for free, current flights only | AirLabs (free tier) |
| Historical flights too without a paid plan | Add OpenSky (free, login required) |
| Historical lookup back to 365 days, free tier | AeroDataBox (RapidAPI BASIC, 600 API-units/month) |
| Everything, willing to pay | Aviationstack ($10/mo entry tier) |
You can configure all four at once — TravStats cascades through them in priority order until one returns a usable result.
How TravStats uses them
Section titled “How TravStats uses them”When you create a flight, the backend calls the providers in sequence, falling back if the previous one returns nothing useful:
1. AirLabs → real-time / scheduled flights, current week2. Aviationstack → historical + future, paid tier covers more dates3. AeroDataBox → tertiary fallback for out-of-live-window queries and historical enrichment (since v1.4.0)4. OpenSky → real-time tracking position, fallback for live5. Local cache → previously-fetched results stay cached for re-importsThe order matches the typical use case — you log a flight either right after it happens (AirLabs sweet spot) or for historical backfill (Aviationstack / AeroDataBox / OpenSky sweet spot).
AirLabs
Section titled “AirLabs”Website: airlabs.co ·
Endpoint TravStats hits: https://airlabs.co/api/v9/schedules
What you get
Section titled “What you get”- Aircraft IATA / ICAO type (e.g.
74Hfor 747-8) - Scheduled departure / arrival times
- Operating airline + codeshare resolution
- Origin / destination terminal info when available
- Distance, flight duration
Cost & limits
Section titled “Cost & limits”- Free tier: “current schedule” — meaning today in most cases. Older or future dates often return empty or wrong data on the free key.
- Paid tiers: start around $10/mo for historical access (their
/flightendpoint). TravStats prefers the free/schedulesendpoint by default and only escalates to paid endpoints if you’ve also added an Aviationstack key.
- Sign up at airlabs.co, create an API key.
- In TravStats: Admin → Settings → External APIs → AirLabs API key → paste, save.
- Test from the same screen with the Test connection button. A green “200 OK” means you’re done.
Env-var fallback (advanced)
Section titled “Env-var fallback (advanced)”If you’d rather pin the key as a deploy-time variable instead of storing it in the database (e.g. for scripted bootstraps):
AIRLABS_API_KEY=your_key_hereThe admin UI shows “configured via environment” for any service where the env var is set. Database-stored keys take precedence if both are present.
Aviationstack
Section titled “Aviationstack”Website: aviationstack.com ·
Endpoint TravStats hits: https://api.aviationstack.com/v1/flights
What you get
Section titled “What you get”- Same fields as AirLabs (aircraft type, times, codeshare resolution)
- Plus historical flight lookup that covers the past 30+ days reliably
- Plus future scheduled flights past today
Cost & limits
Section titled “Cost & limits”Paid only — no free tier that’s useful for TravStats. The “Basic” tier (~$10/mo at time of writing) is the entry point and covers most homelab use. Higher tiers add more requests / day.
Worth it if you frequently re-import old emails and want them auto-enriched, or if you fly the same routes regularly and want canonical data.
- Sign up, pick a tier, get the API key.
- Admin → Settings → External APIs → Aviationstack API key → paste, save, test.
Env-var fallback
Section titled “Env-var fallback”AVIATIONSTACK_API_KEY=your_key_hereAeroDataBox (since v1.4.0)
Section titled “AeroDataBox (since v1.4.0)”Website: aerodatabox.com ·
Hosted on: RapidAPI ·
Endpoint TravStats hits: https://aerodatabox.p.rapidapi.com/flights/...
The provider that closes the gap AirLabs and Aviationstack-Free leave open: historical lookup for any date in the past 365 days on the free tier.
What you get
Section titled “What you get”Core fields (since v1.4.0):
- Aircraft IATA / ICAO type, registration, 24-bit Mode-S hex
- Operating airline + codeshare resolution (operating vs. marketing carrier on shared flights)
- Scheduled departure / arrival times
- Terminal, gate, distance, flight duration
- Status (
Departed,Arrived,Cancelled,Diverted)
Extended capture (since v1.5.0):
runwayDepartureTime/runwayArrivalTime— actual wheels-up / wheels-down stamps where AeroDataBox has them (more precise than the gate-out / gate-in times the other providers return)isCargo— flag for cargo flights, useful for filteringaerodataboxQualityTags— provider-side quality signals (realvs.forecast,actualvs.scheduled)baggageBelt— for the curiouscheckInDesk— for the curious
A backfill scheduler walks existing rows during the nightly re-enrichment pass so previously-logged flights get the extended fields too, without overwriting curated values.
The airport-side fields shortName and municipalityName (also
added in the v1.5.0 schema migration) are populated by the airport
seeder on first boot, not by the AeroDataBox adapter at lookup time.
Cost & limits
Section titled “Cost & limits”- Free tier (RapidAPI BASIC): 600 API-units / month. One flight lookup ≈ 1 unit. Comfortable for a homelab — even an active flier logging 20-30 flights / month uses a small fraction.
- Paid tiers: higher request limits, no feature gates.
- TravStats surfaces the live
X / 600 API unitscounter in Admin → Settings → API Keys → AeroDataBox, plus a secondary HTTP-request counter (a separate, higher RapidAPI counter that is not the budget — easy to misread as headroom; the primary counter is the one that matters).
- Sign up at RapidAPI, subscribe to the AeroDataBox API on the BASIC plan (free), get the API key under Apps → Default Application → Security.
- Admin → Settings → External APIs → AeroDataBox API key → paste, save, Test connection.
- Bulk historical refresh — under the same card, the “Refresh all flights in 365-day range” button backfills tail number, Mode-S, codeshare metadata, distance, and airline IATA/ICAO onto flights you logged before this provider was wired up. A confirmation modal shows how many API calls the run will cost so you don’t accidentally burn the budget. Disabled on the demo account by design.
Env-var fallback
Section titled “Env-var fallback”AERODATABOX_API_KEY=your_rapidapi_keyOpenSky Network
Section titled “OpenSky Network”Website: opensky-network.org ·
Endpoint TravStats hits: https://opensky-network.org/api/flights/callsign?…
OpenSky is a community-run ADS-B aggregation. Free, completely open, but limited compared to commercial APIs.
What you get
Section titled “What you get”- Real-time and recent (~30 days) tracking position for known flight numbers
- Departure / arrival airport from ground-truth ADS-B data — occasionally catches diversions and delays the schedule APIs miss
What you don’t get
Section titled “What you don’t get”- Aircraft type — OpenSky knows the ICAO 24-bit hex but not the type code TravStats needs
- Codeshare resolution
- Anything beyond ~30 days back
So OpenSky is an enrichment fallback, not a primary source.
Setup — modern OAuth2 (recommended)
Section titled “Setup — modern OAuth2 (recommended)”OpenSky moved to OAuth2 in 2024:
- Register at opensky-network.org and create an API client (Account → API → Create API client).
- You’ll get a
client_idandclient_secret. - Admin → Settings → External APIs → OpenSky → Client ID + Client Secret → paste, save, test.
Setup — legacy basic auth (deprecated)
Section titled “Setup — legacy basic auth (deprecated)”The old username + password flow still works for now. TravStats
falls back to it if you’ve configured OPENSKY_USERNAME /
OPENSKY_PASSWORD instead of the modern OAuth2 fields. Prefer the
OAuth2 path; OpenSky may retire basic auth at any time.
Env-var fallback
Section titled “Env-var fallback”# .env — OAuth2OPENSKY_CLIENT_ID=your_client_idOPENSKY_CLIENT_SECRET=your_client_secret
# .env — legacy basic authOPENSKY_USERNAME=your_usernameOPENSKY_PASSWORD=your_passwordWhen TravStats falls back to “no enrichment”
Section titled “When TravStats falls back to “no enrichment””If all configured providers return empty (or none are configured),
the flight saves with whatever you typed manually plus the airport
coordinates and computed great-circle distance. The
enrichmentStatus field on the row is set to pending, and a
nightly cron (default 02:00 UTC) re-tries enrichment for flights
that haven’t been touched in 24 h.
You can also trigger a manual re-enrichment from the flight detail page: Re-enrich → Run now. Useful right after you add an API key.
How to verify enrichment is actually firing
Section titled “How to verify enrichment is actually firing”After adding a flight that should be enriched:
- Look at the flight detail page — fields like aircraft, gate, terminal should populate within seconds.
- If they don’t, check
/app/data/logs/parser*.log:Terminal window docker exec travstats-app tail -f /app/data/logs/app.log | grep -i enrichment - Common failures: rate-limited (free-tier AirLabs caps you fast on bulk imports), unknown flight number (typo), or date out of provider’s reach (free-tier AirLabs for non-today flights).
Privacy
Section titled “Privacy”These calls send the flight number, date, and airline IATA code to the provider. They don’t see your name, your other flights, or anything stored in your TravStats. Each provider has its own privacy policy linked from their websites — read it if that matters to you.
The provider response — including aircraft type, route, codeshare data — gets stored against your flight row inside your own Postgres. Nothing flows back outbound from those reads.