Skip to content
← Blog

September 2026 · Matan Rabi

Cheapest month to fly API: scan a whole month in one parallel burst

Flexible travellers want to see a month of fares at once: every departure date priced side by side, with the cheapest day highlighted. Serial loops at one request per second turn that into a coffee break. Parallel bursts at 150 to 500 requests per minute turn it into one rate-limit window.

The pattern: one date, one request

There is no special "scan a month" endpoint. You fire one one-way search per departure date, in parallel, using your language's standard concurrency primitives. Each request is identical except for departure_date. The rate limits are what make the pattern viable.

POST /v1/flights/oneway per date
// Pick your month
const dates = [
  "2026-11-01", "2026-11-02", "2026-11-03", 
  // ... all 30 days
];

// Fire all requests in parallel
const results = await Promise.all(
  dates.map(date => 
    fetch("https://api.flightpowers.com/v1/flights/oneway", {
      method: "POST",
      headers: {
        "x-api-key": process.env.FLIGHTPOWERS_API_KEY,
        "Content-Type": "application/json"
      },
      body: JSON.stringify({
        from_airport: "LIS",
        to_airport: "JFK",
        departure_date: date,
        limit: 5
      })
    }).then(r => r.json())
  )
);

// Extract cheapest per day
const grid = results.map((res, i) => ({
  date: dates[i],
  price: res[0]?.price_as_number || null,
  verdict: res[0]?.price_insights_verdict || null
}));

Rate limits sized for bursts

The flights API publishes per-minute rate limits: 150 / 250 / 500 requests per minute by tier (Pro / Ultra / Mega). A 30-date month fits inside one minute on every paid plan. A 31-date month plus a few retries fits inside two minutes on the lowest tier.

This is the opposite of a serial loop at 1 req/sec. A 30-date scan serially is 30 seconds of wall time minimum; in parallel it is one burst.

The free demo tool

The site has a live demo that scans ~10 sampled dates across a month and renders them as a heat grid. Green cells sit near the month's cheapest day, red cells near its most expensive. The grid is relative to the scanned month only, separate from Google's own low | typical | high verdict.

The demo samples instead of scanning every day because cost: each date is a real search on our own key. The full every-day grid is what the API is for. Try the demo first to see the shape of the data.

Why per-minute matters

Hourly guarantees like "1,000 requests per hour" are the wrong shape for a date-scan workload. You want the answer in seconds, not distributed across an hour. A per-minute ceiling in the hundreds means the moment a user asks "what is the cheapest week this winter," you scan the dates and answer, not queue them.

The trade is that a per-minute limit is a limit, not a guarantee. If you need a contract-backed throughput number for enterprise planning, read the listing terms. For bursty workloads, the per-minute rate is the useful number.

What the response includes

Each date's search returns flat JSON per itinerary:

  • price (display string) and price_as_number (sortable, comparable)
  • price_insights_low / price_insights_high: Google's historical band for the route
  • price_insights_verdict: low | typical | high, the alerting trigger
  • airline, duration, stops, local times, and a buy_link to reopen the exact itinerary on Google Flights

You sort by price_as_number to find the cheapest day. You filter by price_insights_verdict: "low" to find the days Google calls cheap for the route, not just cheap for the month.

Empty results versus failed searches

Every response carries an X-Search-Status header: ok | empty | partial | degraded. An empty array with X-Search-Status: empty means Google genuinely has no itineraries for that date. An empty array with X-Search-Status: degraded means the search did not complete and the empty array says nothing about availability.

When scanning a month, you render the status per day: show the price when the search succeeded, show a dash or "no flights" when it came back empty, and show "search failed" when it degraded. The free tool does this.

Extending the pattern

The same burst pattern scales to more dimensions:

  • Multiple routes: 3 destinations × 30 dates = 90 requests. Still fits inside one minute on ULTRA or MEGA.
  • Duration flexibility: 3-night, 4-night, 5-night stays = 3 return dates per departure. 30 departure dates × 3 durations = 90 round-trip requests.
  • Nearby airports: 2 origins × 2 destinations × 30 dates = 120 requests. The rate limit is the constraint; the pattern is the same.

Who uses this

  • Deal sites and newsletters: Regenerate monthly grids on a schedule, flag the days whose verdict flips to low, publish.
  • AI travel agents: "Cheapest week to fly this winter" decomposes into exactly this: parallel date searches, compare, answer.
  • Flexible travellers: "Sometime in November" is a scan, not thirty manual searches. Find the cheap pocket, then check that day's live fare before booking.

Try it

The free demo on the site scans ~10 sampled dates live. For the full every-day scan, the $10 PRO plan (2,500 requests/month, 150 req/min) is the entry point. A 30-date month costs 30 requests.

The full grid, every day, on your own key

One request per date in one parallel burst, with the price band and verdict judging each fare. Free tier on RapidAPI, no card to try.

Free tier: 10 requests/month. No card to try.