PPS is a flight planning and EFB system widely used by European operators. When you want to look at what it actually contains — flight schedules, OFPs, fuel figures, briefing packages — you have to talk SOAP. That means XML envelopes, WSDL-defined operations, and session tokens that expire when you least expect it.

I got tired of constructing those requests by hand every time I wanted to inspect something. So I wrote pps-api: a Rust service that sits in front of PPS and exposes a plain REST interface. I can now query flights, fetch OFPs, download EFF packages, and pull NOTAMs with a simple HTTP call instead of wrestling with XML.

Over time I added a PostgreSQL mirror so the data persists between sessions, a state machine that tracks each flight through its operational phases, and analytics views that PPS itself doesn't provide — fuel burn by route, delay patterns, on-time statistics. There's also a terminal UI for when I want to browse flights quickly from the command line.

None of this is a product. It's a personal analysis workbench that happens to be well-structured.

Technical architecture and endpoints

Layers

The service has two distinct API layers sitting on top of a PostgreSQL database:

LayerPath prefixPurpose
PPS Proxy/v1/pps/*Translates REST calls into live SOAP requests
Canonical Hub/v1/flights/*Persistent flight records with full lifecycle tracking
Analytics/v1/analytics/*Aggregated fuel, delay, and route statistics

A background sync task polls PPS every 10 minutes, keeps the local mirror fresh, and fires webhook notifications on phase transitions.

Flight Phase Machine

Every canonical flight moves through a defined lifecycle driven by submitted operational data:

scheduled → pre_flight → airborne → landed → completed
  • scheduled — flight exists in PPS, no crew data yet
  • pre_flight — W&B, PAX count, and fuel uplift submitted
  • airborne — AOBT (off-block time) recorded
  • landed — ALDT (landing time) recorded
  • completed — AIBT (in-block time) submitted, or 24 h automatic timeout

Key Endpoints

PPS Proxy

POST   /v1/auth/login
GET    /v1/pps/flights/by-std?from=&to=   # list by departure window
GET    /v1/pps/flights/{id}               # full OFP — route, fuel, weights, crew
GET    /v1/pps/flights/{id}/atc           # ICAO 4444 ATC flight plan
GET    /v1/pps/flights/{id}/eff           # EFF briefing package download
POST   /v1/pps/flights/{id}/refresh       # re-fetch OFP from dispatcher
POST   /v1/pps/flights/batch              # up to 20 OFPs concurrently
GET    /v1/pps/airports/notams            # active NOTAMs by ICAO code

Canonical Hub

GET    /v1/flights                        # paginated, filterable by date/route/phase
GET    /v1/flights/{uuid}                 # full record with ARINC 633-5 pre-flight data
PUT    /v1/flights/{uuid}/pre-flight      # submit W&B, PAX, fuel uplift
PUT    /v1/flights/{uuid}/post-flight     # submit block times, fuel actuals, delays
GET    /v1/flights/{uuid}/phase           # lightweight phase poll
GET    /v1/flights/{uuid}/route           # waypoints + GeoJSON for map clients

Analytics

GET    /v1/analytics/fuel                 # burn aggregates by route and aircraft type
GET    /v1/analytics/delays               # IATA delay codes + on-time performance
GET    /v1/analytics/routes               # per-route stats: count, fuel, delays, distance

Tech Stack

ComponentTechnology
Web serverAxum 0.8 + Tokio async runtime
DatabasePostgreSQL 16 via SQLx (parameterised queries, no ORM)
SOAP clientreqwest + quick-xml
AuthPer-tenant SHA-256 hashed API keys
API docsutoipa + Swagger UI at /swagger-ui/
Analytics UIGrafana 13 with 11 pre-built dashboards
Terminal UIratatui + Clap subcommands
Web clientVite + React + TypeScript, deck.gl route visualisation

Companion Tools

  • pps-cli — terminal UI for browsing flights, submitting post-flight data, and viewing analytics from the command line
  • client-app — React web client with a deck.gl interactive route map and flight-level profile chart
  • Grafana dashboards — 11 panels covering fuel burn, delay codes, on-time performance, and per-route statistics
← Back