Automated flight price tracker with buy/wait AI signals, email alerts, and a beautiful mission-control dashboard.
- Register at https://developers.amadeus.com/ (free)
- Create a new app → copy your Client ID and s Secret
- The test environment returns synthetic (but structurally correct) data — great for development
- Switch to production with the same keys for real live prices
cp .env.example .env
# Edit .env and paste your Amadeus credentialspython -m venv venv
source venv/Scripts/activate # Windows: venv\Scripts\activate
pip install -r requirements.txtuvicorn main:app --host 127.0.0.1 --port 8000 --reloadOpen http://localhost:8000 in your browser.
skysync/
├── main.py # FastAPI app — routes, startup, shutdown
├── models.py # SQLAlchemy ORM models (Tracker, PriceSnapshot)
├── database.py # SQLite engine + session factory
├── amadeus_client.py # Amadeus API wrapper + window scanning logic
├── analytics.py # Buy/Wait signal (numpy linear regression)
├── scheduler.py # APScheduler background scan jobs
├── notifications.py # Desktop (plyer) + email (SMTP) alerts
├── requirements.txt
├── .env.example
└── templates/
└── index.html # Single-page dashboard (Chart.js + vanilla JS)
- Create a Tracker — Enter origin/destination (IATA codes), trip duration, and the date window you're willing to travel.
- Initial Scan — Fires immediately in a background thread. SkySync queries the Amadeus API across weekly date samples in your window, finding the current cheapest round-trip.
- Periodic Scans — APScheduler fires every N hours (you choose). Each scan stores a
PriceSnapshotin SQLite. - Buy Signal — After 3+ data points, a numpy linear regression on the recent price window classifies the trend as UP/DOWN/FLAT and issues a BUY/WAIT/NEUTRAL recommendation with a confidence score.
- Alerts — If the price drops below your target, a desktop notification fires (via
plyer) and an email is sent if configured.
| Method | Path | Description |
|---|---|---|
| GET | / |
Dashboard UI |
| GET | /api/trackers |
List all active trackers |
| POST | /api/trackers |
Create a new tracker |
| DELETE | /api/trackers/{id} |
Deactivate a tracker |
| POST | /api/trackers/{id}/scan |
Trigger an immediate scan |
| GET | /api/trackers/{id}/history |
Price history + buy signal |
| GET | /api/stats |
Dashboard aggregate stats |
Set these in .env:
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=you@gmail.com
SMTP_PASS=your_app_password # use a Gmail App Password, not your account passwordIn .env, change:
AMADEUS_ENV=productionThe same free Amadeus key works in production with a generous rate limit (1 req/100ms, 1000 calls/month on the free tier).
Optional pacing controls in .env:
AMADEUS_MIN_REQUEST_INTERVAL_SECONDS=0.35
AMADEUS_MAX_RETRIES=2
AMADEUS_RETRY_BASE_DELAY_SECONDS=1.5These settings make SkySync space requests out across concurrent scans and back off when Amadeus responds with 429.
- IATA Codes: TLV (Tel Aviv), NRT (Tokyo Narita), LHR (London Heathrow), JFK, LAX, etc.
- Date Windows: Keep windows under 3 months to get meaningful scan samples.
- Scan Interval: 6 hours is a good default. Prices rarely change faster than this.
- Rate Limits: The scanner uses weekly steps across your window. A 3-month window = ~12 API calls per scan, well within free-tier limits.