Skip to content

Boarding pass scanner

The fastest way to log a flight you’re about to take or just took: point your phone camera at the boarding pass.

The parser handles three pass formats — IATA-standard PDF417 barcode (international air), Aztec / QR (newer e-tickets), and visual-only (some hand-stamped passes from regional carriers). Each is read by a different combination of barcode + vision parser.

1. You upload an image (camera, phone gallery, scanned PDF page)
2. Barcode decoder runs first
↓ if barcode found, parse IATA bcbp string → done, fields filled
↓ if no barcode, fall through
3. Vision parser cascade reads the visual
- Ollama vision (default, local)
- OpenAI Vision (paid, faster)
- Anthropic Claude Vision (paid, alternative)
- Tesseract OCR (always available, fallback)
4. Whichever step extracts a usable flight number wins
5. Flight-lookup API fills in aircraft, distance, scheduled times
6. Review screen — you confirm or edit, then save

Most modern boarding passes carry a PDF417 or Aztec barcode that decodes in milliseconds, so step 2 catches them. The vision cascade is for older, non-barcoded, or poorly-photographed passes.

The IATA “Bar Coded Boarding Pass” (bcbp) standard packs everything about the flight into a single string:

M1WITTKE/DENNIS EFRA LHR LH 401 137Y012A0024 348>2180WW6098B …

Decoded:

  • M1 = Mandatory format, one leg
  • WITTKE/DENNIS = Passenger name
  • EFRA = Booking reference
  • LHR = Departure airport (this is the arrival in this example because the pass is for the return leg)
  • LH 401 = Operating carrier and flight number
  • 137 = Day of year (= 17 May)
  • Y = Cabin class (Y = Economy)
  • 012A = Seat 12A
  • 0024 = Sequence number

TravStats’ barcode parser handles all four mandatory fields plus the optional fields most airlines fill in. Even a corner-mangled photograph of the barcode usually decodes — the format is heavily error-corrected by design.

Flights → Import → Boarding Pass. Three input methods:

  1. Camera — for boarding passes you have in hand. Click Use camera, the browser asks for permission, point at the pass.
  2. File upload — for PDF passes, screenshots, or photos already in your phone gallery.
  3. Drag and drop — for desktop browsers, drag any image file onto the page.

Image size limit is 20 MB. Anything in JPEG, PNG, WebP or PDF (single page).

Configured under Admin → Settings → Boarding Pass Parser. Each tier has an enable/disable toggle and a priority rank. Defaults:

TierDefault rankNotes
Ollama vision1Free, runs in your bundled Ollama container if you’ve pulled a vision model
OpenAI Vision2Cloud, paid, ~$0.001 per scan, fastest and most accurate
Anthropic Claude3Cloud, paid, comparable quality to OpenAI
Tesseract OCR4Always available, slowest, less accurate, last resort

The full breakdown is on the Vision parsers page.

Pass typeDecoding path
Modern e-ticket on phoneAztec or QR → barcode decoder → done in ms
Modern paper boarding passPDF417 → barcode decoder → done in ms
Hand-stamped paper pass (regional carriers)No barcode → vision cascade
Scanned PDF from a print-outBarcode decoder runs first; if scan was clean it works, otherwise vision cascade
Photo of an old boarding pass (retroactive logging)Visible barcode? barcode wins. No barcode? vision cascade

The vision cascade also fires on barcoded passes whose barcode didn’t decode — usually because of glare on the photo. So even when you take a bad picture, you’ll usually still get a result.

Once the parser has a flight number and date, the flight-lookup API auto-fills the rest:

  • Aircraft type (from AirLabs / Aviationstack / OpenSky)
  • Operating carrier vs marketing carrier (codeshare resolution)
  • Scheduled departure / arrival times in canonical UTC
  • Distance (computed from airport coordinates)

If you haven’t configured any flight-data API key yet, you’ll see just what the pass itself carries — flight number, date, seat, class, departure/arrival airport. Aircraft type stays blank until you enable enrichment or fill it in manually.

If you’ve already entered the flight manually and now scan its boarding pass, TravStats matches on flight number + calendar day + departure/arrival airports and fills in fields you didn’t manually set. Curated fields are never overwritten.

You’ll see a flightMerged toast on the dashboard reporting how many fields were filled. The merge fires whether the source is a barcode decode or a vision-parser result — same row gets enriched either way.

Image processing happens inside your TravStats container by default — the bundled Ollama vision model never sees the public internet, and Tesseract OCR is purely local.

The image only leaves your network if the cascade reaches a cloud parser (OpenAI / Claude). You explicitly opt into that by configuring those providers and ranking them in the cascade.

For maximum privacy, configure only Ollama vision + Tesseract; for maximum accuracy with cents-per-year cost, add OpenAI; for both, keep Ollama at rank 1 and OpenAI at rank 2 so the local parser tries first and only falls through on hard cases.