Skip to content
sapiqa

This site

The site is a system too. Here's how it works.

The same method as for clients: a prerendered front end, a stateless API, state kept in services that have to exist anyway, and an agent that doesn't make things up.

← swipe the diagram →

BROWSERCLOUDFLAREGOOGLE CLOUD RUNSERVICESVisitorsite, booking, agentPagesprerendered HTMLFastAPIbooking, agentSite agenttools: knowledge, slotssapiqa-contextRAG: hybrid + rerankBookingslots, hold, paymentGoogle Calendarsource of truth for slotsStripeCheckout + webhookClaudeagent modelResendconfirmationsJitsimeetings (droplet)

Flows

Content is in the HTML before any JavaScript runs.

Step 1 of 2

Click a part of the diagram for details.

  • hardware
  • edge / network
  • service
  • data
  • AI
  • third party
  • people / apps
  • radio
  • tunnel
  • HTTPS
  • local
  • event
Every element, described
Visitor · site, booking, agent
Receives ready HTML with content and meta. JavaScript adds the interactive parts: the 3D hero, diagrams, booking and the agent.
Pages · prerendered HTML
React Router 7 renders every page in both languages to static HTML at build time: canonical, hreflang, JSON-LD, sitemap. Deployed from CI on push.
FastAPI · booking, agent
One container on Cloud Run, scales to zero. Stateless: booking state lives in the calendar and in Stripe, not in a database.
Site agent · tools: knowledge, slots
Answers only from knowledge generated from this site's content and from the calendar. Streams its answer and shows which tools it used. Rate-limited, with a daily budget.
sapiqa-context · RAG: hybrid + rerank
A separate Cloud Run service with local ONNX models: BM25 and multilingual embeddings merged by RRF, then a cross-encoder rerank. IAM access only; while it sleeps the API answers from BM25 + tags.
Booking · slots, hold, payment
Free slots from the calendar (working hours, buffer, lead time). A paid session holds the slot for 30 minutes until paid; confirmation arrives by webhook.
Google Calendar · source of truth for slots
Booking events carry their state (held, confirmed) in private properties, so the API needs no database.
Stripe · Checkout + webhook
Checkout expires with the hold. A signed webhook confirms or releases the slot.
Claude · agent model
A streaming tool loop with prompt caching and a refusal fallback.
Resend · confirmations
Confirmation e-mail with the meeting link, in the visitor's language.
Jitsi · meetings (droplet)
A self-hosted video server on the droplet. Off until the server is upgraded; until then the meeting link arrives in a separate e-mail.

Context Engine

How the agent searches: live RAG, with evals

Hybrid BM25 + embeddings, RRF fusion, cross-encoder reranking, a tag cloud. Type a question and see every stage with its timing.

Decisions

Prerender, not a SPA

The old site loaded content with JavaScript. Now every page in both languages is ready HTML with canonical, hreflang and JSON-LD.

8 MB model → 7 KB of data

The old site's neural network is 42 points and 861 edges. A script extracted the geometry from the FBX, and WebGL draws it in three draw calls.

One source of content

System descriptions are typed data. Pages, diagrams and the agent's knowledge file are built from them, so the agent never says anything the site doesn't.

A stateless API

Bookings keep their state in the calendar and Stripe. Cloud Run scales to zero, and there is no database to run.

No tracking

No advertising cookies and no third-party analytics scripts. Fonts are served from this domain.

Typed translations

Every string is a PL/EN pair in code. A missing translation is a compile error, not a blank label in production.

Stack

React 19fastembed / ONNX RuntimeBM25 + dense + RRFcross-encoder rerankReact Router 7 (prerender)TypeScript strictTailwind CSS 4three.jsVite 8VitestPython 3.14FastAPIPydantic 2ClaudeGoogle Calendar APIStripe CheckoutResendCloudflare PagesGoogle Cloud RunGitLab CI

Got a process that should run itself?

30 minutes, free. I'll tell you if it makes sense, how I'd build it and what it would cost to run.

Book a call