← All work

VeoCabs

An intercity cab lead-generation platform across 150+ Indian cities: instant fare estimates from Google Routes, enquiries pushed to Telegram, and a CRM the business runs on daily. Built and still maintained by me, and run day to day by the business itself.

live · maintainedSolo end-to-end delivery

Next.js · TypeScript · Neon Postgres · Google Routes API · Telegram Bot API · GA4 + GTM · Vercel

150+
Cities served
37
Curated route pages
₹0
Monthly infrastructure cost

The problem

Intercity cab operators in India sell through aggregators, phone calls and WhatsApp. The aggregators take a cut and own the customer; the phone calls do not scale past the person answering them.

The brief was not build a booking engine. It was: capture the demand that already exists as search traffic, qualify it, and put a warm lead in front of the operator fast enough to win the job. The close stays human — that is where the margin is, and an intercity fare genuinely does depend on the exact route, the tolls and what vehicle is free that week.

The other constraint was money. A new operator cannot carry a monthly infrastructure bill before the first booking. The whole thing had to run on free tiers and stay there.

The architecture

The site is a lead generator with a fare estimator attached. A visitor lands on a route page from a Google Ads campaign or organic search, gets an instant all-inclusive estimate, and submits an enquiry. That enquiry fires a Telegram message to the operator, who calls back and quotes the real price.

Pricing runs on two tracks. Thirty-seven popular routes are curated pages with distances known from experience — exact, and free to serve. Everything else is quoted at runtime: the visitor names two places and the fare is computed live.

The fare itself is a formula, not a lookup: a base rate per kilometre, a per-cab-type multiplier and floor, a return-trip discount, and a driver allowance per day. That config lives in Postgres and is merged over coded defaults, so the operator can retune pricing from the admin panel without a deploy.

The hard part: staying free

Google's Routes API is the expensive dependency in this design. Every dynamic quote is potentially a billed call, and a bot crawling the quote endpoint is a bill nobody budgeted for.

So distance resolution goes through three tiers before anything is billed. Curated routes answer from the route table — exact, instant, free. Anything else checks a distance cache in Postgres, keyed on the two endpoints sorted, so Delhi→Jaipur and Jaipur→Delhi are one cache entry rather than two. Only a genuine miss reaches Google, and the result is written back to the cache immediately.

The practical effect: the API cost is bounded by the number of distinct city pairs anyone has ever asked for, not by traffic. A route that goes viral is billed once.

Trusting the operator over the formula

The estimator is deliberately not the final price, and saying so on the page is what makes the whole design work. It removes an entire class of engineering risk: the number has to be close enough to keep someone on the phone, not correct enough to honour.

Every stored fare value is clamped to a sane range on the way in and on the way out. An admin typing a stray zero into a per-kilometre rate cannot produce a quote of ₹4,00,000 — the value is bounded when saved and bounded again when read. A pricing panel that a non-engineer edits daily will eventually receive a bad value, and the estimator has to survive it rather than validate its way out of it.

The operator can also override fares per route outright. Experience beats the formula on the routes run every week, and the system defers to it.

The notification path can fail safely

Telegram was chosen over email because the operator already lives in it and replies in seconds. Enquiries, fare locks and partner sign-ups all push there, to one chat or several.

The part worth copying: if Telegram is unconfigured or unreachable, the enquiry is written to the server log and the submission still returns success. A lead is worth more than a notification. The failure mode of the alternative — a form that errors because a messaging bot is down — loses the customer to protect a side effect.

Built for somebody else to run

The admin panel is the deliverable that makes the business independent of me day to day. It is a small CRM: booking enquiries, vendor records, per-route fare overrides, the global pricing config, page content, FAQs and reviews — all editable by someone who does not write code. Pricing gets retuned, enquiries get worked and content gets edited without a deploy or a developer.

Attribution is wired through GA4 and GTM with Google Consent Mode v2 and region-scoped defaults, plus server-side events for the ones an ad blocker would eat. That matters because the traffic is paid: without trustworthy per-route conversion data, the ad spend is guesswork.

That split is the arrangement: the business runs the operation, and I keep the platform running. It has been live on Vercel's and Neon's free tiers since launch.

Built from scratch with Claude Code. The architecture, the three-tier distance resolution and the decision to keep the close human are mine; a great deal of the typing is not. It is the clearest evidence I have that one engineer can now deliver a complete commercial platform, admin panel included, without a team behind them.

Enquiry path

  1. Landing

    Google Ads · organic

    Curated route page or a live quote

  2. Estimate

    Billed only on a true miss

    Curated distance, then cache, then Google Routes

  3. Enquiry

    Neon Postgres

    Visitor submits; succeeds even if notification fails

  4. Telegram

    Bot API

    Operator alerted in seconds

  5. Callback

    Admin CRM

    Human confirms the real price and closes

The estimate exists to keep someone on the phone, not to be honoured. Pricing precision stays with the person who knows the route.

Building something in this shape?