Skyscanner Flight API Entegrasyonu: Developer Rehberi

Skyscanner Flights Live Prices API entegrasyonunu x-api-key auth, create/poll lifecycle, request-response modelleri, itinerary/leg/segment mapping, agent/pricing option, rate limit, polling ve observability ile developer gözüyle uygulayın.

Editoryal bilgi
Değişiklik geçmişi
  • 2026-09-26 — Provider companion standard applied; rate limits, refresh-price lifecycle, pagination and evidence boundaries clarified.
İlgili platform profilleri
Advertisement

Skyscanner flight entegrasyonunda temel mimari karar, upstream response'u doğrudan UI modeli yapmak yerine async search session + canonical flight model + provider handoff katmanları oluşturmaktır.

Skyscanner'ın güncel Flights Live Prices akışı iki endpoint üzerine kuruludur:

text
POST /flights/live/search/create
        |
        v
initial / partial results
+ sessionToken
        |
        v
POST /flights/live/search/poll/{sessionToken}
        |
        v
progressively richer results
        |
        v
completed

Bu yapı klasik tek-request/tek-response API gibi ele alınmamalıdır.

Provider companion özeti

AlanDurum
ErişimOnaylı Skyscanner partnership + API key
AuthServer-side x-api-key
Primary contractsFlights Live Prices create/poll, itinerary refresh, Autosuggest
Data directionClient/backend initiated create + poll
PaginationLive Prices search lifecycle paginated collection değildir; sonuçlar session polling ile olgunlaşır
PollingContract'ın temel parçasıdır; create sonrası poll gerekir
Public default rate limitsFlights Live Pricing Create: 100/sn ve 100/dk; Poll: 100/sn ve 500/dk. Partner agreement farklı olabilir
Reprice/refreshitineraryrefresh/create + itineraryrefresh/poll ile selected itinerary için güncel price refresh
Booking ownershipPricing option/deeplink sonrası downstream airline/OTA
Evidence levelOfficial public docs reviewed; partner account ile canlı test iddiası yok
Code examplesIllustrative

Capability boundary

text
Place discovery       -> Flights Autosuggest
Initial live search   -> /flights/live/search/create
Search completion     -> /flights/live/search/poll/{sessionToken}
Selected price refresh-> /flights/live/itineraryrefresh/create
Refresh completion    -> /flights/live/itineraryrefresh/poll/{refreshSessionToken}
Booking handoff       -> pricing option / agent deep link

Search session, selected-itinerary refresh ve downstream booking aynı state machine değildir.

Pagination neden N/A?

Flights Live Prices response modeli klasik page=2 collection pagination değildir. Sonuç completeness'i aynı search session üzerinde create/poll lifecycle ile ilerler. Bu nedenle generic pagination implementasyonu eklemeyin; session progress ve merge semantics'i yönetin.

Resmi rate limit sınırları

Skyscanner'ın güncel public Rate Limits sayfasındaki standard Flights değerleri:

APIPer secondPer minute
Flights Live Pricing — Create100100
Flights Live Pricing — Poll100500
Flights Indicative Prices100500

Bu değerler default limitlerdir. Skyscanner limitlerin API key / partner ihtiyacına göre özelleştirilebildiğini açıkça belirtir. Bu nedenle runtime'da 429 metriği ve account-specific quota bilgisi source of truth olmalıdır.

Price refresh / reprice lifecycle

İlk live-search pricing option'ını checkout truth gibi kabul etmeyin. Skyscanner seçilen itinerary için ayrı refresh flow dokümante eder:

text
search/create
   -> search/poll
   -> user selects itinerary
   -> itineraryrefresh/create
   -> itineraryrefresh/poll
   -> refreshed pricing options
   -> agent deeplink

Refresh sonucu değişirse UI eski fiyatı confirmed state gibi göstermemelidir. Internal modelde:

text
SEARCH_PRICE
REFRESHING
REFRESHED
PRICE_CHANGED
HANDOFF_READY

gibi explicit state kullanmak daha güvenlidir.

Platform sorumlulukları, ticari sınırlar ve operasyon kararları için Skyscanner profiline bakın. Bu rehber uygulama sözleşmelerini ve request/response işlemlerini ele alır.

1. Erişim ve authentication

Skyscanner API'lerine erişim için partnership başvurusu ve onaylanmış API key gerekir.

Authentication header:

http
x-api-key: <your-api-key>

API key client-side JavaScript'e veya public repo'ya konmamalıdır.

Önerilen boundary:

ts
interface SkyscannerCredentials {
  apiKeyRef: string;
}

Frontend:

text
Browser
  -> Your backend
      -> Skyscanner API

Doğrudan browser -> Skyscanner çağrısı yapmayın.

2. Flights Live Prices create endpoint

Endpoint:

http
POST https://partners.api.skyscanner.net/apiservices/v3/flights/live/search/create
Content-Type: application/json
x-api-key: <api-key>

Minimal örnek request:

json
{
  "query": {
    "market": "TR",
    "locale": "tr-TR",
    "currency": "TRY",
    "queryLegs": [
      {
        "originPlaceId": {
          "iata": "IST"
        },
        "destinationPlaceId": {
          "iata": "LHR"
        },
        "date": {
          "year": 2026,
          "month": 10,
          "day": 12
        }
      }
    ],
    "adults": 1,
    "cabinClass": "CABIN_CLASS_ECONOMY"
  }
}

Skyscanner dokümantasyonunda create request için temel alanlar:

  • market,
  • locale,
  • currency,
  • queryLegs,
  • adults.

Ek olarak child ages, include/exclude carrier/agent, sustainability, nearby-airports ve baggage gibi seçenekler bulunabilir.

3. Internal search request modeli

Provider contract'ını domain modeliniz yapmayın.

ts
interface FlightSearchRequest {
  market: string;
  locale: string;
  currency: string;

  legs: Array<{
    origin: {
      iata?: string;
      entityId?: string;
    };
    destination: {
      iata?: string;
      entityId?: string;
    };
    departureDate: string;
  }>;

  passengers: {
    adults: number;
    childAges: number[];
  };

  cabinClass:
    | "economy"
    | "premium_economy"
    | "business"
    | "first";
}

Adapter:

text
Internal FlightSearchRequest
        |
        v
Skyscanner request mapper
        |
        v
Skyscanner create payload

Böylece provider enum'ları ürün domain'inize yayılmaz.

4. create response nasıl ele alınmalı?

Skyscanner create çağrısı ilk sonuçları ve sessionToken döndürür. Dokümantasyona göre create sonucu hızlı time-to-first-result amacıyla incomplete/cached subset olabilir.

Conceptual response:

json
{
  "sessionToken": "session-token",
  "status": "RESULT_STATUS_INCOMPLETE",
  "content": {
    "results": {
      "itineraries": {
        "itinerary-1": {
          "pricingOptions": []
        }
      }
    }
  }
}

Buradaki önemli nokta:

create başarılı oldu = search tamamlandı demek değildir.

Internal state:

ts
type SearchStatus =
  | "created"
  | "partial"
  | "polling"
  | "complete"
  | "failed"
  | "expired";

5. poll endpoint

Endpoint:

http
POST https://partners.api.skyscanner.net/apiservices/v3/flights/live/search/poll/{sessionToken}
x-api-key: <api-key>

Request body gerektirmeyen poll çağrısı session token üzerinden devam eder.

Internal session:

ts
interface FlightSearchSession {
  id: string;
  provider: "skyscanner";
  providerSessionToken: string;
  requestHash: string;

  status: SearchStatus;

  createdAt: string;
  lastPolledAt?: string;
  completedAt?: string;

  pollCount: number;
}

6. Polling strategy

Fixed 250ms loop gibi agresif polling yapmayın.

Örnek:

text
poll 1 -> 300 ms
poll 2 -> 500 ms
poll 3 -> 800 ms
poll 4 -> 1200 ms
poll 5+ -> 1500-2000 ms

Stop conditions:

  • API status completed,
  • client disconnect,
  • maximum search duration,
  • unrecoverable provider error,
  • expired/invalid session.

Örnek policy:

ts
interface PollPolicy {
  maxDurationMs: number;
  maxPollCount: number;
  initialDelayMs: number;
  maxDelayMs: number;
}

7. Progressive results

Live flight search'te ilk sonuç ile mature result set arasında fark vardır.

Frontend state:

ts
interface FlightSearchViewState {
  status: "searching" | "partial" | "complete" | "error";
  itineraries: FlightItinerary[];
  lastUpdatedAt: string;
}

UI:

text
create
  -> first results render
  -> poll
  -> merge/deduplicate
  -> rerank
  -> render
  -> poll
  -> complete

Tüm ekranı spinner'da tutmak yerine usable first result erken gösterilebilir.

8. Canonical flight domain modeli

En az şu entity'leri ayırın:

text
Itinerary
  -> Leg
      -> Segment
          -> Carrier

Itinerary
  -> PricingOption
      -> Agent
      -> DeepLink

Itinerary

ts
interface FlightItinerary {
  id: string;
  legIds: string[];
  pricingOptions: FlightPricingOption[];
  score?: number;
}

Leg

ts
interface FlightLeg {
  id: string;
  origin: string;
  destination: string;
  departure: string;
  arrival: string;
  durationMinutes: number;
  segmentIds: string[];
  stopCount: number;
}

Segment

ts
interface FlightSegment {
  id: string;
  origin: string;
  destination: string;
  departure: string;
  arrival: string;

  marketingCarrierId?: string;
  operatingCarrierId?: string;

  flightNumber?: string;
}

9. Carrier ve Agent aynı şey değildir

Carrier uçuşu market eden veya operate eden airline'dır.

Agent ise itinerary'yi satan booking provider olabilir.

ts
interface FlightAgent {
  id: string;
  name: string;
  type?: "airline" | "ota";
  rating?: number;
}

Aynı itinerary farklı agent'larda:

  • farklı fiyat,
  • farklı baggage,
  • farklı booking fee,
  • farklı payment option,
  • farklı deep link

ile bulunabilir.

10. Pricing option modeli

ts
interface FlightPricingOption {
  id: string;

  agentIds: string[];

  price: {
    amount: number;
    currency: string;
  };

  deepLink?: string;

  transferType?: string;
  farePolicy?: string;
}

Important:

text
itinerary != offer

Tek itinerary'nin birden fazla seller/price alternatifi olabilir.

11. Response normalization

Skyscanner response'u çoğunlukla normalized entities + ID references şeklinde okunmalıdır.

Önerilen pipeline:

text
Skyscanner JSON
    |
    v
Provider DTO
    |
    v
Entity dictionaries
    |
    +--> itineraries
    +--> legs
    +--> segments
    +--> carriers
    +--> agents
    |
    v
Canonical flight model

Frontend provider DTO bilmemeli.

12. Search result merge

Poll sonucunda önceki itinerary'ler tekrar gelebilir veya pricing option değişebilir.

Blind append yapmayın.

ts
function mergeSearchResults(
  current: FlightSearchResult,
  incoming: FlightSearchResult
): FlightSearchResult {
  // upsert entities by provider-stable id
  // replace/update pricing options
  // preserve newest provider state
  return current;
}

Merge key:

  • provider itinerary ID,
  • leg/segment IDs,
  • agent + price option identity.

13. Autosuggest entegrasyonu

Flight search input'unda free-text'i doğrudan IATA'ya çevirmeye çalışmayın.

Skyscanner Flights Autosuggest endpoint:

http
POST https://partners.api.skyscanner.net/apiservices/v3/autosuggest/flights

Örnek:

json
{
  "query": {
    "market": "TR",
    "locale": "tr-TR",
    "searchTerm": "Istanbul",
    "includedEntityTypes": [
      "PLACE_TYPE_CITY",
      "PLACE_TYPE_AIRPORT"
    ]
  },
  "limit": 10,
  "isDestination": false
}

Internal place:

ts
interface FlightPlace {
  id: string;
  entityId?: string;
  iata?: string;
  name: string;
  type: "airport" | "city" | "country";
}

14. Cache stratejisi

Live search response'u booking-intent data'dır.

Cache key en az:

text
origin
+ destination
+ dates
+ adults
+ child ages
+ cabin
+ market
+ locale
+ currency

Cache'in amacı:

  • duplicate request suppression,
  • burst control,
  • short-lived UX acceleration.

Ama eski live price'ı booking truth gibi kullanmayın.

15. Indicative Prices boundary

Discovery/flexible-date use case'ini Live Prices'tan ayırın.

text
Discovery
  -> indicative/aggregated pricing

Booking intent
  -> Flights Live Prices

Aylık calendar ekranındaki her hücre için live create/poll yapmak hem quota hem latency açısından yanlış olabilir.

16. Rate limit ve 429

API reference şu response sınıflarını dokümante eder:

  • 400 Bad Request,
  • 401 Unauthorized,
  • 403 Forbidden,
  • 404 Not Found,
  • 429 Too Many Requests,
  • 500 Internal Server Error,
  • 503 Service Unavailable.

429 için:

text
do not hammer retry
  -> exponential backoff
  -> jitter
  -> quota metric
  -> request suppression/cache

Örnek:

ts
interface RetryPolicy {
  retryable: number[];
  maxAttempts: number;
  baseDelayMs: number;
  maxDelayMs: number;
}

Retryable adaylar:

text
429
500
503
network timeout

400/401/403 genellikle blind retry edilmemelidir.

17. Error taxonomy

text
SKYSCANNER_AUTH
SKYSCANNER_FORBIDDEN
SKYSCANNER_BAD_REQUEST
SKYSCANNER_RATE_LIMIT
SKYSCANNER_SESSION_INVALID
SKYSCANNER_TIMEOUT
SKYSCANNER_UPSTREAM
SKYSCANNER_PARSE
SKYSCANNER_EMPTY_RESULT
SKYSCANNER_DEEPLINK

Provider error'u UI mesajı haline doğrudan çevirmeyin.

Pricing option içindeki booking/deep link, kullanıcıyı downstream provider'a taşır.

Kontrol edin:

  • itinerary aynı mı,
  • dates aynı mı,
  • passenger context korunuyor mu,
  • currency tutarlı mı,
  • final price aynı mı,
  • mobile redirect doğru mu.

Internal handoff event:

ts
interface FlightClickEvent {
  searchId: string;
  itineraryId: string;
  pricingOptionId: string;
  agentId: string;

  displayedPrice: number;
  currency: string;

  clickedAt: string;
}

19. Observability

Search-session bazlı metrik tutun.

text
search_created
time_to_first_result
time_to_complete
poll_count
itinerary_count
agent_count
api_429
api_5xx
empty_result
deeplink_click
deeplink_failure

Log context:

json
{
  "searchId": "srch_123",
  "provider": "skyscanner",
  "market": "TR",
  "currency": "TRY",
  "route": "IST-LHR",
  "pollCount": 4,
  "providerStatus": "complete"
}

20. SLO önerileri

Kendi trafiğinize göre kalibre edin.

text
create success              >= 99%
time to first useful result <= product budget
poll completion             >= 98%
429 rate                    < agreed quota threshold
deeplink success            >= 99%
search error rate           < 1%

21. Test matrisi

TestBeklenen
one-waytek leg
returniki leg
direct0 stop
multi-segmentdoğru segment chain
multiple agentsaynı itinerary, farklı offers
child passengerage context korunuyor
business cabindoğru cabin
different currencydoğru price currency
first create partialUI partial gösteriyor
multiple pollsmerge duplicate üretmiyor
completed statuspolling duruyor
429backoff
401retry yok / credential alert
provider 503controlled retry
click handoffitinerary korunuyor

22. Go-live checklist

  • API key server-side
  • partnership/access hazır
  • create request mapper test edildi
  • poll orchestration test edildi
  • session state persisted
  • cancellation/timeout policy var
  • itinerary/leg/segment model ayrı
  • carrier/agent ayrımı doğru
  • pricing option normalize
  • autosuggest place mapping hazır
  • poll merge idempotent
  • 429/backoff uygulanmış
  • observability dashboard hazır
  • deep-link testleri tamam
  • search/session correlation ID var
  • client disconnect polling'i durduruyor

Sonuç

Skyscanner Flights API'yi yalnız endpoint entegrasyonu olarak kurmak eksik kalır.

Doğru boundary:

text
Search Request
   -> Skyscanner Adapter
   -> create
   -> partial normalize
   -> poll
   -> merge
   -> canonical itinerary
   -> pricing options
   -> agent deep link
   -> post-click quality measurement

Developer açısından başarı, yalnız JSON response almak değil; async search lifecycle'ını doğru yönetmek, provider-specific entity'leri normalize etmek ve kullanıcıyı tutarlı itinerary/price context'iyle booking provider'a taşımaktır.

Idempotency ve ordering

Search create, poll ve itinerary refresh event'lerini provider session/token identity ile correlate edin. Aynı poll response'un tekrar işlenmesi duplicate itinerary veya pricing option üretmemelidir. Incoming entity state provider-stable ID ile upsert edilmeli; eski poll snapshot'ı daha yeni refresh sonucunu ezmemelidir.

text
same session + same entity revision -> idempotent upsert
older snapshot                 -> ignore
newer pricing state            -> replace/update
Teknik danışmanlık

Benzer bir entegrasyon mu planlıyorsunuz?

Gereksinim, feed/API tasarımı ve production yaklaşımını birlikte değerlendirebiliriz.

Projenizi konuşalım →

Kaynaklar

İlgili içerikler

flight-metasearch

Skyscanner: Uçuş Keşfi, Canlı Fiyatlar ve Rezervasyon Yönlendirmesi

skyscanner.com

Skyscanner canlı ve tahmini uçuş verilerini ayırın; seyahat ve satıcı kimliğini koruyup fiyat, polling ve rezervasyon yönlendirme hatalarını teşhis edin.

skyscannerflightapi
İncele →
integration

Wego Affiliate API Entegrasyonu: Developer Rehberi

developers.wego.com

Wego Affiliate API entegrasyonunu OAuth client credentials, search creation, polling, offset merge, trip/fare/provider modeli, rate limit, handoff ve commercial reconciliation ile developer gözüyle uygulayın.

wegoaffiliateapi
İncele →
comparison

Google Flights vs Skyscanner: Uçuş Metasearch Karşılaştırması

Google Flights ve Skyscanner'ı flight search, discovery, price tracking, API erişimi ve provider handoff açısından karşılaştırın.

google-flightsskyscannerflight
İncele →
car-rental-metasearch

Skyscanner Cars: Canlı Arama, Keşif ve Satıcı Yönlendirmesi

skyscanner.com

Skyscanner araç kiralama live, indicative ve agents ürünlerini ayırın; kiralama bağlamını koruyup oturum, fiyat ve yönlendirme hatalarını teşhis edin.

skyscannercar-rentalapi
İncele →
turkey-market

ENUYGUN vs Skyscanner Türkiye: Comparable Dimensions

ENUYGUN ve Skyscanner'ı Türkiye bağlamında yalnız karşılaştırılabilir boyutlarda: discovery, transaction ownership, vertical kapsam, handoff ve developer modelinde karşılaştırın.

enuygunskyscannerturkiye
İncele →
operations

Rate Limit ve Quota Exhaustion Playbook

Supplier API rate-limit ve quota tükenmesi olaylarını token budget, backoff, queue, caching ve traffic shaping ile yönetin.

apirate-limitquota
İncele →