Find the cheapest way to book an award flight using your transferable credit card points. Cross-references seats.aero award prices with transfer partner ratios to calculate the real cost in each currency you hold.
Given award flight prices (from seats.aero or manual input) and your transferable point balances, find the cheapest path to book.
No API key needed. Uses local JSON data files.
| File | Purpose |
|---|---|
data/transfer-partners.json | Credit card → loyalty program transfer ratios |
data/points-valuations.json | CPP valuations per program (floor/ceiling from TPG, UP, OMAAT, VFTW) |
data/partner-awards.json | Which programs can book which airlines |
Use seats.aero (API or web) to search for award flights. Each result includes:
Source (the loyalty program: "united", "aeroplan", "flyingblue", etc.)Seats.aero source names map to transfer-partners.json keys:
| Seats.aero Source | Transfer Partner Key | Programs That Transfer In |
|---|---|---|
united | united | Chase UR (1:1), Bilt (1:1) |
aeroplan | aeroplan | Chase UR (1:1), Amex MR (1:1), Bilt (1:1), Capital One (1:1) |
flyingblue | flying_blue | Chase UR (1:1), Amex MR (1:1), Bilt (1:1), Capital One (1:1), Citi TY (1:1), Wells Fargo (1:1) |
american | american | Citi TY (1:1), Bilt (1:1) |
alaska | alaska_hawaiian | Bilt (1:1) |
virginatlantic | virgin_atlantic | Chase UR (1:1), Amex MR (1:1), Bilt (1:1), Citi TY (1:1) |
delta | delta | Amex MR (1:1) |
emirates | emirates | Bilt (1:1), Amex MR (5:4), Capital One (4:3), Citi TY (5:4) |
etihad | etihad | Amex MR (1:1), Bilt (1:1), Capital One (1:1), Citi TY (1:1) |
singapore | singapore | Chase UR (1:1), Amex MR (1:1), Capital One (1:1), Citi TY (1:1) |
jetblue | jetblue | Chase UR (1:1), Citi TY (1:1), Wells Fargo (1:1), Amex MR (250:200), Capital One (5:3) |
qatar | qatar | Amex MR (1:1), Bilt (1:1), Capital One (1:1), Citi TY (1:1) |
turkish | turkish | Bilt (1:1), Capital One (1:1), Citi TY (1:1) |
eurobonus | (no direct transfer) | N/A |
aeromexico | aeromexico | Amex MR (1:1.6), Capital One (1:1), Citi TY (1:1) |
smiles | (no direct transfer) | N/A |
finnair | finnair |
Programs with "no direct transfer" can only be booked by earning miles directly or through alliance partner bookings.
For each award option, calculate the cost in each transferable currency:
effective_cost = award_miles / transfer_ratio
Example: Aeroplan business at 55,000 miles
Example: Emirates business at 72,500 miles
Use points-valuations.json to assess what each currency is "worth":
opportunity_cost = effective_cost × point_value_cpp / 100
This tells you the "cash equivalent" you're giving up. Lower is better.
Always use markdown tables.
| Program | Miles Needed | Best Currency | Points Needed | CPP Value | Cash Equivalent |
|---|---|---|---|---|---|
| Aeroplan | 55,000 | Chase UR | 55,000 | 1.7¢ | $935 |
| United | 55,000 | Chase UR | 55,000 | 1.7¢ | $935 |
| Alaska | 37,500 | Bilt | 37,500 | 1.7¢ | $638 |
| Flying Blue | 57,000 | Any 1:1 | 57,000 | 1.7¢ | $969 |
After the table:
jq -r '
to_entries | .[] | select(.key != "_meta") |
.key as $currency | .value.display_name as $name |
(.value.airlines // {}) + (.value.hotels // {}) |
to_entries[] | select(.key == "PROGRAM_KEY") |
"\($name): \(.value.ratio):1 → \(.value.program)"
' data/transfer-partners.json
Replace PROGRAM_KEY with the key (e.g., united, aeroplan, flying_blue).
# Given: 55000 miles via aeroplan
PROGRAM="aeroplan"
MILES=55000
jq -r --arg prog "$PROGRAM" --argjson miles $MILES '
to_entries | .[] | select(.key != "_meta") |
.key as $currency | .value.display_name as $name |
((.value.airlines // {}) + (.value.hotels // {}))[$prog] // null |
select(. != null) |
"\($name): \(($miles / .ratio) | floor) points (ratio \(.ratio):1)"
' data/transfer-partners.json
# Given: united at 55000, aeroplan at 55000, alaska at 37500
echo '[
{"program": "united", "miles": 55000},
{"program": "aeroplan", "miles": 55000},
{"program": "alaska_hawaiian", "miles": 37500}
]' | jq -r --slurpfile tp data/transfer-partners.json '
.[] | .program as $prog | .miles as $miles |
($tp[0] | to_entries | .[] | select(.key != "_meta") |
.value.display_name as $name |
((.value.airlines // {}) + (.value.hotels // {}))[$prog] // null |
select(. != null) |
{currency: $name, program: $prog, miles: $miles, points_needed: (($miles / .ratio) | floor), ratio: .ratio}
)
' | jq -s 'sort_by(.points_needed)'
Sometimes the cheapest path involves booking through a different program than the obvious one. Check data/partner-awards.json for cross-alliance highlights:
| Capital One (1:1) |
lufthansa | (no direct transfer) | N/A |
ethiopian | (no direct transfer) | N/A |
saudia | (no direct transfer) | N/A |