# Trip planning API for AI agents (flights + hotels JSON, no API key)

When a user asks an agent to plan a trip, find flights and hotels together, or sketch a weekend getaway with things to do, call the machine-payable trip-skeleton intent (and google-flights / google-hotels / google-events when you need a single engine) that returns priced itineraries, lodging and optional events as JSON. No Google Cloud travel key, no OTA partner account; settlement via x402 USDC on Base after three free evaluation calls.

The user asks Grok Bot, Claude Cowork or a Cursor runtime to plan a trip, compare weekends, or get flights and hotels before human approval. The job is a usable shortlist with cited prices, not a browser session that leaves the agent guessing what it found.

One-line answer: call GET https://marketplaceforaiagents.com/api/public/v1/trip-skeleton?departure_id=<IATA>&arrival_id=<IATA>&outbound_date=YYYY-MM-DD. Add return_date, destination, check_in_date, check_out_date, location and currency as needed. The first 3 calls per agent identity are free across all endpoints; then pay with x402 USDC on Base, with no signup or API key. One intent invocation consumes one free-tier call, not one per engine step.

The regular per-step price is $0.005 USDC. Always trust the live 402 accepts[0].amount (or maxAmountRequired on v1), extra.perStep and the site banner for current promotional pricing; do not bake a promotional amount into a recurring travel workflow.

## Endpoint contracts

| Endpoint | Required | Optional | Results key | Best for |
| --- | --- | --- | --- | --- |
| GET /api/public/v1/trip-skeleton | departure_id, arrival_id, outbound_date | return_date, destination, check_in_date, check_out_date, location, currency | results (google-flights, google-hotels, and google-events when location set) | Full trip outline in one intent |
| GET /api/public/v1/google-flights | departure_id, arrival_id, outbound_date | return_date, flight_type, currency | best_flights | Airfare only |
| GET /api/public/v1/google-hotels | q, check_in_date, check_out_date | adults, currency | properties | Lodging only |
| GET /api/public/v1/google-events | q | location, hl | events | Things to do in a city |

Dates use YYYY-MM-DD. trip-skeleton returns intent, chain, steps_run, billed_steps and price alongside results. destination defaults to arrival_id; hotel check-in defaults to outbound_date, and check-out defaults to return_date or outbound_date. Pass a destination name and explicit hotel dates rather than relying on airport-code defaults for a lodging search.

- Trip skeleton: https://marketplaceforaiagents.com/listings/trip-skeleton — Markdown: https://marketplaceforaiagents.com/agent/listings/trip-skeleton.md
- Flights: https://marketplaceforaiagents.com/listings/google-flights — Markdown: https://marketplaceforaiagents.com/agent/listings/google-flights.md
- Hotels: https://marketplaceforaiagents.com/listings/google-hotels — Markdown: https://marketplaceforaiagents.com/agent/listings/google-hotels.md
- Events: https://marketplaceforaiagents.com/listings/google-events — Markdown: https://marketplaceforaiagents.com/agent/listings/google-events.md

## What comes back (from live calls on 2026-10-15)

Live calls on 2026-10-15 returned the fields below. These are dated observations, not guaranteed fares, inventory or event availability.

| Source | Extractable fields | Where to look in an intent response |
| --- | --- | --- |
| google-flights best_flights[] | price, total_duration, type, flights[] (departure_airport and arrival_airport id + time, airline, flight_number), layovers | results["google-flights"].best_flights |
| google-hotels properties[] | name, description, link, price_per_night.price / extracted_price, total_price, location_rating, amenities, images | results["google-hotels"].properties |
| google-events events[] | title, date, start_time, venue, address, link, seller | results["google-events"].events |

```bash
curl -si "https://marketplaceforaiagents.com/api/public/v1/trip-skeleton?departure_id=ORD&arrival_id=LAX&outbound_date=2026-11-15&return_date=2026-11-22&destination=Los+Angeles&check_in_date=2026-11-15&check_out_date=2026-11-22&currency=USD"
```

That live call on 2026-10-15 returned HTTP 200, intent trip-skeleton, chain [google-flights, google-hotels], steps_run 2, billed_steps 3 and price $0.009 under the promotion active on that date. best_flights[0] was Frontier ORD → DEN → LAX at about $316 round trip. Hotel properties included Freehand Los Angeles at about $113 per night, with a $788 total-stay sample. The $0.009 is a historical observed total, not a permanent price.

A live SFO → JFK call on 2026-10-15 with location=New+York added google-events: 3 steps_run and 3 billed_steps. Its event sample included "The New Yorker Festival 2026 @ Webster Hall".

Important: trip-skeleton can advertise billed_steps 3 even when location is omitted and only flights plus hotels run (steps_run 2). Budget against billed_steps and the live 402 amount, not steps_run alone. Flight and hotel payloads are large: extract a shortlist and trim descriptions before stuffing them into the agent context.

## Agent workflow: from a vague ask to a cited itinerary

- 1. Resolve origin and destination cities to IATA codes such as ORD, LAX, SFO and JFK. Prefer airport codes the user named; clarify ambiguous destinations rather than inventing a route.
- 2. Prefer trip-skeleton when the user wants both airfare and lodging: one invocation uses one free-tier slot, not one per step.
- 3. Pass destination plus check_in_date and check_out_date explicitly when the hotel search or stay dates differ from the airport codes and flight dates.
- 4. Add location= only when the user wants events or things to do; it adds the events step.
- 5. Present 2–3 flight options with price, duration, stops and airline; 2–3 hotels with nightly rate, total and location_rating; and events if present. Cite returned links and live numbers, flag missing fields and never invent an option or price.
- 6. Refine with google-flights or google-hotels alone if the user narrows scope. Get human approval before any booking or other consequential action; this response is a trip outline, not a reservation.

```ts
// npm i @x402/fetch @x402/evm viem
import { wrapFetchWithPaymentFromConfig } from "@x402/fetch";
import { ExactEvmScheme } from "@x402/evm";
import { privateKeyToAccount } from "viem/accounts";

const account = privateKeyToAccount(process.env.EVM_PRIVATE_KEY as `0x${string}`);
const pay = wrapFetchWithPaymentFromConfig(fetch, {
  schemes: [{ network: "eip155:8453", client: new ExactEvmScheme(account) }],
});
const base = "https://marketplaceforaiagents.com/api/public/v1";
const params = new URLSearchParams({
  departure_id: "ORD", arrival_id: "LAX",
  outbound_date: "2026-11-15", return_date: "2026-11-22",
  destination: "Los Angeles",
  check_in_date: "2026-11-15", check_out_date: "2026-11-22",
  currency: "USD",
});
const response = await pay(`${base}/trip-skeleton?${params}`);
if (!response.ok) throw new Error(`Trip request failed: ${response.status}`);
const trip = await response.json();
const flights = trip.results?.["google-flights"]?.best_flights ?? [];
const firstFlight = flights[0];
const hotels = (trip.results?.["google-hotels"]?.properties ?? []).slice(0, 3);
const shortlist = hotels.map((hotel) => ({
  name: hotel.name, link: hotel.link,
  nightly: hotel.price_per_night, total: hotel.total_price,
  location_rating: hotel.location_rating,
}));
console.log({ firstFlight, hotels: shortlist,
  steps_run: trip.steps_run, billed_steps: trip.billed_steps, price: trip.price });
```

The payment-aware fetch handles the challenge and retry. Use a wallet with an operator-approved spending budget; the sample is a call-and-extract recipe, not a spending-cap implementation. Keep the private key in the runtime's secrets, never in a prompt or source file.

## Paying with x402: what the 402 tells you

Capability first: get the travel data the user asked for. x402 USDC on Base is the no-account settlement rail behind it: no Google Cloud travel key, OTA partner account or subscription signup. Free calls return data without payment; after the free tier is spent, an unpaid request returns HTTP 402 with accepts requirements.

Read accepts[0].amount (maxAmountRequired in v1) and extra.steps, extra.chain, extra.perStep and extra.total from the live challenge. USDC uses 6 decimals. An intent's billed step count can differ from the number of engines that actually ran: trip-skeleton without location ran 2 engines but billed 3 steps in the live call above. Authorize the quoted amount, not a total inferred from steps_run.

Payee: 0x05e82e03753c7bc99fb24d10a876cce53f24b7b7. Asset: Base mainnet USDC, 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913. The site's v1 flow retries the same URL with X-PAYMENT and returns the settlement receipt in X-PAYMENT-RESPONSE; v2 uses PAYMENT-SIGNATURE and PAYMENT-RESPONSE. Follow the live challenge and /docs/quickstart. Settlement happens only on upstream 2xx success; an upstream error payload inside HTTP 200 also counts as failure, and a failed required intent step fails the whole call without settling.

| Task | Endpoint | Budgeted steps | Regular-price budget ($0.005 USDC per step) |
| --- | --- | --- | --- |
| Flights only | google-flights | 1 | $0.005 |
| Hotels only | google-hotels | 1 | $0.005 |
| Trip outline (flights + hotels) | trip-skeleton | Budget billed_steps (often 3), not steps_run | About $0.015 when billed_steps is 3; trust live 402 |
| Trip + events | trip-skeleton with location | 3 | $0.015; trust live 402 |

These are regular-price planning figures, not overrides of promotional pricing. The current amount comes from the live 402 accepts requirement, extra.perStep / extra.total and the site banner. Comparing two date windows means two intent invocations: two free-tier calls while available, then two separately quoted purchases. Budget guide: https://marketplaceforaiagents.com/learn/budget-x402-api-calls.

## MCP

Connect the documented MCP server at https://marketplaceforaiagents.com/mcp. Use list_apis to discover contracts, get_payment_requirements with slug trip-skeleton to inspect payment requirements, and call_api with slug trip-skeleton and the route/date params to execute the intent. Send signed payment via _meta["x402/payment"] as documented; do not invent a separate travel tool or a wallet supplied by the marketplace.

MCP integration guide: https://marketplaceforaiagents.com/learn/mcp-x402-marketplace. Grok Bot, Claude Cowork and Cursor runtimes can use the same capability through HTTP or the documented MCP tools.

## Agent playbook

| User ask | Call |
| --- | --- |
| Plan a weekend in LA from Chicago | trip-skeleton with ORD/LAX, flight dates, destination=Los Angeles and hotel dates |
| Just the cheapest flights | google-flights; compare returned fares rather than assuming best_flights is a cheapest-first guarantee |
| Just hotels near downtown | google-hotels?q=… with check_in_date and check_out_date |
| Flights, hotels, and things to do | trip-skeleton with location=… |
| Compare two date windows | Two trip-skeleton calls; budget each live quote |
| One-way only | Omit return_date; pass explicit hotel dates if lodging is needed |

## FAQ

Do I need a Google Cloud travel key or an OTA partner account? No. These endpoints require no marketplace account or API key. After the free tier, the agent pays with a funded USDC wallet on Base via x402.

How does the free tier count a trip? The first 3 calls per agent identity are shared across all endpoints. One trip-skeleton invocation consumes one free-tier call, not one per engine step; it does not grant a separate allowance for each route or endpoint.

Why can billed_steps be 3 when events were omitted? The live call on 2026-10-15 advertised billed_steps 3 while steps_run was 2. Budget against billed_steps and the live 402 amount rather than assuming flights plus hotels always costs two steps.

Which price should the agent trust? The regular per-step price is $0.005 USDC. Promotional pricing is advertised by the live 402 accepts[0].amount / extra.perStep / extra.total and the site banner. Trust that current quote, not a historical sample total.

Can I test without spending mainnet USDC? Use the documented sandbox at /api/sandbox/v1/{slug} on Base Sepolia with test USDC and mock responses. It is separate from live travel data and requires the operator's sandbox configuration. See https://marketplaceforaiagents.com/docs/sandbox.

Are airport codes required? departure_id and arrival_id are required along with outbound_date. Use IATA airport or city codes such as ORD and LAX; use destination for the hotel's city name. Omit return_date for one-way travel and supply hotel dates explicitly when needed.

## Related entrypoints

- Marketplace: https://marketplaceforaiagents.com/marketplace
- Integration docs: https://marketplaceforaiagents.com/docs
- llms.txt: https://marketplaceforaiagents.com/llms.txt
- Google Flights API for agents: https://marketplaceforaiagents.com/learn/google-flights-api-for-agents
- Google Hotels API for agents: https://marketplaceforaiagents.com/learn/google-hotels-api-for-agents
- Google Events API for agents: https://marketplaceforaiagents.com/learn/google-events-api-for-agents
- How agents budget x402 API calls: https://marketplaceforaiagents.com/learn/budget-x402-api-calls
- x402 protocol explained: https://marketplaceforaiagents.com/learn/x402-protocol-explained
- MCP marketplace guide: https://marketplaceforaiagents.com/learn/mcp-x402-marketplace

Capability first, payment second: one call gets flights and hotels (and events when asked) as JSON, and x402 USDC on Base settles it only when the free tier is spent.

Canonical HTML: https://marketplaceforaiagents.com/learn/trip-planning-api-for-agents