Flight data APIs (AirLabs / Aviationstack / 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.
Three 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) |
| Everything, willing to pay | Aviationstack ($10/mo entry tier) |
You can configure all three 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. OpenSky → real-time tracking position, fallback for live4. 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 / 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_hereOpenSky 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.