---
title: "Medication Resolver"
description: "AI service that normalizes free-text drug queries into structured medications, used by PatientOS and available via the /resolve API."
date: 2026-08-17
lastModified: 2026-08-17
category: "developer"
author: "Dr. Umesh Bilagi"
beta: true
---

## Overview

The Medication Resolver turns free-text drug queries — brand names, misspellings, regional variations, or manufacturer names — into a structured, normalized medication. It powers the drug resolution inside PatientOS and is also exposed as a standalone REST API (`/resolve` and `/resolve/batch`).

## How resolution works

The resolver runs a tiered pipeline, falling through to the next tier when a tier is not confident enough:

| Tier | Source | Notes |
|------|--------|-------|
| 1. Exact match | Local synonym table | Highest confidence; brand and generic synonyms |
| 2. Local registry | Postgres `drug_registry` (pg_trgm) | Fuzzy trigram match on brand name and generic |
| 3. ABDM drug registry | ABDM search + brand detail | Authoritative Indian drug registry |
| 4. LLM resolve | DeepSeek | Structures misspellings and brand→generic |
| 5. Web search | Tavily | Last resort, feeds results back to the LLM |

A manufacturer query (e.g. "Alred Healthcare") is recognised as a manufacturer and returns that manufacturer's products rather than resolving the name as a single drug.

## API

### `POST /resolve`

Normalizes a single query.

**Request**

```json
{ "query": "dolo 650", "context": { "language": "en" } }
```

**Response**

```json
{
  "resolved": {
    "brandName": "Dolo",
    "genericName": "Paracetamol",
    "strength": "650mg",
    "formulation": "Tablet",
    "manufacturer": "",
    "drugCode": ""
  },
  "confidence": 0.9,
  "resolutionPath": "local_registry",
  "alternatives": [
    { "brandName": "Calpol", "genericName": "Paracetamol", "confidence": 0.8 }
  ],
  "suggestions": []
}
```

`resolutionPath` is one of `exact_match`, `local_registry`, `manufacturer`, `drug_registry`, `llm_resolve`, `web_search`, or `llm_fallback_failed`.

### `POST /resolve/batch`

Normalizes multiple queries in one call.

**Request**

```json
{ "queries": ["dolo 650", "voveran", "glycomet 500"] }
```

**Response**

```json
{ "results": [ { "query": "dolo 650", "resolved": { ... }, "confidence": 0.9, "resolutionPath": "local_registry", "alternatives": [], "suggestions": [] } ] }
```

## Local drug registry

The resolver checks a local Postgres table (`drug_registry`) before calling external services. It is created automatically on service start and can be populated with the seed script:

```bash
node scripts/seed-drug-registry.mjs
```

The table is indexed with pg_trgm so near-miss brand names and generics resolve without a network call.

## FAQ

**Q: Is the resolver authoritative?**
A: It prefers the ABDM drug registry for authoritative matches; the LLM and web search tiers are fallbacks for spelling errors and uncommon names.

**Q: Can I call it from my own client?**
A: Yes — `/resolve` and `/resolve/batch` are plain JSON endpoints on the LangGraph service.
