Guide
Selling on both GetYourGuide and Viator: how operators get double-booked and what prevents it
Two channels can sell the same seat when the thing answering them is working from a copy of your availability. Here is how that happens, step by step, and what has to be true of a connection for it not to.
Last updated 24 October 2026
Two channels sell the same seat when the system answering them is working from a copy of your availability rather than from the calendar that holds it. A read happens, then a write happens, and two reservation requests can both pass the read before either write lands. Two properties close that window, and both are structural rather than a matter of care: the layer in the middle holds no copy of availability, and the seat check happens inside the same database transaction that writes the booking.
Every operator who lists the same departure on more than one channel asks the same question, and it is the right question to ask. A boat with six seats can be sold seven times if the two channels selling it are not looking at the same thing. The failure is almost never carelessness at the operator's end. It is a property of how the connection is built, and it is worth understanding well enough to ask a supplier about it.
Three copies of the truth
When a tour is bookable on GetYourGuide and on Viator, a statement about seat availability exists in at least three places.
- Your calendar, which is the only place a seat is actually held.
- Each channel's own copy, which it keeps so that it can show a search result without calling you on every page view.
- In many setups, a third copy inside the reservation system or the connectivity layer that sits between the two.
The channels' copies are not optional, and on their own they are not the problem. GetYourGuide hosts an availability update notification endpoint that a connected system calls when availability changes, which exists precisely because GetYourGuide keeps a copy it wants kept current. Viator refreshes its calendar on a published cadence: every two hours for the next zero to two days, every one and a half days for three to thirty days, every three days at ninety days, every four and a half days at one hundred and eighty days, and every seven days beyond that.
A channel's copy being a few minutes out of date does not oversell a seat by itself, because no channel treats its own copy as authoritative at the moment of sale. Both of them call back to ask for the seat before they confirm anything. What matters is what answers that call.
Where exactly does it go wrong?
In the interval between a system reading its own copy of your availability and writing the result of that read back. Everything before that interval is correct, and everything after it is a consequence. Take a departure with six seats, five of them already sold. One seat is left.
- GetYourGuide asks whether a seat is free. It is told yes, and that answer is correct.
- Viator asks the same question a moment later. It is told yes, and that answer is also correct, because nothing has changed yet.
- GetYourGuide sends a reservation request. The system in the middle reads its own copy, sees one seat, marks it held in that copy, and queues an update towards your calendar.
- Viator sends a reservation request while that update is still in flight. The system reads its own copy again. Depending on when that copy was last written, it sees a free seat and answers yes.
- Both reservations become bookings. Seven passengers hold tickets for six seats, and nobody finds out until people are standing on the quay.
Step four is the whole failure. A read happens, then a write happens, and there is time in between. Two requests can both pass the read before either write lands. The gap might be milliseconds if the system in the middle reconciles immediately, or minutes if it reconciles on a schedule. It only has to be wide enough for two requests to arrive inside it, and the moments when two requests are most likely to arrive together are exactly the moments when the last seats are selling.
Reservation holds widen that window rather than closing it. GetYourGuide asks that a reservation hold a seat for sixty minutes where possible, and for no less than fifteen minutes. If the hold is recorded only in the middle system's copy, and not in the calendar that direct bookings are written into, then for the length of that hold your own website, your telephone bookings and the other channel are all still being told the seat is free.
What has to be true instead
Two properties prevent this, and both are structural. Neither is a matter of being careful, and neither can be added later by tuning a sync interval.
The layer in the middle holds no copy. RezRoute stores no availability of its own. When a channel asks whether a seat is free, the request is routed to the marketplace backend that owns that product, and it is answered from the live calendar. There is no second version of the truth, so there is no reconciliation window for two requests to sit inside.
The seat check happens inside the transaction that writes the booking. The check and the write are not two steps with a gap between them. They are one step, and the database decides the outcome. When two reservation requests for the same last seat arrive at the same instant, the database serialises them: the first commits, and the second finds the seat gone and is refused. The race is not avoided by good timing. It is resolved by the component that owns the row, which is the only component that can resolve it.
Because the hold is written into the same calendar as everything else, a held seat is unavailable to the other channel and to a direct booking for as long as the hold lasts, and it returns to sale by itself when the hold expires.
What this does not fix
A guarantee stated too broadly is the one an operator remembers on the day it fails, so here is the boundary of this one.
- A channel can still display a seat that has just been sold. Its copy refreshes on its own schedule, and no connection can change that. What the customer meets is a refused reservation at the moment of booking, rather than a confirmed booking for a seat that does not exist. That is the difference between a disappointment on a website and two families on the quay for one cabin.
- Anything selling the same seats outside this calendar is outside the guarantee. A separate reservation system, a spreadsheet, or a walk-up sale written down at the end of the day is another copy of the truth, and it can oversell in exactly the way described above.
- Reducing a departure's capacity after seats have been sold produces an overbooking that has nothing to do with routing. If the boat changes, the seats already sold have to be dealt with by a person.
- The guarantee belongs to one marketplace at a time. RezRoute routes to two marketplace backends, and a product belongs to one of them. The transaction that resolves the race is a property of that marketplace's database. There is no guarantee spanning the two, and none is needed, because a seat exists in exactly one of them.
Questions worth asking any connectivity provider
Each of these is answerable in a sentence, and the answers tell you whether the failure above is possible on your tours.
- When a channel asks about availability, where does the answer come from: the calendar that holds the seat, or a copy held by the provider?
- Is the seat check performed inside the same database transaction as the booking write, or before it as a separate step?
- Where is a reservation hold recorded, and does a direct booking on my own site see it?
- How long is a hold, and what releases it?
- If two channels request the last seat in the same second, which component decides who gets it?
A provider that keeps a copy is not necessarily doing something wrong, and there are reasons to build that way. But if the answer to the first question is a copy, then the answer to the last question is a schedule rather than a database, and the useful follow-up is how wide the window is and what happens to the loser of the race.