Dawai Data API

Bangladesh's medicine catalogue, and what pharmacies actually sell — by medicine, generic, company, district and month. Counted across many shops together; no shop, customer or price list is ever exposed.

Getting started

Every call needs your key, sent as a bearer token. Keys start with dwk_. Keep yours on a server — never in a web page or app, where anyone can copy it.

curl https://data.dawai.com.bd/v1/demand/medicines?from=2026-07&to=2026-09 \
  -H "Authorization: Bearer dwk_your_key_here"

Every answer is JSON: { "data": … } on success, { "error": { "code", "message" } } otherwise. Lists take limit (default 25) and offset.

Sales figures take a range of whole months, from and to as YYYY-MM; without them you get the last three complete months. The current month may be asked for and is marked "partial": true. Figures are rebuilt every night.

How figures are made

Figures come from the bills of pharmacies using Dawai that have not switched themselves out. Every number is built from cells of one medicine, in one district, in one month, and a cell is used only if at least five different pharmacies sold that medicine there that month (the number is returned as minShops). Cells under that are left out before anything is added up — so a country total is the sum of the districts that pass, and a missing month means too few shops or no sales; the two are not told apart.

pieces are single units sold (tablets, capsules, bottles), net of returns. value is what customers paid, in taka. share is a percentage of the pieces in the answer.

Catalogue

GET/v1/catalogue/medicines catalogue

Search registered medicines. q matches the start of a brand or generic name; filter with generic, company (ids) or form (e.g. Tablet).

{ "data": { "total": 30, "rows": [ { "id": "…", "brand": "Napa", "generic": "Paracetamol", "genericId": "…",
  "strength": "500 mg", "form": "Tablet", "packSize": "", "price": 1.2, "company": "Beximco Pharmaceuticals Ltd.",
  "companyId": "…", "dar": "…" } ] } }

GET/v1/catalogue/medicines/:id catalogue

One medicine, with its indications, description and side effects where known.

GET/v1/catalogue/generics · /v1/catalogue/companies catalogue

Names and ids, searchable with q; up to 500 a page.

Sales figures

Each takes from, to, and optionally generic and company ids. district (any spelling, either script — see districts) needs a plan with district figures.

GET/v1/demand/medicines demand

The most-bought medicines, ranked by pieces.

{ "data": { "range": { "from": "2026-07", "to": "2026-09", "partial": false }, "filter": { … }, "minShops": 5,
  "total": { "pieces": 1520400, "value": 9120333.5, "medicines": 2210 },
  "rows": [ { "rank": 1, "medicine": { "id": "…", "brand": "…", "generic": "…", "company": "…", … },
              "pieces": 40311, "value": 51210, "share": 2.7 } ] } }

GET/v1/demand/medicines/:id demand

One medicine month by month (months, with null where it cannot be said), and — on plans with district figures — by district.

GET/v1/demand/generics demand

Each generic's pieces, value, number of brands sold, and share.

GET/v1/demand/generics/:id/brands demand

Within one generic, each brand's share — who sells the most paracetamol.

GET/v1/demand/companies demand

Each company's pieces, value, medicines sold and share.

GET/v1/demand/districts districts

Each district's share, optionally of one medicine, generic or company.

GET/v1/trends trends

Medicines rising and falling: the range against the same number of months just before it (returned as previous). Only medicines with at least 20 pieces in one of the two.

{ "data": { …, "previous": { "from": "2026-04", "to": "2026-06" },
  "rising": [ { "medicine": { … }, "pieces": 840, "piecesBefore": 440, "change": 90.9 } ], "falling": [ … ] } }

Your account

GET/v1

Your plan, what it includes, how far back it reaches, and when the figures were last rebuilt.

GET/v1/usage

Calls today and this month, against your limits. Refused calls are not counted.

GET/v1/meta/districts

Bangladesh's 64 districts with Bangla names and divisions — the names district takes and returns. Unknown collects shops that have not said where they are.

Errors & limits

StatusCodeMeaning
400bad_month, bad_range, bad_id, bad_district, bad_requestSomething in the request is not right; the message says what.
401no_key, bad_keyNo key, a wrong or revoked key, or the account is suspended or its contract has ended.
403not_in_plan, history_limitYour plan does not include this, or does not reach that far back.
429rate_limited, daily_quota, monthly_quotaToo many calls; Retry-After says when to try again for the per-minute limit.

Every answer carries X-RateLimit-Limit-Day and X-RateLimit-Remaining-Day. Limits are per account, shared by all its keys.

Questions, a key, or a different plan: alnoman.cse@outlook.com