API Documentation
Send a raw Sabre or Amadeus PNR and get back a fully structured itinerary — not just flights, but hotels, cars, cruises, tours, transfers, insurance, passengers, seats, e-tickets, SSRs/meals, fares and remarks. It's the same engine that powers the web app. Grab your API key from your dashboard.
What it decodes
Recent additions
The /api/convert JSON returns arrival_date and duration per flight, and keeps raw 24-hour HH:MM times and ISO dates. Purely visual touches (12-hour times, layovers, “+1 day”, local-time note) are applied when you render an itinerary via the builder, shareable link or PDF/HTML export.
https://pnrdecode.com/api/convertParses a raw PNR/itinerary string and returns enriched flight segments plus a rich model object containing every non-flight service. Auto-detects Sabre vs Amadeus and reports a confidence score.
Authentication
Pass your API key as a Bearer token. Requests without a valid key return 401; the public API requires the Conversion API plan (403 otherwise). Once your monthly plan limit is reached, requests return 429 until the next billing cycle.
Authorization: Bearer YOUR_API_KEY
Example request
curl -X POST https://pnrdecode.com/api/convert \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"pnr_text": "*ABC123\n 1.1SMITH/JOHN MR\n 2 EK 202Y 09OCT JFKDXB HK1 1010P 705P\n 4 HHL EK HK1 DXB 10OCT-17OCT\n ATLANTIS THE PALM"}'{
"pnr_text": "raw multi-line GDS itinerary string"
}Send the PNR exactly as displayed in your GDS — including hotel (HHL/9H), car (CCR/9C), cruise, tour, transfer, insurance, seat and e-ticket lines. Multi-line native Sabre and Amadeus formats are supported.
Example response
{
"gds": "Sabre",
"gds_confidence": 0.83,
"segments": [
{
"gds": "Sabre",
"airline_code": "EK",
"airline_name": "Emirates",
"airline_logo_url": "https://img.logo.dev/emirates.com?token=...",
"flight_number": "202",
"booking_class": "Y",
"cabin_class": "Economy",
"date_raw": "09OCT",
"date": "9 Oct",
"arrival_date": "10 Oct",
"origin_code": "JFK",
"origin_name": "John F. Kennedy International Airport",
"origin_city": "New York",
"destination_code": "DXB",
"destination_name": "Dubai International Airport",
"destination_city": "Dubai",
"departure_time": "22:10",
"arrival_time": "19:05",
"duration": "11h 55m",
"status_code": "HK1",
"status": "Confirmed",
"record_locator": "ABC123",
"seat": "22A",
"eticket": "1761234567890",
"checkin_baggage": "2PC",
"carry_on_baggage": "7KG",
"frequent_flyer": "EK123456789",
"meal": "Vegetarian (Indian)",
"origin_country": "United States",
"destination_country": "United Arab Emirates",
"origin_latitude": 40.63975, "origin_longitude": -73.77893,
"destination_latitude": 25.25278, "destination_longitude": 55.36444,
"origin_timezone": "America/New_York", "destination_timezone": "Asia/Dubai",
"origin_timezone_short": "EDT", "destination_timezone_short": "+04",
"departure_datetime": "2026-10-09 22:10", "departure_day": "Fri",
"arrival_datetime": "2026-10-10 19:05", "arrival_day": "Sat",
"distance_km": 11000, "distance_miles": 6835,
"transit_time": { "minutes": 150, "hours": 2.5 },
"operated_by": null,
"aircraft": null
}
],
"model": {
"source": { "gds": "Sabre", "confidence": 0.83, "level": "MEDIUM" },
"pnr": { "recordLocator": "ABC123", "creationDate": "2026-10-01", "officeId": "NYCXY1234", "receivedFrom": "JOHN SMITH" },
"passengers": [
{
"id": "1.1", "lastName": "Smith", "firstName": "John", "title": "MR",
"passengerType": "ADT", "passengerTypeName": "Adult",
"seat": "22A", "eticket": "1761234567890", "frequentFlyer": "EK123456789",
"tickets": [ { "airline": "EK", "number": "1761234567890" } ],
"raw": "1.1SMITH/JOHN MR", "confidence": 0.85
}
],
"flights": [
{
"type": "AIR", "segmentNumber": 2,
"marketingCarrier": "EK", "operatingCarrier": null, "codeshare": false,
"airlineName": "Emirates", "flightNumber": "202",
"bookingClass": "Y", "cabin": "Economy",
"departureAirport": "JFK", "departureCity": "New York", "departureCountry": "United States",
"arrivalAirport": "DXB", "arrivalCity": "Dubai", "arrivalCountry": "United Arab Emirates",
"date": "2026-10-09", "rawDate": "09OCT",
"arrivalDate": "2026-10-10", "arrivalRawDate": "10OCT", "arrivalNextDay": true,
"departureTime": "22:10", "arrivalTime": "19:05",
"duration": "11h 55m", "durationMinutes": 715,
"statusCode": "HK", "statusDescription": "Confirmed", "passengerCount": 1,
"terminal": null, "equipment": null, "meal": null, "seat": null,
"gds": "Sabre", "confidence": 0.97
}
],
"hotels": [
{
"type": "HOTEL", "hotelName": "Atlantis The Palm", "city": "DXB", "address": null,
"checkIn": "2026-10-10", "checkOut": "2026-10-17",
"roomType": "Deluxe Ocean Room", "guests": "2 Adults",
"rate": "450.00", "currency": "USD", "confirmationNumber": "H889900",
"cancellation": null, "guarantee": null,
"raw": "4 HHL EK HK1 DXB 10OCT-17OCT ATLANTIS THE PALM", "confidence": 0.8
}
],
"cars": [
{
"type": "CAR", "supplier": "Hertz", "supplierCode": "ZE", "city": "DXB",
"pickupLocation": "DXB", "dropoffLocation": "DXB",
"pickupDate": "2026-10-10", "pickupTime": "21:00",
"dropoffDate": "2026-10-17", "dropoffTime": "06:00",
"vehicleCategory": "Suv", "transmission": "Automatic",
"rate": null, "currency": null, "confirmationNumber": "AVS456123",
"raw": "5 CCR ZE HK1 DXB 10OCT-17OCT/HERTZ", "confidence": 0.7
}
],
"cruises": [
{
"type": "CRUISE", "shipName": "MSC Euribia", "category": "Balcony", "cabin": "12034",
"sailingStart": "2026-10-13", "sailingEnd": "2026-10-17",
"confirmationNumber": "CRUISE12345", "city": "DXB",
"raw": "6 OTH CRUISE MSC EURIBIA ...", "confidence": 0.7
}
],
"tours": [
{
"type": "TOUR", "name": "Dubai Desert Safari", "city": "DXB", "date": "2026-10-12",
"pickup": null, "timeFrom": "15:00", "timeTo": "22:00", "duration": null,
"confirmationNumber": "T1", "raw": "TOUR DUBAI DESERT SAFARI 12OCT 1500-2200", "confidence": 0.75
}
],
"transfers": [
{ "type": "TRANSFER", "detail": "Airport-Hotel", "city": "DXB", "date": "2026-10-13",
"confirmationNumber": null, "raw": "TRF DXB AIRPORT-HOTEL 13OCT", "confidence": 0.7 }
],
"rail": [],
"insurance": [
{ "type": "INSURANCE", "provider": "Travel Insurance", "policyNumber": "ABC123456",
"city": null, "raw": "INSURANCE TRAVEL INSURANCE POLICY ABC123456", "confidence": 0.75 }
],
"seats": [
{ "type": "SEAT", "seats": [ { "seat": "22A", "passengerId": "1.1", "segment": "2" } ],
"raw": "ST/22A/P1/S2", "confidence": 0.85 }
],
"ssr": [
{ "code": "VGML", "description": "Vegetarian (Indian)", "airline": "EK", "status": "HK",
"passengerId": "1.1", "text": "HK1/P1", "raw": "SSR VGML EK HK1/P1", "recognized": true,
"confidence": 0.9, "flightIndex": 0, "associationConfidence": 0.9 }
],
"osi": [],
"tickets": [
{ "kind": "ticket", "ticketNumber": "1761234567890", "airlinePrefix": "176", "status": "ISSUED",
"passengerId": "1.1", "passengerName": null, "raw": "FA PAX 176-1234567890/ETEK/P1",
"confidence": 0.85, "associationConfidence": 0.9 }
],
"emds": [],
"payments": [],
"fares": [],
"remarks": [],
"contacts": [
{ "type": "CONTACT", "kind": "email", "phone": null, "email": "john.smith@example.com",
"belongsTo": null, "raw": "CTCE JOHN.SMITH//EXAMPLE.COM", "confidence": 0.8 }
],
"addresses": [],
"ticketing": {
"ticketTimeLimit": null, "validatingCarrier": "EK", "receivedFrom": "JOHN SMITH",
"endorsement": null, "commission": null, "corporateDiscount": null, "nonRefundable": null
},
"confidence": { "overall": 0.82, "level": "MEDIUM", "uncertainCount": 0 },
"validation": { "ok": true, "notes": [] },
"unknownSegments": [],
"errors": [],
"classifiedLines": [ { "lineNumber": 1, "raw": "*ABC123", "text": "*ABC123", "type": "PNR_HEADER", "confidence": 0.9 } ]
},
"extras": {
"frequent_flyer": [], "meals": [], "special_assistance": [], "ssr": [], "contacts": [],
"fare": {}, "baggage": [], "eticket_numbers": [], "record_locator": null, "conditions": []
},
"warnings": [],
"error": null,
"calls_remaining": 19
}Every array is always present (empty [] when the PNR has none). In segments, date / arrival_date are short display strings; in model, dates are ISO YYYY-MM-DD and times are 24-hour HH:MM. Anything the parser couldn't confidently map appears in model.unknownSegments, and any credit-card PAN in the source is masked.
Response fields
Complete list of keys returned per segment type. Keys marked optional are omitted when the PNR has no such data; every other key is always present (value may be null). Airport geo/timezone fields on segments[] are derived offline from the bundled airports dataset by IATA code.
gdsstringSabre · Amadeus · Genericairline_codestring2-letter IATA marketing carrierairline_namestringResolved airline name (falls back to the code)airline_logo_urlstring | nullLogo URL when availableflight_numberstringbooking_classstringRBD letter, e.g. Ycabin_classstringEconomy · Premium Economy · Business · Firstdate_rawstringDeparture date as written, e.g. 09OCTdatestringDeparture date display, e.g. 9 Octarrival_datestringResolved arrival date display (explicit /DDMMM, +1 markers and overnight legs handled)origin_code / destination_codestringIATA airport codesorigin_name / destination_namestringAirport name (falls back to the code)origin_city / destination_citystringCity (empty string when unknown)departure_time / arrival_timestringLocal airport time, 24-hour HH:MMdurationstringTimezone-aware block time, e.g. 11h 55m (empty when it can't be computed)status_codestringRaw GDS status incl. pax count, e.g. HK1statusstringConfirmed · Waitlisted · Pending · Cancelled …record_locatorstringOptional — only present when the PNR carries the data (airline locator on the line)next_daybooleanOptional — only present when the PNR carries the data (only on native multi-line PNRs)seat, eticket, checkin_baggage, carry_on_baggage, frequent_flyer, mealstringOptional — only present when the PNR carries the dataorigin_country / destination_countrystring | nullCountry name from the airports datasetorigin_latitude, origin_longitude, destination_latitude, destination_longitudenumber | nullDecimal degreesorigin_timezone / destination_timezonestring | nullIANA zone, e.g. Asia/Kolkataorigin_timezone_short / destination_timezone_shortstring | nullAbbreviation at the local date/time, e.g. IST, GMT, +03departure_datetime / arrival_datetimestring | nullLocal, YYYY-MM-DD HH:MMdeparture_day / arrival_daystring | null3-letter weekday, e.g. Satdistance_km / distance_milesnumber | nullGreat-circle (Haversine) distance, roundedtransit_timeobject{ minutes, hours } gap to the next segment's departure (timezone-aware); {} on the last segmentoperated_by / aircraftstring | nullOperating carrier / equipment when present in the PNR, else nulltype"AIR"segmentNumbernumber | nullGDS element numbermarketingCarrier / operatingCarrierstring | nulloperatingCarrier is reserved; currently nullcodesharebooleanReserved; currently falseairlineName, flightNumber, bookingClass, cabinstringdepartureAirport / arrivalAirportstringIATA codesdepartureCity, departureCountry, arrivalCity, arrivalCountrystring | nulldate / arrivalDatestringISO YYYY-MM-DDrawDate / arrivalRawDatestring | nullAs written in the PNR, e.g. 10OCTdepartureTime / arrivalTimestring24-hour HH:MM localarrivalNextDaybooleanTrue when a +1/#1 marker (or overnight roll-over) appliesduration / durationMinutesstring / number | nullTimezone-awarestatusCode / statusDescriptionstringe.g. HK / ConfirmedpassengerCountnumber | nullterminal, equipment, meal, seatstring | nullReserved slots; populated when present on the linegds, confidencestring, numbertype"HOTEL"hotelName, city, addressstring | nullcheckIn / checkOutstring | nullISO YYYY-MM-DDroomType, guestsstring | nullrate, currencystring | nullconfirmationNumber, cancellation, guaranteestring | nullraw, confidencestring, numberSource text and 0–1 confidencetype"CAR"supplier, supplierCodestring | nulle.g. Hertz / ZEcity, pickupLocation, dropoffLocationstring | nullpickupDate / dropoffDatestring | nullISO YYYY-MM-DDpickupTime / dropoffTimestring | null24-hour HH:MMvehicleCategory, transmissionstring | nullrate, currency, confirmationNumberstring | nullraw, confidencestring, numbertype"CRUISE"shipName, category, cabinstring | nullsailingStart / sailingEndstring | nullISO YYYY-MM-DDconfirmationNumber, citystring | nullraw, confidencestring, numbertype"TOUR"name, citystring | nulldatestring | nullISO YYYY-MM-DDpickup, timeFrom, timeTo, durationstring | nullconfirmationNumberstring | nullraw, confidencestring, numbertype"TRANSFER"detail, citystring | nulldatestring | nullISO YYYY-MM-DDconfirmationNumberstring | nullraw, confidencestring, numberpassengers[]objectid, lastName, firstName, title, passengerType, passengerTypeName, raw, confidence + optional seat, eticket, frequentFlyer, tickets[{airline, number}]insurance[]objecttype, provider, policyNumber, city, raw, confidenceseats[]objecttype, seats[{seat, passengerId, segment}], raw, confidencessr[]objectcode, description, airline, status, passengerId, text, raw, recognized, confidence, flightIndex, associationConfidence + document{} (DOCS) / frequentFlyer (FQTV)tickets[]objectkind, ticketNumber, airlinePrefix, status, passengerId, passengerName, raw, confidence, associationConfidenceemds[] · payments[] · fares[]objectemdNumber · method, brand, maskedNumber, last4, expiry · baseFare, taxes, total, currency, fareBasiscontacts[] · addresses[] · osi[] · remarks[]objecttype/kind, phone, email, belongsTo · kind, text · code, carrier, text · type, qualifier, textpnr · ticketingobjectrecordLocator, creationDate, officeId, receivedFrom · ticketTimeLimit, validatingCarrier, receivedFrom, endorsement, commission, corporateDiscount, nonRefundableconfidence · validation · errors[] · classifiedLines[] · unknownSegments[]objectParser diagnostics: overall score, sanity notes, unmatched lines with reasons, per-line classificationgds / gds_confidencestring | null / numberDetected GDS and 0–1 confidencesegments[]arrayFlat enriched flights (above)modelobjectUniversal PNR Model (above)extrasobjectfrequent_flyer[], meals[], special_assistance[], ssr[], contacts[], fare{}, baggage[], eticket_numbers[], record_locator, conditions[] — legacy aggregate; may be {} for native multi-line PNRswarnings[]string[]Unknown airline/airport codeserrorstring | nullcalls_remainingnumber | nullnull on unlimited tiers