Gap-Night Pricing: Discount Bookable Gaps

Jun Zhou, Founder at AirROI
by Jun ZhouFounder at AirROI
Published: September 4, 2026
Updated: September 5, 2026

A gap-night rule adjusts a short run of available nights between known reserved or blocked nights. The gap must also be bookable: lowering the rate cannot fix a minimum stay or check-in restriction that prevents the stay.

See the gap, then test whether it can be sold

See exactly which nights form a gap

Illustrative calendar: June 12–17, 2026. Calculation date June 13; $200 per night after model effects.

Fri 12
Reserved
Boundary
Sat 13
Available
$170.00
1-night gap
Sun 14
Reserved
Boundary
Mon 15
Available
$184.00
2-night gap
Tue 16
Available
$184.00
2-night gap
Wed 17
Reserved
Boundary
June 13 is a one-night gap (−15%). June 15–16 forms a two-night gap (−8% per night).
Labels carry the same meaning as colors. Reserved boundary nights are not discounted in this illustration. No other rules or price limits.

Try each calendar scenario. A “gap” is a continuous stretch of known available nights with known unavailable boundaries. A missing date is not a boundary. A matching gap length alone is also not enough: the stay must be bookable.

Three reasons an apparent gap may not receive a discount

SituationOne-night gap on June 13Two-night gap on June 15–16
Minimum stay is two nightsToo short; no gap adjustmentCan qualify
Custom rule excludes weekendsSaturday excludedMonday and Tuesday still eligible
June 17 is unknownUnaffected; both boundaries knownRight boundary unknown; no gap adjustment

For the original -15% one-night / -8% two-to-three-night policy, the standalone prices are $170 and $184 respectively. In the “no adjustment” cases, $200 is retained before other rules and limits, not guaranteed as the final API price.

Gap nights versus adjacent nights

A blocked night can bound a gap, but it cannot anchor an adjacent-day reservation search. A nonzero gap adjustment prevents the adjacent rule from also adjusting that same date. If the gap is ineligible or its band has a zero adjustment, a separately eligible adjacent rule can still run.

Set up a worked calendar

The JSON below is an addition to this complete Calendar Prices request. Merge fields into one request; do not send a rule fragment by itself.

{
  "location": {
    "latitude": 25.7907,
    "longitude": -80.13
  },
  "currency": "USD",
  "base_price": 200
}

All worked prices use USD and assume a $200 price after model effects, with no other adjustments unless stated. They demonstrate arithmetic, not live forecasts.

Gap-day, adjacent-day, and occupancy-pacing rules need calendar. Each row requires a unique date and a status: available, reserved, or blocked. For this historical illustration, assume today is June 13, 2026:

{
  "calendar": [
    {"date": "2026-06-12", "status": "reserved", "reservation_id": "booking-a"},
    {"date": "2026-06-13", "status": "available", "price": 240, "min_stay": 1,
     "check_in_allowed": true, "check_out_allowed": true},
    {"date": "2026-06-14", "status": "reserved", "reservation_id": "booking-b"},
    {"date": "2026-06-15", "status": "available"},
    {"date": "2026-06-16", "status": "available"},
    {"date": "2026-06-17", "status": "reserved", "reservation_id": "booking-c"}
  ]
}

This creates a one-night gap on June 13 and a two-night gap on June 15–16. Use your current dates in a real request. Send up to 1,000 rows; order does not matter. Missing dates mean unknown, not available.

Optional min_stay (1–365), check_in_allowed, and check_out_allowed help test whether a gap is bookable when no corresponding custom stay rule is set; defaults are one night and both permissions true. price must be positive in the request currency but does not affect calculations. reservation_id must be nonblank and is allowed only on reserved or blocked rows; it is not currently used by pricing rules.

DateJune 12June 13June 14June 15June 16June 17
StatusReservedAvailableReservedAvailableAvailableReserved
GapBoundary1 nightBoundary2 nights2 nightsBoundary

Apply a gap rule

Add this rule alongside the calendar above:

{
  "pricing_rules": {
    "gap_day": {
      "mode": "custom",
      "settings": [
        {"min_days": 1, "max_days": 1, "adjustment_percent": -15},
        {"min_days": 2, "max_days": 3, "adjustment_percent": -8}
      ],
      "apply_on_weekends": true
    }
  }
}

June 13 receives −15% (200 → 170); each night of June 15–16 receives −8% (200 → 184). A gap needs known reserved or blocked nights on both sides and must be bookable under the effective stay restrictions. A two-night minimum would make the one-night gap ineligible.

Gap bands are inclusive, ascending, non-overlapping, and within 1–30 nights. Uncovered lengths receive no adjustment. apply_on_weekends is required in custom mode; false excludes Friday and Saturday nights, including June 13.

Bookability comes before the discount

A two-night gap with a three-night minimum is not eligible. Likewise, disallowing the required check-in or checkout can prevent a gap stay. Custom stay rules take precedence over the corresponding calendar-row restrictions; without them, the supplied row restrictions apply.

If an available run began before today, its gap length counts only the remaining nights from today onward. Each night qualifies only if at least one allowed stay within the gap can include it. The minimum stay is evaluated on that stay's check-in date, and checkout permission on its departure date.

For custom mode with apply_on_weekends: false, Friday and Saturday dates are excluded from adjustment. This is the engine's weekend definition, not a locale-dependent setting.

Why did the gap rule do nothing?

Check the evidence in this order:

  1. Is each gap night explicitly available, with known boundaries on both sides?
  2. Is its length covered by one of your non-overlapping bands?
  3. Can the gap be booked under the effective stay restrictions?
  4. Is this date excluded by the weekend setting?
  5. Did a nonzero adjustment occur but a later price limit change the result?
Missing dates mean unknown—not available. Use the calendar guide to avoid incomplete evidence. A nonzero gap adjustment suppresses the adjacent-day adjustment on that date; it does not stack both discounts.

Check bookability before changing the discount

A larger discount cannot make an unbookable gap eligible. Confirm the boundaries and stay restrictions first, then compare the qualifying night's explanation. If you want to target a night beside a reservation without requiring a bounded gap, explore adjacent-day pricing.