Distribution
ProntoVA
ProntoVA is a WhatsApp receptionist for Madrid clinics — one backend running many bots, each defined by a config file, deployed and running 24/7. Nobody is paying for it, and why not is the most useful thing on this page.
My role
Solo. The product, the code, the GDPR work, the pricing, the target list and the CRM behind it. No co-founder, no client brief, no agency.
The decision
The comfortable version of this is a general-purpose WhatsApp chatbot framework. I picked a buyer instead: appointment-based clinics in Madrid — dental, aesthetic, physio. They take inquiries on WhatsApp all day, the owner answers personally, and because they are health-adjacent, Spanish data-protection guidance turns GDPR from a tax into the differentiator. Then I built the distribution alongside the software: a researched target list in a self-hosted CRM, a written outreach playbook, and a pilot offer where the client sets the success criteria.
Choosing a real buyer is what killed my channel, and that is the decision worth reading. V1 ran on Baileys, an unofficial WhatsApp library: QR login, no Meta approval, live in a day — and it worked, a real five-turn conversation through the full pipeline on 2026-07-07, ten messages persisted and metered end to end at $0.026. Then I deployed to a VPS and it failed deterministically: WhatsApp accepted the pairing, registered the device, then killed the authenticated session five seconds later with a 401. Residential connection fine, datacentre never. IP policy, not a bug I could fix.
A workaround existed — residential egress. I didn't take it. The bar is not "can I link once for a demo", it is "can a clinic depend on this for weeks without their business number being banned", and that channel had already silently de-registered my own working session inside an hour. So on 2026-07-08 I demoted Baileys to zero-stakes internal demos and made the official WhatsApp Cloud API the pilot channel: a bigger build, and one that has to clear Meta's business verification first. I traded my launch date for a channel a paying client can depend on.
Proof
Live at prontova.net. The runtime — app plus its own Redis, against Postgres over a private network — has run 24/7 on a VPS since 2026-07-08. Channel, model, payment and speech-to-text are each swappable per project in config, which is why the channel decision above is a new adapter, not a rewrite. 194 automated tests pass on the gate every goal had to clear — one further test, a live-API smoke, is opt-in and skipped by default. Tenancy is enforced by isolation tests, every model call is metered to a cost, and the privacy layer — retention purge, erasure, opt-out, PII redaction in logs — shipped and was reviewed before any clinic could be onboarded.
One review catch is a product judgment, not a code bug: my opt-out keyword list originally matched the bare Spanish words cancelar and baja. In a dental clinic those mean "cancel my appointment" and "sick note" — a patient typing either would have been silently and permanently blocked. Caught before it shipped; the list narrowed to unambiguous unsubscribe phrases, and the test now asserts those two inputs must not match.
Repo link placeholder — private today.
What it shows I build the whole path to a paying user — product, offer, and distribution, not just code.
Honest limitations
No client is paying and no pilot has started. At the last recorded pipeline snapshot, on 2026-07-09, every row in the CRM was still at "lead" — the outreach hadn't gone out, because I wasn't willing to sell a pilot I couldn't deliver on a clinic's real number until the official channel was live. Booking is a request-capture stub, not a calendar integration, and the sales copy says so.
So what's demonstrated is that I can build the system, the offer, and the route to market. That I can close is not. That's the next number I owe this page.
Stack
TypeScript on Node, Anthropic API behind a swappable model adapter, BullMQ on Redis for durable per-conversation queuing, Postgres with pgvector enabled on day one (RAG not built), Docker Compose, Caddy, zod, vitest. EspoCRM self-hosted for the pipeline.