Bowmark AIdocs

Car hire

Search car hire at an airport for a date range and get back normalized offers, cheapest total first — total and per-day price, the agency you collect from…

Search car hire at an airport for a date range and get back normalized offers, cheapest total first — total and per-day price, the agency you collect from AND the separate company that sold the booking, vehicle class, seats/bags/doors, transmission, mileage and cancellation policy, and whether pickup is in-terminal or a shuttle. Direct API, no browser.

Also known as: car, rental car, rental, car rental, hire car, vehicle, rent a car, hire a car, car hire

Call it

bowmark.cars.search(query: CarQuery, limit?: number, options?: CallOptions): Promise<CarSearchResult>

Functions

FunctionWhat it does
searchSearches car hire for an airport and date range — { pickup: "SFO", pickupDate: "2026-09-01", dropoffDate: "2026-09-05" } — and returns up to limit normalized offers (default and max…

Types

type CarQuery = {
  pickup: string        // IATA airport code ("SFO") — the vertical is airport-first
  dropoff?: string      // defaults to pickup; set it for a one-way hire
  pickupDate: string    // ISO date "2026-09-01"
  dropoffDate: string
  pickupHour?: number   // 0-23, defaults to the site's own 10:00
  dropoffHour?: number
  driverAge?: number    // under-25 changes which fleet is quotable at all
}

// One normalized offer. Nulls mean "this site does not report it for this
// offer", never "we failed to read it" — so a filter can tell an absent
// perk from a declined one.
type Car = {
  source: string                 // which site this came from
  id: string                     // that site's id for the offer
  price: number | null           // TOTAL for the whole hire
  dayPrice: number | null        // per-day, as the site computes it
  currency: string
  agency: string                 // who you collect the car from ("Fox")
  seller: string                 // who sold the booking ("Wisecars") — often different
  carName: string                // "Mitsubishi Mirage", an "or similar" example
  carClass: string               // "Economy", "Compact SUV"
  passengers: number | null
  bags: number | null
  doors: number | null
  transmission: "automatic" | "manual" | null
  airConditioning: boolean | null
  unlimitedMileage: boolean | null
  freeCancellation: boolean | null
  pickupType: string | null      // "IN_TERMINAL" / "SHUTTLE" — counter walk vs bus
  pickupAddress: string | null
  url: string                    // deep link to this offer
}
type CarSearchResult = {
  cars: Car[]                    // cheapest TOTAL first; unpriced offers last
  warnings: string[]             // always present; empty when nothing was dropped. A
                                 // site named here quoted NOTHING, which is a different
                                 // fact from an airport with no availability
}

type CallOptions = {
  timeoutMs?: number   // per-provider budget in ms, default 30000, clamped to 1000-55000.
                       // A provider slower than this is DROPPED from the results and
                       // NAMED in warnings — never silently absent
}

Examples

// Cheapest week away: price the same hire at three airports and compare the
// real totals, not the advertised per-day rate.
const airports = ["SFO", "OAK", "SJC"];
const quotes = await Promise.all(airports.map(async (pickup) => {
  const { cars, warnings } = await bowmark.cars.search({
    pickup, pickupDate: "2026-09-01", dropoffDate: "2026-09-08",
  }, 25);
  for (const w of warnings) log(`${pickup}: ${w}`);
  const best = cars[0] || null;
  log(`${pickup}: ${best ? best.currency + best.price + " total (" + best.carClass + ")" : "nothing quoted"}`);
  return best ? { pickup, total: best.price, perDay: best.dayPrice, car: best.carName, agency: best.agency, url: best.url } : { pickup, total: null };
}));
return quotes.filter(q => q.total).sort((a, b) => a.total - b.total);
// A tight connection: only offers you can walk to, that you can cancel, with
// room for four and their bags. Nulls are "unstated", so require true.
const { cars, warnings } = await bowmark.cars.search({
  pickup: "MCO", pickupDate: "2026-10-02", dropoffDate: "2026-10-06", pickupHour: 22,
}, 50);
for (const w of warnings) log(w);
const walkable = cars.filter(c =>
  c.pickupType === "IN_TERMINAL" && c.freeCancellation === true &&
  (c.passengers ?? 0) >= 4 && (c.bags ?? 0) >= 3);
log(`${walkable.length} of ${cars.length} offers are in-terminal, refundable and big enough`);
return walkable.slice(0, 5).map(c => ({
  car: c.carName, class: c.carClass, total: c.price, perDay: c.dayPrice,
  // who you collect from vs who you bought from — routinely different companies
  collectFrom: c.agency, soldBy: c.seller,
  unlimitedMiles: c.unlimitedMileage, url: c.url,
}));

Providers behind it

Provider
momondoMomondo