
🤖 Ghostwritten by Claude Opus 4.6 · Fact-checked & edited by GPT 5.4
If a travel-planning agent is supposed to protect loyalty value, it cannot rely on a generic hotel aggregator alone. Aggregator APIs are useful for broad public-rate search, but they typically do not expose the full set of member-specific outcomes a traveler cares about: signed-in member rates, points redemption pricing, some award inventory, and elite-linked booking context. For Outback, that made the architecture choice straightforward: integrate chain by chain, through each chain's own authenticated booking surface, and treat aggregators as insufficient for the core job.
That choice is more expensive to build and maintain. Every chain needs its own adapter, every session has its own quirks, and every surface can change without notice. But the trade-off is clear: a chain-direct design preserves the traveler context that a public-rate feed usually cannot represent.
This post explains that initial topology decision, the adapter contract behind it, and the security rules that come with handling authenticated hotel sessions locally.
TL;DR: Aggregators are good at broad public shopping, but they usually do not expose the loyalty-specific pricing and inventory a signed-in traveler needs.
Most travel products start with an aggregator because the benefits are obvious: one integration, broad coverage, and normalized responses. That works well if the goal is public comparison shopping.
It works less well if the goal is loyalty-aware booking.
A typical aggregator response can show publicly available room types, cash rates, taxes, and cancellation terms. What it often cannot reliably show is the member-specific layer that appears only after a traveler signs in on a chain's own site or app. Depending on the chain and the commercial relationship, that missing layer may include:
That distinction matters. A five-night stay might appear through a public shopping feed as a standard cash booking, while the chain's own signed-in flow could show a lower member rate, an award option, or a mixed cash-and-points path. The exact gap varies by brand and program, so it is better to state this as a common limitation than as a universal rule. But for a loyalty-aware agent, even occasional blind spots are a serious product problem.
So the architectural conclusion is not that aggregators are useless. It is that they are incomplete for this use case.
TL;DR: Outback uses one adapter per hotel chain so the planner sees a uniform interface while each adapter handles chain-specific authentication and search behavior.
Outback's topology puts a dedicated internal adapter between the planning layer and each hotel chain's own booking surface. The planner calls a shared contract. Each adapter implements that contract in a chain-specific way.
That separation keeps the planning logic clean while acknowledging a practical reality: hotel booking surfaces are not standardized in any meaningful operational sense. Authentication, search parameters, room taxonomy, and pricing presentation vary widely.
Here is the illustrative contract scaffolded for the project:
interface ChainAdapter {
searchAvailability(params: {
propertyId: string;
checkIn: Date;
checkOut: Date;
guests: number;
memberAuthenticated: boolean;
}): Promise<AvailabilityResult[]>;
getRates(propertyId: string, roomType: string): Promise<RateBreakdown>;
sessionStatus(): SessionState;
}In practice, a normalized AvailabilityResult may include fields such as:
memberCashRatepointsCostawardNightAvailablepointsPlusCashOptioncancellationPolicytaxesAndFeesEstimateNot every chain supports every field, and not every field will be available on every request. That is another reason to prefer adapters over a single flattened abstraction: the contract can express optionality explicitly instead of pretending every chain behaves the same way.
One adapter might manage a session-heavy web flow with anti-automation checks and dynamic pricing widgets. Another might interact with a cleaner JSON-backed surface. A third might require more defensive parsing because room labels and rate plans are inconsistent across properties. The planner should not need to know any of that. It should only receive a normalized result and enough metadata to compare options responsibly.
This is still the adapter pattern. The opinionated part is where the boundary sits: at the chain's own authenticated surface, not at a third-party feed that normalizes away loyalty context.
TL;DR: Chain-direct architecture preserves more traveler value, but it creates a larger maintenance burden and narrower initial coverage.
The cost of this decision is real.
| Concern | Aggregator Approach | Chain-Direct Approach |
|---|---|---|
| Integration count | One primary integration | One adapter per supported chain |
| Surface stability | Vendor absorbs some upstream change | Each chain surface can change directly |
| Authentication | Often unnecessary for public shopping | Authenticated sessions must be managed safely |
| Coverage | Broad initial coverage | Deeper support for fewer chains at first |
| Maintenance burden | Lower | Higher and ongoing |
Each chain introduces its own failure modes. Search forms change. Session behavior changes. Rate labels change. Front-end markup changes. Even when the underlying traveler experience looks stable, the implementation details can shift enough to break automation or parsing.
That means chain-direct is not the right answer for every travel product. If the goal is broad market coverage and public-rate comparison, an aggregator may be the right first move. But if the goal is to help a traveler make decisions using real loyalty context, then broad-but-shallow coverage can become misleading.
The trade-off here is depth over breadth. Fewer chains can be supported well at the start, but the supported chains can reflect the traveler's actual membership value instead of a public approximation.
TL;DR: Once an agent handles real hotel logins, credential boundaries, session hygiene, and challenge handling become core architecture decisions.
Chain-direct design changes the security model because the system is now dealing with real member authentication states rather than anonymous public search.
Credentials should be retrieved only when needed, stored in a secrets manager, and kept out of logs, traces, and planner-visible state. The planner should request an action from the adapter; the adapter should handle the sensitive session work behind that boundary.
That separation reduces accidental exposure. It also makes review easier because the sensitive code path is narrower and more explicit.
Implementation-specific vault names, storage paths, and local session file locations are intentionally omitted here. For an architecture post, the important point is the boundary, not the secret material or internal wiring.
A second rule is just as important: security challenges must be surfaced, not bypassed.
If a chain presents a CAPTCHA, device verification step, step-up authentication prompt, or similar anti-abuse control, the adapter should stop and hand control back to the user. It should not attempt to solve the challenge automatically or route around it.
if (response.requiresChallenge) {
throw new BotChallengeError({
chain: this.chainId,
challengeType: response.challengeType,
message: "Security challenge detected — manual intervention required"
});
}That is not just a compliance preference. It is a trust boundary. The system is acting on behalf of a real member account, so challenge handling needs to be explicit and conservative.
One caution is worth adding: whether a given automation pattern is permitted depends on the chain's terms, technical controls, and applicable law. So the safest framing is not merely "do not bypass challenges," but "design the system so it respects platform boundaries and requires human intervention when those boundaries appear."
TL;DR: Once the adapter contract exists, the next hard problem is making one chain integration reliable enough to use in real trip planning.
With the topology decision made, the next engineering step is not more abstraction. It is proving that one adapter can survive contact with a real booking surface.
That means handling authentication state, search flow sequencing, pricing extraction, optional fields, retries, and challenge escalation without pretending the surface is cleaner than it is. The contract can stay elegant. The implementation will not.
That is the real value of this first decision: it defines the shape of the system early. If the product is meant to reason about loyalty value, then the architecture has to preserve loyalty context from the start.
That hybrid model can work as a discovery layer, but it does not remove the need for chain-direct support. If the final decision depends on member rates, award pricing, or signed-in availability, the chain-specific integration still becomes the source of truth. In that setup, the aggregator is a convenience layer, not the core booking intelligence.
It scales organizationally only if the product accepts selective coverage. Every new chain adds maintenance cost, test burden, and operational edge cases. For a loyalty-focused agent, that can still be a good trade if the supported programs match where users actually hold meaningful balances and status.
No. The stronger and more accurate claim is that aggregators generally do not provide a complete, standardized view of loyalty redemption pricing and availability across major hotel programs. Some partners may expose partial data in specific contexts, but that is not the same as full signed-in parity with the chain's own booking flow.
A local-first design can reduce credential exposure by keeping authenticated sessions on the traveler's own machine instead of routing them through a hosted service. That does not eliminate risk, but it narrows where sensitive session state lives and can simplify the trust model for users.
The contract is valuable precisely because the chains are different. It gives the planner a stable interface for search, pricing, and session state while allowing each adapter to handle chain-specific behavior internally. Without that boundary, chain quirks leak into the planning layer and make the whole system harder to reason about.
The most important decision in Outback was not a model choice or a UI choice. It was deciding what kind of truth the system would rely on.
An aggregator-first design would have been faster and easier, and for some products it would be sufficient. But for a loyalty-aware travel agent, public-rate truth is not enough. The system has to see what the traveler sees when signed in: member pricing, redemption options, and the constraints that come with a real account.
That is why chain-direct is the foundation here. It is more fragile, more expensive, and less scalable at the beginning. It is also the only approach in this design that keeps the loyalty layer intact instead of flattening it away.
Discover more content: