7Buy a fare that cannot be held
/api/v1/flights/purchasesReachable with a narrow key: flight_booking
holdable: false fares: book and ticket in one call with the passengers, the bill_to, the price_token and the payment. Send the same bill_to and company you priced for. A purchase takes money at once, so it needs a customer: with no VKN, TCKN or passport to go on it answers 422 payer_required. A fare that moved since answers 409 price_changed with no figure: price again and send the new token with a new Idempotency-Key.Parameters
Headers
Idempotency-KeystringrequiredYour own unique string for this purchase, max 255 characters.
Body
company_iduuidThe agency company that sells. Defaults to the account's default company.
search_idstringrequiredFrom the search answer.
offer_keystringrequiredThe chosen offer's
key.passengersobject[]requiredOne entry per passenger, as many as the search asked for.
Show fieldsHide fields
first_namestringrequiredAs on the passport.
last_namestringrequiredAs on the passport.
passenger_typeenumrequiredADTadult,CHDchild,INFinfant. The counts must match the search.one of
ADTCHDINFdate_of_birthdateRequired for children and infants, and by some suppliers for every passenger.
genderenumForM, as on the passport.one of
FMpassport_numberstringWritten into the booking; never read back.
passport_countrystringIssuing country (ISO 3166 alpha-2).
passport_expirydateMust be valid beyond the travel dates; many countries ask for six months.
national_idstringNational identity number, where the route asks for one (e.g. Turkish domestic flights).
nationalitystringISO 3166 alpha-2.
frequent_flyerstringLoyalty number, credited by the airline.
contactobjectWritten into the booking so the airline can reach the traveller about a schedule change.
Show fieldsHide fields
emailemailWhere the airline sends schedule changes.
phonestringWhere the airline calls or texts about disruptions. International format.
bill_toobjectWho the booking bills, found by the ticket import's own rules. A company (
corporate) is found by its VKN, then by its legal name, and opened when neither is on file. A person (individual) is found by TCKN (this one, else the first passenger'snational_id), then by passport (this one, else the first passenger's), and opened from these fields or the first passenger. Never by email, phone or name. A cari that is found only has its blank fields filled; nothing on file is overwritten. Sendcustomer_idinstead when you hold it.Show fieldsHide fields
typeenumindividual(a person) orcorporate(a company). Defaults toindividual; a 10-digittax_numberreads as corporate.one of
individualcorporatelegal_namestringThe company's registered name. Corporate: required when
tax_numberis missing; finds the cari when the VKN does not.tax_numberstringVKN (10 digits) for a company, TCKN (11 digits) for a person. The first key the cari is found by.
tax_officestringThe company's tax office, for the invoice.
passport_numberstringIndividual: finds the cari when there is no TCKN.
first_namestringIndividual: the payer's first name, when it is not the first passenger.
last_namestringIndividual: the payer's last name.
emailemailWritten onto the cari for the invoice; never used to find one.
phonestringInternational format; never used to find a cari.
address_linestringStreet and number, for the invoice.
districtstringDistrict (ilçe).
citystringCity (il).
zipstringPostal code.
countrystringISO 3166 alpha-2.
customer_iduuidInstead of
bill_to, when you hold the agency's id for the payer.remarksstringA free-text note written into the booking.
price_tokenstringrequiredFrom
price, for the same offer, bill-to and company. Valid 15 minutes.paymentobjectrequiredThe payment your website already took on its own POS. Recorded only if the ticket is issued.
Show fieldsHide fields
amountstringrequiredMust equal the booking total.
currencystringMust equal the booking's currency.
referencestringrequiredYour POS transaction reference.
installmentsintegerNumber of installments taken on the card. Defaults to 1.
paid_atdate-timeWhen the card was charged. Defaults to now.
merchant_account_iduuidRequired when the agency has more than one POS.
Response · 201
iduuidThe booking id.
statusenumheldwaits for payment,ticketingis paid and waiting for numbers,ticketedis done;cancelled,expiredandfailedare closed.one of
pendingheldawaiting_approvalticketingticketedpartially_ticketedcancelledexpiredfailedrecord_locatorstringThe airline booking reference (PNR).
ticketing_time_limitdate-timeWhile
held: ticket before this, or the hold lapses.sale_iduuidThe sale in the agency's books.
totalstringThe sell total of the booking.
currencystringISO 4217 code of
total.pendingbooleanPaid, ticket numbers not issued yet. The ticket webhook fires when they are.
ticketsobject[]One per passenger once issued.
Show fieldsHide fields
ticket_numberstringThe e-ticket number.
passenger_namestringAs printed on the ticket (SURNAME/GIVEN).
booking_iduuidThe booking id.
payment_recordedbooleanFalse: the ticket stands, but the payment must be recorded by hand.
amount_mismatchbooleanTrue: the supplier booked at another total than the one you charged. The agency is told; settle the difference with your customer.
payerobjectThe cari this booking bills.
customer_id: the id you sent won.matched: a cari on file carried the identity (bysays which);filledlists the blank fields your bill-to completed.created: a new cari was opened from your bill-to or the first passenger.none: no cari yet;warningsays why (payer_unidentified: no VKN, TCKN or passport to go on). Sendbill_towith the ticket call then.Show fieldsHide fields
outcomeenumHow the cari was resolved.
one of
customer_idmatchedcreatednonebyenumOn
matched: the identity that found it.one of
tax_numberlegal_namepassportcustomer_iduuidThe cari's id; keep it and send it as
customer_idnext time.filledstring[]On
matched: the blank fields your bill-to completed.warningenumWhy there is no cari, or why your bill-to filled nothing.
one of
payer_unidentifiedpayer_fill_skipped
Responses
202The call is running. Readpoll_urlafterRetry-Afterseconds until it answers anything but202; after 3 minutes the call is lost and the poll says what to do.401Missing or invalid Bearer token403The key cannot reach the booking API: the account lacks an add-on (addon_required, withdetails.missing), the plan has no API access, or the key's scope is narrow.409The booking cannot go ahead as asked.price_changed: price again and confirm the new total with your customer.approval_required: the agency approves the ticket first, then call ticket again.hold_expired: search again.410The search or the offer has expired. Search again.422The request was refused before anything was booked, or the supplier refused it (provider_rejected, with its reason inerror).502The supplier's answer is unknown: the booking may or may not exist, and money may already have moved. It is also whatpoll_urlanswers when a hold, a ticket, a release or a purchase did not finish in 3 minutes, and what a hold, a ticket or a purchase sent again with itsIdempotency-Keyanswers once its call can no longer be read. Read the booking (GET /api/v1/flights/bookings/{booking_id}) before you retry or refund anything, and refund the card only if it was not ticketed. A hold, a ticket or a purchase keeps this answer under itsIdempotency-Key, so a new attempt takes a new key; a release is sent again. With nobooking_id, no booking was found under the key: hold again with a new key, and ask the agency before you refund a purchase.503The supplier could not be reached, the call could not be queued, or a search, a price or the rules did not finish in 3 minutes (provider_unavailable). Nothing was booked: a search costs nothing, and a hold or a purchase is retried with the sameIdempotency-Key.
curl -X POST 'https://YOUR-CELL.lydira.com/api/v1/flights/purchases' \
-H 'Authorization: Bearer sek_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: 8f14e45f-ea2c-4f33-9a3b-6d0c1b7e5a90' \
-d '{
"company_id": "3f1c2b9a-6d4e-4c1a-9b2f-1a2b3c4d5e6f",
"search_id": "eyJfcmFpbHMiOnsiZGF0YSI6eyJhY2NvdW50X2lkIjoi",
"offer_key": "sbx_TK_1979_Y",
"passengers": [
{
"first_name": "Deniz",
"last_name": "Arslan",
"passenger_type": "ADT",
"date_of_birth": "1985-06-01",
"gender": "F",
"passport_number": "U7654321",
"passport_country": "TR",
"passport_expiry": "2031-01-01",
"nationality": "TR"
}
],
"contact": {
"email": "deniz@example.com",
"phone": "+905551112233"
},
"bill_to": {
"type": "individual",
"tax_number": "10000000146",
"email": "deniz@example.com"
},
"price_token": "eyJfcmFpbHMiOnsiZGF0YSI6eyJzZWxsX3RvdGFsIjoi",
"payment": {
"amount": "412.50",
"currency": "EUR",
"reference": "POS-884213",
"installments": 1
}
}'{
"id": "2c3d4e5f-6a7b-4c8d-9e0f-1a2b3c4d5e6f",
"status": "ticketed",
"record_locator": "ABC123",
"ticketing_time_limit": "2026-10-08T18:00:00Z",
"sale_id": "7e6d5c4b-3a2f-4e1d-8c0b-9a8f7e6d5c4b",
"total": "412.50",
"currency": "EUR",
"pending": false,
"tickets": [
{
"ticket_number": "235-1234567890",
"passenger_name": "ARSLAN/DENIZ"
}
],
"booking_id": "2c3d4e5f-6a7b-4c8d-9e0f-1a2b3c4d5e6f",
"payment_recorded": true,
"amount_mismatch": false,
"payer": {
"outcome": "matched",
"by": "tax_number",
"customer_id": "5b4a3c2d-1e0f-4a9b-8c7d-6e5f4a3b2c1d",
"filled": [
"tax_office",
"address"
],
"warning": "payer_unidentified"
}
}