● Internal build brief Β· for engineering

Sukoon.mom β€” the real WhatsApp product

A safety-first baby-care companion for Indian parents, delivered over WhatsApp. This is the end-to-end spec to build the production product on modern rails β€” not a prototype.

Audience Β· Shreesh (tech lead) + eng
Version Β· v1.0
Date Β· 19 Aug 2026
Status Β· Approved to build
Owner Β· Sanchit (product)

0Read this first

We have a validated prototype of this product built on an agent framework (OpenClaw). It works, real parents used it, and it proved the demand and the conversation quality. It is not the foundation we scale on β€” it drives WhatsApp as a "linked device", which is against WhatsApp's terms for automation, keeps getting de-linked, and handles payments and subscription state manually.

Your job: rebuild the same product as a proper WhatsApp Business product on modern, boring, reliable technology β€” with automated subscription billing as the first milestone.

The one sentenceReuse the brain and the rules from the prototype (behavior, safety, pricing model, pediatric knowledge β€” all handed to you as a spec repo), and rebuild the plumbing (WhatsApp, database, payments, hosting) as real software.
Two decisions already made β€” don't re-litigate WhatsApp = official Cloud API (not any linked-device/unofficial library, ever). Payments = Razorpay Subscriptions (UPI AutoPay + cards). Rationale is in Β§5 and Β§7. Spend your energy on the product, not on re-choosing these.

Read Β§0–§3 for orientation, Β§4–§10 for the system, Β§14–§16 before you write a line of code. Β§16 exists specifically so you don't get sidelined.

1What we're building

Sukoon is a WhatsApp companion for new parents. A parent messages our number, tells us about their baby once, and then has a calm, always-available helper that:

  • Answers everyday baby questions (feeding, sleep, growth, vaccines, common symptoms) grounded in trusted Indian pediatric guidance, in the parent's language (Hindi / Marathi / English).
  • Remembers their baby β€” age, term/preterm, conditions, what happened last week β€” so answers are specific, not generic.
  • Flags red-flag symptoms and tells them to call a doctor / emergency services. It is explicitly not a doctor and never diagnoses or prescribes.
  • Turns messy parent notes into timelines, checklists, and questions to ask their pediatrician.

Business model

10-day free trial β†’ β‚Ή199/month per baby. Recurring via UPI AutoPay. The bot handles trial, expiry, renewal prompts and premium gating automatically once billing is wired.

Why WhatsApp

Indian parents already live on WhatsApp β€” zero app install, zero learning curve, works on any phone. That is the entire distribution thesis. The product must feel like texting a knowledgeable, kind friend, not "using an app".

2Product principles (non-negotiable)

πŸ›Ÿ Safety over everything

When a description could be serious, we never guess urgency. We say we can't judge from text and push them to a pediatrician / emergency care. Safety text is given even to free/expired users.

🩺 Not a doctor

No diagnosis, no prescriptions, no medication doses, never override a real doctor. Every health reply makes this clear. This is a legal and ethical hard line.

🎯 Specific, not generic

Answers are grounded in this baby's age and history. "For a 6-week-old, guidelines say… for your baby specifically…". Generic copy-paste is a failure.

πŸ—£οΈ Their language, their tone

Warm, calm, short. Detect Hindi/Marathi/English and match it. Parents are often exhausted and anxious β€” reduce anxiety, don't add jargon.

πŸ”’ One baby's world stays private

Strict tenant isolation. Never let one family's data touch another's. This is both a trust promise and a compliance requirement (Β§12).

πŸ“š Grounded, not made up

Health answers come from the vetted knowledge base (and, for premium, live guideline lookups) β€” never a random blog. Always able to say "I'll check" and cite the source.

These are product requirements, not vibesEvery one of these is enforced in the prototype's behavior spec (SOUL.md, AGENTS.md). They become code: a safety classifier, a disclaimer injector, prompt construction rules, and tenant-scoped queries. Don't drop them in the rebuild.

3The prototype & exactly what to reuse

The prototype lives in a scrubbed repo you already have access to: sukoon-baby-dev (bot brain) and sukoon-web (the web app). Treat sukoon-baby-dev as the product specification, file by file:

Prototype fileWhat it really isRebuild as
workspace-baby-template/SOUL.mdThe behavior + safety + tone specSystem prompt + guardrail logic
.../AGENTS.mdTenant routing + entitlement rulesRouter + subscription/entitlement service
commerce/COMMERCE.md + bot-defaults.jsonThe billing rules (β‚Ή199, 10-day trial, 30-day cycle)Billing config + Razorpay integration (Β§7)
commerce/registry/children.jsonThe tenant/subscription data shapePostgres tables (Β§6)
docs/iap_*.mdVetted pediatric knowledge baseRAG corpus (Β§10)
workspace-baby-poc-onboard/*The signup flow + provisioningOnboarding state machine (Β§9)
What the prototype already proved β€” don't re-question itParents will tell a WhatsApp bot about their baby. They ask real questions (feeding, cough, sleep, cluster-feeding, vaccines). The safety-first, memory-grounded, multilingual approach lands. The product is right β€” the engineering is what changes.
The lesson that cost usThe prototype once ran on a personal WhatsApp number with an open policy and auto-replied to the owner's real personal contacts with error text. Never run the bot on a personal line. Never let an unauthenticated sender reach the agent. The production design must make this structurally impossible (dedicated business number, explicit opt-in, Β§5/Β§11).

4Target architecture

Boring, proven, cheap to run. Nothing exotic. Everything here is a managed service or a standard library.

Channel
WhatsApp Cloud APIMeta-hosted, official. Webhooks in, Graph API out.
Web (sukoon-web)Next.js β€” landing, pricing, self-serve start, admin.
Edge
Webhook receiverVerifies Meta signature, ACKs <5s, enqueues.
Razorpay webhooksPayment / subscription events.
Core services
Message routerResolve tenant β†’ load context β†’ dispatch.
Conversation enginePrompt build + LLM + safety + RAG.
Subscription serviceTrial/active/expiry state machine.
Onboarding serviceNew-parent signup FSM.
Async
Queue (BullMQ / Redis)Inbound processing + outbound send, retries, idempotency.
SchedulerTrial-expiry sweep, renewal nudges, journaling.
Data
PostgresTenants, children, subs, messages, usage, consent.
Vector storepgvector β€” pediatric KB + per-child memory embeddings.
Object storageMedia (images parents send), backups.
External
LLM APIGemini / Claude β€” conversation + summarization.
RazorpaySubscriptions, UPI AutoPay, invoices.

Recommended stack

LayerPickWhy
BackendNode + TypeScript (NestJS) or FastAPI if you prefer PythonStrong typing for a stateful messaging system; great WhatsApp/Razorpay SDKs; one language with the web app.
DBPostgres + pgvectorRelational tenant data + vector search in one engine. No separate vector DB to run.
QueueRedis + BullMQWebhooks must ACK fast and process async with retries + dedup.
LLMGemini or Claude via APIProvider-swappable behind one interface. Keep a cheap model for routing, a strong model for medical-adjacent answers.
PaymentsRazorpay SubscriptionsOnly mature India option for recurring UPI AutoPay + cards + webhooks.
HostingRender / Railway / Fly / AWSManaged Postgres + Redis + containers. Start simple, scale later.
WebNext.js (existing sukoon-web)Already started. Landing + pricing + self-serve entry + internal admin.
Provider-abstract the two externalsPut WhatsApp and the LLM behind thin interfaces (MessagingProvider, LlmProvider). If we later move from Meta-direct to a BSP (360dialog/Gupshup) or swap models, it's a config change, not a rewrite.

5WhatsApp Business Cloud API β€” the hard part

This is the riskiest, slowest integration. Spike it first (Β§14). The LLM is easy; WhatsApp is where projects stall.

What you must set up

  1. Meta Business account + WhatsApp Business Platform access.
  2. Business verification with Meta (documents; can take days–weeks β€” start early).
  3. A dedicated phone number for the bot. Never a personal number. It cannot already be on a personal WhatsApp account.
  4. Message templates pre-approved by Meta for anything we initiate (welcome, trial-ending, renewal, payment confirmation).
  5. A public webhook endpoint (HTTPS) registered with Meta, with a verify token + signature validation.
Direct vs BSP β€” recommendationStart on Meta Cloud API directly for max control and lowest cost. If Meta onboarding/verification is painful, fall back to an Indian BSP (360dialog or Gupshup) which eases verification + INR billing while still giving you raw API access. Avoid no-code platforms (they want to own the bot logic). Keep it behind the MessagingProvider interface either way.

The two rules that shape the whole design

⏱️ The 24-hour window

You can send free-form messages only within 24h of the user's last message. Outside it, you may only send approved templates. β†’ Renewal nudges, trial-ending alerts, and payment reminders must be templates.

βœ… Opt-in is mandatory

A user must initiate or explicitly opt in before we message them. The self-serve model (they message us first) satisfies this naturally β€” lean into it. This is also what makes the "personal contacts" disaster impossible.

Inbound message flow

Parent sends WA msg→ Meta → our webhook→ verify signature, ACK 200 <5s→ enqueue→ router: resolve tenant→ engine: build reply→ send via Graph API

Pricing model (know it before you design)

Meta bills per conversation (not per message), in categories (service / marketing / utility / authentication), with a monthly free tier of service conversations. Design implication: batch outbound, avoid needless template sends, and track conversation cost per tenant so unit economics stay honest. A single β‚Ή199/mo subscriber must not cost more than a fraction of that in WhatsApp + LLM fees.

Number-ban risk is realAutomated sends to people who didn't opt in, or high block/report rates, get the business number quality-rated down and eventually banned. Opt-in + genuinely useful replies + never messaging non-subscribers unprompted keep the number healthy.

6Data model

Replaces the prototype's JSON registry with real tables. Core entities (fields abbreviated β€” design the full schema, add timestamps, soft-delete, and indexes on lookup keys):

tenant            -- one family / account
  id, wa_phone_e164 (customer), display_name, locale,
  status, created_at

child             -- one baby (a tenant may have >1 later)
  id, tenant_id β†’ tenant, name, dob, term (full/preterm),
  conditions[], pediatrician, notes, created_at

caregiver         -- mom/dad; who may message
  id, tenant_id, wa_phone_e164, role, name

subscription      -- billing state per tenant/child
  id, tenant_id, child_id, plan (β‚Ή199/mo),
  status (trial|active|past_due|expired|canceled),
  trial_start, trial_end,
  current_period_start, current_period_end,
  razorpay_subscription_id, last_payment_at, last_payment_ref

message           -- every inbound/outbound (audit + context)
  id, tenant_id, direction, wa_message_id (idempotency!),
  body, media_url, template_name, created_at

usage_daily       -- throttling + cost control
  tenant_id, date, user_messages, tool_calls,
  llm_tokens, wa_conversations, renewal_nudge_sent

memory            -- long-term curated facts about a child
  id, child_id, kind (fact|concern|plan), text, embedding

journal_entry     -- daily events (symptoms, sleep, feeds, visits)
  id, child_id, date, text, embedding

consent           -- DPDP compliance (Β§12)
  id, tenant_id, purpose, granted_at, withdrawn_at, source

kb_chunk          -- pediatric knowledge base for RAG
  id, doc, section, text, embedding, source_org, source_year
Idempotency is not optionalMeta will redeliver webhooks. Store wa_message_id unique and skip duplicates, or you'll double-reply and double-charge conversations. Same for Razorpay event ids.

7Subscriptions & payments Milestone 1

This is your first shippable win and the whole reason the product can make money. Today it's manual (bot quotes UPI, a human verifies and edits JSON). Replace it with Razorpay Subscriptions driving state automatically.

The lifecycle state machine

trial10 days β†’ trial_ending (template @ day 8)β†’ activeAutoPay renews β†’ active
payment fails / no mandate→ past_due (retry + nudge template)→ expired (premium off)→ reactivate on payment

How it works with Razorpay

  1. At signup, create a Razorpay Plan (β‚Ή199/mo) once; create a Subscription per tenant with a 10-day trial / first-charge date.
  2. Parent authorizes a UPI AutoPay mandate (or card) via a Razorpay checkout link sent in chat / on web.
  3. Razorpay webhooks (subscription.charged, subscription.halted, payment.failed, etc.) flip subscription.status and period dates in our DB. No human edits JSON ever again.
  4. The entitlement check runs on every inbound message: is this tenant premium right now? Gate features accordingly (Β§8).

Entitlement gating (ported from the prototype rules)

FeatureTrial / ActiveExpired / Free
Conversational answersFull, long-formShort answers only
Live web/guideline lookupYesNo β€” local KB only
Rich daily journalingYesLimited
Daily message capHigh (e.g. 80)Low (e.g. 8)
Safety / escalationAlwaysAlways β€” never gated
Renewal messaging lives in templatesBecause of the 24-hour window (Β§5), the "your trial ends tomorrow" and "renew to continue" messages are pre-approved templates, sent by the scheduler. Draft and submit these to Meta early.
Compliance for paymentsYou handle recurring payments and PII of minors' families. Razorpay is PCI-compliant so you never touch card data β€” keep it that way (hosted checkout only). Log payment references, not card details.

8Conversation engine

The bit that makes it feel human. A single pass per inbound message:

  1. Resolve tenant + child (from the sender's WA number).
  2. Safety pre-check: a fast classifier scans for red-flag symptoms (breathing trouble, blue/grey colour, high fever in young infants, seizures, severe lethargy, dehydration). If hit β†’ respond with escalation guidance immediately, regardless of tier, and still log it.
  3. Entitlement check (Β§7) β†’ decide premium vs free behavior + caps.
  4. Build the prompt: system prompt (from SOUL.md rules) + this child's profile + relevant memory/journal (vector search) + relevant KB chunks (RAG) + recent conversation.
  5. Call the LLM (strong model for health-adjacent, cheap model for chit-chat/routing).
  6. Post-process: ensure the "not a doctor" disclaimer is present on health replies; enforce length by tier; strip anything unsafe.
  7. Send via WhatsApp; persist the message; update usage counters; optionally journal a memory note.

Grounding & language

  • RAG over the pediatric KB (the iap_* docs, expandable). Answers cite the source org + rough year. Premium tier may additionally do live guideline lookups from trusted bodies (WHO/AAP/NHS/IAP).
  • Language detection per message; reply in the parent's language (Devanagari for Hindi, Latin/Devanagari for Marathi as they write). Safety text especially must be crystal-clear in their language.
Keep the LLM swappable and cheap where possibleTwo tiers: a small fast model for language-detect / intent / safety-screen, a strong model for the actual answer. Cache KB embeddings. Track tokens per tenant in usage_daily so a β‚Ή199 subscriber never costs more than a few rupees a day.

9Onboarding flow (self-serve)

The whole loop must run without a human. A parent should go from "never heard of us" to "trial active, baby set up" in one WhatsApp conversation (kicked off from an ad, a link, or a QR on sukoon-web).

Parent messages our numberβ†’ welcome + consent + ask baby basicsβ†’ create tenant + child + start 10-day trialβ†’ first helpful answerβ†’ …day 8: trial-ending templateβ†’ Razorpay AutoPay linkβ†’ active
  • Collect the minimum to be useful: baby name, DOB, term/preterm, any known conditions, primary language. Capture conversationally, not a rigid form.
  • Consent is captured here (data use + medical disclaimer) and stored (Β§12).
  • Model onboarding as an explicit state machine so a parent can drop off and resume. Don't rely on the LLM to "remember where we were" β€” persist the step.
One business number for everyoneUnlike the prototype (which needed a separate number per family), the official Cloud API serves all families from one business number β€” Meta routes by the sender. Tenant identity = the sender's WA number. Simpler, and it scales. (Β§11)

10Memory & knowledge

Per-child memory

Long-term facts (conditions, doctor plans, preferences) + daily journal (symptoms, feeds, sleep, visits). Both embedded for retrieval. On each message, pull the few most relevant notes into the prompt so answers stay specific and continuous across days.

Pediatric knowledge base

The curated iap_* docs β†’ chunked, embedded, RAG-retrieved. Expand over time (safe sleep, growth, weaning, red flags, vaccine schedule). Answers cite source + year. This is the "grounded, not made up" guarantee.

Write memory deliberatelyDon't dump every message into memory. Summarize: when a parent shares something ongoing ("doctor said watch her weight this month"), write one curated note. A nightly job can roll daily journals into long-term summaries. Keep it tenant-scoped β€” never let one child's notes leak into another's context.

11Multi-tenancy & isolation

  • Tenant = the family, keyed by the caregiver's WhatsApp number. One business number serves all tenants (Meta routes inbound by sender).
  • Every query is tenant-scoped. Row-level scoping on tenant_id everywhere. A bug here = a family sees another family's baby data = catastrophic trust + compliance failure.
  • Conversation context is per-tenant. Never build a prompt with another tenant's messages/memory. (The prototype enforced this via session scoping; you enforce it via scoped queries + tests.)
  • Support multiple caregivers per tenant (mom + dad) mapping to the same child.
Write an isolation test on day oneAn automated test that seeds two tenants and asserts tenant A can never retrieve tenant B's child, memory, messages, or subscription. Run it in CI forever.

12Compliance, privacy & safety

This is a health-adjacent product storing PII about infants. Compliance is not a phase-2 nicety; design it in now β€” it's far cheaper than retrofitting and it's a genuine trust selling point for a moms' brand.

AreaWhat to do
DPDP Act (India)Explicit consent at onboarding (purpose-bound), ability to withdraw, data-retention limits, and a deletion path ("delete my data"). Store consent records (consent table).
WhatsApp opt-inOnly message opted-in users; respect the 24h window; honour block/stop.
Medical disclaimerClear "not a doctor / not medical advice" surfaced at onboarding and on health replies.
Data minimizationCollect only what's needed to help. No unnecessary sensitive data. Encrypt at rest + in transit.
Access & secretsNo secrets in the repo (env vars / secret manager). Least-privilege DB access. Audit-log admin actions.
PaymentsHosted Razorpay checkout only β€” never handle card data. Log references, not instruments.
Get a real legal review before chargingBefore live payments + scaled onboarding, have the consent language, disclaimer, and retention policy reviewed. Product-side owner: Sanchit.

13Reliability & operations

Webhooks must be fast + safe

ACK Meta in <5s then process async. Validate signatures. Idempotent on wa_message_id / Razorpay event id.

Retries + dead-letter

Outbound sends and LLM calls retry with backoff; failures go to a dead-letter queue, not silent drops.

Observability

Structured logs, error tracking (Sentry), and dashboards for: messages/min, LLM cost/tenant, WA conversation cost, subscription conversions, failed payments.

Rate + cost control

Per-tenant daily caps (from usage_daily). Global backpressure. Alert if cost/subscriber approaches the β‚Ή199 margin.

Backups

Automated Postgres backups + tested restore. This holds families' health data β€” losing it is unacceptable.

Environments

Separate dev/staging/prod, with a Meta test number for staging. Never test against the live business number.

14Build plan

Phase 0 β€” De-risk the unknowns Week 1–2

  • Spike WhatsApp Cloud API: get a test number, receive a webhook, send a reply, send a template. Prove the whole round trip.
  • Spike Razorpay Subscriptions: create a plan, a subscription with trial, complete a UPI AutoPay mandate in test mode, receive the webhook.
  • Stand up the skeleton: repo, Postgres, Redis, CI, env config, provider interfaces.
  • Start Meta business verification + draft message templates (long lead time β€” begin now).

Phase 1 β€” MVP conversation + trial Week 3–5

  • Inbound pipeline: webhook β†’ queue β†’ router β†’ engine β†’ reply. Idempotent.
  • Onboarding FSM: welcome β†’ consent β†’ capture baby β†’ create tenant/child β†’ start trial.
  • Conversation engine v1: system prompt + child context + RAG over KB + safety pre-check + disclaimer. One language first (whatever your test users use), then add.
  • Per-child memory (write + retrieve). Tenant-isolation test in CI.

Phase 2 β€” Payments live Week 6–7

  • Full subscription state machine driven by Razorpay webhooks.
  • Entitlement gating (premium vs free) on every message.
  • Trial-ending + renewal + payment-confirmation templates via scheduler.
  • Admin view in sukoon-web: tenants, subscription status, message audit.

Phase 3 β€” Harden & scale Week 8+

  • Multi-language, richer journaling, premium live-lookup, media (parents sending photos).
  • Observability dashboards, cost controls, backups, load test.
  • Migrate the one live prototype family onto the new system; then open the doors.
Keep the prototype running until Phase 3The existing OpenClaw bot keeps serving its live family while you build. Don't cut over until the new system is proven end-to-end.

15Definition of done

PhaseDone when…
Phase 0You can send + receive a real WhatsApp message and complete a test Razorpay AutoPay mandate, both through your own code.
Phase 1A new parent can message the number, set up their baby, get grounded + safe answers, and it remembers the baby the next day. Isolation test green.
Phase 2A trial converts to paid via UPI AutoPay with zero manual steps; expiry + renewal happen automatically; premium gating works.
Phase 3Observable, backed up, multi-language, and the live prototype family is migrated. Unit cost per subscriber < margin.

16How not to get sidelined

Read this whenever you feel a rabbit hole opening.

βœ… Do

  • Spike WhatsApp + Razorpay before anything else.
  • Use managed services (Postgres, Redis, hosting) β€” don't self-host infra.
  • Hide WhatsApp + LLM behind interfaces.
  • Ship Phase 1 in one language, then expand.
  • Write the tenant-isolation test on day one.
  • Track cost per subscriber from the start.

🚫 Don't

  • Don't reopen the WhatsApp-API or Razorpay decisions.
  • Don't build your own auth, queue, or vector DB β€” use Postgres/pgvector + BullMQ.
  • Don't gold-plate the LLM (no fine-tuning, no multi-agent frameworks) β€” a good prompt + RAG is enough.
  • Don't run the bot on a personal number, ever.
  • Don't let the LLM own subscription state β€” that's deterministic code + webhooks.
  • Don't collect data you don't need.
When you hit a real fork, askIf a decision materially changes scope, cost, or the data model, raise it in the open-questions list with Sanchit rather than guessing. A one-line question now beats a week rebuilt later.

17Open questions for Sanchit

  • Business number β€” which dedicated number do we verify with Meta? (Needs to be a fresh line, not on any personal WhatsApp.)
  • Meta business verification β€” who owns the Meta Business account + verification docs?
  • Razorpay account β€” existing merchant account to reuse, or new one for Sukoon?
  • Languages at launch β€” Hindi + English first? Marathi when?
  • Pricing confirmation β€” β‚Ή199/mo, 10-day trial, per baby β€” locked, or revisit for launch?
  • LLM provider β€” Gemini or Claude as primary? (Cost vs quality tradeoff.)
  • Data residency / legal review β€” timeline for consent + disclaimer legal sign-off before live payments.
  • Migration β€” when do we move the existing live family off the prototype?

Glossary & links

TermMeaning
TenantOne family/account, keyed by the caregiver's WhatsApp number.
Cloud APIMeta's official WhatsApp Business Platform (hosted). The only sanctioned way to automate WhatsApp.
BSPBusiness Solution Provider (360dialog, Gupshup) β€” a Meta partner that eases onboarding/billing.
24h windowFree-form replies allowed only within 24h of the user's last message; else templates only.
TemplatePre-approved message format required for business-initiated messages.
RAGRetrieval-augmented generation β€” ground LLM answers in our vetted docs.
UPI AutoPayRecurring UPI mandate β€” how β‚Ή199/mo renews automatically.
EntitlementWhether a tenant is premium right now (drives feature gating).

Reference material

  • Spec repo β€” sukoon-baby-dev (behavior, commerce rules, pediatric KB) β€” the source of truth for what to build.
  • Web app β€” sukoon-web (Next.js).
  • WhatsApp Cloud API docs Β· Razorpay Subscriptions docs Β· pgvector Β· BullMQ Β· NestJS.
  • Git primer for onboarding: Pro Git Β· Learn Git Branching.

Sukoon.mom β€” Product & Engineering Build Bible v1.0 Β· 19 Aug 2026 Β· Internal, confidential. Contains no personal or customer data. Product owner: Sanchit. Built for engineering handoff.

This document is the plan of record. If reality diverges from it, update the document β€” don't let it go stale.