Flight v2 API Guideline
Flight v2 is the multi-provider flight flow. A single set of endpoints fans out to every flight provider enabled for your partner account, merges the results, and completes the booking through the shared Unified Booking checkout used by all Onlynx products.
:::info Flight v1 vs Flight v2
The Flight section documents the original single-provider (Fliggy) flow, where booking
was submitted to a flight-only make-order endpoint. Flight v2 keeps the same search →
enrich → pricing → ancillary stages, but the booking itself is created through
/unified-booking/checkout and /unified-booking/checkout/confirm, so a flight can share a
cart, a payment and a booking number with hotels, tours and transfers.
Both are live. Flight v2 is the recommended integration for new partners. :::
Providers
Three providers sit behind the same endpoints:
| Provider | provider in response | Identifier prefix | Notes |
|---|---|---|---|
| Fliggy | FLIGGY | (none) | Legacy default. No seat map. |
| Hitit | HITIT | HITIT_ | Baggage + meal ancillaries, seat map. |
| FlightRoute | FLIGHTROUTE | FR24_ | Baggage ancillaries, seat map. |
You never select a provider explicitly. Every identifier you receive (solutionId,
session_id) carries its provider prefix, and the API routes the follow-up call for you.
Which providers are queried is controlled by the flight providers enabled on your partner
account, so an account may see results from one, two or all three.
Base URLs
- UAT (Testing/Development):
https://api.dev.onlynx.co.th - Production:
https://api.onlynx.co.th
All Flight v2 endpoints are under the /api/v1 prefix.
Headers
Every endpoint in this section accepts the same headers.
| Header | Value | Required | Description |
|---|---|---|---|
Partner-Access-Token | Base64 String | Yes | Your encrypted AES-256 time-sensitive token. |
X-Currency | Currency Code | Optional | Display currency, e.g. THB, MMK, USD. Falls back to your partner default, then THB. |
Accept-Language | Language Code | Optional | e.g. en, th, my. Falls back to en. |
Content-Type | application/json | Yes | |
Accept | application/json | Yes |
The four My Bookings endpoints additionally require an end-user token:
| Header | Value | Required | Description |
|---|---|---|---|
Authorization | Bearer <token> | Yes | Customer access token from the Login endpoint. |
Response Envelope
Every JSON endpoint returns the same envelope.
{
"result": 1,
"message": "success",
"data": { },
"meta": { }
}
| Field | Type | Description |
|---|---|---|
result | Integer | 1 on success, 0 on failure. |
message | String | Human-readable status or error message. |
data | Object/Array | Payload. Omitted on plain failure responses. |
meta | Object | Present only on endpoints that return one (pricing, checkout, booking list). |
A failed call still returns HTTP 200 with "result": 0 and a message. Validation errors
are returned as HTTP 422 in Laravel's standard shape:
{
"message": "The products.0.passengers.0.document_number field is required.",
"errors": {
"products.0.passengers.0.document_number": [
"Passenger document number is required."
]
}
}
Authentication failures return HTTP 401 with {"error": "..."}.
Key Casing
The two endpoint families differ, and this catches integrations out:
| Endpoints | Casing |
|---|---|
/flights/* | Provider payloads keep their original camelCase keys — solutionId, journeyList, segmentList, pricingDetails. |
/unified-booking/* | The whole response is converted to snake_case — solution_id, journey_list, segment_list, pricing_details. |
/bookings* | Not converted. Nested provider payloads keep camelCase. |
All-uppercase keys (ADT, CHD) and keys containing punctuation or spaces ("0-0",
"Checked Baggage") are never converted.
Booking Flow
Identifier Lifecycle
This is the part that most often trips up an integration. Flight v2 uses three different identifiers, and each one is produced by one endpoint and consumed by another.
| Identifier | Produced by | Consumed by | Meaning |
|---|---|---|---|
solutionId | /flights/search | /flights/enrich, /flights/pricing, /flights/ancillary, /flights/seat-map (as solution_id) | A specific priced itinerary from a provider. |
session_id (pricing) | /flights/pricing | /unified-booking/checkout and /checkout/confirm (as products[].solution_id) | The confirmed, margined price snapshot. |
session_id (ancillary / seat map) | /flights/ancillary, /flights/seat-map | passengers[].ancillary.session_id, passengers[].selected_seats[].session_id | The priced add-on snapshot. |
:::danger The most common integration mistake
At checkout, products[0].solution_id must be the session_id returned by
/flights/pricing — not the solutionId you got from /flights/search.
Passing the search solutionId will fail with
Flight pricing details not found or expired. Please search again.
:::
Sessions are short-lived. If the customer idles between pricing and checkout, re-run
/flights/pricing to obtain a fresh session_id before confirming.
Currency Layers
Three currencies are in play on every flight response. Knowing which is which prevents reconciliation surprises.
| Layer | Field suffix | Description |
|---|---|---|
| Provider | provider_price, original_price | The raw amount the airline/provider quoted, in the provider's own currency. |
| System | _thb (e.g. grand_total_thb, fare_thb) | THB. The internal base currency all margin maths and stored booking totals use. |
| Display | no suffix (e.g. grand_total, fare) | The customer-facing amount, in the currency you requested via X-Currency. |
Margins (admin + partner) are applied at the THB layer, then converted out to the display currency. The amount the customer is charged is the display value; the amount stored on the booking is the system value.
Product Type
Flights are product type pd9 in the Unified Booking payload, for all three providers.
Endpoints
| # | Endpoint | Method | Purpose |
|---|---|---|---|
| 1 | /api/v1/flights/airports | GET/POST | Airport & city lookup. See Flight › Airports. |
| 2 | /api/v1/flights/search | POST | Multi-provider availability search. |
| 3 | /api/v1/flights/enrich | POST | Baggage allowance and refund/change rules. |
| 4 | /api/v1/flights/pricing | POST | Final price + pricing session_id. |
| 5 | /api/v1/flights/ancillary | POST | Extra baggage and meals. |
| 6 | /api/v1/flights/seat-map | GET | Seat map with per-seat pricing. |
| 7 | /api/v1/flights/bookings/* | POST | Direct flight booking, ticket issue, cancel, refund. |
| 8 | /api/v1/unified-booking/checkout | POST | Cart review and totals. |
| 9 | /api/v1/unified-booking/checkout/confirm | POST | Create the booking. |
| 10 | /api/v1/unified-booking/result | POST | Post-payment booking result. |
| 11 | /api/v1/bookings | GET/POST | Customer's booking list. |
| 12 | /api/v1/bookings/{booking_number} | GET/POST | Full booking detail. |
| 13 | /api/v1/bookings/{id}/voucher | GET | Download voucher PDF. KKday only — not for flights. |
| 14 | /api/v1/bookings/{booking_number}/items/{id}/cancel | POST | Cancel a booking item. Tour and KKday only — flights cancel via Booking. |
:::caution Two shared endpoints do not cover flights
/bookings/{id}/voucher and /bookings/{booking_number}/items/{id}/cancel are shared across
all Onlynx products but do not currently handle flight items. Each page explains the
flight alternative.
:::