Car rentalscar_rentals
/api/v1/imports/car_rentalsCreate-once: re-sending the same external_id skips rather than duplicating.
Endpoints
- validatePOST /api/v1/imports/car_rentals/validate
- importPOST /api/v1/imports/car_rentals
- feedGET /api/v1/imports/car_rentals/records
- read_backGET /api/v1/imports/car_rentals/records/{external_id}
A new row must carry
pickup_locationdropoff_locationpickup_atreturn_at
Sample request billed by its bill-to (no customer key)
curl -X POST 'https://YOUR-CELL.lydira.com/api/v1/imports/car_rentals/validate' \
-H 'Authorization: Bearer sek_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: 8f14e45f-ea2c-4f33-9a3b-6d0c1b7e5a90' \
-d '{
"source_system": "crm",
"rows": [
{
"external_id": "CAR-RENTAL-1001-B",
"vehicle_class": "compact",
"pickup_location": "IST Airport",
"dropoff_location": "Beyoğlu, İstanbul",
"pickup_at": "2026-03-14T09:30:00+03:00",
"return_at": "2026-03-14T12:45:00+03:00",
"pax_count": 2,
"currency": "EUR",
"supplier_external_id": "SUPPLIER-1001",
"status": "draft",
"notes": "Imported from the source system.",
"rate_basis": "net",
"margin_mode": "percent",
"option_date": "2026-03-20T18:00",
"transaction_date": "2026-03-14",
"invoice_date": "2026-03-18",
"cost_lines": [
{
"kind": "daily_rate",
"amount": "1250.00",
"label": "Imported line",
"currency": "EUR",
"vat_rate": "20",
"tax_inclusive": true,
"quantity": 1
}
],
"sell_lines": [
{
"kind": "package_price",
"amount": "1250.00",
"label": "Imported line",
"currency": "EUR",
"vat_rate": "20",
"tax_inclusive": true,
"quantity": 1
}
],
"travelers": [
{
"first_name": "Ada",
"last_name": "Lovelace",
"nationality": "TR",
"national_id": "10000000146",
"passport_number": "U01234567",
"passport_country": "TR",
"passport_expiry": "2031-06-30",
"date_of_birth": "1988-04-21",
"gender": "MRS",
"frequent_flyer_number": "TK123456789"
}
],
"bill_to_legal_name": "Lovelace Seyahat A.Ş.",
"bill_to_tax_number": "1234567890",
"bill_to_tax_office": "Beşiktaş",
"bill_to_address_line": "Nispetiye Cad. No:12",
"bill_to_city": "İstanbul",
"bill_to_country": "TR"
}
]
}'Fields(43)
external_idstringvehicle_classstringValues the app uses:
economycompactintermediatestandardfullsizesuvpremiumluxuryminivanpickup_locationstringrequireddropoff_locationstringrequiredpickup_atdatetimerequiredreturn_atdatetimerequiredpax_countintegercurrencycurrencycustomer_external_idreferencesupplier_external_idreferencecustom_fieldsobjectthe account's own fields on the booking, by key
statusenumOne of:
draftoptionconfirmedoutreturnedcancelledno_shownotesstringrate_basisenumnet ⇒ cost typed / sell derived; commissionable ⇒ the reverse
One of:
netcommissionablemargin_modeenumpercent ⇒ the margin was typed as a %; amount ⇒ as a flat figure
One of:
percentamountoption_datedatetransaction_datedateişlem tarihi — the FX anchor for every cost line
invoice_datedatecost_linesobject[]cost-side pricing lines for the "car_rental" pricing context
Each item
kindstringrequiredValues the app uses:
daily_rateinsurancefuel_planyoung_driver_feeadditional_drivergpschild_seatone_way_feeextra_equipmentextra_mileageservice_feesupplier_refundinsurance_premiumamountmoneyrequiredlabelstringcurrencycurrencyvat_ratedecimalpercent (20 ⇒ 20% KDV); omit to take the kind's default
tax_inclusivebooleantrue ⇒ the amount includes VAT. A hotel stay or a charter takes one VAT mode: the lines' flags decide it, lines stating both are refused, and every line follows the booking's mode afterwards
quantityinteger
sell_linesobject[]sell-side pricing lines for the "car_rental" pricing context
Each item
kindstringrequiredValues the app uses:
package_pricemarkupservice_feesupplier_commissioncancellation_feeinsurance_premiumdiscountrefund_allowancedaily_rateinsurancefuel_planyoung_driver_feeadditional_drivergpschild_seatone_way_feeextra_equipmentextra_mileagesupplier_refundamountmoneyrequiredlabelstringcurrencycurrencyvat_ratedecimalpercent (20 ⇒ 20% KDV); omit to take the kind's default
tax_inclusivebooleantrue ⇒ the amount includes VAT. A hotel stay or a charter takes one VAT mode: the lines' flags decide it, lines stating both are refused, and every line follows the booking's mode afterwards
quantityinteger
markupmoneythe agency's hidden markup on the whole booking, in its currency: split across the guests by their cost (by their sell when the booking carries no cost) and folded into each guest's fare on the invoice
markup_percentdecimalthe markup as a percentage of the booking's cost; wins over
markupdiscountmoneythe whole booking's discount (iskonto), a positive figure: split across the guests by what each owes, after the markup and the service fee
discount_percentdecimalthe discount as a percentage of everything the booking sells, the markup and the service fee included; wins over
discountservice_feemoneythe agency's fee for the whole booking, in its currency; split across the guests like the booking form's. Sent, the account's service-fee rules write nothing
service_fee_percentdecimalthe fee as a percentage (0-100) of the booking's sale before fee and discount, instead of
service_fee; split like itservice_fee_vat_ratedecimalthe fee's VAT, percent (0 ⇒ exempt); omit it and the law decides, else the seller's standard rate
service_fee_waivedbooleantrue: the account's service-fee rules write no fee on this booking
travelersobject[]PIIguests; auto-saved to the customer's traveller directory
Each item
first_namestringPIIlast_namestringPIInationalitystringnational_idstringPIIpassport_numberstringPIIpassport_countrystringpassport_expirydatedate_of_birthdatePIIgenderstringValues the app uses:
MRMRSMISSMSTRfrequent_flyer_numberstringcustom_fieldsobjectthe account's own fields on the guest, by key
bill_to_typeenumomit to infer: a legal name or a 10-digit tax number ⇒ corporate
One of:
corporateindividualbill_to_legal_namestringbill_to_tax_numbertax_numberPIIVKN for a corporate payer, TCKN for an individual; matched digits-only
bill_to_tax_officestringbill_to_passport_numberstringPIIindividual only; used when there is no TCKN
bill_to_first_namestringPIIbill_to_last_namestringPIIbill_to_emailemailPIIstored on a NEW cari; never used to match
bill_to_phonephonePIIstored on a NEW cari; never used to match
bill_to_address_linestringPIIbill_to_districtstringPIIbill_to_citystringPIIbill_to_zipstringPIIbill_to_countrystringISO-2 code, e.g. TR
Your account's own fields (custom_fields)
Each agency adds its own fields in Settings → Custom fields: a project code, a trip reason, an employee number. They differ from account to account, so this page cannot list them. Your integration asks the API for them.
GET /api/v1/imports/entities/{key} answers, under custom_fields, the fields your key's account has on this entity: record for the record itself, traveler for each traveller. Each one names its key (what the row sends), its type, whether it is required, which customers it applies_to and, for a choice, its options. Read it when you build the mapping and again when the agency says it changed a field: it is the account's live list.
Request · the account's fields
curl -X GET 'https://YOUR-CELL.lydira.com/api/v1/imports/entities/car_rentals' \
-H 'Authorization: Bearer sek_YOUR_API_KEY'{
"key": "car_rentals",
"custom_fields": {
"record": [
{
"key": "project_code",
"label": "Project code",
"type": "text",
"required": "always",
"applies_to": "all"
},
{
"key": "trip_reason",
"label": "Trip reason",
"type": "select",
"required": "listed_customers",
"applies_to": "listed_customers",
"options": [
{
"value": "meeting",
"label": "Meeting"
},
{
"value": "fair",
"label": "Trade fair"
}
],
"customers": [
{
"id": "9d2f7c3a-1b4e-4a7d-8e51-2c0f6b9a4d18",
"external_id": "CUST-17",
"required": true
}
]
}
],
"traveler": [
{
"key": "employee_no",
"label": "Employee no",
"type": "text",
"required": "never",
"applies_to": "all",
"pii": true
}
]
}
}What each type takes
| type | value in the row |
|---|---|
text | "PRJ-2026-001" |
long_text | "Fair delegation, second group" |
number | 12.5 |
date | "2026-03-14" |
boolean | true |
select | "meeting" |
multi_select | ["meeting", "fair"] |
number takes a number or a numeric string; date an ISO date; select one
option value (or its label); multi_select a list of them.
required and applies_to
requiredneveralwayslisted_customerslisted_customers: required only for the customers markedrequiredincustomers.applies_toalllisted_customerslisted_customers: the field is accepted only on those customers' records.
Send the values as one JSON object by key. An unknown key, a value of the wrong type or a missing required field fails the row and names the key. On an amendment (on_conflict: update) the object merges by key: a key you leave out is kept, a key sent as null is removed. A field the agency prints on the customer's documents cannot change once the record is invoiced.
Traveller fields go on each traveller, under that item's own custom_fields.
They come back the same way: under detail.custom_fields in the read-back and the webhook body (and on each passenger of a ticket). A field marked personal comes back only to a key whose role can read personal data, and never in a webhook.
Reading it back
Once the agency works the record (confirms it, numbers the tickets, invoices it) this is what GET /api/v1/imports/{entity}/records/{external_id} answers, and what every webhook delivers. detail carries what only the agency can add after your push.
{
"entity": "car_rentals",
"external_id": "CAR-RENTAL-1001",
"source_system": "crm",
"type": "CarRental",
"id": "9d2f7c3a-1b4e-4a7d-8e51-2c0f6b9a4d18",
"created_at": "2026-03-14T09:30:00Z",
"updated_at": "2026-03-15T11:05:00Z",
"status": "confirmed",
"locked": true,
"lock_reason": "invoiced",
"currency": "EUR",
"totals": {
"cost": "1100.0",
"sell": "1250.0"
},
"invoices": [
{
"id": "4b8e1f60-7c2d-4e9a-b3f5-0a6d2c9e8b71",
"number": "LYD2026000000117",
"status": "issued",
"currency": "EUR",
"total": "1250.0",
"balance": "1250.0"
}
],
"detail": {
"voucher_number": "VCH-2026-000412",
"supplier_confirmation_no": "CNF-77821",
"supplier": "Lovelace Travel Partners",
"custom_fields": {
"project_code": "PRJ-2026-001",
"trip_reason": "meeting"
},
"vehicle_class": "compact",
"pickup_at": "2026-03-14T06:30:00Z",
"return_at": "2026-03-18T06:30:00Z",
"pickup_location": "IST Airport",
"dropoff_location": "Beyoğlu, İstanbul"
}
}Request · dry run, every field
curl -X POST 'https://YOUR-CELL.lydira.com/api/v1/imports/car_rentals/validate' \
-H 'Authorization: Bearer sek_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: 8f14e45f-ea2c-4f33-9a3b-6d0c1b7e5a90' \
-d '{
"source_system": "crm",
"rows": [
{
"external_id": "CAR-RENTAL-1001",
"vehicle_class": "compact",
"pickup_location": "IST Airport",
"dropoff_location": "Beyoğlu, İstanbul",
"pickup_at": "2026-03-14T09:30:00+03:00",
"return_at": "2026-03-14T12:45:00+03:00",
"pax_count": 2,
"currency": "EUR",
"customer_external_id": "CUSTOMER-1001",
"supplier_external_id": "SUPPLIER-1001",
"custom_fields": {
"project_code": "PRJ-2026-001",
"trip_reason": "meeting"
},
"status": "draft",
"notes": "Imported from the source system.",
"rate_basis": "net",
"margin_mode": "percent",
"option_date": "2026-03-20T18:00",
"transaction_date": "2026-03-14",
"invoice_date": "2026-03-18",
"cost_lines": [
{
"kind": "daily_rate",
"amount": "1250.00",
"label": "Imported line",
"currency": "EUR",
"vat_rate": "20",
"tax_inclusive": true,
"quantity": 1
}
],
"sell_lines": [
{
"kind": "package_price",
"amount": "1250.00",
"label": "Imported line",
"currency": "EUR",
"vat_rate": "20",
"tax_inclusive": true,
"quantity": 1
}
],
"markup": "1250.00",
"markup_percent": "10",
"discount": "1250.00",
"discount_percent": "5",
"service_fee": "1250.00",
"service_fee_vat_rate": "20",
"service_fee_waived": true,
"travelers": [
{
"first_name": "Ada",
"last_name": "Lovelace",
"nationality": "TR",
"national_id": "10000000146",
"passport_number": "U01234567",
"passport_country": "TR",
"passport_expiry": "2031-06-30",
"date_of_birth": "1988-04-21",
"gender": "MRS",
"frequent_flyer_number": "TK123456789",
"custom_fields": {
"employee_no": "E-10442"
}
}
]
}
]
}'{
"import": {
"id": "9d2f7c3a-1b4e-4a7d-8e51-2c0f6b9a4d18",
"entity": "car_rentals",
"source_system": "crm",
"status": "ready",
"company_id": "9d2f7c3a-1b4e-4a7d-8e51-2c0f6b9a4d18",
"stats": {
"total": 1,
"will_create": 1,
"will_update": 0,
"created": 0,
"updated": 0,
"skipped": 0,
"invalid": 0,
"failed": 0,
"not_selected": 0
},
"error": null,
"created_at": "2026-03-14T09:30:00Z",
"links": {
"self": "/api/v1/imports/9d2f7c3a-1b4e-4a7d-8e51-2c0f6b9a4d18",
"rows": "/api/v1/imports/9d2f7c3a-1b4e-4a7d-8e51-2c0f6b9a4d18/rows"
},
"mode": "validate",
"async": false,
"on_conflict": "skip",
"pricing": "apply_rules"
},
"ignored_fields": [],
"results": [
{
"row": 1,
"external_id": "CAR-RENTAL-1001",
"status": "will_create",
"payer": {
"outcome": "external_id",
"customer_id": "9d2f7c3a-1b4e-4a7d-8e51-2c0f6b9a4d18"
}
}
]
}