Departures · the document, by section.
Click any row to jump. The full document is one continuous read; the board exists for navigation, not as a substitute for the narrative.
The MVP, the price, the timeline, the risks — in one screen.
A 90-second read. Everything that follows is detail. If you only read this section, you have the shape of the build.
- AX sells premium experiential travel through a workflow built for phone calls and back-office vendors.
- Every customer interaction routes through DigitalTrip — a platform AX doesn't own and one that's reaching end-of-life.
- Without rebuilding, AX cannot capture more leads, deliver an AI-native discovery experience, or scale beyond the current operating envelope.
- A bounded MVP (12–14 weeks, £40k) that replaces DigitalTrip with an AX-owned platform.
- AI advisor at discovery, structured TripBuilder at fallback, booking-ops vendor (TBD between FacilitaTrip and Travel Compositor) for back-office.
- Multi-currency, ATOL-compliant, observable, secure — production-grade architecture from commit one.
- Migration-safe by design: Year-3 vendor swap rewrites the integration seam, not the customer experience.
Top risks · explicit mitigations.
A platform built for the way Awesome Experiences sells.
Technical architecture for the AX MVP. What gets built, how, where the risks are, and how cost and timeline are protected. Written for the people deciding whether this gets built.
AX owns the platform.
- Every line of code, every database row, every booking record stays portable.
- FacilitaTrip is a back-office vendor — not a lock-in.
- Year-3 swap rewrites the integration layer only, not the customer experience.
Premium, not demo.
- No disabled features, no Vietnam-only restrictions, no mocked-for-screenshot flows.
- Multi-currency from day one. Six languages activated at launch.
- Production-grade security and performance budgets enforced in CI.
AI as advisor, not autopilot.
- Mid-tier conversational LLM with in-session memory; cross-session persistence architected for Phase 2.
- Hard-bounded to AX-approved inventory — cannot invent trips or quote unsanctioned prices.
- Cannot bypass booking guardrails. Accelerates discovery, never impersonates.
Build a system serious enough that customers trust it with the most expensive holidays they take, and investors trust it with the next round.
- Pioneers Club + structured discount-code engine
- Live agent take-over of customer bookings
- Multi-currency real-time + six-language launch, architected day one
- Defence-in-depth security: removed the attack surface, then hardened what's left
- In-flow lead capture, abandoned-search recovery automation
- Editorial blog module + structured SEO / GEO schema
- MVP fixed price: £40,000 + VAT
- Ongoing retainer: £500/month — website hosting + 3–4 hrs/month (maintenance of the live system, plus small development requests)
- AI / LLM usage billed at cost, on top of the retainer
- 12–14 weeks from project start to live launch
- Five named gates with descope / proceed / rescope option
- 10% AX-controlled change-request budget (£4k) — for items AX requests outside agreed scope; only invoiced if used
- Weekly Loom updates, fortnightly checkpoint calls
- Code, IP and data fully assigned on payment
A real platform with a deliberately narrow launch.
The most common question a CTO asks when reading an MVP plan is: where does MVP end and full-scale begin? That distinction is set out below. The platform we architect is sized for the full envelope from commit one. The catalogue we launch with is curated, not exhaustive. Phase 2 expands it.
Real, live, fully-functional.
Nothing in MVP scope is disabled, mocked, or placeholder. ATOL certificates are real. Stripe takes real money. The DMC genuinely receives the email. The matching algorithm genuinely learns. Cold Lava does not ship demonstration-only software.
Phase 2 expansion path.
The MVP catalogue of 40-50 trips across 15-20 countries is the starting envelope. The platform is built to scale to a full-scale catalogue of approximately 250 trips across 50 countries without architectural rework. Phase 2 expansion is a content and operational exercise, not a technical re-platforming.
Side by side.
The business model the platform is built around.
The platform is not a generic booking engine. It is a wrapper around AX's specific operating model: DMC-anchored, ATOL-protected, catalogue-owned, with a Pioneers Club layer for early adopters and discount-driven cohorts. Every architectural decision below traces back to one of those facts.
DMC-anchored business logic.
Awesome Experiences books packages, not flights. The Destination Management Company on the ground confirms inventory, supplies the experience, and handles in-resort. The platform is built around DMC orchestration: every booking starts with a DMC notification and ends with a DMC confirmation. The technology is a wrapper around that real-world workflow.
AX owns the catalogue.
Tour templates, day templates, components, pricing matrices, margin rules, hotel tier definitions, SEO copy, imagery, constraint rules — all stored in AX's database, not the vendor's. FacilitaTrip is a back-office booking engine; it does not own AX's product structure. This is the migration-safety guarantee written into the data model.
Booking confirmation within 48 hours.
Customer-facing promise: any booking that starts has a confirmed DMC outcome (accept / alternative / reject) within 48 hours of deposit. The system enforces this as an SLA — if a DMC is silent, escalation routes to AX admin automatically. Customers are not left waiting in 'DMC pending' state without a human eye on it.
ATOL legal model — confirmed at kick-off.
ATOL compliance is not primarily a software question. It is a question of who is legally principal for each package booking. The answer is a kick-off decision — and it determines who issues the ATOL Certificate, who holds customer money, and which booking system is mandated. The platform implements to whichever model AX confirms.
AX holds its own ATOL licence.
AX is the principal for every package. AX issues every ATOL Certificate. AX bears the financial protection responsibility — bonding, audited accounts, APC payments per passenger, CAA reporting, claims handling. The platform issues certificates directly from the booking flow. Most flexible long-term; highest compliance overhead up front.
AX sells under a host operator's ATOL.
AX operates as an agent under a written agreement with an ATOL-licensed host. The host is the principal; the host issues the ATOL certificate; the host typically holds the customer payment. The host's booking system may be mandated. Lower compliance overhead; some operational constraints depending on the host. Many UK boutique tour operators run this model.
Pioneers Club — discount and membership layer.
AX’s loyalty and acquisition model. Members get early access, exclusive trips, and discount codes scoped at trip or cohort level. Built into the data model from commit one so AX can run promotions from launch — not bolted on after.
Promo codes scoped per-tour, per-cohort, percentage or absolute, with date constraints. Powers Pioneers Club offers and standalone sales promotions alike — including partner-tied campaigns. Enforced on every quote.
Selected tours flagged as Pioneers Club exclusives, hidden from public catalogue, only visible to logged-in members.
New trips visible to Pioneers Club for a configurable window before opening to general catalogue.
Codes apply to sell price, never to net cost. AX margin is preserved even on the most aggressive discount.
Agent takeover.
AX staff can open any customer’s session from the admin dashboard, edit the booking on their behalf, and complete the payment via a Stripe payment link sent during a phone call. Every edit is audited under the agent’s identity; the customer sees the change set in their booking history with the agent’s name. Detail in §013 Booking Flow.
It is treated as a first-class state transition rather than a side feature. It is how AX retains high-touch customer service in a self-serve digital flow.
The end-to-end customer flow.
From the first ad impression to the post-trip review and back into the matching engine. Two parallel discovery paths (AI advisor and structured wizard), an exception loop on DMC rejection, and a self-perpetuating feedback loop that returns from post-trip improvements into both the matching algorithm and discovery for the next traveller.
Acquire
Lead enters via paid, organic, partner, or remarketing. UTM and behavioural data captured pre-consent at minimum-necessary level only; full tracking activates on cookie permission. Landing page is dynamic — same template, different hero based on campaign source.
Discover & match
Customer chooses path: AI advisor or structured wizard. Both feed the same matching engine. Engine applies hard filters, then ranks AX-approved trips with weighted scoring and returns top 5. Customer selections train the algorithm via damped feedback.
Tailor, book, confirm
Detail page → live tailoring with real-time re-pricing → provisional booking + Stripe deposit → DMC confirmation step (accept / alternative / reject) → confirmed booking with ATOL Certificate issued, margin frozen, customer in their account.
Trip & loop
In-resort experience and live itinerary in the web app. Post-trip questionnaire feeds Improvements — which tunes match-engine weights and seeds discovery for the next traveller in the same cohort. The system self-perpetuates.
Six layers, named at every level.
Stated precisely. The system is six horizontal layers, each owned explicitly by AX or by a vendor. AX owns every layer above the Integration Bus. The Integration Bus is the seam where AX-owned code talks to vendor systems — and the seam where a Year-3 swap would rewrite the integration layer only, not the customer experience above it.
Layer-by-layer.
Booking-ops vendor evaluation — Week 0 / Week 2 gate.
The AX brief leaves the vendor open between FacilitaTrip and Travel Compositor (§004b makes the comparison explicit). Week 0 is sales calls and demos with both. Week 1-2 is contractual and technical review of whichever vendor AX confirms — sandbox access, payload examples, sandbox booking proven end-to-end, gap analysis. AX retains the right at this gate to descope, defer, or proceed at the original scope.
The booking-ops vendor is a Week 0 evaluation. Architecture is shape-agnostic until it's resolved.
AX has left the booking-ops vendor open: ‘most probably FacilitaTrip or Travel Compositor.’ The architecture commits to neither until the Week 0 evaluation gate. The Integration Bus connects to whichever vendor AX confirms — and the rest of the API stack adjusts accordingly.
FacilitaTrip vs Travel Compositor — both are candidate connectors.
Pricing for both: not publicly available. FacilitaTrip starts at €1,500/user/month per Capterra. Travel Compositor is tier-based (‘choose 8 of 20 engines’). Both require sales conversations as a Week 0 gate item.
Connector inventory · MVP / Phase 2 hedged by booking-ops choice.
Flight connectors — the named primary.
The named primary flight connector is the Lyme / Aviate consolidator — two sides of the same business: Lyme handles British Airways and the broader BA group; Aviate handles all other airlines. Both expose an API (recently introduced; their previous model was offline-only via phone, email, or manual entry). They are named here as the most likely default for MVP and Phase 2, not as a required dependency — additional flight inventory sources can be added as connectors over time.
Why the booking-ops choice cascades.
FacilitaTrip's supplier breadth is shallower. Direct connectors fill the gap on day one.
- Duffel for flights — MVP day one
- Direct Viator Merchant — MVP day one
- Hotelbeds APItude — Phase 2
TC's 100+ supplier connectors collapse most of the direct-API stack into the booking-ops layer.
- Hotelbeds inventory — already in TC, no separate integration needed
- Viator inventory — already in TC, direct Merchant becomes optional Phase 2
- Duffel — Phase 2 / case-by-case (TC covers most flight needs)
Every choice named. Every alternative named.
Each technology was selected against named alternatives. Click any row to see why it won and what was rejected.
Speed is a budget. We commit to numbers.
Performance is treated as a budget, not an afterthought. The platform commits to specific Core Web Vitals targets per region, monitored from launch via Vercel Speed Insights. Regressions of more than 10% week-over-week trigger an alert.
Production targets per region.
Targets measured at the median of real-world traffic captured by Vercel Speed Insights. Lighthouse scores measured on mobile profiles in CI before each release.
How we hit them.
Edge rendering on Vercel.
Stateless pages — homepage, category landings, trip detail — render at the edge with Incremental Static Regeneration on a 5-minute revalidation cadence. Stateful pages (TripBuilder, account, booking) render from the user's nearest region.
Image pipeline.
Every image served via next/image with AVIF and WebP fallbacks, responsive sizes per breakpoint, blur placeholders. Vamoos-sourced imagery auto-resized and cached on Vercel's image CDN. Hero images carry priority and a per-page bundle budget of 350 KB.
Font subsetting.
Brand fonts subset to the Latin-1 character set, served via next/font with display: swap. Total font payload under 60 KB gzip. No FOUT, no FOIT, no layout shift on text load.
Bundle budget per route.
Hard limit of 180 KB JS gzip per route, enforced via next-bundle-analyzer in CI. Route-level code splitting on the TripBuilder, the LLM advisor, and the tailoring module — each is a separate bundle, loaded only when entered.
Database query budget.
Any list endpoint serving search results returns in ≤ 180 ms p95 from a warmed Postgres. Indexes on tour_template (destination, duration, party_size), pricing_matrix (tour_id, date_band, party_size), and a denormalised trip_search_index materialised view rebuilt nightly.
Reference points.
Liverpool Cotton Brokers
Built by Cold Lava, live since Q1 2026. 1.4 s LCP from UK in real-world traffic. The performance discipline behind that score carries directly into AX.
Greenstar Solar
Cold Lava rebuild of a legacy WordPress site. Image-heavy domain, rendered fast through the same image-pipeline approach used here.
Every browser, every screen, tested before release.
Browser and device coverage, made explicit. The platform supports an explicit matrix of browsers and three responsive breakpoints. The MVP ships as a fully responsive website — no native iOS or Android binary, no App Store / Play Store distribution. AX’s spec calls for a ‘downloadable APP’; the architecture is PWA-ready, with home-screen install activated in Phase 2 rather than the MVP build (see Phase 2 Roadmap).
Browser support matrix.
Coverage figures from StatCounter UK, rolling 90-day window. On iOS, third-party browsers (Chrome, Firefox, Edge) run on the same Safari / WebKit engine, so the Safari row covers them. Older browsers receive a simplified server-rendered fallback — bookings still complete, with reduced visual polish.
Three breakpoints, intentional layouts.
Single column. Sticky bottom nav on TripBuilder. Tap targets ≥ 44 × 44 px.
Two column. Sidebar collapsible. TripBuilder steps stack vertically with persistent progress bar.
Full layout. Persistent left sidebar. Map and itinerary share viewport. Hover affordances active.
PWA-ready architecture — home-screen install activates in Phase 2.
Home-screen install as a Progressive Web App — on iOS 16+ Safari and Android 12+ Chrome, with an icon, splash screen, and full-screen launch — is a Phase 2 addition. It bridges the spec’s “downloadable APP” ask without the App Store review cycle or the native-code maintenance burden.
MVP scope is the fully responsive website. Both the PWA home-screen install and the richer in-trip companion experience — offline-first vouchers, push for flight delays, daily itinerary map, in-app contact-AX — are mapped in the Phase 2 Roadmap, not in the £40k commercial scope.
QA pipeline + accessibility.
BrowserStack matrix on every release branch.
A smoke suite covers homepage, TripBuilder happy path, search results, trip detail, booking flow on each browser × breakpoint combination. Visual regression diffs via Percy — any unexpected diff blocks the release until resolved.
WCAG 2.2 AA throughout.
Keyboard navigation, contrast ratios, ARIA labels, focus management on the TripBuilder steps. Verified via axe-core in CI plus a manual NVDA and VoiceOver pass before launch. No interactive element relies on hover or colour alone.
Multi-currency and i18n, day one architecture.
Multi-currency is built into the data model from commit one. Sterling is the platform's source-of-truth currency. Suppliers price in around ten base currencies; the platform retails to customers in three presentment currencies — GBP, EUR and USD. The MVP launches in six languages; the i18n architecture scaffolds further locales for activation as AX expands, quoted separately at that point.
FX rate freeze — five points, named.
Travel pricing is a finance system requirement, not a feature. The platform defines exactly when an FX rate is sourced, when it freezes, who bears exposure, and how refunds compute. Five named points; nothing implicit.
i18n architecture — six languages at launch.
ICU message catalogues.
All UI copy lives in next-intl JSON catalogues, keyed by string ID. Activating a language is a translation and review pass over the catalogue, not a code change. The catalogue ships with the six launch languages populated and further locales stubbed.
Locale-prefixed routes from commit one.
The site ships with locale-prefixed route segments in place for the launch languages. Further locales can be activated by populating the catalogue and toggling a flag — no routing rework, no new Next.js patterns to learn.
Currency abstraction.
The pricing layer takes a quote in supplier currency and renders in the requested presentment currency. Adding a presentment currency beyond the launch set is a Stripe configuration change plus a single backend toggle — no schema migration.
Supplier-currency capture.
Every component (hotel night, transfer, experience) stores its net cost in the supplier's currency. Margin computation respects supplier currency. This is what makes future multi-currency expansion non-disruptive.
Five layers of test coverage. Failures block merges, not launches.
Five test tiers, each with a tool, a coverage bar, and a CI gate. The point isn't 100% coverage — it's that nothing breaks silently between AX sign-off on staging and the customer reaching the deposit page.
Five tiers of coverage.
What blocks what.
Every test seeds its own data via fixtures. Production database is never touched. Stripe uses test mode keys. ATOL generation runs against a sandbox issuer. Anthropic uses a separate API key on a $20/month spend cap so test runs can't accidentally tip the production budget.
AX staff run a structured UAT pass against staging. Acceptance script per deliverable in §3 of the proposal. Failures block production promotion. UAT is a sign-off ritual, not a discovery — automated tests catch regressions before they reach UAT.
Four environments. Preview-per-PR. Migrations isolated by Neon branching.
The defensive answer to ‘how does code get from a developer's machine to production safely?’ Vercel handles deploys; Neon handles database branching; CI handles gates. Every PR has its own preview URL. Every migration is rehearsed on a branch before it touches production.
Four environments.
Pipeline · code → production.
- 01PR opened. Vitest + ESLint + type-check + axe-core + Percy diff. Vercel preview URL posted to PR.~3 min
- 02PR merged. Playwright golden flows on Chromium. Auto-deploy to staging.~6 min
- 03Staging deployed. Cross-browser Playwright on BrowserStack. Smoke test against real Stripe sandbox + ATOL sandbox.~12 min
- 04UAT sign-off. AX runs structured acceptance script. Tickets opened against any failures.Ad-hoc
- 05Production promote. Manual click in Vercel dashboard. Database migrations run via Neon branch-then-merge.~2 min + monitor
Database migrations · Neon branch-then-merge.
Migrations are the highest-risk part of any deployment. Neon's branching model lets us rehearse each migration against a real copy of the database before touching production.
Every PR gets a Neon branch off staging. Migrations run against the branch. Application connects via env-var-injected DSN.
Integration tests + E2E run against the branched DB. Real data shape, isolated writes. Branch is read-only against parent.
On PR merge, the migration is applied to staging. Forward-only — no rollback once merged. Reverts go through a new corrective PR.
Production migration is a separate explicit step at promotion time. Schema dry-run on a fresh production-clone branch first to catch surprises.
14 entities. Three layers. Audited everywhere.
The platform's data model is structured in three layers: catalogue (the AX product), booking (transactions), and user (identity + history). Every transactional row is versioned, every booking-affecting write is audited, every user-owned table is RLS-protected. The ERD below is the spine.
Catalogue layer.
AX-owned. Pre-built structured content. The differentiation lives here — AX’s curated tours, pricing rules, supplier mapping. Year 3 FacilitaTrip swap leaves this layer untouched.
Booking layer.
Transactional. Regulated (ATOL audit). Linked to FacilitaTrip via booking reference but not dependent on FacilitaTrip's schema.
User layer.
Identity, preferences, GDPR audit, AI session state. The only layer carrying personally-identifiable information at scale.
Versioning + audit — example.
The PricingMatrix is the most temporally-sensitive table. Below is its shape. Every other transactional table follows the same audit-column pattern.
CREATE TABLE pricing_matrix (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tour_template_id UUID NOT NULL REFERENCES tour_template(id),
date_band_start DATE NOT NULL,
date_band_end DATE NOT NULL,
party_size party_size_enum NOT NULL,
hotel_tier_id UUID NOT NULL REFERENCES hotel_tier(id),
room_type room_type_enum NOT NULL,
-- Costs in supplier currency, sells in GBP
net_cost NUMERIC(12,2) NOT NULL,
net_currency CHAR(3) NOT NULL, -- ISO 4217
sell_gbp NUMERIC(12,2) NOT NULL,
margin_pct NUMERIC(5,4) GENERATED ALWAYS AS
((sell_gbp - (net_cost * fx_to_gbp)) / sell_gbp) STORED,
-- Validity window, versioning
valid_from TIMESTAMPTZ NOT NULL,
valid_to TIMESTAMPTZ, -- NULL = current
superseded_by UUID REFERENCES pricing_matrix(id),
-- Audit
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
created_by UUID NOT NULL REFERENCES users(id),
version INT NOT NULL DEFAULT 1,
CONSTRAINT no_overlap EXCLUDE USING gist
(tour_template_id WITH =, party_size WITH =, hotel_tier_id WITH =,
tstzrange(valid_from, valid_to) WITH &&)
);
CREATE INDEX idx_pricing_lookup
ON pricing_matrix (tour_template_id, party_size, hotel_tier_id)
WHERE valid_to IS NULL;Versioning rules — applied across the model.
Audit columns on every transactional table
created_at, created_by, updated_at, updated_by, version. Standard across User, Booking, Passenger, Payment, DMCRequest, ATOLCertificate.
PricingMatrix versioned, never overwritten
Each price update creates a new row with a valid_from / valid_to window. Historical bookings always reference the price they were booked at.
Immutable audit_log for booking writes
Every write to a booking-related table writes a row to audit_log. actor_id, action, before, after, correlation_id. 7-year retention for ATOL.
Soft deletes for user-deletable data
User-initiated deletion soft-deletes the record (deleted_at). Anonymisation pass redacts PII while preserving financial integrity. Hard delete after 30-day cooling-off.
An advisor, not an autopilot. Bounded by design.
The AI advisor is a Cold Lava USP — a mid-tier conversational interface, hard-bounded to AX-approved inventory. It cannot invent trips. It cannot quote prices it has not been given. It cannot bypass the booking guardrails. It accelerates the discovery experience, it does not impersonate the platform.
Try it. The advisor is live, scoped to a sample of AX's catalogue.
This is the actual claude-sonnet-4.6 model running through Vercel's AI Gateway against 157 real AX toursscraped from the existing site. The model is bounded by the same guardrails described below — try asking for Antarctica or somewhere AX doesn't cover, and watch what happens.
Destination, party, rough dates, budget, style — anything works. I'll search AX's 157 tours and recommend a few that fit.
This demo is an illustrative example. The production advisor — its prompts, conversational flow, and behaviour — is tailored to AX following detailed requirements discussions.
How it's wired.
Claude Sonnet 4.6 (Anthropic).
Mid-tier reasoning with strong instruction-following and tool use. Public pricing: $3 / $15 per million input / output tokens. Enough capability to handle nuanced travel preferences at materially lower latency and cost than the Opus 4.7 top tier ($5 / $25 — about 1.7× Sonnet, not the 3× ratio that Opus 4.x shipped with). The architecture supports an upgrade to Opus in Phase 2 with no application code change — only a model identifier swap. Pricing verified at docs.claude.com on 10 May 2026.
In-session in the MVP; cross-session in Phase 2.
Within a session, the advisor holds the full conversation context — preferences, dislikes, stated constraints. Cross-session persistence — remembering you didn't enjoy long bus transfers in Vietnam when you return weeks later to plan Cambodia — is architected from commit one but activated in Phase 2. Once live, AI memory falls under the right-to-erasure scope (§018), purged with the customer record on the 30-day hard-delete cadence.
Tool-calling schema.
The model interacts with the platform through four named tools. Conversation orchestration is the model’s job; data retrieval and scoring belong to deterministic Cold Lava code.
Hallucination guardrails — three layers.
System prompt as policy.
The Claude system prompt is a 1,200-word document, versioned in the repo, reviewed at every change. It explicitly bounds the model: AX trip catalogue only, no fabricated pricing, no fabricated routes, no fabricated hotel names, no off-catalogue destinations. Loaded fresh at every session start.
Tool-calling schema, not free generation.
The model does not produce trip recommendations directly. It calls four tools, each implemented in Cold Lava code, each backed by the AX catalogue. The model orchestrates the conversation; the matching engine produces the recommendations.
Output validation before render.
Every tool result is validated before reaching the user. Trip IDs must exist in the catalogue. Prices must match current pricing. Hotel names must match catalogue records. Validation failures route the model back through a stricter retry. Three consecutive failures end the session and route the user to the structured TripBuilder.
When a user requests a destination AX does not currently offer, the model never invents a trip. It acknowledges the gap and offers the closest available match.
Cost model and controls.
Cost model: pay-as-you-go metered API with multi-layer cost controls. Per-session cost, with optimisations applied: £0.08–0.15; pessimistic ceiling £0.20. AI / API run-rate costs are carried by Cold Lava through the build and testing phases; metered cost passes to AX at handover.
The £400-per-booking concern — where the maths breaks down.
A fair question raised in scoping: could pay-as-you-go LLM costs, in a worst case, eat into tour margin? The reasoning — roughly £0.40 per advisor session against a 1-in-1,000 visitor conversion is ~£400 of LLM cost per booking, which a 10–15% gross-margin tour could not sustain. The arithmetic is sound. Three of the inputs are not.
At current Anthropic pricing, a 25,000-token session breaks down as below. With the optimisations in the six layers — prompt caching, model tiering, structured outputs — the working cost lands at £0.08–0.15, with £0.20 a pessimistic ceiling. £0.40 was a deliberately conservative pre-optimisation estimate, not the working assumption.
The 0.1% figure is the conversion rate across all visitors from a channel. Visitors who engage the advisor are a different population — they have self-selected by describing their trip in detail, which signals materially higher intent. Comparable high-intent conversational funnels convert at 3–5%, often higher on deep engagements: 30–50× the baseline channel rate. Using the general rate to price advisor cost dramatically overestimates cost per conversion.
Without protection, a single attacker could generate thousands of pounds of API spend in an hour. The answer is not a different pricing model — it is to stop automated traffic reaching the API at all. The bot-protection layer below reduces automated abuse to effectively zero before it generates any token cost.
Even on the pessimistic line, £30 of LLM cost on a £2,500 average booking is 1.2% of revenue — comfortably inside tour gross margin. The £400-per-booking figure requires every input at worst case simultaneously and every protective control absent; the architecture is built specifically to prevent that combination.
Six-layer defence-in-depth on run-rate.
- 01Structural optimisation. Prompt caching on system prompts (~90% cost reduction on repeated context), Haiku for filtering/classification, Sonnet for advisor reasoning, structured outputs. Combined: ~50–70% reduction vs unoptimised baseline.
- 02Per-session caps. 25,000-token budget per session, with graceful auto-handoff to the TripBuilder when reached.
- 03Per-user rate limiting. ~10 advisor sessions per IP per day, with cooldown windows on rapid-fire usage.
- 04Bot protection. Vercel BotID plus CAPTCHA on AI advisor entry, server-side request validation. See §017 Security for the full bot-protection scope.
- 05Real-time monitoring with AX-controlled safety threshold. Continuous token-spend monitoring with anomaly detection. A configurable monthly safety threshold (default £500/month) acts as a final backstop: when reached, the advisor temporarily pauses with a polite handoff to the TripBuilder until AX raises the threshold or investigates the cause. The threshold sits under AX’s control — it can be raised, lowered, or effectively disabled at any time, and is a commercial decision, not a Cold Lava-imposed ceiling. Alerts fire at configurable percentages (defaults 50% / 75% / 90%) ahead of the threshold.
- 06TripBuilder primacy. The structured 6-step TripBuilder is the default flow; the AI advisor is for complex or free-form needs. ~80–90% of visitors never invoke LLM spend. See §011.
£180–300 / month at MVP scale — assumes ~10,000 monthly visitors, ~15% engaging the AI advisor.
£500 / month default — a configurable backstop, not a fixed ceiling. AX can raise, lower, or effectively disable it at any time. When reached, the advisor pauses with a polite handoff to the TripBuilder until AX adjusts the threshold or investigates.
Hard filters, then weighted scoring, with damped feedback.
The engine ranks in clear stages. Hard filters come first — destination and activity type — narrowing the catalogue to trips that structurally fit; a trip that fails a hard filter is never shown. A weighted scoring pass then ranks what remains across the softer dimensions and returns a top-5. A conservative safety-and-suitability overlay sits across both, hard-excluding trips that would be genuinely unsuitable for the traveller. The weighting profile is configuration-driven and AX-owned: Awesome Experiences sets the initial values, and the profile itself is AX IP. Cold Lava's contribution is the engine and the damped-feedback loop — assigned to AX on payment, like every other Cold Lava-authored module in §025. Both the structured TripBuilder and the LLM advisor feed the same engine.
Try the matching engine live.
Drag the sliders. The top-5 reorders in real time as the engine rescores every catalogue trip against your preferences. The score breakdown bars show which dimensions drove each placement. Six dimensions shown here for clarity — the production engine runs the full set detailed below, across both stages.
- #1Highlights of Vietnam & Cambodia with Phu Quoc 14 Nights91 / 10015d£1,000slowVietnam · CambodiaPaceBudgetDurationAdventurePartyMonth
- #2Conquer Mount Kilimanjaro - Private Climb with Zanzibar88 / 10011d£750moderateTanzaniaPaceBudgetDurationAdventurePartyMonth
- #3Head to Toe Chile86 / 10013d£1,000moderateArgentina · ChilePaceBudgetDurationAdventurePartyMonth
- #4Head to Toe Chile86 / 10013d£1,000moderateChilePaceBudgetDurationAdventurePartyMonth
- #5Luxury Chile - Head to Toe86 / 10013d£1,000moderateChilePaceBudgetDurationAdventurePartyMonth
This demo is an illustrative example. The production matching engine — its filters, dimensions, weights, and scoring — is tailored to AX following detailed requirements discussions.
Try the structured trip builder.
The 6-step structured path — the default flow for most visitors. Each step writes to the same structured field set the matching engine consumes. This mirrors the functionality of AX’s existing trip builder, rebuilt to the platform’s design language.
What kind of experience are you after?
- Experience typeNot selected
- RegionNot selected
- DepartureNot selected
- PreferencesNot selected
- Guides & transfersNot selected
- Budget ppNot selected
This demo is an illustrative example. The production trip builder — its steps, options, and flow — is tailored to AX following detailed requirements discussions.
Matching engine: hard filters and scored dimensions.
The engine ranks trips against the customer’s stated preferences and returns a small ranked set — a top-5 with an overall match score. Not every input plays the same role. Some define structural feasibility and are applied as hard filters; the rest are weighted, scored, and ranked. A walking holiday returns walking trips — never a city break that happened to score well on budget and dates.
Applied before any scoring. A trip that fails one of these is excluded — or down-ranked so heavily it effectively never appears in the top results.
Destination, region, country
The customer must specify — or have inferred — at least a region before meaningful ranking can occur. A trip outside the stated destination is excluded; it does not enter the ranked set however well it scores on everything else.
Category / activity type
Specialist activity products — walking, wildlife, festival, culinary and similar — are respected as categorical needs. A customer who selects a walking holiday does not see non-walking tours in their top results, however well those tours score elsewhere. Category is matched directly, not approximated by a generic adventure score.
Run only on the trips that pass the hard filters. These contribute to the overall match score but do not exclude trips outright. Pace is decomposed into two underlying dimensions — physical intensity and schedule tempo — because it means two different things.
Safety and suitability overlay.
Certain combinations of customer attributes and trip attributes are treated as hard fails regardless of overall score:
- High-intensity treks for travellers who indicated mobility constraints, limited fitness, or relevant age flags — excluded.
- Trips requiring sustained altitude or remote conditions for travellers with relevant health flags — excluded.
The safety overlay is deliberately conservative. It is better to exclude a marginal-fit trip than to recommend something that would be unsafe or unpleasant for the traveller.
Configurable weighting.
The matching engine is data-driven, not hard-coded. Each scored dimension carries a weight (0–100) that determines its contribution to the overall match score. Weights are stored as a configurable data record, editable by Awesome Experiences without code changes, and new dimensions can be added with their own weights.
The initial weighting profile is provided by Awesome Experiences’ founder, William Burton, drawing on two decades of operating a tour-matching business. The weights themselves are provided at project kick-off; every weight shown or implied in this document is placeholder and illustrative until then. The relative shape is deliberate: destination and category weights sit very high — at near-hard-filter levels — while pace and adventure are important but subordinate, and other soft preferences lower still.
Booking-conversion data then refines the weights over time. The refinement is conservative— adjustments are small, validated against booking outcomes, and reversible if they degrade match quality. A poor initial profile destabilises the feedback loop, so AX’s existing operating intuition is the starting position; data-driven refinement layers on top of it, it does not replace it.
Damped feedback loop — how the algorithm learns.
Selection signal recorded.
When a customer selects one of the top 5, the dimensions where that trip outscored its peers are reinforced. Dimensions where it underperformed are softly downweighted.
Damping applied.
Each weight update is dampened by a momentum coefficient (default α = 0.15). Single sessions don't whip the algorithm — only consistent signal across many sessions moves weights materially.
Per-cohort, not per-individual.
Phase 1 learns at cohort level (segment buckets like 'culture-focused 30-50 traveller'). Individual-level personalisation is Phase 2, with explicit consent.
Bounded weight range.
No weight can grow beyond 2× its initial value or shrink below 0.25×. Prevents runaway feedback loops that lock the algorithm into a local optimum.
The update rule.
# Pseudo-code — scored-dimension weights only.
# Hard filters (destination, activity type) and the safety
# overlay run before this; only trips that pass are scored
# and ranked here.
def update_weights(prefs, ranked_top5, selected_index, weights, alpha=0.15):
selected = ranked_top5[selected_index]
for dim in SCORED_DIMENSIONS:
dim_score_selected = score(prefs[dim], selected[dim])
dim_score_others = mean(score(prefs[dim], t[dim])
for t in ranked_top5
if t is not selected)
# Reinforce dimensions where selected outscored others
delta = alpha * (dim_score_selected - dim_score_others)
# Damped update with bounds
new_weight = weights[dim] * (1 + delta)
weights[dim] = clamp(new_weight,
0.25 * INITIAL[dim],
2.00 * INITIAL[dim])
return weightsPace and adventure: getting the wording right.
The TripBuilder asks about pace and adventure in language that distinguishes the underlying dimensions without overwhelming the customer with questions. “How physically demanding do you want this trip to be?” drives the physical-intensity dimension. “How busy do you want your days to be?” drives the schedule-tempo dimension. Each question carries short helper text, so the customer always knows what it controls — the wording deliberately avoids the common mistake of conflating walking intensity with itinerary busy-ness.
Adventure level is asked separately again, and kept distinct from activity type — activity type is the categorical need, matched as a hard filter, not a slider. Where an answer is genuinely ambiguous, conversational follow-up and disambiguation are the job of the LLM Advisor: the structured TripBuilder stays structured, the Advisor is the conversational path, and both feed the same engine.
Two paths in, one engine.
The TripBuilder is the default flow for most visitors — its structured 6-step path handles the majority of trip-planning needs efficiently and intuitively. The AI Advisor is available for visitors with complex, multi-constraint, or free-form needs the structured path cannot easily express: pasted dream-trip descriptions, voice input, or unconventional combinations of regions and themes. Most visitors complete a trip via the TripBuilder; the AI Advisor is a power-user path.
6-step TripBuilder
Customer chooses dates → countries → experience type → guide preference → budget → review. Each step writes to the same structured field set the engine consumes.
LLM Advisor
Customer types a paragraph or pastes an itinerary. Claude extracts to the same structured fields via the extractPreferences tool (§010). Validates completeness before passing to the engine. Identical output format, identical scoring.
Allowed actions, named constraints, real-time pricing.
Tailoring is the most interactive piece of the platform — and the place where unbounded flexibility breaks the booking economics. The engine takes a small, named set of allowed actions, enforces a constraint engine, and re-prices every change. No free-text 'change anything' — every mutation is a typed action with rules.
Allowed actions — six, named.
Constraint engine — declarative DSL, evaluated per action.
Every action passes through a constraint engine before it commits. Rules are declarative (per-tour configuration, not hard-coded). If a rule fails, the customer sees an explanation, not a broken itinerary.
Live re-pricing pipeline.
- — 01Mutate. Customer triggers an action (add day, swap activity). The action is captured as a typed event.
- — 02Validate. Constraint engine checks the proposed mutation against all rules. Failure surfaces immediately to the customer with the rule name.
- — 03Recompute pricing. Pricing engine recalculates total + margin from PricingMatrix. Includes any FX delta if supplier-currency exposure shifts.
- — 04Persist. Tailored itinerary version saved with audit columns. Saved-search token updated so the customer can resume.
- — 05Render. UI updates with new total + margin (margin only visible to AX agents, not the customer).
A booking is a state machine. Every transition is named and audited.
The booking layer is regulated. ATOL, payments, supplier confirmation, and accounting all interact. The way to keep that surface honest is to model the booking as a state machine — every transition triggered by a named event, every transition logged. The diagram below is the system in one read.
Triggers and side effects.
Every transition is owned by a named event. The events listed are the load-bearing ones — the ones that move money, issue regulated documents, or notify external systems. Everything is logged to the immutable audit trail with correlation ID.
DMC email-confirmation model — edge cases.
Phase 1 uses an email-based DMC confirmation, not API integration. That constrains the failure modes we need to handle explicitly in the state machine. Each one below has an enforced behaviour, not an aspirational one.
DMC silent (no response)
Reminder at 48 h, AX admin alerted at 72 h, manual escalation from there. Booking holds in DMC Pending — deposit refundable on customer request until confirmed.
DMC partial accept (e.g. days 1-8 yes, day 9 no)
DMC submits an alternative via the hosted form. Booking transitions to Alternative. Customer reviews, accepts, or routes back to Tailored to adjust.
DMC accepts then later cancels
Booking reverts to Cancelled. Issued ATOL certificate is voided. Refund to customer triggered manually by AX with full record in audit log. ATOL host informed if applicable.
Multiple DMC channels per tour
Out of scope Phase 1. Each tour has one nominated DMC channel. Multi-channel routing is Phase 2.
DMC insolvency mid-booking
Manual ops by AX. Platform records the event and freezes the booking; refund / re-routing handled outside the system in v1.
Customer abandons mid-payment
Booking transitions Provisional → Cancelled after PaymentIntent expiry. Saved-search recovery email fires after 24 h with a resume link.
Agent takeover.
Agent take-over is a first-class state transition, not a feature bolted on. AX staff open a customer’s live session from the admin dashboard. Edits commit under the agent’s identity and are audited — the customer can see every change, with a timestamp and a reason note. Stripe payment links can be sent for phone bookings, completing the loop.
Customer trust is preserved by transparency. A booking edited by AX shows that fact in the customer’s booking history, with the agent’s name and the change set. There are no silent modifications.
Stripe-native, multi-currency, zero PCI burden.
Payments are handled end-to-end by Stripe Elements. Cold Lava code never sees, stores, or transmits card data. PCI compliance lands at SAQ-A — the lightest scope possible — by deliberate design: we removed the attack surface, then hardened what's left. 3DS / SCA enforced. Multi-currency built in from launch — see §008 Currency for the FX rate-freeze model that makes this work.
Deposit + balance, decoupled.
Deposit and balance are separate Stripe PaymentIntents linked by booking reference. A partial refund on deposit does not corrupt balance state. A failed balance does not reverse the deposit. Each intent has its own webhook, its own state, its own audit row. Two money events are not one event.
Locks the booking, freezes margin and FX.
On Stripe success, FX rate is captured against the booking record, margin snapshot persists, DMC notification fires, booking transitions Provisional → Deposit Paid → DMC Pending. ATOL Certificate is NOT issued at this stage — see §013 for the ordering that protects AX from issuing regulated documentation against unconfirmed inventory.
Scheduled, automated, monitored.
Balance due date is computed from tour start and supplier terms. Stripe PaymentIntent for balance is created when due. Customer reminder fires N days before; failure routes to AX admin chase flow. Late payment does not silently break the booking — exception path is named and visible.
Accounting webhook — the contract.
Every Stripe state transition fires a webhook to the accounting layer (Xero or QuickBooks at MVP launch, configurable). The webhook payload carries the fields below. AX’s accountant uses these to compute TOMS quarterly — the platform records the data, the accountant runs the calculation. TOMS-aware journal entries direct from the platform are Phase 2.
Captured at every step. Recovered automatically. Saved with audit.
Travellers do not book in one sitting. The platform captures lead data at every plausible stage, recovers abandoned searches automatically, and feeds the CRM with structured records. Every consent is logged with the wording version active at capture time. No exit pop-ups.
Capture points — six, distributed.
Every capture writes a row to the GDPR consent_ledger with timestamp, IP, and wording version. The platform never silently captures or repurposes data.
Recovery automation — five trigger paths.
CRM record shape.
The platform syncs records to AX's CRM (HubSpot at MVP launch, or equivalent — configurable) on every meaningful state change. The record below is the canonical shape; CRM-specific field mapping is configurable.
Email deliverability · ATOL certificates must never land in spam.
SendGrid handles transactional sends with Postmark as fallback (§015 stack). Beyond the provider choice, deliverability is its own discipline:
Deliverability monitored via SendGrid + Postmark dashboards plus weekly DMARC report review. ATOL cert delivery rate is a tracked SLO (target: 99.5% inbox placement, p95).
The screens AX staff use every day. Not an afterthought.
A platform that replaces phone calls with software needs the staff-side screens to be at least as polished as the customer-side. Ten named screens, four roles, every action audit-logged — the staff-side experience scoped as deliberately as the customer-side.
Screens · ten of them, all in MVP scope.
Role-based access · four roles.
Every write — bookings, refunds, catalogue edits, agent take-overs — produces an audit row containing actor, target, before/after diff, IP address, timestamp. Audit log is append-only, replicated to a separate Postgres database, retained seven years per ATOL + accounting rules.
Admin tooling is route-protected pages inside the same Next.js codebase as the customer site. No separate admin app, no separate deploy. Login uses the same auth, so AX staff can move between admin and customer-facing views with one session.
A single signed-in home for every customer.
Every customer who books or saves a trip with Awesome Experiences has access to a dedicated My Account portal. It consolidates all customer-facing functionality into a single signed-in experience, accessible from the main site header at all times.
What the portal covers.
Account management
Register, log in, manage profile, set communication preferences, update payment methods.
Saved trips and quotes
Resume any saved search or in-progress quote via signed magic-link emails. Trips stay saved indefinitely unless the customer deletes them.
Booking history
Full record of past, current, and upcoming bookings — status, payment history, and itinerary access.
Active itineraries
For trips in progress or imminent: itinerary details, vouchers, certificates, and supplier documents in one place. Read-only access to the in-trip dashboard views (§018b).
Documents
Centralised storage of all booking-related documents — invoices, vouchers, e-tickets, visa letters, insurance certificates, supplier confirmations.
Travel preferences
Dietary requirements, accessibility needs, room preferences and traveller details recorded once and carried forward to all future bookings.
After booking — a personalised checklist.
The moment a booking is confirmed, the portal switches the customer into a personalised to-do list — a clear, ordered view of everything they need to do and submit before they travel. Each item shows its status, what is needed, and a one-click action: upload a document, pay a balance, follow a link. It pulls directly from the pre-travel compliance checks in §018b, so the customer sees the same requirements AX’s staff track — visa requirements, passport validity, insurance proof, balance payments — without chasing or guessing. The journey is designed to be calm and obvious: the customer always knows exactly what is outstanding and what is done.
- ✓Booking confirmedATOL certificate issued and stored in your account
- Passenger & passport detailsAdd each traveller's details — passport flagged automatically if expiry is close
- Visa requirementsVisa needed for your destination — your responsibility, with a direct link to official guidance
- Travel insuranceUpload your policy document — one click, straight into your account
- Balance paymentDue date shown clearly; pay early or on schedule
- Pre-departure packItinerary, vouchers, contacts and packing notes — available from T-21 days
Why it matters.
Reduces customer-service load.
Customers self-serve on the majority of 'where do I find X' or 'what's my booking reference' queries.
Builds loyalty.
A saved account with travel history is a switching cost — customers have more reason to return to AX for their next trip.
Centralises compliance documents.
Vouchers, certificates and travel documents live in one customer-controlled location, reducing lost paperwork and missed pre-departure requirements.
SEO and GEO — built into the data model, embedded on handover.
Travel discovery starts on Google and increasingly runs through LLMs. The platform ships with structured data, server-rendered metadata, clean URLs, and an editorial blog framework — SEO and GEO are embedded into the build, not bolted on afterwards. Cold Lava also provides SEO and GEO audits of the live surface as part of the engagement.
JSON-LD structured data — six schemas.
Every page emits structured data. Google reads it for rich results; LLMs read it for retrieval-augmented generation. Both matter for travel discovery.
URL structure.
Server-rendered metadata.
Editorial blog module — Phase 2 framework, MVP foundations.
Foundation in place.
Routes scaffolded (/blog, /blog/[slug]). Database schema for posts (title, body, hero image, author, publish date, tags). RSS feed endpoint. JSON-LD Article schema. Editorial tooling itself (CMS, editor experience, scheduling) is Phase 2.
Editorial workflow.
Sanity (or equivalent headless CMS) for content authoring. Multi-author support with approval workflow. Image management. Scheduled publishing. Internal linking suggestions. AX content team gets a real authoring experience without paying for it twice in MVP.
Defence in depth, from edge to data.
Security is the single concern raised most often by serious technical reviewers, and the one most easily reduced to platitudes. This section is specific. Named controls at every layer, named tooling, named cadences. Nothing aspirational.
Edge
Vercel Firewall blocks known bad IPs and common WAF patterns. Rate-limiting on every /api/* route at 60 req/min per IP with burst tolerance. Vercel BotID challenges bot traffic across the booking flow, the AI advisor, and lead-capture forms. DDoS absorption is handled at Vercel's edge.
Transport
TLS 1.3 enforced. HSTS with preload. Strict CSP (default-src 'self', allow-list for Stripe, GA4, Meta Pixel). Trusted Types enforced. Subresource Integrity on all third-party scripts.
Application
Next.js 16 with Server Components — most data flows server-side, minimising client surface. All API routes guard on the userId from session. No user can read another user's saved trips, account data, or bookings under any code path.
Data
Postgres with Row-Level Security policies on every user-owned table — saved_searches, bookings, passengers, payments. AX admin role bypasses RLS via a separate service-role connection used only by admin endpoints, all of which require explicit re-authentication.
Secrets
All secrets in encrypted Vercel environment variables, scoped per environment. No .env in the repo. Rotation cadence: Stripe / FacilitaTrip / Anthropic keys every quarter. Rotation runbook lives in docs/runbooks/secrets-rotation.md.
OWASP Top 10 — every category, named mitigation.
Beyond the checklist.
Zero card data on Cold Lava infrastructure.
Stripe Elements iframes the payment form. PCI compliance is fully offloaded to Stripe (SAQ-A scope). Cold Lava code never sees, stores, or transmits card data — not even transiently.
CREST-accredited test against staging in Week 13.
A third-party penetration test runs against the staging environment one week before go-live. Findings triaged by severity; all critical and high findings are fixed before production launch.
Credential stuffing, payment fraud, ATOL-cert phishing.
Customer accounts use 2FA + email-confirmation on payment-method changes. Stripe Radar enabled with custom rules flagging high-value first-time bookings, IP/billing-country mismatch, unusual booking velocity. Audit log makes any post-incident forensics straightforward.
No unverified packages.
Only npm packages on Snyk's no-known-malware list with weekly downloads above 10k. Lockfile checked in. SRI on third-party scripts. No package added without a security review note in the PR.
Disaster recovery · explicit RTO and RPO.
A fair question of any booking platform: what happens if Postgres is down for 4 hours mid-booking? Concrete answer below.
RTO = recovery time objective (how long until service restored). RPO = recovery point objective (acceptable data loss window).
Backup and continuity.
The platform is resilient to multiple categories of failure — regional outage, database compromise, code-host loss, slow corruption, operational error. The continuity model rests on three independent layers.
Hourly snapshots (rolling 24-hour recovery), nightly off-region backups copied to an independent geographic region, and Write-Ahead Log replication for point-in-time recovery. Combined: an RPO of seconds, not hours.
All code in GitHub with full Git history. Production deployments versioned through Vercel — any version rolls back in seconds. A branch-based workflow means no production deploy without a tested, reviewed change.
All repositories mirrored weekly to a Hetzner Storage Box in Europe — different jurisdiction, different credentials from GitHub. Multi-generation retention (weekly snapshots kept for months) means a slow compromise can be recovered from a known-good state prior to the compromise window.
ATOL, GDPR, accessibility — designed in, not bolted on.
Travel is regulated. Selling to UK and EU residents adds GDPR and accessibility obligations. The platform handles each compliance surface explicitly: ATOL Certificate generation tied to confirmed bookings, GDPR consent ledger and DSAR/erasure tooling, WCAG 2.2 AA verified in CI.
ATOL Certificate generation.
On confirmed booking (post-DMC accept — see §013 Booking Flow), the platform generates an ATOL Certificate PDF. The certificate is emailed to the customer, stored on the booking record, and an immutable audit log entry is written. ATOL legal model (Option A: AX as principal vs Option B: host operator agency) is confirmed at kick-off — see §002 Operating Model.
GDPR — consent, DSAR, erasure, residency.
Consent capture
Every consent action (cookies, marketing, third-party) writes a row to the consent_ledger table with timestamp, wording version, and IP. Wording is versioned in repo; if it changes, prior consents are flagged for re-collection.
Data subject access (DSAR)
Admin endpoint returns a customer's full record (account, saved searches, bookings, communications) in machine-readable form. SLA: 30 calendar days, target 5 working days.
Right to erasure
Customer-initiated deletion soft-deletes account, anonymises booking records (PII redacted, financial records retained for legal requirement), tombstones consent ledger entries. ATOL audit retention overrides for 7-year window.
Data residency
Postgres + Redis instances run in eu-west-2 (London). Vercel Edge serves UK + EU customers from European edge nodes. No customer PII transits to US infrastructure.
Accessibility — WCAG 2.2 AA.
Terms & Conditions — visa requirements clause.
“It is the sole responsibility of each traveller to obtain any visa, entry permit, transit visa, or other travel documentation required by the countries of destination, transit, or return. Awesome Experiences will provide reasonable advisory information (including links to official government sources) but does not guarantee the accuracy, completeness, or currency of such information, nor accept liability for travel arrangements that cannot proceed because of missing, invalid, or refused visa documentation. Travellers are advised to verify visa requirements with the relevant embassy or consulate well in advance of travel. Refunds and rebookings in the event of visa failure are subject to the applicable cancellation policy and any insurance the traveller has in place.”
The clause above is indicative wording and is subject to legal review by AX’s solicitor before publication as live Terms & Conditions.
From deposit to departure to return — every check, every reminder, named.
Checks on passports, visas, vaccinations, insurance, and balance payments — with reminders and customer assistance during travel. In the MVP these run as a manual-plus-automated workflow: automated expiry flags and reminder cadences, with visa and vaccination data from AX-maintained tables. Real-time API validation (Sherpa) is the Phase 2 upgrade, costed when volume justifies it.
Pre-travel checks · MVP delivery vs Phase 2 upgrade.
Reminder cadence · seven touchpoints from deposit to T-1.
Customer assistance during travel.
Operational maturity, from the day the URL goes live.
The platform is observable from commit one. Every error has a stack trace, every request has a correlation ID, every booking-affecting write is audited. Custom dashboards surface the metrics AX will check daily — funnel, AI cost, DMC SLA, conversion. On-call paging is wired in for the launch window.
Custom dashboards.
Four dashboards ship with the platform. Each is curated for a real AX user role — leadership looks at funnel + revenue, ops staff look at operational, the AX growth lead looks at AI advisor health.
Booking funnel
- TripBuilder start → step 6 → results → trip detail → booking
- LLM advisor session → recommendation → click-through to trip detail
- Save-search → email capture → resume rate
- Deposit-paid → DMC confirmation latency
- Top abandonment points (per step + per source)
AI advisor health
- Sessions started, sessions completed, abandonment by step
- Token usage per session, per day, per month
- Hallucination guardrail triggers (validation failures + retries)
- Off-catalogue suggestions vs in-catalogue matches
- Spend vs the £500/month safety threshold — alerts at 50%, 75%, 90%
Operational
- DMC confirmation SLA: time from deposit to confirmed (target <48h)
- DMC silence escalations triggered (48h, 72h)
- Stripe payment success rate, 3DS challenge rate, fraud flag rate
- ATOL Certificate issuance — count, time-to-issue post-DMC
- Refunds initiated (count, value, reason code distribution)
Conversion + revenue
- Booking conversion by traffic source (organic / paid / partner)
- Average order value, by trip and by cohort
- Pioneers Club discount usage + revenue attribution
- Repeat customer rate
- FX exposure tracked (live supplier-payable across currencies)
Year 3 swap = rewrite the seam, keep the spine.
A core requirement: AX does not get locked into a single booking-ops vendor indefinitely. Six architectural principles applied from commit one. The Year 3 swap-out cost is bounded by design: 3-6 months of integration work, not a full rebuild. (Vendor-agnostic from day one — see §004b.)
The six principles, applied today.
AX owns the catalogue.
Tour templates, day templates, components, pricing matrices, margin rules, hotel tier definitions, SEO copy, imagery, constraint rules — all stored in AX's database. FacilitaTrip is a back-office booking engine; it does not own AX's product structure.
API abstraction layer.
The frontend never talks directly to FacilitaTrip. Every vendor call goes through the AX API → Integration Bus. Vendor-specific quirks live in the Bus only — they never leak into the AX-owned layers.
Portable booking records.
Bookings are stored in AX's Postgres with ALL relevant fields — passenger details, financial records, status history, ATOL certificate, payment references. Data export is tested monthly. Migration assumes export will happen one day.
Stripe under AX control.
Payment orchestration is owned by AX, not the vendor. Stripe API keys belong to AX. PaymentIntent records are linked from AX's Booking table. If FacilitaTrip is replaced, Stripe stays. PCI scope stays SAQ-A.
Accounting integration owned by AX.
Webhook fires from the Integration Bus to Xero/QuickBooks, not from FacilitaTrip directly. The accounting sync is replaceable as a single component, not a vendor-specific dependency tree.
Audit trail belongs to AX.
Booking audit log is in AX's Postgres, not FacilitaTrip's logs. ATOL audit (7-year retention legal requirement) survives any vendor change. CAA can audit AX directly without vendor cooperation.
Year 3 swap — what changes vs what doesn’t.
Mapped against today’s components. The honest assessment: the Integration Bus rewrites; everything above it stays.
Built to be built upon.
The MVP is not a standalone system that is set aside when Phase 2 begins. It is the foundation the entire roadmap is built on — and it is built that way deliberately. Cold Lava builds in stepping stones: each piece is designed to be extended, so the platform grows rather than restarts.
A planned progression, not a restart.
Phase 2 does not begin from scratch. The architecture for later phases is anticipated in how the MVP is built — every layer is designed to be extended, not replaced. The next phase grows from this platform; it does not require a rebuild.
A stepping-stone build.
Each component is built so the next can be added without rework. The broader roadmap is already planned — subject to change as the MVP's review and real-world performance inform priorities. Growth and scalability are designed in from commit one.
Every asset is AX-owned and reusable.
Everything built — including Additional Works modules such as the Contract Ingestion Agent, detailed in the Additional Works document — is an Awesome Experiences-owned asset. AX can carry it forward into any future amendment, build, or system it chooses. Nothing delivered is locked to this platform alone.
DigitalTrip → AX-architecture, with link equity preserved.
DigitalTrip end-of-life is end of June. The platform must replace it without losing search rankings or breaking customer-facing URLs. Migration is a four-phase activity overlapping the build, with redirect mapping and content audit as Week 1 work, not Week 14.
- Crawl existing DigitalTrip pages with Firecrawl — capture every URL, status code, and content hash
- Vamoos-source image catalogue inventoried — every image referenced + intended target
- Existing data export from DigitalTrip dump (already received) parsed and mapped to AX schema
- Content audit: which pages have material SEO equity, which are dead weight
- AX confirms the MVP catalogue (40-50 trips across 15-20 countries per §001b)
- Trips have full content drafted into the new platform: text, imagery, day-by-day breakdowns, pricing matrix, supplier mapping
- Imagery resized and optimised through next/image pipeline
- FAQ content for each trip + landing page entered
- 301 redirect map produced from existing DigitalTrip URLs to new AX URLs
- High-equity pages prioritised — those with backlinks, search rankings, or social shares
- Edge-level redirects via Vercel — fast, no application code involved
- Sitemap.xml regenerated and submitted to Google Search Console
- DNS cutover from DigitalTrip to AX-architecture (Vercel)
- DigitalTrip put into read-only mode for 30 days for any orphaned content
- Search Console monitored daily for crawl errors + ranking shifts
- First 14 days post-launch: dedicated on-call rotation watching for traffic anomalies
Premium-restrained, warm, editorial.
The visual register Cold Lava builds in is not 'agency premium' (mood-board mockups) and not 'big-tech minimalism' (cold, Helvetica-everywhere). It's editorial — tech publication, warm and confident, where every typographic choice and every motion cue earns its place.
Premium-restrained.
Lots of whitespace. Serif headings used as confident accents, not as decoration. Precise typography rhythm. Restrained motion — every animation has a reason. The editorial register: tech publication, not agency pitch.
Warm, not icy.
Backgrounds are warm-black (never pure #000). Text is paper-cream (never #FFF). Accent is burnt coral, confident and warm, not the AI-pink default. The system reads like print quality, not screen quality.
Type as architecture.
Display: Instrument Serif at editorial sizes. Body: Inter at honest reading sizes. Monospace: JetBrains Mono for codes, dimensions, signatures. The hierarchy is clear at a glance — every page is laid out, not just composed.
Typography scale.
Motion principles.
Every animation has a reason
Reveal on viewport entry communicates section structure. Hover-state changes communicate interactivity. Loading shimmers communicate state. Decoration is not a reason.
Reduced-motion respected
All animation queries useReducedMotion() and degrades to instant reveal. Accessibility built in, not bolted on.
No bouncing, no springing
Eased curves only ([0.2, 0.8, 0.2, 1] for primary motion, [0.16, 1, 0.3, 1] for hero reveals). Premium-restrained means no toy physics.
Velocity matched to scale
Large elements move slowly (0.7-0.9s); small elements move quickly (0.3-0.45s). Physically intuitive.
The way we deliver. Visible, testable, predictable.
Software is hard. Delivery against fixed price + fixed timeline is harder. The way to keep a 12-week regulated build honest is rigour about cadence, testing, and acceptance — and visibility for the client at every step. The detail below is what AX gets, by the week, by the test layer, by the acceptance test.
Communication rhythm.
Test approach — five layers, each in CI.
Every failing test in CI blocks merge to main. No silent passes. Pre-launch: a one-week UAT window where AX staff exercise the platform on a staging URL, identical to production except for test Stripe keys.
Acceptance criteria — per proposal §3 deliverable.
Each deliverable in proposal §3 has a corresponding test that AX or Cold Lava QA executes at UAT. A deliverable is “accepted” when its test passes. AX signs off acceptance per row; aggregated sign-off triggers the final 34% invoice (proposal §6).
Five gates. No silent overruns. AX controls every decision.
A fixed-price build lives or dies on one question: does the budget run out mid-build? The contract is built around five named gates, each with an explicit pass/fail criterion and an explicit descope/proceed/rescope option. Cost or time pressure shows up as a conversation at a gate, never as a surprise invoice or a silently shipped subset.
The five gates.
Drift protections — controls already in the contract.
The contingency model.
The £40k+VAT headline price covers everything in the agreed MVP architecture. A 10% scope-change contingency of £4,000 sits alongside it, available for items AX requests during the build that fall outside the agreed scope. It is not an automatic uplift and is not pre-billed — it is a pre-approved buffer for fast-tracking small, clearly-defined extras without a full re-proposal each time.
- 01AX identifies a change or extra during the build that isn’t in the architecture document.
- 02Cold Lava provides a quick estimate (typically in half-day or day units).
- 03AX approves the draw against the contingency pot.
- 04Cold Lava delivers the item and invoices the agreed amount from the pot.
- 05Unused contingency is not invoiced. If AX uses none of it, the project total is £40k+VAT.
Insurance, IP, continuity — every contract risk named.
The contract risks that matter before a build proceeds: are we insured against catastrophe, who owns the IP, what happens if Cold Lava disappears. Every line below is a real policy or commitment, named, and willing to be evidenced at contract.
Insurance — three policies in force.
Certificates of insurance available on request before contract signature. Renewal cycle is annual; certificates re-issued automatically.
IP — clean assignment, full transferability.
Code ownership
Full IP assignment to AX on payment of final invoice. Clean assignment, not a licence. Cold Lava retains no rights to the codebase post-handover.
Repository transfer
Git history transferable. Repo is moved to AX's GitHub organisation on handover, with all commits, branches, PR history, deployment history, and observability logs intact. No rewrites, no obfuscation.
No proprietary build steps
The build is `npm install && npm run build`. No Cold Lava-only tooling, no secret npm packages, no obfuscated build scripts. AX's next developer can clone and run.
Third-party licenses inventoried
All npm dependencies catalogued with their licenses. MIT/Apache/BSD only — no GPL, no AGPL surprises in the dependency tree.
Brand assets
AX-provided imagery, copy, and brand assets remain AX's property. Cold Lava-produced design work (component library, motion patterns) assigns to AX on payment.
Continuity — what happens if Cold Lava isn’t around.
Code escrow option
Iron Mountain or NCC escrow available as an add-on. Quarterly snapshots deposited; AX gains access on Cold Lava insolvency, breach, or written request.
Key-person redundancy
Minimum 2 senior developers across the project at all times. Cover policy means no single point of failure. Holiday rotated, not bunched.
Documentation handover pack
On project completion: README, architecture doc (this site), runbook for every operational task, secret-rotation guide, monitoring playbooks. AX's next developer can operate without contacting Cold Lava.
Handover support window
30 days of priority support included after final acceptance. Out-of-scope work in the window billed at £120/hour, on-demand. Beyond 30 days: standard support retainer or per-engagement.
Training & handover · seven sessions, then forty days of cover.
AX is replacing phone-call workflows with software. A single pre-launch handover session isn't enough — the schedule below replaces it with seven.
Written runbooks (every operational task).
Every runbook lives in docs/runbooks/ in the repository AX owns. Updated as the platform evolves.
Post-launch support window.
Daily Cold Lava check-in (15 min Loom or live). Same-day response on bugs. Slack channel staffed 09:00–18:00 UK. AX comfort grows fastest in this window.
Weekly check-in. 24-hour response on bugs. Customer-impacting issues escalate to same-day. Slack channel still staffed.
Standard support retainer (£500/month, scoped) or per-engagement at £120/hour. AX's call — never imposed.
Continuity if Cold Lava is no longer involved.
If Cold Lava ceases to operate or is no longer engaged for any reason, AX has everything required to keep running and developing the platform without us. Concretely:
- Source code and full Git history are held in AX’s own GitHub organisation, with full ownership transferred on final payment. No proprietary licence, no usage restrictions.
- All commits, branches, PR history, deployment history, and observability logs transfer with the repository. Nothing material is withheld.
- An independent off-platform mirror (see §017) holds weekly snapshots in a separate jurisdiction under different credentials — the codebase cannot be lost or locked away by any single account or provider.
- A handover documentation pack covers architecture, deployment, environment setup, observability, and runbooks — a new developer or agency can pick up the codebase from documentation alone.
- Operational accounts (hosting, database, vendor APIs, DNS, payment) are held directly by AX. None depend on Cold Lava’s continued involvement.
The platform is built on standard infrastructure (Vercel, GitHub Actions, Postgres) with no proprietary build steps. Any reasonably competent successor developer or agency can take over operation without rebuilding from scratch. Continuity is a transition exercise, not a recovery exercise.
14 weeks. Five named gates. Critical path called out.
The build is 14 weeks from kick-off. Five named gates with explicit pass/fail criteria. Critical-path phases highlighted — these are the ones where slip is hardest to absorb. Buffers stated explicitly: AX always knows what slack exists and where.
Phase plan, week-by-week.
- FacilitaTrip API contractual + technical review
- Sandbox booking written end-to-end against FacilitaTrip
- Data model approved against AX's spec
- ATOL legal model confirmed in writing (Option A or B)
- MVP catalogue (40-50 trips / 15-20 countries) confirmed with AX
- Brand assets, imagery, copy delivered by AX
- Homepage + navigation + brand system
- TripBuilder 6-step wizard with state management
- Trip detail pages, dynamic from catalogue
- Customer account: register / login / 2FA / saved trips
- MVP catalogue trips populated with content
- Staging URL live for AX review
- Matching algorithm with 14-dim weighted scoring
- Damped feedback loop on customer selection
- LLM advisor (Claude Sonnet 4.6) with tool-calling schema
- Hallucination guardrails — system prompt, validation, retry
- Saved searches, abandoned-search recovery automation
- Trip tailoring module: day add/remove/move, activity swap, hotel grade upgrade
- Live re-pricing pipeline with constraint engine
- Skyscanner-equivalent flight check on date change
- Stripe Elements integration: deposit + balance, multi-currency, 3DS
- Accounting webhook to Xero/QuickBooks
- Booking state machine with all transitions
- ATOL Certificate generation (post-DMC accept)
- DMC notification + accept/exception/alternative form
- Agent take-over flow with audit
- Pen-test against staging (CREST-accredited)
- Full UAT pass with AX staff on staging
- Acceptance criteria signed off per §3 deliverable
- DigitalTrip → AX-architecture cut-over
- Production monitoring + on-call paging activated
- Handover pack delivered (runbooks, secrets rotation, ops playbooks)
Visual timeline.
Buffer + slip handling.
Buffer week
1 weekBuilt in to weeks 9-11. Absorbs minor slip without renegotiating the launch date.
FacilitaTrip API gap
0-2 weeksIf gate 1 reveals material gaps, project pauses for re-quote. Not absorbed silently.
Pen-test remediation
0-1 weekPen-test runs week 13. Critical findings fixed before launch; medium findings tracked into hyper-care.
Content readiness
AX-sideMVP catalogue content must be ready by end Week 5. Slip is AX-managed; affects launch date directly if not met.
What's deliberately not in the £40k. What gets added later.
Every section that says 'Phase 2' in the doc collects here. Each item has the trigger that typically activates it and a section reference. Phase 2 is the architectural promise: nothing here requires a rebuild, only an addition. Costs are scoped at the time AX activates each item — no Phase 2 cost is committed in this document.
Phase 2 inventory.
Manual contract loading, replaced by a self-checking agent.
In scoping, William Burton singled out supplier contract loading as one of the most labour-intensive, error-prone, and risk-laden parts of running the inventory side of the business. The Contract Ingestion Agent is the priced, ready-to-commission Phase 2 upgrade that addresses it directly — turning long, semi-structured supplier contracts into structured, quality-checked inventory records, so AX's team reviews and approves rather than re-keying every figure. This section sets it out in full: the requirement-by-requirement build, worked examples, commercial structure, total cost of ownership, and the case for building it alongside the MVP.
The problem.
Suppliers send contracts as PDF or Word documents — typically 10 to 20+ pages — defining tour content (route, hotels, excursions, components), date bands and blackout periods, pricing by season, room type and extra-night structure, and child pricing rules and occupancy constraints. Historically this data is manually keyed into the inventory system by staff or outsourced teams. Three concrete problems with that:
Cost.
An intern or administrator dedicated to contract loading is approximately £12,000 per year at MVP scale. At full scale — 200–600 tours with frequent re-issues and updates — this becomes a major and growing cost centre.
Pricing risk.
A single mis-typed digit or missing decimal can underprice a holiday by hundreds or thousands per passenger. Bookings are typically honoured at the published price, so a typo on a long-haul package sold twenty times is a six-figure margin loss before anyone notices.
Fatigue errors.
Contract loading is repetitive detail work. Human attention degrades, and the errors get harder to catch because they look correct at a glance.
The stated goal is to replace the manual loading process with an AI-assisted agent that does the extraction and mapping, runs price sanity checks, and presents the result for human approval. Economically attractive at MVP scale; operationally vital at full scale.
What we will build.
A Contract Ingestion Agent that turns long, semi-structured supplier contracts into structured, quality-checked inventory records, so AX's team only needs to review and approve — not manually re-enter every figure. The agent will:
- 01Accept supplier contract documents (PDF, Word) via the back-office.
- 02Extract all pricing, availability, and rule information into structured data.
- 03Map that data into the inventory schema — tours, components, pricing matrices.
- 04Run configurable sanity checks against expected price bands and standard rule patterns.
- 05Flag anything unusual or potentially incorrect for human attention.
- 06Produce a clear, human-readable summary for review.
- 07Hold all extracted data in a draft state until a person on AX's team approves it.
- 08Never auto-publish to live inventory under any circumstance.
Requirements cross-reference.
Each requirement, as stated in scoping, mapped to the specific deliverable Cold Lava will build.
This is the layer that protects against the two business risks driving the module: financial catastrophe from price typos — a single mis-typed digit on a long-haul package sold twenty times wipes a quarter of the margin on those bookings, with no path to recover the loss under consumer-protection rules — and operational fallout from mis-interpreted rules, where an unusual child age or blackout pattern accepted as standard leads to bookings that cannot be honoured as priced.
Beyond the structured anomaly flags, the agent generates a short interpretive commentary on every contract — the qualitative “this looks unusual versus the normal pattern” judgement a human reviewer brings, expressed in language a product manager can act on directly.
The commentary draws on three inputs:
- The structured anomaly-detection output from the sanity-check layer (the numeric basis).
- Historical contracts from AX's supplier base (comparative anchors).
- Configured product knowledge: typical bands, standard child rules, typical seasonal patterns.
“All three date bands sit within the typical short-haul range. Child rule (under 12, 70% discount) matches the standard. No unusual constraints. Ready for review.”
“Adult prices for July are ~20% below the typical short-haul band for 10-night trips. Possible explanations: launch promotion, supplier discount, or extraction error. Please verify against the source contract.”
“Child age cut-off (8) is non-standard; the usual is under 12. Festival-week rates ~60% higher than this supplier's shoulder season; likely valid due to festival demand. No other unusual rules.”
Worked examples.
Simple tour-level contract — “Chile Head to Toe”
- 16-page PDF.
- Tour-level pricing: Low (Jan–Mar) £1,800 adult, Shoulder (Apr–Jun) £2,100 adult, High (Jul–Sep) £2,700 adult.
- Blackout: 20 Dec to 5 Jan.
- Child = under 12, pays 70% if sharing with two adults, no minors alone in a room.
- 01Detects a tour-level pricing structure (not component-level).
- 02Extracts and normalises tour name, country (Chile), region (Latin America), duration (10 nights, from the descriptive text), three date bands with adult and 70%-derived child prices, the blackout, and the child policy.
- 03Maps into inventory as a tour template with the pricing matrix populated.
- 04Sanity-checks the three band prices against the configured Latin America long-haul range. All three pass without flags.
- 05Generates a plain-language summary of the tour, bands, child discount, and blackout.
- 06No warnings raised. Product manager opens the summary, scans, clicks Approve. Data commits to inventory.
A clean contract, no flags — reviewed and approved in seconds.
Component-level contract with non-standard rules — Iceland weekend
- 3-night Iceland weekend break.
- Per-night hotel pricing in ISK, varying by room type and month.
- Extra-night rules: specific ISK per adult, lower for child.
- Child = under 8 (non-standard; AX's typical standard is under 12); 8–12 year-olds treated as adults.
- Blackout: a specific winter festival week.
- 01Detects a component-level pricing structure.
- 02Extracts tour and hotel details, per-night ISK pricing per room type by month, extra-night pricing as a separate component, the non-standard child policy, and the festival-week blackout.
- 03Maps into inventory as a 3-night base package built from per-night hotel pricing, with extra nights as a repeatable component and a non-standard child policy attached.
- 04Flags the non-standard child age cut-off for confirmation, and compares the computed per-person package price against the weekend-break band — flagging it if festival demand has pushed it unusually high.
- 05Generates a summary that calls out the non-standard child rule and the festival-week blackout in the warnings panel.
- 06Product manager reviews, confirms the non-standard child rule is intended, confirms festival-week pricing is correct, and approves.
Non-standard rules surfaced, not silently absorbed — the reviewer confirms intent before it goes live.
Catching a dangerous typo
- European city break, 5 nights with flights.
- Someone has typed £200 where the intended figure was £2,000 — a missing digit.
- 01Extracts pricing as normal.
- 02Sanity check: an expected short-haul weekend with flights is ~£1,000–2,000 per head. The extracted £200 is roughly 80% below the lower bound.
- 03Flags loudly: “Adult price appears significantly below the expected range. Please double-check digits, currency, and date band. Extracted: £200 per head. Expected range for this route type: £1,000–2,000.”
- 04Product manager opens the summary, sees the warning, checks the source PDF, identifies the typo, corrects the field inline, and approves the corrected version.
The single highest-value behaviour in the system. One catch on a long-haul package sold twenty times is a six-figure margin loss avoided — the module pays for itself the first time it catches one.
Deliberately out of scope (v1).
To keep the v1 build focused, the following are explicitly not included, and would be quoted separately if added later.
Auto-fetching contracts from email or Drive.
v1 is manual upload only. The architecture leaves room to add inbox/Drive monitoring later without rework.
OCR for scanned / image-based PDFs.
v1 assumes text-native PDFs. If a meaningful share of supplier contracts are scanned images, OCR can be added as an extension.
Multi-language contract support.
v1 assumes English-language contracts. Other languages can be added supplier by supplier.
Automatic re-extraction on contract updates.
v1 treats each upload as a new event. Diff-and-update workflows can be added as a Phase 2 enhancement to this module.
Architecture summary.
- 01Upload interface — in the back-office. Drag-and-drop, file-picker.
- 02Document parsing layer — extracts raw text and structural cues from PDF and Word inputs.
- 03AI extraction layer — a structured-output LLM pipeline converts raw text into structured fields matching the inventory schema, prompt-engineered against real supplier-contract examples from AX's Drive folder.
- 04Mapping layer — translates the extracted structured data into the inventory data model — tour templates, components, pricing matrices, policies.
- 05Sanity-check engine — runs the configured business heuristics over the mapped data, producing a list of warnings.
- 06Review UI — shows the extracted record, the source document side-by-side, and the warnings panel. Supports inline editing.
- 07Approval pipeline — commits approved drafts to live or staging inventory, maintaining a full audit trail.
The whole pipeline runs server-side. Nothing leaves AX's infrastructure except the LLM API calls, handled with the same data-protection controls as the rest of the AX platform.
Commercial structure.
The commercial structure is deliberately benchmarked against the ~£12,000/year cost of a manual contract loader — the role this module replaces. Year One is set to match that benchmark exactly — the same cash outlay as hiring the intern, but for an owned asset. From Year Two onwards the retainer steps up to its standard £4,000/year as volume and API usage scale, leaving the agent meaningfully cheaper than the manual benchmark every year thereafter.
Total cost picture.
Year One matches the outsourced alternative pound-for-pound — £12,000 either way — but that £12,000 buys AX an owned asset rather than twelve months of someone’s time. From Year Two onwards the saving is approximately £8,000 every year. Over three years AX saves roughly £16,000; over five years, roughly £32,000 — and those numbers are before counting the value of pricing errors prevented, which is the higher-impact saving in practice.
Why this is better value than the outsourced alternative.
- AX owns the asset. The outsourced alternative is a recurring cost forever; this is a one-off cost for an asset that lives in the AX codebase and improves over time.
- No fatigue, no human error. The agent processes contracts to the same standard at 9 a.m. and at 11 p.m. It doesn't tire, drift, or rush at end-of-quarter.
- Concurrent processing. Multiple contracts can be processed at once — a batch of fifteen supplier updates ahead of a season change is handled in parallel, not sequentially.
- Scales with the catalogue. Going from 50 tours to 250 does not require hiring five times the loaders; the agent's cost is roughly flat.
- Compounding error reduction. The sanity-check engine catches a class of mistake — typos, mis-typed digits, currency confusion — that human loaders systematically miss because the errors look plausible to a tired eye.
- Audit trail by default. Every extraction, edit, and approval is logged. The outsourced alternative produces no equivalent record.
The case for building this.
Beyond the price comparison, the economic case rests on five reinforcing arguments. Each would justify the investment on its own.
The alternative is a perpetual cost; this is a one-off investment.
The outsourced contract loader (~£12,000/year) is a forever-overhead — AX writes that cheque every year and at no point owns anything. Over five years the outsourced path costs roughly £60,000 and leaves AX with the same dependency it started with. The Contract Ingestion Agent inverts that shape: a £10,000 install is a one-off investment in an asset assigned to AX in full on final payment, with an annual retainer (£2,000 in Year One while MVP volume is low; £4,000 thereafter as volume and API costs scale) covering maintenance and refinement — not the underlying capability. Over the same five-year window the agent costs roughly £28,000 and leaves AX with an owned, improving system.
The productivity gain is a category change, not an incremental improvement.
A human contract loader processes one document at a time, fatigues across the day, and operates at the throughput of a single brain — and degrades at exactly the season-change peaks when workload is highest. The agent processes a batch of fifteen supplier updates in parallel, holds the same standard at 9 a.m. and 11 p.m., and applies structural verification to every contract by default rather than when someone remembers. Productivity, consistency, and quality move in the same direction at the same time — something manual loading cannot deliver.
The risk asymmetry is heavily in AX's favour.
AX operates on tour gross margins of roughly 10–15%. A single mis-typed digit on a long-haul package — selling a £6,000-per-head tour at £600 because someone missed a zero — produces a margin loss in the order of £5,400 per booking. Sold twenty times before it is spotted, that is roughly £108,000 of margin gone, and AX is typically obligated to honour mis-priced bookings under consumer-protection rules. The sanity-check engine is built specifically to catch this class of error before it reaches live inventory. One prevented error pays for the entire module several times over.
The value compounds with the catalogue.
At MVP scale (40–50 trips) contract loading is manageable manually, albeit expensively. At full scale (200–600 tours with frequent re-issues) it becomes an operational bottleneck and a serious cost centre. Manual loading scales roughly linearly with catalogue size; the agent's cost stays roughly flat. The agent also gets better at AX's specific supplier base over time — lightweight supplier-specific extraction patterns are maintained alongside the core prompts, so by the time AX is processing 200–600 contracts a year it is tuned against AX's actual portfolio, not a generic baseline.
The institutional and investor narrative.
A platform that uses AI-assisted contract ingestion with structured sanity checks and a human-approval gate reads as a materially different operation to one running on manual loading. The function is automated, with humans applying judgement only where it adds value; every action is audited; pricing errors are caught structurally, not just procedurally; and cost per contract falls with catalogue growth instead of rising. To investors, partners, and acquirers, that is operational maturity — and a small but real competitive moat.
Why now, not later.
Deferring the build means continuing to pay an outsourced loader through Year One, then building the agent in Year Two. The two-year totals compare as follows.
The cost of deferral
Building now is approximately £8,000 cheaper across the first two years — Year One matches the outsourcer pound-for-pound (£12,000 either way, but with an owned asset to show for it), then Year Two pulls a full £8,000 ahead. The gap continues at £8,000 per year thereafter — £12,000/year for the outsourcer versus £4,000/year for the agent in steady state.
The MVP launch risk
The launch period is the time of highest reputational fragility — customer trust is being established and marketing spend is converting the first cohorts. A pricing error visible to customers at this stage carries disproportionate damage. Manual contract loading is the highest-error-risk part of the operations stack; building the QA layer into the MVP means launching with the protection in place, not exposed.
Operational continuity
Deferring means running an outsourced process in Year One, then transitioning to the agent in Year Two — with its own costs: training staff on the new process, parallel running, comparing outputs for drift, migrating partial data. None of those costs apply if the agent is the process from day one.
Compounding tuning value
The agent's accuracy improves with use. Building it from day one means that by the time the catalogue reaches full scale it has been tuned against real AX contracts for a meaningful period. Deferring means starting from cold prompts at the point the catalogue is already at scale.
Building the Contract Ingestion Agent alongside the MVP matches the outsourced alternative pound-for-pound in Year One — at the cost of hiring the intern, with an owned asset to show for it — then saves £8,000 every year thereafter, removes the launch-period error risk, eliminates the eventual transition cost, and gives AX a more accurate agent by the time it matters most.
What happens next.
- 01A short kick-off (one hour) to confirm the inventory schema and the configurable sanity-check bands.
- 02Collect representative final contracts from AX's existing Drive folder, organised by supplier where possible, to tune the extraction prompts and templates. The agent is initialised with each supplier's recurring formatting patterns, so it handles the existing supplier base accurately from day one.
- 03Build runs over approximately 4–6 weeks, alongside or after the MVP depending on preferred sequencing.
- 04Delivered to staging, tested against a batch of real contracts with AX's team, then promoted to live.
Other capabilities discussed in scoping.
Beyond the £40,000 MVP and the Phase 2 Contract Ingestion Agent detailed above, several further capabilities were raised in scoping conversations with AX. This is not the next phase in full — the architectural roadmap is §026b. Each item here is optional, separately quoted following discovery, and detailed in full in the Awesome Experiences — Additional Works companion document.
Capabilities discussed.
Hotel Change Tracker & Customer Notifications
Active monitoring of hotel websites and supplier feeds for operational changes — pool closures, restaurant renovations, access restrictions — with automatic identification of affected bookings and draft customer notifications for staff review.
Pre-Travel Compliance & Document Checklist
Active collection and tracking of traveller documents (passports, insurance, visas, vaccinations) with expiry parsing, destination-requirement mapping, proactive customer reminders, and a staff-side compliance dashboard.
FCDO Monitoring & Customer Alerts
Active monitoring of UK Government travel advisories with affected-booking detection, booking-date-versus-advisory-date classification, and draft customer notifications for staff review.
Sherpa Visa Requirements Integration
Third-party data integration surfacing live visa requirements by nationality, destination, and travel date, embedded in the booking flow and customer portal.
Sales & Customer Operations (BOS-native CRM)
A custom-built sales and customer-operations capability covering lead pipeline, AI-generated lead summaries, searchable advisor transcripts, automated nurture sequences, behavioural segmentation, and investor-grade funnel reporting. Built natively into the AX platform; HubSpot or Salesforce integration available as an alternative path.
Additional language activation
Beyond the MVP six languages, further languages can be added — quoted separately per language, based on content volume and QA scope.
Sign-off, kick-off, build.
Five steps to start. Each named, each owned. The fastest version of this is one approving email from AX, a signed SoW the next day, and Cold Lava on the FacilitaTrip API by the end of the week.
Approve this document.
AX reviews this site end-to-end. Any concern, any gap, any change request — flag it as a comment or in writing. Cold Lava responds within 48 hours with either a clarification or an action.
Sign the contract + SoW.
MSA + SoW with the proposal §3 inclusions, §4 exclusions, §8 assumptions, and §9 protections as the canonical scope. Patches v1 + v2 (TOMS, refund/amendment, volume caps, ATOL legal model, narrowed launch catalogue) merged in. Clean revision, no tracked-change ambiguity.
Issue project kick-off invoice (33%).
First payment. Triggers Cold Lava's calendar reservation, FacilitaTrip API access request, and project board provisioning. AX confirms the MVP catalogue (40-50 trips / 15-20 countries) by end of kick-off week.
Kick-off call.
30 minutes. Cold Lava + AX. Walkthrough of the project board, communication rhythm, gate dates, AX-side content readiness milestones. Loom recording for anyone who couldn't attend.
Build begins.
Weeks 1-2 are FacilitaTrip API discovery + architecture sign-off (gate 1). Build proper starts week 3. From here, the contract is the source of truth. Surprises become conversations at the next gate, not silently absorbed.
Contacts.
Cold Lava's calendar is held for the build window. Sign-off triggers the project. Two flights from contract to live: one signed page, one kick-off call.
This document is a single living URL. It updates as the build progresses. Every change ships as a deploy. Every section’s state can be referenced by anchor link in any conversation. When the platform launches, this document becomes the handover record.
Cold Lava is built to ship platforms that survive their delivery. This is the start.
