
Last fall a trip that should have been simple turned into twenty browser tabs and a spreadsheet. Four nights: fly to Denver, drive toward Albuquerque for a Saturday event, drive back. Every leg had a "deal" attached, and by tab fifteen I had a nagging feeling that half of them were not deals at all. The problem was not finding prices. It was that I could not compare any two of them on the same basis. A cheap flight that lands near midnight, a room rate quoted per night, a rental total that quietly folds in cleaning and service fees. Each looked fine alone. Lined up honestly, half of them lost.
Here is the part that took me too long to see. The prices in front of you are not on the same scale, so the cheapest number wins by default even when it is the worse plan. A nonstop near a thousand dollars sits next to a one stop saver that is cheaper on paper but costs you the evening. A hotel rate is per room for the party; a whole home rental total already has fees baked in, which makes a one night stay look expensive per night and a five night stay look cheap. If you do not label the basis, you are not comparing, you are guessing. The fix is dull and it works: pick the unit first, total for the stay with per night shown for context, and make every option state it before it gets to sit in the table.
For each night I actually needed, I pull the properties near the anchor with their live nightly rate, their total for the stay, the rating, and the review count, and I rank on those. Not on star class, which is noise. For the Denver nights that came back as about twenty properties near the airport, cheapest a Garner hotel at 113 dollars. The important part is what it does not do: it reads and ranks rooms, it does not book them. It is the raw price data, not a reservation. That distinction is the whole reason it is useful for planning, because I can line every option up myself instead of trusting a booking funnel to rank them for me.
The most useful failure in the whole workflow is a night that comes back empty. A blank rate does not mean free, it means sold out, and if you read the blank as "nothing there" you will build a plan around a room that does not exist. On the Denver trip the small town nearest the event had sold out, so those middle nights moved to Albuquerque and the drive got a little longer. An empty cell is a prompt to widen the search to a bigger city nearby, not a hole to skip past. Treat the gap as a claim to check, not a fact to accept.
Flights get the same treatment. Pull the round trip fares, and use the read that tells you whether the current fare is low, typical, or high, which is the difference between a list of numbers and an actual decision. Then assemble the thing I wanted all along: fly in, drive, the anchor day, drive back, fly home, every night priced, with a per person and a total cost. One table you can paste into an email and book from. If you would rather not run each step by hand, I packaged the workflow as open Claude skills you install with one line: npx skills add johnisanerd/claude-skill-plan-a-trip, with a companion for hotel stays.
The two sources are public data: live fares from Google Flights and live room rates from the Google Hotels API. I also wrote the step by step technical version, with the code, on Dev.to.
A few questions I keep getting:
The whole-trip comparison is more compelling than another travel search tool, especially because you’re solving for apples-to-apples cost. Have other travelers used the workflow on real trips yet, and did it change what they actually booked versus the options they would have chosen normally?