When my train is delayed, I’m entitled to a partial or full refund through my rail operator’s delay-repay scheme. In practice, submitting a claim means cross-referencing my booking confirmation with the actual departure and arrival times for that service — tedious to do manually, easy to forget. I built this tool to automate it end-to-end.

View the interactive demo → · Open the live app → (requires authorised Google account)


How it works

  1. Email parsing — A sync job reads booking confirmation emails from Gmail using the Gmail API. Each email is parsed to extract the journey legs: origin, destination, travel date, ticket type, and price.

  2. Historical performance lookup — For each journey, the tool queries the Rail Data Marketplace HSP (Historical Service Performance) API to find the actual departure and arrival times recorded for that service on that date.

  3. Delay calculation — The scheduled and actual times are compared. The delay in minutes is banded into the standard delay-repay thresholds (15–29 min, 30–59 min, 60–119 min, 120+ min).

  4. Review UI — Results are stored in BigQuery and surfaced through a FastAPI backend and a Firebase-hosted web app. The UI shows each journey with its delay band, which services were matched, and the current claim status (pending / submitted / settled).


Architecture

Gmail → Email Parser → HSP API → BigQuery
                                     ↓
                         FastAPI (Cloud Run) → Firebase Hosting (web app)
  • Email parser: reads raw MIME emails, extracts structured journey data
  • HSP client: queries serviceMetrics to list candidate service IDs, then serviceDetails for per-stop times; handles 429 rate-limiting with exponential back-off
  • BigQuery: stores journeys and service candidates; station configuration lives in a stations table so the code is generic
  • FastAPI on Cloud Run: REST API with Firebase Auth — only my account can access real data
  • Firebase Hosting: single-page app; /api/* rewrites proxied to Cloud Run

Key features

  • Automatically surfaces delay-repay opportunities from booking emails without any manual input
  • Matches each journey against multiple candidate services and lets me pick the correct one
  • Tracks claim status (pending → submitted → settled) per journey leg
  • Supports both advance (fixed-time) and flexible return tickets, with different time-window logic for each
  • Station configuration stored in BigQuery — no hardcoded routes in the source code

Stack

LayerTechnology
BackendPython, FastAPI
Data storeGoogle BigQuery
Train dataHSP API (Rail Data Marketplace)
EmailGmail API (OAuth2)
HostingFirebase Hosting + Cloud Run
AuthFirebase Authentication (Google sign-in)
InfraGoogle Cloud (Secret Manager, Artifact Registry)
Package managementuv