---
title: "Skyscanner Flight API Entegrasyonu: Developer Rehberi"
description: "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."
slug: "skyscanner-flight-api"
translationKey: "integration-skyscanner-flight-api"
locale: "tr"
type: "guide"
category: "integration"
tags: ["skyscanner","flight","api","live-prices","create","poll","itinerary","agent","rate-limit"]
vertical: ["flight"]
platform: "Skyscanner"
domain: "developers.skyscanner.net"
featured: true
publishedAt: "2026-09-19"
updatedAt: "2026-09-26"
reviewedAt: "2026-09-26"
technicalVerifiedAt: "2026-09-26"
sourceVersion: "Travel APIs v3 public docs reviewed 2026-09-26"
testedAgainst: "Official public documentation; not an authorized partner account"
codeExampleStatus: "illustrative"
changelog:
  - "2026-09-26 — Provider companion standard applied; rate limits, refresh-price lifecycle, pagination and evidence boundaries clarified."
sources:
  - title: "Skyscanner — Flights Live Prices overview"
    url: "https://developers.skyscanner.net/docs/flights-live-prices/overview"
  - title: "Skyscanner — Flights Live Prices quick start"
    url: "https://developers.skyscanner.net/docs/flights-live-prices/quick-start"
  - title: "Skyscanner — Flights Live Pricing API reference"
    url: "https://developers.skyscanner.net/api/flights-live-pricing"
  - title: "Skyscanner — Authentication"
    url: "https://developers.skyscanner.net/docs/getting-started/authentication"
  - title: "Skyscanner — Flights Autosuggest"
    url: "https://developers.skyscanner.net/docs/autosuggest/flights"
  - title: "Skyscanner — Rate limits"
    url: "https://developers.skyscanner.net/docs/getting-started/rate-limits"
  - title: "Skyscanner — Refresh Prices"
    url: "https://developers.skyscanner.net/docs/flights-live-prices/refresh-prices"
---

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

| Alan | Durum |
|---|---|
| Erişim | Onaylı Skyscanner partnership + API key |
| Auth | Server-side `x-api-key` |
| Primary contracts | Flights Live Prices create/poll, itinerary refresh, Autosuggest |
| Data direction | Client/backend initiated create + poll |
| Pagination | Live Prices search lifecycle paginated collection değildir; sonuçlar session polling ile olgunlaşır |
| Polling | Contract'ın temel parçasıdır; create sonrası poll gerekir |
| Public default rate limits | Flights Live Pricing Create: 100/sn ve 100/dk; Poll: 100/sn ve 500/dk. Partner agreement farklı olabilir |
| Reprice/refresh | `itineraryrefresh/create` + `itineraryrefresh/poll` ile selected itinerary için güncel price refresh |
| Booking ownership | Pricing option/deeplink sonrası downstream airline/OTA |
| Evidence level | Official public docs reviewed; partner account ile canlı test iddiası yok |
| Code examples | Illustrative |

### 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:

| API | Per second | Per minute |
|---|---:|---:|
| Flights Live Pricing — Create | 100 | 100 |
| Flights Live Pricing — Poll | 100 | 500 |
| Flights Indicative Prices | 100 | 500 |

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](/tr/metasearch/flights/skyscanner) 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.

## 18. Deep link handoff

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

| Test | Beklenen |
|---|---|
| one-way | tek leg |
| return | iki leg |
| direct | 0 stop |
| multi-segment | doğru segment chain |
| multiple agents | aynı itinerary, farklı offers |
| child passenger | age context korunuyor |
| business cabin | doğru cabin |
| different currency | doğru price currency |
| first create partial | UI partial gösteriyor |
| multiple polls | merge duplicate üretmiyor |
| completed status | polling duruyor |
| 429 | backoff |
| 401 | retry yok / credential alert |
| provider 503 | controlled retry |
| click handoff | itinerary 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
```
