Caching & monitoring

Error handling and empty-result states: Error handling. Platform HTTP errors and retries: Error Handling.

Data freshness

Ticket results are cached by the API for up to 1 hour. The cache key is the full query tuple: (origin, destination, date, passengers). Any change in passengers or date produces a separate cache entry and a fresh API call.

EndpointRecommended TTLCache keyNotes
GET /tickets/search1 hour maxtickets:{origin}:{dest}:{date}:{passengers}Matches API cache lifetime — longer TTLs risk showing stale prices

Disclosure: Always present prices as indicative market snapshots. State clearly in passenger-facing UI that prices may change between search and booking (for example: "Prices may change at booking. Confirm fare on the airline's site.").

Debounce

Ticket search UIs typically fire on every airport or date selection change. Debounce inputs at 300–500 ms before issuing a request to avoid flooding the API with partial queries while the user is typing.

import os
import time
import requests

HEADERS = {
    "X-RapidAPI-Key": os.getenv("RAPIDAPI_KEY", "YOUR_RAPIDAPI_KEY"),
    "X-RapidAPI-Host": "skylink-api.p.rapidapi.com",
}
BASE = "https://skylink-api.p.rapidapi.com"

_cache: dict[str, tuple[dict, float]] = {}
TTL = 3600  # 1 hour — matches API cache lifetime


def search_tickets_cached(
    origin: str,
    destination: str,
    date: str,
    passengers: int = 1,
) -> dict:
    """
    Cache-wrapped ticket search. TTL 1 hour, keyed on (origin, dest, date, passengers).
    Raises ValueError on 422. Returns full response dict including count and flights.
    """
    cache_key = f"tickets:{origin}:{destination}:{date}:{passengers}"
    cached = _cache.get(cache_key)
    if cached and time.time() < cached[1]:
        return cached[0]

    r = requests.get(
        f"{BASE}/tickets/search",
        headers=HEADERS,
        params={
            "origin": origin,
            "destination": destination,
            "date": date,
            "passengers": passengers,
        },
        timeout=(10, 15),
    )
    if r.status_code == 422:
        detail = r.json().get("detail", "validation error")
        raise ValueError(f"422 Unprocessable: {detail}")
    r.raise_for_status()

    data = r.json()
    _cache[cache_key] = (data, time.time() + TTL)
    return data


if __name__ == "__main__":
    result = search_tickets_cached("JFK", "LAX", date="2026-09-15", passengers=1)
    flights = result.get("flights", [])
    print(f"Found {result.get('count', 0)} option(s).")
    if flights:
        cheapest = flights[0]
        duration = cheapest.get("total_duration_min", 0)
        print(
            f"Cheapest: ${cheapest.get('price_usd', 0):.2f}  ·  "
            f"{duration // 60}h {duration % 60:02d}m"
        )
        print("Prices may change at booking.")

    result2 = search_tickets_cached("JFK", "LAX", date="2026-09-15", passengers=1)
    print("Cache hit:", result2 is result)

For production, replace the dict-based cache with Redis or Memcached so the cache survives restarts and is shared across instances.

Rate limits

HeaderValue
X-RateLimit-Requests-LimitYour plan's monthly request quota
X-RateLimit-Requests-RemainingRequests left this month
X-RateLimit-Requests-ResetSeconds until the quota resets

With a 1-hour TTL per (origin, destination, date, passengers) tuple, each unique search consumes at most one API call per hour. For high-traffic flows, pre-populate the cache with the most common routes during off-peak periods.

Monitoring

Log on every ticket search:

  • origin, destination, date, passengers
  • status_code
  • elapsed_ms
  • count (from response — useful for tracking no-availability rates)
  • cache_hit (boolean)
  • quota_remaining (from X-RateLimit-Requests-Remaining)

Alert on:

  • count: 0 rate spike — may indicate a broken date range or query parameter issue
  • status = 429 more than twice in a 5-minute window — increase TTL or throttle concurrent searches
  • elapsed_ms > 5000 repeatedly — consider a shorter timeout with a "try again" fallback message
  • quota_remaining < 200 — approaching monthly limit; extend TTLs or reduce unique search volume

Related: Flight Tickets · Airport Search · Error handling · Error Handling