General aviation customs and immigration form generator. Enter your flight details, crew, and passengers — get back pre-filled official forms ready for submission.
FlightForms has three components:
- API server (FastAPI) — stateless form generation service that accepts flight data and returns filled PDF, DOCX, or XLSX forms
- iOS/macOS app (SwiftUI) — manage crew, passengers, aircraft, and trips with CloudKit sync across devices
- CLI — batch form generation from the command line
PII is never stored server-side. Passenger and crew data exists only in memory during form generation.
| Region | Form | Format |
|---|---|---|
| LSGS (Sion, Switzerland) | Immigration | |
| LF* (France) | Customs declaration (Préavis Douane) | |
| LFQA + 10 airports (CODT Metz) | Customs declaration | |
| EG* (United Kingdom) | General Aviation Report (GAR) | XLSX |
| 50+ European airports | MyHandling FBO Request | XLSX |
| All other airports | General Declaration (3 variants) |
New forms are added by dropping a template file and a JSON mapping into src/flightforms/templates/ and src/flightforms/mappings/ — no code changes required.
Base URL: https://forms.flyfun.aero
| Endpoint | Method | Description |
|---|---|---|
/airports |
GET | List airports with available forms |
/airports/{icao} |
GET | Form details for an airport (required fields, max crew/pax) |
/generate |
POST | Generate a filled form (returns the file) |
/validate |
POST | Dry-run validation without generating |
/email-text |
POST | Localized email subject and body for a form |
/health |
GET | Health check |
- Python 3.11+
- (Optional) Docker for containerized deployment
cp .env.sample .env
# Edit .env with your settings (ENVIRONMENT=development for SQLite)
pip install -e .
uvicorn flightforms.api.app:create_app --factory --port 8030 --reloaddocker compose up --buildThe service runs on port 8030 behind a Caddy reverse proxy in production.
# List available airports and forms
flightforms airports
# Generate a single form
flightforms generate --origin LFPB --destination LSGS \
--registration HB-ABC --aircraft-type PA28 \
--crew crew.csv --passengers pax.csv \
--date 2026-03-15 --time 14:30
# Generate forms for a multi-leg trip
flightforms trip --trip trip.json --people people.csv
# Preview all forms with self-describing dummy data
flightforms preview --output-dir previews/The SwiftUI app lives in app/flyfun-forms/ and requires:
Features include passport MRZ scanning, multi-document support per person, timezone-aware time entry, and CSV import for bulk data entry.
src/flightforms/
├── api/ # FastAPI endpoints and Pydantic models
├── fillers/ # PDF, DOCX, XLSX form filler modules
├── templates/ # Blank form template files
├── mappings/ # JSON field mappings per airport/form
├── registry.py # Discovers and loads form configurations
└── cli.py # Command-line interface
app/flyfun-forms/ # iOS/macOS SwiftUI application
The form system follows a template + mapping + filler pattern:
- Registry loads all JSON mappings at startup
- Resolver matches an ICAO code to available forms (exact match → prefix match → default)
- Filler reads the template, maps canonical field names to template-specific fields, and writes the filled file
This makes the system extensible — adding a new airport or country requires only a template file and a JSON mapping.
FlightForms is designed with privacy as a core principle. See PRIVACY.md for full details.
This project is licensed under the MIT License — see LICENSE for details.