Skip to content

Lookups

A lookup retrieves one booking. It starts with a request, runs in the background, and ends with the reservation or the reason it couldn't get one.

Start a lookup

POST/v1/lookups

FieldRequiredWhat it is
airlineYesThe airline's two-letter IATA code, like LH
pnrYesThe booking reference, as the passenger has it
surnameYesThe passenger's surname, as it is on the booking
passengerFor some airlinesfirst_name, email or ticket_number, when the airline asks for more. Airlines says which
consentYespassenger_authorised: your confirmation that the passenger asked you to retrieve this booking
freshNotrue reads the booking again even if we read it in the last ten minutes. See Repeats

Send an Idempotency-Key header unique to the request, such as your order ID. If the request is retried with the same key within 24 hours, you get the same lookup back rather than a second one.

Statuses

StatusWhat it meansWhat you do
queuedAccepted, waiting its turnNothing
processingThe booking is being readNothing
action_requiredThe airline asked for something only the passenger hasAsk them, then send it back
manual_reviewA person is finishing it, if you turned that onNothing: a webhook follows
completedRetrieved and confirmed against the published scheduleRead reservation
failedCouldn't be retrieved, and error says whySee Failures
expiredThe passenger's answer didn't arrive in timeStart a new lookup

Every change of status sends a lookup.status_changed webhook. Only completed counts toward your plan.

When the airline asks the passenger

Some airlines send the passenger a code, or ask for a detail the booking reference doesn't cover. The lookup moves to action_required and says what's needed:

{
  "id": "lkp_01JC9V2M8R",
  "status": "action_required",
  "required_input": {
    "type": "one_time_code",
    "prompt": "Enter the code the airline sent to the passenger's email",
    "expires_at": "2026-12-04T09:24:05Z"
  }
}

Show the prompt to your user, then send their answer:

POST/v1/lookups/{id}/input

curl https://api.pnrstack.com/v1/lookups/lkp_01JC9V2M8R/input \
  -H "Authorization: Bearer pk_live_…" \
  -H "Content-Type: application/json" \
  -d '{ "value": "482913" }'

The lookup carries on from where it stopped. type is one of one_time_code, email, first_name, ticket_number or date_of_birth. A code has to arrive within 10 minutes and anything else within an hour, because the airline's session is held open until then. After expires_at the lookup is expired, and isn't charged.

Failures

A failed lookup has an error with a code, a message for your logs, and retryable:

CodeWhat happenedRetry
invalid_credentialsThe airline didn't accept that booking reference and surname togetherNo
booking_not_foundThe airline has no booking with that referenceNo
unsupported_airlineWe don't retrieve from that airline. Airlines lists the ones we doNo
airline_unavailableThe airline's site was down or not answeringYes, after a few minutes
extraction_unverifiedWe read the booking but couldn't confirm its detailsYes
rate_limitedToo many lookups on your account at onceYes, after Retry-After

A failed lookup is never charged.

Repeats

A lookup for the same airline, booking reference and surname within ten minutes of a completed one returns that result at once, and isn't charged. Send "fresh": true when you need the booking read again; that one counts as a new lookup.