Skip to content

Flights

Flights are TravStats’ first-class entity. There are four ways to get one into the database, ranked by how much typing they save:

MethodTime per flightBest for
Forward a confirmation email~5 sFuture flights (booking → trip prep)
Scan a boarding pass~10 sAt the gate or right after landing
Bulk import (XLSX/CSV/JSON)seconds for thousandsBackfilling years of past flights
Manual entry~30 sOld flights, no email/pass available

Flights → Add Flight opens a step-by-step form:

  1. Departure / arrival airports — type IATA (FRA), ICAO (EDDF), or city (Munich); the autocomplete searches all ~9000 airports seeded on first boot.
  2. Date and times — local times in each airport’s timezone (TravStats stores everything as canonical UTC behind the scenes; v1.2.0 fixed a long-running bug where reminder emails fired 1–2 h off because of mixed conventions).
  3. Airline — IATA (LH) or ICAO (DLH) plus the operator name. Auto-fills if the IATA matches a known airline.
  4. Aircraft — IATA-T type code (32A for A320neo, 744 for 747-400) or freeform.
  5. Flight number — normalised to LH123 style automatically; case and whitespace don’t matter.
  6. Optional fields — booking reference (PNR), seat, cabin class, tags. All searchable later.

Distance is computed from the airport coordinates; you don’t enter it yourself.

The fastest path for booked-but-not-yet-flown flights.

Flights → Import → Email — paste the email body or upload an .eml / .msg file. The parser pipeline (Ollama-first when configured — strongly recommended):

  1. Clean the email body and detect the sender / subject for routing.
  2. User template if you’ve recorded one with confidence ≥ 80 % — runs first.
  3. Ollama LLM (recommended primary parser) — your local LLM, default gemma3:12b, runs as a sidecar container next to TravStats. Handles multi-flight bookings (round trips, connections, group itineraries) reliably across any airline. Benchmark accuracy: ~95–100 %.
  4. Built-in regex templates as the fallback for these eight European carriers when Ollama is unavailable: Lufthansa (LH, plus the older “Buchungsdetails” format), Swiss (LX), Austrian (OS), Brussels (SN), Ryanair (FR), easyJet (U2), Eurowings (EW), Wizz Air (W6). Single-leg bookings on these carriers parse fine without Ollama. Multi-flight emails are the regex layer’s weak spot — if you fly multi-leg itineraries, run Ollama.
  5. Generic regex extractor as last resort.
  6. Review screen before anything is saved. You can edit any field, delete suggestions you don’t want, or hit Save all.

For airlines you fly often that aren’t on the built-in list and where you’d rather not depend on Ollama, you can record a user template — paste an example email, mark which lines contain which fields, and TravStats will reuse the rules on future emails from the same sender.

Common cases and what to do:

SymptomCauseFix
Aircraft type missingAirline doesn’t include it in the emailManually edit, or enable AirLabs/Aviationstack enrichment for auto-fill on next save
Wrong departure dateEmail has multiple legs, parser picked the firstReview screen lets you delete the unwanted ones before saving
Codeshare flight numberOperator vs. marketing carrier mismatchThe flight-lookup API resolves codeshares — set an AirLabs/Aviationstack key in Admin → Settings
All fields blankEmail is OCR’d from a forwarded photo, or HTML is heavily styledTry uploading the original .eml file instead of pasting body text

Flights → Import → Boarding Pass takes a photo or uploaded image.

Three vision parsers are tried in order, falling back if the previous one isn’t configured or fails:

  1. Ollama with a vision-capable model (default), running locally
  2. OpenAI / Claude if you’ve set an API key in Admin → Settings
  3. Tesseract OCR as last resort — pure-CPU, slower, less accurate

Whichever extracts a usable flight number first, wins. If nothing works you’ll get a manual-entry form pre-filled with whatever text the OCR could read.

The PDF417 / Aztec barcode on the pass is decoded too — once we have the flight number and date, the flight-lookup API fills in the aircraft, distance, scheduled times, and operating carrier.

Edit any field after the fact: click a flight in the list, change, save. Distance recomputes when you change either airport. The audit trail in Admin → Logs tracks who changed what, when, and what the previous value was.

Bulk editsFlights → Filter, select rows, Bulk edit. Useful for one-time corrections like:

  • Renaming an airline (merger or rebrand: “Air Berlin” → “AB”)
  • Replacing an aircraft type (typo: 74474H)
  • Adding a tag to all flights of a trip
  • Deleting test flights from a demo run

If you re-import a boarding pass for a flight you’ve already entered, TravStats fills in missing fields on the existing row instead of creating a duplicate. Same flight number + same calendar day + matching airports = match. The dashboard surfaces a flightMerged toast that reports how many fields were filled in.

To force a merge explicitly via the API:

Terminal window
curl -X POST https://travstats.example.com/api/v1/flights?merge=true \
-H "Authorization: Bearer ts_pat_…" \
-H "Content-Type: application/json" \
-d '{ "flightNumber":"LH401", "departure": …, "arrival": … }'

The merge respects manual edits — fields you’ve curated never get overwritten. Only blank fields are filled. See the OpenAPI docs at /api/v1/docs for the full request/response schema.

The dashboard has six map modes for the same data:

  • Routes — great-circle arcs on a 2D world map
  • Heatmap — density by airport
  • Hexagon — H3 hex bins for clustered analysis
  • 3D Columns — column heights = flight counts
  • Trips — animated playback of routes through time
  • 3D Globe — three.js spinning globe with arc traces

Plus statistics across the lot: total distance (”× around Earth”), total time, countries visited, top airlines, top aircraft, top airports.

Add free-form tags (business, family, solo, expat-life, 2026) on any flight. The filter sidebar lets you mix tags, airlines, aircraft, year and country to narrow the dataset for both the map and the statistics — handy for “all family trips in 2026” kind of slices.

Every save kicks off the achievement engine. Distance milestones, country counts, route patterns, equator/antimeridian crossings, all 58 awards are checked on every flight create / update / delete and unlocked retroactively. You’ll see a toast on the dashboard when a new one fires.