Sovereignty

A taxi booking system with no cookies, no backend and no Big Tech

Taxi Ghis case study: how I replaced a bloated American SaaS with a self-hosted Next.js stack, 100% European, with zero tracking cookies and zero databases.

A taxi booking system with no cookies, no backend and no Big Tech
Contents (12 sections)
  1. The brief: one driver, one mailbox, zero back office
  2. The architecture in four building blocks
  3. The magic trick: no stateful backend
  4. The life cycle of a ride in 6 steps
  5. Geocoding that does not leak
  6. Postmark and its EU alternatives
  7. The GDPR scorecard
  8. What it costs (and how long it lasts)
  9. Who it works for, and who it does not
  10. Lessons learned, one year on
  11. In summary
  12. Sources and references

When Ghislain, the driver behind Taxi Ghis in Belfort, asked me for a booking website, I started by looking at what the competition sells to independent drivers: American SaaS products at €80 to €150 a month, with a Booking-style interface, twenty-five sub-processors listed in the privacy policy when there is one, a three-column cookie banner, and the charming line “your data may be transferred to the United States” buried at the end. For a single driver who just wants to receive ride requests by e-mail, it is a bloated machine that solves problems they do not have.

This article describes the architecture we built instead: a static Next.js site, a booking form that calls European APIs, and an Outlook mailbox that serves as the database. Not a proof of concept: it has been in production since April 2026 at www.taxighis.com.

The brief: one driver, one mailbox, zero back office #

Taxi Ghis is a driver approved by the CPAM (the French state health insurance fund) to carry patients in Belfort since 2014. The need fits in five lines:

  • Receive ride requests by e-mail (with all the useful details: addresses, date, phone number)
  • Be able to accept or decline from a phone, with no app to install
  • Show the customer an honest price estimate before they confirm
  • Not pay a monthly subscription for it
  • Comply strictly with the GDPR, because an approved taxi carries patients (Article 9 of the GDPR)

None of these lines requires a database, a user account, an admin panel or an American third-party service. That is exactly what guides the architecture.

The architecture in four building blocks #

The site rests on four components, all hosted or operated in Europe:

  1. Next.js 16 + React 19 + Tailwind v4, standalone build, deployed as a container on a SoYouStart dedicated server in France (OVH data centre).
  2. OpenRouteService (HeiGIT, Heidelberg, Germany) for geocoding European addresses and calculating the real road distance.
  3. Base Adresse Nationale (the French national address database, run by Etalab) for autocompleting French addresses, more accurate than any competitor.
  4. Postmark for transactional e-mail delivery (yes, it is American, but we minimise the content sent so much that it remains defensible; more on this below).

For form security: Cloudflare Turnstile (invisible anti-spam, with no puzzle for the user, unlike reCAPTCHA), a honeypot, and an application-level rate limit of five submissions per hour per IP address. No bot gets through.

Architecture diagram of the Taxi Ghis website with four connected technical building blocks: Next.js on an OVH server in France, OpenRouteService in Germany, Base Adresse Nationale in France, Postmark in the United States, and an Outlook mailbox that serves as the database
Four-block architecture. Next.js orchestrates everything on the server side, the external services never see the visitor's IP address, and the driver's Outlook mailbox plays the role of the database.

The magic trick: no stateful backend #

The workflow looks like this. A customer fills in the booking form. The Next.js server validates the data, calculates the estimate, checks Turnstile on the server side, then sends two e-mails via Postmark: a confirmation to the customer and a notification to the driver. The e-mail to the driver contains two links: “Accept” and “Decline”.

These two links do not point to a database. They contain an HMAC-signed token that carries all the ride information (reference, customer, addresses, date, price). When Ghislain clicks, the server checks the signature, generates a confirmation e-mail to the customer (with their ride number), and that is it. No data has been stored on the server. Ghislain's Outlook mailbox plays the role of the database.

TypeScript
// Signed token sent to the driver in the notification e-mail.
// No server-side persistence: everything is in the URL.
const token = signBookingToken({
  ref,
  clientName,
  clientEmail,
  clientPhone,
  pickup,
  destination,
  when,
  priceEur,
});
const acceptUrl  = `${siteUrl}/accepter-course?t=${token}`;
const declineUrl = `${siteUrl}/refuser-course?t=${token}`;

The HMAC secret is known only to the server, so nobody can forge an acceptance link. The token expires after a few days. To look at the history, Ghislain opens Outlook: that is the source of truth. No need for a back office, no password to remember, no interface to be trained on.

Flow diagram of a signed HMAC token: the server signs the ride data with a secret, the token travels in the e-mail sent to the driver, and clicking 'Accept' triggers a server-side signature check before a confirmation e-mail is sent to the customer
The HMAC token flow: server signature, transit in the e-mail, verification on click. No data is stored: the cryptographic signature replaces the database.

The life cycle of a ride in 6 steps #

To make the architecture concrete, here is what happens between the moment a patient clicks “Book” and the moment the driver receives the final confirmation e-mail.

  1. Input: the customer fills in the form. Address autocompletion goes through /api/autocomplete on the server side, never directly to BAN or ORS. The visitor's IP address never reaches the sub-processors.
  2. Validation and estimate: the Next.js server checks that the data is consistent (French phone number, future dates, non-empty addresses), queries OpenRouteService for the road distance, calculates the price according to the applicable fare scale (peak and off-peak hours, supplements), and checks the Cloudflare Turnstile token on the server side.
  3. Immediate confirmation to the customer: a summary e-mail is sent via Postmark. The customer receives the details of their request and a reminder: the ride is only confirmed once the driver accepts it.
  4. Notification to the driver: at the same time, Ghislain receives a structured e-mail in the Outlook mailbox with two HMAC-signed links: “Accept” and “Decline”. The e-mail contains all the operational information that matters at 6 am (address, phone number, estimated distance).
  5. The driver's decision: Ghislain clicks from a phone. The server checks the HMAC signature (rejected if altered or expired), extracts the data from the token and triggers the corresponding e-mail.
  6. Final confirmation to the customer: a last e-mail confirms acceptance with the ride number and the driver's direct phone number (or politely explains the refusal and invites the customer to get in touch again). On the server side, no trace remains: the cycle is complete.

Six steps, two e-mails for the customer, one e-mail for the driver, one click to confirm. No database touched, no account created, no session opened. The server literally knows nothing more about the ride after the 30 seconds of the form: the memory is in Outlook.

Geocoding that does not leak #

On the taxi websites you usually see, address autocompletion calls Google Maps directly from the customer's browser. The result: Google receives the customer's home address + their IP address + their user-agent as soon as they start typing, before they have confirmed anything at all. That is a transfer outside the EU which requires, at the very least, prior consent.

On taxighis.com, autocompletion goes through our own Next.js API (/api/autocomplete), which queries the Base Adresse Nationale and OpenRouteService on the server side. The customer has no direct contact with these services. Their IP address never reaches OpenRouteService's OVH servers or data.gouv.fr. We checked the network trace with Playwright: zero requests to an external domain when you type “1 avenue de la République”.

Postmark and its EU alternatives #

This is the stack's only non-EU concession. Postmark is based in the United States (Wildbit Inc.) and is certified under the EU-US Data Privacy Framework, a legal framework recognised by the European Commission in July 2023, which secures the transfer. To minimise exposure, the e-mail content is deliberately kept to a minimum: no attachments, no tracking pixel, no open tracking enabled.

For clients who require 100% EU (public administrations, strictly regulated health sector, public procurement), there are four credible alternatives with the same transactional capabilities.

  • Tipimail (Brevo): France, based in Paris. A Brevo subsidiary that handles 100 billion e-mails a year. Transactional SMTP + REST API. Pricing comparable to Postmark.
  • Mailjet: France, based in Paris (part of the Sinch group since 2019, French operations retained). SMTP + API + optional tracking that can be switched off.
  • Brevo: France, formerly Sendinblue. More marketing-oriented, but with a solid transactional offer.
  • Mailtrap: Poland (Railsware). A good option for dev/staging + production set-ups, 100% EU infrastructure.

For Taxi Ghis we chose Postmark for two reasons: deliverability (inbox placement rate > 99% against ~95% for the French providers), and the DPF, which is legally sufficient for a CPAM-approved transport provider. If you are a public administration or working on a public contract, switching to Tipimail or Mailjet takes 10 minutes of configuration in Next.js.

The GDPR scorecard #

When you honestly list the chain of sub-processors for a CPAM-approved taxi website, you expect the worst: it is a field where Article 9 of the GDPR (health data) hangs over the slightest destination entered (a trip to a hospital reveals something about a person's health). Here is what we ended up with:

  • Cédric Santiago (me): hosting and managed services, in France, under a contractual commitment.
  • OpenRouteService (HeiGIT, Germany): European geocoding, purely EU sub-processing.
  • Base Adresse Nationale (Etalab, France): French address autocompletion.
  • Cloudflare Turnstile (Cloudflare Germany GmbH for EU matters): anti-spam in invisible managed mode, without tracking cookies, legitimate interest under Art. 6.1.f.
  • Postmark / Wildbit Inc. (US): transactional SMTP, covered by the EU-US Data Privacy Framework (European Commission adequacy decision of July 2023).
  • Microsoft Outlook (Ireland, US operations): the driver's mailbox, direct customer contract (Microsoft 365 Business).

Six sub-processors, four of them in the EU and two in the US under the DPF. No audience measurement cookie, no advertising pixel, no consent banner. The only possible technical cookie is the Turnstile one for the duration of the challenge, exempt from consent under CNIL decision 2020-091 (the CNIL being the French data protection authority).

For health data that might be revealed (destination = hospital, mention of dialysis in the “Comments” field), we rely on Article 9.2.h of the GDPR combined with the professional secrecy of medical transport providers (Article L.1110-4 of the French Public Health Code). This is documented in black and white in the site's privacy policy.

What it costs (and how long it lasts) #

Recurring monthly costs for Ghislain: nothing for Next.js (hosted on the shared infrastructure I manage), nothing for OpenRouteService and BAN (the free tier is enough for the volume), nothing for Cloudflare Turnstile (free), Postmark billed per e-mail sent (~€5 a month for 1,500 transactional e-mails a month). Domain and SSL certificate: ~€10 a year. Annual total excluding development time: less than €100.

On the maintenance side: no database to back up, no CMS to update, no plugin to patch after a WordPress CVE. The site is static and will outlive any change of heart from the driver. The day Ghislain wants a new service, we add a Next.js page and redeploy in five minutes.

Who it works for, and who it does not #

This architecture is cut out for small businesses that want to simplify, not to computerise everything. It works very well for:

  • Independent drivers who take requests by e-mail or phone (1 to 3 drivers)
  • Tradespeople and service professions with a moderate volume of requests (10-50 a day)
  • Health-insurance-approved professionals (CPAM taxis, physiotherapists, osteopaths) who want a light appointment booking form
  • Any brochure website with a contact or quote form that has to be strictly GDPR compliant

It is not suited to large fleets that need real-time dispatch, live driver geolocation or a multi-user back office. There, you need a real backend (Next.js + Postgres + WebSockets, for example). But 80% of the SMEs I come across do not have that need: they may have imagined it while watching SaaS demos, that is all.

Lessons learned, one year on #

A few lessons in hindsight, after several hundred rides booked through the form and a year of user feedback.

  • E-mail as a “database” works better than expected: Ghislain has never needed an application history; Outlook search (by name, date, address) covers 100% of the need to find a past ride.
  • The HMAC token is more than enough: not a single forgery attempt since go-live. The secret is in .env on the server, the token is time-limited (7 days), and nobody in the street is going to guess the HMAC.
  • BAN autocompletion beats Google in rural areas: many addresses in the Territoire de Belfort and the Vosges are simply not indexed on Google Maps, but are in the BAN. On the outskirts, we even got better results than the national taxi apps.
  • A form with no cookie banner has a strong psychological effect: several elderly patients commented positively, “oh, that makes a change, there's nothing to click to accept”. Removing friction is as noticeable as technical performance.
  • Local SEO requires nothing extraordinary: between carefully written location content (Belfort + the municipalities served) and the absence of a banner slowing down rendering, the home page ranks without paid backlinks for “taxi conventionné Belfort” (approved taxi Belfort) and “VSL Territoire de Belfort” (light medical transport vehicle).

In summary #

Taxi Ghis runs on static Next.js, six documented sub-processors (four in the EU), zero databases, zero tracking cookies, and an Outlook mailbox that serves as the source of truth. The site costs less than €100 a year to run, requires no application maintenance, and the privacy policy fits on one page without euphemisms. It is the exact opposite of the roadmap a Booking-clone salesperson will offer you, and it is probably what your independent business or small company needs.

If you are a driver (taxi, private hire, CPAM-approved), a therapist or a tradesperson, and you are looking for an appointment booking site that does not feel like an American marketplace, let us talk: the stack is proven, the privacy policy is ready, and the time to go-live is measured in weeks, not months.

Sources and references #

The legal, technical and institutional references that guided the project's architecture and compliance, checked as of May 2026.

  1. EUR-Lex, Regulation (EU) 2016/679, GDPR, Article 9 (special categories of data, including health): https://eur-lex.europa.eu/eli/reg/2016/679/oj
  2. Légifrance, French Public Health Code, Article L.1110-4 (professional secrecy of medical transport providers, in French): https://www.legifrance.gouv.fr/codes/article_lc/LEGIARTI000041721185
  3. Légifrance, Article 82 of Law no. 78-17 (French Data Protection Act, in French): https://www.legifrance.gouv.fr/loda/article_lc/LEGIARTI000037813978
  4. CNIL, Decision no. 2020-091 (cookies and trackers, audience measurement exemption, in French): https://www.cnil.fr/fr/cookies-et-autres-traceurs-la-cnil-publie-des-lignes-directrices-modificatives-et-sa-recommandation
  5. CNIL, practical guide to contact forms (in French): https://www.cnil.fr/fr/securite-des-donnees-personnelles-les-bonnes-pratiques-formulaire-en-ligne
  6. European Commission, EU-US Data Privacy Framework adequacy decision (July 2023): https://commission.europa.eu/document/fa09cbad-dd7d-4684-ace2-be9a59a44d70_en
  7. Etalab / data.gouv.fr, Base Adresse Nationale (BAN), official address reference: https://adresse.data.gouv.fr/
  8. Etalab, BAN autocompletion API (documentation): https://adresse.data.gouv.fr/api-doc/adresse
  9. OpenRouteService, HeiGIT, Heidelberg University: https://openrouteservice.org/
  10. OpenRouteService, Pelias geocoding documentation: https://openrouteservice.org/dev/#/api-docs/geocode
  11. Cloudflare Turnstile, official documentation (managed mode without cookies): https://developers.cloudflare.com/turnstile/
  12. Postmark, EU-US Data Privacy Framework certification: https://postmarkapp.com/eu-privacy
  13. Next.js, official documentation (standalone output, deployment): https://nextjs.org/docs/app/api-reference/config/next-config-js/output
  14. Brevo / Tipimail, French transactional SMTP alternative: https://www.brevo.com/fr/produits/e-mail-transactionnel/
  15. Mailjet, French alternative: https://www.mailjet.com/fr/
  16. Caisse Nationale d'Assurance Maladie (French national health insurance fund), medical transport agreement (in French): https://www.ameli.fr/transporteur-sanitaire
  17. RFC 2104, HMAC: Keyed-Hashing for Message Authentication: https://www.rfc-editor.org/rfc/rfc2104
About
01/Read nextThree articles

Related articles

Sovereignty

NIS2: what the directive says, where France stands, and why we do all this without being required to

Bastion, SIEM, immutable backups, deliberate patching, ANSSI self-audit: for six months this blog has documented an infrastructure that a company of our size has no legal obligation to build. The reason fits in four characters. What NIS2 really requires, the state of French transposition in autumn 2026, and how our building blocks line up against the 20 objectives of the ANSSI framework.

nis2anssi
Sovereignty

One consultant, one AI, 25 million SIM cards

A national interception platform written by a lone consultant, the court warrant requirement removed at the client's request, and an account ban that stopped nothing because the software now runs locally. The surveillance chapter of the Anthropic report is the most disturbing, and it says something very concrete about the data you hold.

surveillanceai
Sovereignty

ReCyF explained for SMEs: the ANSSI cyber framework, who must apply it, and where to start

On 17 March 2026, ANSSI published the Référentiel Cyber France (French cyber framework): 20 security objectives, four pillars, an operational translation of NIS2 before the law even exists. Many companies wonder whether they are concerned, and what they risk. A clear answer in three questions, a jargon-free reading of the 20 objectives, and the five to start with even when nothing obliges you to.

recyfanssi

What next

Keep your data in France, out of reach of the Cloud Act?

Dedicated servers in France, known sub-processors, backups kept out of reach. First conversation free.

Discuss your project

Reply within 24 working hours, from one of the two founders. Or by phone: +33 7 59 96 14 99.