-
-
Home page: photo or batch number, three sample strips, and the CDSCO data loaded
-
A check of a sample strip: each Nemotron step with its time, then the verdict citing the official CDSCO record
-
WhatsApp check: one strip photo shows batch TG25-1814A failed a CDSCO quality test. The medicine is saved to the family cabinet.
-
Cabinet alert: when a new CDSCO list flags a saved medicine, DawaGuard messages the family on its own. (Simulated list for this demo.)
Inspiration
Every month, India's drug regulator CDSCO publishes the medicine batches that failed government lab tests ("Not of Standard Quality") or were found to be spurious. Between January 2025 and September 2026 that was 3,788 failed batches and 49 suspected fakes, including 355 batches of paracetamol. More than half of the failed batches don't expire until 2027 or later, so they are still on pharmacy shelves and in family medicine boxes.
The lists are public, but they are long monthly tables on a government website. Nobody checks them before giving their father his blood-pressure tablet. Indian families do, however, use WhatsApp for everything. So I built a checker that lives there.
What it does
Send DawaGuard a photo of a medicine strip, on WhatsApp or the web. About ten seconds later you get:
- A verdict: failed a government quality test, suspected fake, a near-match to check, expired, or not on any CDSCO alert.
- An explanation in English or Hindi, citing the official CDSCO record first, with safe next steps. For a failed batch that means: ask your pharmacist for a different batch, and talk to your doctor before changing anything. It never says "stop taking it".
- A short message to forward to family.
Every checked medicine goes into the family's medicine cabinet. DawaGuard syncs CDSCO's lists every day; when a new list flags a batch in someone's cabinet, it messages them on WhatsApp without being asked.
How I built it
- NVIDIA Nemotron 3.5 Super VL on Nebius Token Factory reads the strip photo into structured JSON: brand, ingredients, strength, batch number, expiry, manufacturer.
- Deterministic code decides the verdict. It matches the batch against a local copy of every CDSCO flagged batch, tolerating misreads (O/0, S/5, B/8), and requires the product to match too, because batch codes repeat across companies. Then it parses the expiry date.
- Tavily searches official and pharma-news sites for anything newer than the monthly lists, in parallel with the matching.
- NVIDIA Nemotron 3 Ultra writes the explanation with citations. NVIDIA Nemotron 3.5 Lightning writes the WhatsApp message in under a second, with thinking turned off. Hindi messages go to Ultra, whose Devanagari held up where the fast model drifted.
- Spring Boot 4 (Java 21) with virtual threads runs the steps in parallel. The web page streams each step as newline-delimited JSON, so you watch each model work, with timings and token counts.
- WhatsApp Cloud API carries the bot: signed webhooks, duplicate-delivery protection, a per-family cabinet, and code-worded alerts. An approved template is used when WhatsApp's 24-hour window has closed.
- Deployed with Docker and Caddy (automatic HTTPS) on a small AWS server in Mumbai. The public demo is rate-limited so it can stay free for judges.
Challenges I ran into
- Models want to help too much. Left alone, the fast model put a green ✅ on a failed batch, told the owner of an un-flagged batch to replace it, and signed off with "Hello [Name]". The fix was architectural: the verdict, the emoji, and the closing advice are chosen in code, and the models only fill in wording within hard rules.
- Hindi. The fast model's Hindi slid into romanised Hinglish with mangled words. Routing Hindi to Nemotron 3 Ultra fixed it at a cost of about two seconds.
- Thinking leaking into replies. Nemotron 3.5 Lightning wrote its reasoning into the message until I passed
enable_thinking: false, which also cut its latency from 3.4 s to 0.4 s. - Batch codes aren't unique. The same code appears for unrelated products from different companies. Matching on the batch alone gave false alarms, so a hit only counts if the product words match too.
- WhatsApp's sandbox. Incoming messages went nowhere until the app was subscribed to the sandbox business account, and only the developer's own token could send from it.
Accomplishments that I'm proud of
- It works end to end on a real phone: photo in, verdict and a forwardable message back in about ten seconds.
- The verdict can't be hallucinated. If every model call failed, the answer would still be right, just less well explained.
- It watches. The cabinet and re-check turn a one-off lookup into an assistant that tells you when something you already own becomes a problem.
- It's careful in the ways that matter for health: it cites the official record, separates a failed batch from the brand, never tells anyone to stop a medicine, and never calls anything "safe".
What I learned
- Pick the model size per job: a vision model to read, the large model where reasoning and language quality matter, and the small model where speed matters.
- In a safety product, the most valuable prompt engineering is deciding what the model is not allowed to decide.
- Public government data is often already enough. The work is making it reach people at the moment they need it.
What's next for DawaGuard
- A verified WhatsApp Business number, so anyone can message it.
- More Indian languages (Tamil, Bengali, Marathi) and voice notes for elderly users.
- State drug-controller alerts and manufacturer recalls alongside the CDSCO lists.
- A pharmacy mode, where a chemist scans incoming stock against the lists before it reaches the shelf.
Built With
- amazon-web-services
- caddy
- css3
- docker
- h2
- html5
- java
- javascript
- meta-graph-api
- nebius-token-factory
- nvidia-nemotron
- spring-boot
- tavily
- whatsapp-cloud-api
Log in or sign up for Devpost to join the conversation.