Inspiration

Every doctor's appointment is different for every patient. Any information the provider talks about in the meeting could be lost, misinterpreted, not understood by the patient or simply forgotten. We wanted the thing a doctor hands a patient to be a link: one medication, plain language, every sentence traceable back to the FDA-approved label it came from and the two hard questions a patient actually has, "is this covered?" and "what does this word mean?", answered from real data rather than guessed. a medication guide must never say something the label doesn't. Not a language model, not a coverage tool, not a summary. If we couldn't trace it, we didn't show it.

What it does

On the clinician's side: pick a medication, preview the guide, hand it over: by share sheet, QR code, an NFC tag, or a two-second burst of sound between two phones. Search any of the ~150,000 FDA labels on DailyMed to add a product. Find registered clinicians and pharmacies near a ZIP from the federal NPI registry. On the patient's side: a mobile page built from the label: what it's for, what to watch for, boxed warnings first. Ask a question and get an answer composed only from retrieved label passages, with citations that are checked before you see them. Read it aloud in English, Spanish or French. Check whether the drug is on your Medicare Part D plan's formulary using CMS's published data: which tier, prior-auth, quantity limits and whether the plan lists the brand or only the generic.

How we built it

We built it in the order the data flows, because every layer only has permission to say what the layer below it can prove.

We split the work three ways and built in parallel, then merged everything into one app.

First — Sandeep built the core and the data. He started with the patient page: pull the FDA label for one medication (Singulair) from openFDA and DailyMed, write the plain-language guide with every claim cited back to the label, and add the assistant on top with BM25 retrieval so the model can only answer from label text it was actually given. Then he built the data pipeline: ingest three medications from openFDA, DailyMed and RxNorm, resolve each product's identity across all three sources, and pull the Medicare Part D formulary data from CMS for 5,517 plans. He ran three audit passes on the pipeline's own output before he trusted it.

Second — Akshaya built the clinician side and the deployment. She reorganized the codebase into patient, doctor, and sources so the two audiences could be worked on separately, added APP_MODE so one build deploys as two Vercel projects (the patient link and the clinician workspace), built the doctor page as a phone-app layout, and reworked both sides for fair balance so a boxed warning always comes before a benefit. Then she wired Sandeep's pipeline into the app — three medications instead of one — and put the 5,517 plan identities behind the insurance picker.

Third — Jyoti built the handoff hardware. On her own branches she built the clinician's sharing workflow, then nearby sound sharing (a two-second audio burst carrying an encrypted token from the doctor's phone to the patient's), then the NFC tap point: browser → Arduino → I²C → an ST25DV64 tag that the doctor programs with the guide's URL.

Then we pulled it together. Merging Jyoti's branches surfaced the first real bug: sound sharing, coverage, QR codes and chat all only worked for Singulair, because they were resolving medications through a registry that only knew about the one authored product. We fixed that in one place. Then the insurance flow: the CMS data was in the repo but never reached the deployed app — it was gitignored, read from disk in a way Vercel can't see, and in the wrong shape. We fixed all of that, wrote a test that checks the app's answers against the pipeline's own answers for the same plans, and got real formulary results showing on both sites.

Sandeep and Akshaya had each fixed some of the same coverage bugs on separate branches, so instead of merging his whole branch we took the parts that were right — his trigger logic, his snapshot adapter, his tests — and combined them with hers. That also fixed the daily refresh job, which had been running green every morning without ever actually regenerating anything.

Last stretch. Akshaya unified the two guide types so chat works on every medication, renamed it MediZ, and hardened sound sharing for Safari. Sandeep added read-aloud in Spanish and French, rate limits, real clinicians and pharmacies from the federal NPI registry, and search across every FDA label on DailyMed. Every push got pulled, tested, built, and deployed to both Vercel projects.

Challenges we ran into

The NFC tag we couldn't tap. The original plan for the handoff was simple: the doctor taps the patient's phone on an NFC tag and the guide opens. We built the whole chain — the browser talks to an Arduino over Web Serial, the Arduino writes the guide's URL into an ST25DV64 tag over I²C, and the firmware reads it back to prove the write took. Then we hit the wall: the chip needs an external 13.56 MHz antenna to be readable by a phone, and we didn't have one. We could program the tag and verify it in memory, but nobody could tap it. So the NFC tap point stayed in the app as a working proof of concept, honestly labeled, and we needed another way to get a link from one phone to another without typing.

Landing on sound. The answer was to send the link through the air anyway — as audio. The doctor's phone plays a short burst of tones, the patient's phone listens and decodes it. Under the hood it's the same idea as the NFC tag: a short token, not the medical content, and the token expires in two minutes. Getting it reliable was its own fight: iOS won't start audio without a user gesture, microphone permission can come back after the user already cancelled, and a signal interrupted halfway had to fail cleanly instead of decoding garbage. We got it down to a two-second transmit.

AirDrop for the demo, and for real patients. Sound sharing is still experimental, and a patient who's been on a medication for years isn't standing next to their doctor. So the primary path is the native share sheet — AirDrop, Messages, copy link, QR code — which works on every phone today. That's what we demo with, and it's what a clinician could actually use to send a guide to an existing patient. We wanted it to be an NFC sticker, but we couldn't get our hands on them.

Only Singulair worked. Coverage, QR codes, chat, and sound sharing were all resolving medications through a registry that only knew the one hand-authored product. Two of our three medications silently failed everywhere except the page itself. Now, we made sure it works for all the medications we have data for, without assuming information. If it doesn't know, it simply lets the provider and patient know.

The insurance data that never arrived. 979 real formulary rows were in the repo the whole time, and every coverage check on the live site said "not connected." The file was gitignored, read from disk in a way Vercel's serverless bundle can't see, and in a shape the app didn't recognize — four small things stacked, every test green. Going back and forth and making the insurance claims fully accessible took forever.

A plan name is not a plan. 39 Medicare plans share the exact name "AARP Medicare Rx Preferred from UHC (PDP)." And a formulary that lists generic montelukast doesn't list brand Singulair. Both had to be handled explicitly or the coverage answer would be confidently wrong.

Accomplishments that we're proud of

This was one of our first in-person hackathons — and we finished in under 24 hours. Three of us went from an empty repo to two live deployments with 964 passing tests.

The software is fully working. A clinician can pick a medication, build a guide from the real FDA label, and hand it to a patient by share sheet, QR code, or sound. The patient gets plain-language information with every claim traceable to the label, can ask questions that are answered only from that label, can check real Medicare Part D formulary data for their exact plan, can hear it read aloud in English, Spanish, or French, and can find registered clinicians and pharmacies near them. None of it is mocked.

The hardware is one component away. None of us had ever connected software to hardware before this weekend. We got a browser talking to an Arduino over USB, the Arduino writing to an NFC tag over I²C, and the tag reading back exactly what we asked it to store. The only thing standing between that and a phone tap is a 13.56 MHz antenna we didn't have in the room.

We built things we had never seen before. Sending a link between two phones as audio tones, with a clock signal so timing can't drift and a checksum so noise can't decode into a wrong URL. Range-fetching 8.8 MB out of a 2.14 GB government archive instead of downloading the whole thing. A refresh pipeline that polls five federal data sources daily and opens a pull request when something changes. Resolving one drug's identity across three databases that disagree with each other. A week ago none of us knew these were problems, let alone how to solve them.

We were honest the whole way. The app never says "covered" — only "listed" or "listed with restrictions." It never lets the model invent a citation. It says "unable to verify" out loud instead of guessing. And the NFC feature is labeled a proof of concept because that's what it is.

We also figured out how to make sure patients can access their insurance and how that would affect their coverage without saving their data which is huge. This makes sure patients can make educated decisions without sharing sensitive data with us, Since we do not store it.

What we learned

Hardware, from zero. None of us had touched an Arduino before this weekend. We learned what I²C is, why a board resets when you open its serial port, why "the write succeeded" means nothing until you read the memory back, and why an NFC chip without an antenna is just a chip. We also learned how much of hardware work is knowing which one missing part is the reason nothing happens — and that you can build the entire chain on either side of it and still not be able to demo it.

The gap between a doctor and a patient is mostly paperwork and information. Coming in, we didn't really understand what happens between a prescription being written and a patient actually taking it. We learned that a medication guide is a folded sheet almost nobody reads; that a doctor doesn't know what a patient's plan will charge them; that "is it covered" has no clean answer — the honest answer is "listed on your plan's formulary, tier 3, with prior authorization required," and even that isn't a price. We learned that 39 Medicare plans can share the same name and mean different things, and that a plan listing the generic doesn't mean it lists the brand.

FDA labels are not built for patients. One label document can cover four different products at different doses. Sections don't say which product they apply to. The information that matters most — the boxed warning — is legally required and still widely unknown. We learned how much careful work it takes to pull one strength of one drug out of that document without accidentally attaching a child's dose to an adult's tablet.

Public health data exists, and it's hard to reach. openFDA, DailyMed, RxNorm, CMS, and the NPI registry are all free and all official. They also all identify the same drug differently, publish on different schedules, and in one case ship as a 2.14 GB archive. We learned that the data is there — the work is in the seams between the sources.

Honesty is something you have to build in. The easiest thing to build is an interface that looks like it knows the answer. We learned to make "unable to verify" a first-class state, to test for the failures that would hurt someone rather than the paths that look good in a demo, and to label a proof of concept as a proof of concept.

Working in parallel only works if you merge carefully. Three people, three branches, and two of us independently fixed the same bug in different ways. We learned to read every conflict before resolving it, to run the tests after every merge, and to take the best parts of both versions instead of picking a winner.

What's next for MediZ

Making sure that we use the NFC tags in the future and making it less dependent on airdrop and audio NFC. This would make the "tapping mechanism" extremely fast and nearly seamless where patient's can simply tap on the sticker in person on the physicians desk or card and get all the information they need.

More medications. The pipeline was built so that adding a drug is a config entry and an ingest, not a rewrite — it resolves the identity, pulls the label, fetches the coverage rows, and the app picks it up. The clinician can already search every FDA label on DailyMed; the next step is letting that search add a product to the library on the spot.

The antenna. One 13.56 MHz antenna turns the NFC proof of concept into a real tap. That's the first thing we'd buy.

Clinical review. Nothing in the app has been reviewed by a clinician, and it says so on every page. Before a real patient uses it, the plain-language layer for each medication needs a pharmacist or physician to sign off — and the app already has a separate clinicallyReviewedAt field waiting for that date.

Beyond Medicare. Coverage is Medicare Part D only, because that's the formulary data CMS publishes openly. Commercial and Medicaid plans would need either a payer integration or a real-time benefit check API.

Partner integration. The clinician workspace was built to sit inside a partner's existing app; the next step is actually embedding it there so a doctor doesn't leave their workflow to send a guide. We would like this to be a part of docupdate and become a patient facing interface after information is shared where they can choose to sign in or not.

What scales well:

  • ** Adding medications is cheap. ** The CMS fetch only pulls rows for the products you have (~1–2 MB each, not the 2.14 GB archive), medication pages are statically generated, and the daily refresh handles any number of products the same way. The plan directory is fixed cost — 5,517 plans whether you have 3 drugs or 300. Label-only guides work for any drug with no authoring — that's how Toprol and Ozempic shipped.

  • Every source refreshes itself. The daily workflow polls openFDA, DailyMed, RxNorm, CMS, and VA Medicaid, regenerates only when something actually changed, validates the whole app, and opens a review PR — so keeping 300 medications current costs the same human effort as keeping 3: read the PR and merge it.

Built With

Share this project:

Updates

Submission history