What the Sabre documentation describes, and how it fits the existing Next.js and Supabase system, ahead of our call.
The core principle: Sabre is the source of truth for external booking state, not for our application. Supabase stays the single source of truth for clients, trips, and bookings. Sabre is one upstream feed into it, isolated behind an integration layer so its shapes never leak into the app.
01 THE MENTAL MODEL
Sabre is pull, not push
Sabre doesn't push changes to us. When a PNR needs attention (schedule change, ticketing deadline, status update) it lands on a numbered queue. We poll the queue, read each PNR in full, sync it, and remove it. The queue holds references, not the booking data, so finding what changed and reading what changed are two separate steps.
02 WHY IT'S BUILT THIS WAY
Correct under failure, not just on the happy path
Idempotent writes (upsert on a unique record-locator constraint) mean the same PNR arriving twice updates one row, not two. Dequeue only after commit means a crash mid-cycle always leaves the PNR on the queue to retry safely; the one unsafe state, removed but not written, is designed out. This is the same queue-and-reconcile pattern behind the ticket-routing system I run in production, so retries, overlaps and reprocessing are non-events by construction.
03 WHERE THE DATA LIVES
Our application
Supabase (Postgres)
Owns clients, trips, bookings, families and workflow. Everything the Next.js app reads and writes. The record locator is stored here as an external reference, not as our primary key.
External state
Sabre GDS
Authoritative for booking state only. On a re-sync, Sabre wins for the fields it owns; our own internal fields live in separate columns the sync never touches.
04 THE TERMS, BRIEFLY
PCC
Pseudo City Code. Identifies our agency account and scopes every queue and PNR operation — the tenant boundary for the relationship.
PNR
Passenger Name Record. One booking / one journey, keyed by a six-character record locator. Maps one-to-one to a booking; separate trips are separate PNRs.
QueueAccessRQ
Tells us which PNRs are waiting on a queue.
GetReservationRQ
Tells us what is in each PNR — the full reservation, per locator. Not a queue call.
QueueRemoveRQ
Removes a processed PNR from the queue. Called only after a successful write.
05 BEFORE I'D WRITE CODE — WHAT I'D CONFIRM WITH YOU
?Queue numbers. Queue meaning is configured per PCC, not a Sabre standard. Which queues does PureLuxe use, and what places a PNR on each?
?Scope of the sync. This covers reading and syncing existing bookings. Creating or modifying bookings through Sabre (shop, book, ticket) is a separate set of product-specific APIs I'd map out separately.
?Poll cadence and volume. Interval and expected PNR throughput, so the worker and backpressure are sized right.