United MileagePlus award flight search CLI
Project description
Searchaero
Award flight search for Claude Code. Scrapes United MileagePlus award pricing, stores results in a local SQLite database, and exposes a /flights skill that teaches Claude the full workflow — scrape, handle MFA, query, alert, watch.
Scope
- Airline: United MileagePlus only
- Routes: Any origin/destination United serves
- Coverage: Full 337-day booking window, economy/business/first
- Not supported: Partner awards, cash fares
Quick start
Open Claude Code and paste this. Claude does the rest.
Install searchaero: run
uv tool install searchaeroto install the CLI, then runsearchaero setupto configure credentials and verify Playwright. After setup, ask me to find cheap flights.
Requirements: Claude Code, Python 3.13+, uv
That's it. The /flights skill ships with this repo — when you clone it, Claude already knows how to use searchaero.
Manual install (without Claude)
1. Install
uv tool install searchaero
Why uv? One dependency (
bezier) doesn't ship Python 3.13 wheels yet.uvhandles the source build automatically; regularpipfails without workarounds.
Or install from source:
git clone https://github.com/JadedOut/searchaero.git
cd searchaero
uv tool install .
2. Set up credentials
searchaero setup
Creates the database, checks Playwright, and prompts for your MileagePlus number and password. Just your MP number and password — no API keys needed. If all three checks show green, you're ready.
Heads up: United requires verification on your first login. When you trigger your first scrape, you'll be prompted for a code. This is a one-time step per browser session.
3. Ask Claude
In Claude Code, just ask:
What's the cheapest flight from Toronto to LA next month?
Or invoke the skill directly with /flights.
See it work
You: What's the cheapest business class from Toronto to London next month?
Claude: Checking cached data... no results for YYZ-LHR.
Starting a fresh scrape — this takes about 2 minutes.
[MFA code requested — enter the 6-digit code from your phone]
┌──────────┬──────────┬─────────┬──────────┐
│ Date │ Cabin │ Miles │ Stops │
├──────────┼──────────┼─────────┼──────────┤
│ Jul 12 │ Business │ 55,000 │ Nonstop │
│ Jul 15 │ Business │ 45,000 │ 1 stop │
│ Jul 19 │ Business │ 60,000 │ Nonstop │
└──────────┴──────────┴─────────┴──────────┘
You: Show me the price trend as a graph.
Claude: YYZ -> LHR | Business | Price Trend
80,000 ┤
75,000 ┤ ╭╮
70,000 ┤ ╭──╯│
65,000 ┤ ╭╯ ╰╮
60,000 ┼──╮ ╭╯ ╰╮
55,000 ┤ ╰╮╭╯ │
50,000 ┤ ╰╯ ╰╮
45,000 ┤ ╰──
Jul 01 Jul 15 Jul 29
Min: 45,000 mi Avg: 59,167 mi 8 dates
You: Set up a watch — notify me if business drops under 50K.
Claude: [runs searchaero watch add YYZ LHR --max-miles 50000 --cabin business]
Done. I'll check every 12 hours and notify you via ntfy.
You ask a question. The agent checks cached data, scrapes if needed, handles MFA, and presents the answer. One skill, end to end.
Example prompts:
- "Scrape fresh data for cheapest business class from New York to London in July"
- "Show me a price chart for YYZ to LAX for the next year"
- "Find deals under 30K miles from any airport I've scraped"
- "Set up a watchlist for paris to sanfran, business class, under 70K miles"
CLI reference
The agent uses these commands under the hood. You can also run them directly:
| Action | Command |
|---|---|
| Check cache | searchaero query ORIG DEST --json |
| Show table | searchaero query ORIG DEST |
| Show graph | searchaero query ORIG DEST --graph |
| Show summary | searchaero query ORIG DEST --summary |
| Find deals | searchaero deals --json |
| DB status | searchaero status --json |
| Scrape fresh | searchaero search ORIG DEST --mfa-file --mfa-method email |
| Add alert | searchaero alert add ORIG DEST --max-miles N |
| Check alerts | searchaero alert check --json |
| Add watch | searchaero watch add ORIG DEST --max-miles N |
| Check watches | searchaero watch check --json |
| Diagnostics | searchaero doctor |
How scraping works
- Seataero opens a Chromium browser via Playwright and logs into united.com with your MP number
- United may send a verification code — the agent handles this automatically (email via Gmail) or asks you (SMS)
- Once logged in, searchaero scrapes the award calendar API (one request returns ~30 days of pricing)
- Results are stored in SQLite. Subsequent queries are instant (no scraping needed)
- The browser session stays warm between scrapes — MFA is typically only needed once per session
Rate limiting: Seataero adds delays between requests to avoid triggering United's bot detection. For recurring scrapes, use a minimum interval of 10 minutes between runs.
Troubleshooting
| Problem | Cause | Fix |
|---|---|---|
BROWSER CRASH detected |
United's Akamai bot detection blocked your IP | Wait 10 minutes and retry, or use --proxy |
| MFA code times out | The 5-minute code window expired | Re-run the search — United will send a new code |
No availability found |
No scraped data for this route yet | Ask your agent to scrape it, or run searchaero search ORIGIN DEST |
| Database errors | Corrupted SQLite file | Delete ~/.searchaero/data.db and run searchaero setup |
| Repeated Akamai blocks | Your home IP is flagged | Wait 10–15 minutes, or use --proxy. See searchaero help proxy |
Run searchaero doctor for a comprehensive diagnostic check.
More documentation
- Getting Started — full walkthrough from install to first query
- CLI Reference — every command and flag
- FAQ — common questions and troubleshooting
- Push Notifications — set up ntfy for phone alerts
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file searchaero-0.2.0.tar.gz.
File metadata
- Download URL: searchaero-0.2.0.tar.gz
- Upload date:
- Size: 68.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
03501d7a1d3b45b31690ee7eaf1cf7a8bc3af2499457ae82688a23242597a6e2
|
|
| MD5 |
db7ffd979fa6253b1a5e5927e7ce9e15
|
|
| BLAKE2b-256 |
db720c49f88982f8a24a41539937e85eb04f97737f0ac8885330a0534b49cb01
|
File details
Details for the file searchaero-0.2.0-py3-none-any.whl.
File metadata
- Download URL: searchaero-0.2.0-py3-none-any.whl
- Upload date:
- Size: 71.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f3b383b5e8254aa5669ba1c897877e3c5796ad92c865f947b168632de307bd68
|
|
| MD5 |
23b9118228e496a57e7233e086cc9a22
|
|
| BLAKE2b-256 |
0ef287c7d056d1c1efbb3810221d83879f864a279148d4d41edc3d006ea314bc
|