Metadata-Version: 2.4
Name: travelmaxx
Version: 0.3.0
Summary: Search award flights across 14 mileage programs from your terminal
License-Expression: MIT
Project-URL: Homepage, https://travelmaxx.app
Project-URL: Documentation, https://travelmaxx.app/cli/docs
Keywords: awards,flights,miles,points,travel
Classifier: Environment :: Console
Classifier: Intended Audience :: End Users/Desktop
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Utilities
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: httpx>=0.27
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: respx>=0.22; extra == "dev"

# travelmaxx

Search award flights across 28 airline mileage programs from your terminal,
powered by [TravelMaxx](https://travelmaxx.app).

```sh
curl -fsSL https://travelmaxx.app/cli | sh
travelmaxx login
travelmaxx search SFO NRT --date 2026-10-05 --programs ALASKA
travelmaxx book start SFO NRT --date 2026-10-05 --flight AS1042
```

Everything the TravelMaxx chat agent can do, the CLI and the MCP server can do
too — searching, your profile and points, trips, live airline-account reads,
and booking award tickets on the airline's own site.

## Install

Any of:

```sh
curl -fsSL https://travelmaxx.app/cli | sh        # auto-detects uv/pipx/pip
uv tool install travelmaxx
pipx install travelmaxx
brew install travelmaxx/travelmaxx/travelmaxx     # once the tap is live
```

Requires Python 3.10+ (macOS or Linux), an active TravelMaxx subscription, and
Roame credentials linked at <https://travelmaxx.app/dashboard/settings>.

## Update

```sh
travelmaxx update           # upgrade to the latest release
travelmaxx update --check   # report what's available without installing
travelmaxx update --json    # {current, latest, update_available, install_method, command}
```

`update` reads PyPI directly (it works signed out) and hands the upgrade to
whichever tool owns this install — `pipx upgrade`, `uv tool upgrade`,
`brew upgrade`, or `pip install --upgrade`. In a git checkout it refuses and
tells you to use git.

Once a day, before the command runs, the CLI checks whether your version is
current and prints one line to **stderr** if it isn't:

```
travelmaxx 0.2.1 is available (you have 0.2.0) — run `travelmaxx update` for the newest version. View docs.
```

`docs` links to https://travelmaxx.app/cli/docs. It never goes to stdout, so
`--json` stays parseable, and it is skipped when
stderr isn't a TTY, when `CI` is set, or when `TRAVELMAXX_NO_UPDATE_CHECK=1` —
so agents driving the CLI never see it.

## Sign in

```sh
travelmaxx login              # opens your browser; click Approve
travelmaxx login --no-browser # headless/SSH: 6-digit code at travelmaxx.app/activate
travelmaxx whoami
travelmaxx logout
```

Tokens are stored in `~/.config/travelmaxx/credentials.json` (chmod 600) and
refresh automatically for 30 days. Your Roame credentials never touch this
machine — searches run through the TravelMaxx server.

## Search

```sh
# Single date (always pass --programs when you know them: 40-50x faster)
travelmaxx search SFO NRT --date 2026-10-05 --programs ALASKA

# Business class, 2 passengers, flexible ±2 days
travelmaxx search SFO CDG --date 2026-09-12 --class BUSINESS \
  --programs ALASKA,UNITED --pax 2 --days-around 2

# A whole month in parallel, with a live progress bar
travelmaxx search SFO NRT --date-range november --programs ALASKA

# Explicit range / year / "next year"
travelmaxx search SFO HEL --date-range 2026-09-12:2026-10-18 --programs ALASKA
```

Options: `--sort points|duration`, `--limit N`, `--max-wait SECONDS` (5–120;
results are marked `partial` if the search returns early), `--min-results N`,
`--max-workers N` (range searches), `--json`, `--output-file FILE`.

### Programs

Pass canonical program codes to `--programs` (common aliases like `AVIANCA` →
`LIFEMILES` or `BA` → `BRITISH_AIRWAYS` are normalized automatically):

- **oneworld**: `ALASKA, AMERICAN, BRITISH_AIRWAYS, CATHAY, FINNAIR, IBERIA,
  QANTAS, QATAR`
- **Star Alliance**: `AEROPLAN, ANA, LIFEMILES, LUFTHANSA, SINGAPORE, TAP,
  TURKISH, UNITED`
- **SkyTeam**: `CLUB_PREMIER, DELTA, FLYING_BLUE, SAS, VIRGIN_ATLANTIC`
- **Non-alliance**: `AER_LINGUS, EMIRATES, ETIHAD, GOL, JETBLUE, SPIRIT,
  VIRGIN_AUSTRALIA`

Fastest programs: `ALASKA, UNITED, DELTA, JETBLUE, LIFEMILES` (1–5 s).

An alliance member program's awards often include flights operated by other
airlines in that alliance — searching `AMERICAN` can surface JAL, Qantas, or
British Airways metal. To search a whole alliance, pass the shortcut and it
expands to the member programs:

```sh
travelmaxx search SFO NRT --date 2026-10-05 --programs ONEWORLD
travelmaxx search JFK CDG --date-range november --programs SKYTEAM
# Shortcuts: ONEWORLD, STAR_ALLIANCE, SKYTEAM
```

## SkyView (cached bird's-eye search)

One instant read of Roame's cached fare database — no polling, and origins/
destinations can be airports (`SFO`), metro city codes (`NYC`, `TYO`, `LON`),
or continents (`Europe` / `EU`), with windows up to 60 days:

```sh
# Airport to airport across two weeks
travelmaxx skyview SFO JFK --start 2026-08-01 --end 2026-08-14

# Where in Europe can I go from NYC in business, all of August?
travelmaxx skyview NYC Europe --from-type CITY --to-type CONTINENT \
  --start 2026-08-01 --end 2026-08-30 --class BUSINESS

# All Tokyo-area airports for a month
travelmaxx skyview SFO TYO --to-type CITY --start 2026-09-01 --end 2026-09-30
```

SkyView results are **cached observations, not live inventory**: every fare
carries an `updated_at` timestamp and the response includes
`newest_updated_at` / `oldest_updated_at`, so you always know how old the
data is ("as of 3h ago"). Verify with `travelmaxx search` before booking.
Options: `--from-type/--to-type AIRPORT|CITY|CONTINENT`, `--programs`,
`--pax`, `--max-stops N`, `--sort`, `--limit`, `--json`, `--output-file`.

## Your profile & points

```sh
travelmaxx profile                                     # cards, balances, status, saved flights
travelmaxx profile update "I have Alaska MVP Gold and a Sapphire Reserve"
travelmaxx profile points "Alaska Mileage Plan" --set 142500
travelmaxx profile points skymiles --delta -60000      # logs the redemption as a transaction
travelmaxx profile airports SFO SJC                    # --add / --remove to amend
travelmaxx profile holder "Mom" --exclude              # keep her points out of your totals
```

Any balance change through `profile points` is recorded as a points
transaction, so `--delta` is how you log earnings and redemptions.

## Airline accounts (Alaska, Delta)

Read the airline's own account pages with the credentials you've linked at
<https://travelmaxx.app/dashboard/settings>:

```sh
travelmaxx account alaska              # cached snapshot if it's under 24h old
travelmaxx account alaska --fresh      # live sign-in; prompts for the code Alaska texts you
travelmaxx account alaska --json       # the whole snapshot, verbatim
travelmaxx account alaska --section certificates
```

You get miles balance, elite tier and status points, lifetime miles (Million
Miler progress), discount and companion-fare codes, vouchers, upgrade
certificates, lounge membership, wallet balance and transactions, recent
mileage activity, rolling 12-month totals, and upcoming trips. Sections:
`summary`, `status`, `certificates`, `activity`, `wallet`, `trips`.

**The texted code.** A fresh sign-in pauses for Alaska's verification code.
At a terminal you're prompted for it inline and the command finishes on its
own. If you're driving the CLI from a script or an AI agent (no TTY, or
`--json`), the command exits `2` and tells you to continue with the code:

```sh
travelmaxx account alaska --fresh --otp 123456
```

An agent should relay that as "read me the code Alaska just texted you" — the
code is never echoed, logged, or stored by the CLI.

Delta has no server-side sign-in; it reads through the paired Delta companion
Chrome extension:

```sh
travelmaxx account companion pair       # get a pairing code for the extension
travelmaxx account companion            # status
travelmaxx account delta
```

## Booking

```sh
travelmaxx book start SEA SFO --date 2026-12-01 --flight AS1042 \
  --cabin business --expected-miles 25000
travelmaxx book status                  # what the session is waiting on
travelmaxx book confirm flight
travelmaxx book provide 2fa_code        # prompted without echo
travelmaxx book confirm passenger
travelmaxx book provide cvv
travelmaxx book confirm purchase        # final approval — Alaska buys here
travelmaxx book cancel
```

The session stops at every step and tells you the exact next command. Pass
`--expected-miles` / `--expected-taxes` from your search and it will stop
instead of buying a re-priced award. `--dry-run` walks the whole flow except
the purchase click.

- **Alaska** completes the purchase, but only after `book confirm purchase`.
- **Delta** goes through the companion extension and stops at Delta's final
  review page — it never clicks buy. You finish in your own browser.
- **One booking at a time.** Starting a second one returns "booking in
  progress"; cancel or finish the open one first. Searches aren't limited that
  way — run as many `travelmaxx search` commands in parallel as you like,
  including while a booking is open.

## Trips & booked flights

```sh
travelmaxx trips create "Tokyo spring 2027"
travelmaxx trips add-leg <trip-id> Outbound --origin SFO --destination NRT
travelmaxx trips get <trip-id>
travelmaxx trips select <trip-id> <option-id>
travelmaxx trips share <trip-id>

travelmaxx booked save AS1042 --date 2026-12-01 --origin SEA --destination SFO \
  --confirmation ABCDEF --points 25000
travelmaxx booked list
```

## Fares, status & research

```sh
travelmaxx fares alaska SFO LAX --date 2026-09-12       # Alaska award fares
travelmaxx fares jetblue JFK LAX --date 2026-09-12      # JetBlue TrueBlue fares
travelmaxx calendar alaska SFO LAX --month 2026-09      # cheapest day per month
travelmaxx status match ALASKA --from "Delta Platinum"
travelmaxx status image ALASKA "MVP Gold"
travelmaxx web-search "alaska mileage plan award chart change"
```

The two Alaska fare commands run the request **from your own machine** by
default: travelmaxx.app hands back a short-lived signed list of alaskaair.com
URLs, your CLI fetches them over your own connection, and the server turns the
responses into fares. That keeps your lookups out of the shared server queue,
so they don't wait behind other users. Pass `--fetch server` to have
travelmaxx.app fetch instead — slower under load, but it can answer from a
recent cached result and works from a network that can't reach alaskaair.com.

```sh
travelmaxx fares alaska SFO LAX --date 2026-09-12 --fetch server
```

Either way the CLI reports which route was used (`Fetched from your machine.`)
and sends travelmaxx.app only the raw airline responses plus the usual usage
counts — never account data, credentials, or codes.

## Alerts & discovery

```sh
travelmaxx alerts create SFO NRT --class BUSINESS --max-points 75000
travelmaxx alerts list
travelmaxx alerts delete <uuid>
travelmaxx discover --limit 10
```

## JSON output

`--json` prints the full API response. Single-date searches return
`{"fares": [...], "percent_completed": 100, "partial": false}`; job-based
searches return `{"status", "percent", "fares_count", "fares", ...}`.
Each fare:

```json
{
  "departure_date": "2026-10-05",
  "origin": "SFO", "destination": "NRT",
  "mileage_program": "ALASKA",
  "award_points": 75000, "surcharge_usd": 18.1,
  "num_stops": 0, "duration_minutes": 630,
  "cabin_classes": ["BUSINESS"], "operating_airlines": ["JL"],
  "equipment_types": ["77W"], "available_seats": 2, "roame_score": 1684
}
```

## Configuration

| Env var | Purpose |
|---|---|
| `TRAVELMAXX_API_URL` | Point at a different server (also `--server URL`) |
| `XDG_CONFIG_HOME` | Relocate the config dir (default `~/.config/travelmaxx`) |

## Rate limits

Searches are budgeted per account (~10 search starts/minute, staggered, with
an hourly ceiling), and the API additionally rate-limits each client IP.
Scripts that hammer the API will see `429` with a `Retry-After` header —
back off and retry. Separately, **one booking may be open at a time**; that
limit is per user and does not restrict parallel searches.

## Development

```sh
cd cli
python3 -m venv .venv && .venv/bin/pip install -e ".[dev]"
.venv/bin/pytest
.venv/bin/travelmaxx --server http://localhost:8000 login
```

Every command above has an equivalent MCP tool for AI assistants — the REST
routes and the MCP tools wrap the same handlers, so the two surfaces can't
drift apart. See <https://travelmaxx.app/mcp/docs>.

Design doc: `../CLI.md`. Releases: tag `cli-vX.Y.Z` (see
`.github/workflows/release-cli.yml`).
