CMED Brazil Drug Prices Scraper - ANVISA PF/PMC avatar

CMED Brazil Drug Prices Scraper - ANVISA PF/PMC

Pricing

from $0.85 / 1,000 drug price delivereds

Go to Apify Store
CMED Brazil Drug Prices Scraper - ANVISA PF/PMC

CMED Brazil Drug Prices Scraper - ANVISA PF/PMC

Official Brazilian drug price ceilings from the CMED/ANVISA monthly sheet: factory price (PF) and maximum consumer price (PMC) per presentation, with EAN, product, laboratory and the state ICMS rate. No login. US$ 1 per 1,000 rows; failed items are free.

Pricing

from $0.85 / 1,000 drug price delivereds

Rating

0.0

(0)

Developer

Scrapewise Data

Scrapewise Data

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

8 days ago

Last modified

Categories

Share

CMED Brazil Drug Prices - ANVISA PF/PMC

Reads the official CMED price table published by ANVISA and returns one row per drug presentation, with produto (product name), laboratorio (manufacturer), apresentacao (pack and strength), ean (barcode), pf (factory ceiling price), pmc (consumer ceiling price for the state you choose), pmcSemImpostos, uf, aliquotaIcms, restricaoHospitalar, mes, coletado_em and url_origem.

For pharmaceutical pricing and market access teams, international reference pricing, pharmacy and distributor compliance, price comparison products and anyone who needs Brazil's regulated ceiling next to a retail price. AI agents can call it through the Apify MCP server.

What CMED is, in one line

CMED (Câmara de Regulação do Mercado de Medicamentos, the drug market regulation chamber attached to ANVISA, Brazil's health regulator) publishes a monthly spreadsheet with the legal maximum price of every medicine sold in the country. No drug may be sold above that ceiling, so the file is the reference price for the whole market.

Two numbers matter in it:

ColumnWhat it isWho pays it
PF (Preço Fábrica)Factory ceiling: the most industry may charge a distributor, hospital or pharmacyWholesale buyers
PMC (Preço Máximo ao Consumidor)Consumer ceiling: the most a pharmacy may charge at the counterRetail buyers

PMC is published once per ICMS rate, because ICMS (the Brazilian state sales tax) is charged at a different rate in each state. The same box has a different legal ceiling in São Paulo and in Rio de Janeiro, so this Actor asks for a state code and reads the PMC column that matches it.

At a glance

  • Price per 1,000 rows, Free plan: US$ 1.00
  • Price per 1,000 rows, Gold plan and above: US$ 0.85
  • Runs in 30 days: 5 of our own

Pay per event: charged once per row written to the dataset. No monthly fee, no start fee, nothing for the run itself, proxy included. A run that finds nothing fails with a clear message instead of handing you an empty dataset.

Quick start

Minimal input:

{
"termoOuEan": "dipirona"
}

With a state and a cap:

{
"termoOuEan": "dipirona",
"uf": "SP",
"maxItems": 50
}

By barcode, for one exact pack:

{
"termoOuEan": "7896714261515",
"uf": "RJ"
}

One real output row

From the run of 2026-09-23 (build 0.1.8, input {"termoOuEan": "dipirona", "uf": "SP", "maxItems": 50}, 50 rows in 35 seconds):

{
"ean": "7896714261515",
"produto": "DIPIRONA + CAFEÍNA",
"laboratorio": "BRAINFARMA INDÚSTRIA QUÍMICA E FARMACÊUTICA S.A",
"apresentacao": "500 MG + 65 MG COM CT BL AL PLAS AMB X 16",
"pf": 16.08,
"pmc": 29.46,
"pmcSemImpostos": 22.23,
"uf": "SP",
"aliquotaIcms": 18,
"restricaoHospitalar": false,
"mes": "2026-09",
"coletado_em": "2026-09-23T11:59:08.712324+00:00",
"url_origem": "https://www.gov.br/anvisa/pt-br/assuntos/medicamentos/cmed/precos/arquivos/xls_conformidade_site_20260909_222937320.xlsx/@@download/file"
}

apresentacao is the packaging text used by ANVISA. Here: 500 mg plus 65 mg, tablets (COM), carton (CT), blister (BL), aluminium and opaque plastic, 16 units.

What data you get

One row per presentation that matches your term. Field names are the Portuguese names used in the source file, kept so the row matches the official table column by column.

Fill rates below were measured on the run above (50 of 50 rows read, "dipirona", SP, 2026-09-23). They describe that sample, not the whole CMED table, which has tens of thousands of presentations.

FieldTypeExampleFilled in that run
eanstring"7896714261515" (barcode, column EAN 1)50 of 50
produtostring"DIPIRONA + CAFEÍNA"50 of 50
laboratoriostring"BRAINFARMA INDÚSTRIA QUÍMICA E FARMACÊUTICA S.A"50 of 50
apresentacaostring"500 MG + 65 MG COM CT BL AL PLAS AMB X 16"50 of 50
pfnumber16.08, factory ceiling in BRL, PF column without tax50 of 50
pmcnumber29.46, consumer ceiling in BRL, PMC column of your state's ICMS rate46 of 50, see below
pmcSemImpostosnumber22.23, consumer ceiling without tax46 of 50
ufstring"SP", the state you asked for50 of 50
aliquotaIcmsnumber18, the ICMS rate whose PMC column was read50 of 50
restricaoHospitalarbooleanfalse; true means hospital use only50 of 50
messtring"2026-09", year and month of the run, UTC50 of 50
coletado_emstring"2026-09-10T21:36:54.753941+00:00", ISO 860150 of 50
url_origemstringlink to the .xlsx the row came from50 of 50

Why 4 rows have no pmc. All four are marked restricaoHospitalar: true. CMED does not publish a consumer ceiling for hospital-only presentations, because they are not sold at the pharmacy counter, so pmc is null by design and pf is still filled. Prices come as numbers in BRL; a footnote mark the file puts after some prices (such as 240,11*) is dropped.

One more note: mes is the year and month at run time in UTC, not a value parsed from inside the file. The file is identified by url_origem, whose name carries the publication timestamp.

Use cases

International reference pricing and market access

Brazil is a common comparator in external reference pricing baskets. pf is the wholesale ceiling and pmc the retail ceiling, both legal maximums rather than negotiated prices. laboratorio and apresentacao line up the exact pack size across markets, and ean gives you a barcode to join on.

Regulated ceiling against real retail price

Run this Actor for a molecule, then collect pharmacy or marketplace prices for the same ean. The gap between the retail price and pmc is discount depth by pack: one join key, two sources.

Pharmacy, distributor and health plan compliance

A pharmacy that charges above PMC is breaking the ceiling. Schedule the Actor for the products you carry and keep ean, pmc and coletado_em: that is a dated record of the legal maximum for each pack. Health plans use the same rows to audit reimbursement claims.

Portfolio research in Brazilian pharma

Search by manufacturer instead of by molecule: termoOuEan also matches laboratorio, so one run returns every presentation a company has in the table, with pack sizes and barcodes.

AI agents and assistants

An agent asked "what is the legal maximum retail price of dipyrone in São Paulo" calls this Actor through the Apify MCP server with a two-field JSON input. Every row carries url_origem and coletado_em, so the agent cites the exact source file and the moment it was read instead of answering from memory.

Input guide

FieldTypeDefaultWhat it does
termoOuEanstring"dipirona"Search term. Required, but it ships with a default, so an empty call from the API or an MCP client still runs.
ufstring"SP"Brazilian state code, chooses the PMC column by the state's ICMS rate.
aliquotaIcmsstringemptyOptional ICMS rate in %, such as 12 or 19.5. Overrides the state rate when your product has its own.
maxItemsinteger30Stops the run after this many rows.
proxyConfigurationobjectApify proxy onProxy settings; the default is fine here.

How termoOuEan matches

The term is lowercased and compared three ways against each line of the table:

  1. as a substring of produto (the product name);
  2. as a substring of laboratorio (the manufacturer name);
  3. as an exact match against ean (the barcode in column EAN 1).

So "dipirona" returns every presentation whose name contains it, including combinations such as "DIPIRONA + CAFEÍNA"; a manufacturer name returns that company's catalogue; a 13-digit barcode returns one pack. Matching is plain text: accents and spacing follow the source, and there is no wildcard or regular expression.

{
"termoOuEan": "brainfarma",
"maxItems": 50
}

How uf works

Each of the 27 state codes maps to that state's standard ICMS rate in 2026, and the Actor reads the PMC column for that rate: SP and MG 18%, RJ 22%, PR and RO 19.5%, MA 23%, PI 22.5%, BA, PE and AL 20.5%, ES, MS, MT, RS and SC 17%, and so on. The rate used comes back in aliquotaIcms on every row.

Some medicines carry a reduced rate in some states. When yours does, send aliquotaIcms (for example 12) and it overrides the state rate. CMED publishes 0, 12, 17, 17.5, 18, 19, 19.5, 20, 20.5, 21, 22, 22.5 and 23; any other value returns one free row with errorCode: "INVALID_INPUT" listing the valid ones.

How maxItems controls the run

The Actor stops as soon as it has delivered maxItems rows, and you pay only for rows delivered, so maxItems is the cost ceiling of the run. The form default is 30. Raise it when you search by manufacturer, where one company can have hundreds of presentations ({"termoOuEan": "ibuprofeno", "uf": "RJ", "maxItems": 200}).

Pricing

Pay per event, one charge per row written to the dataset. The event is called Drug price delivered.

Apify planPrice per rowPer 1,000 rows
FreeUS$ 0.001US$ 1.00
BronzeUS$ 0.00095US$ 0.95
SilverUS$ 0.0009US$ 0.90
Gold and aboveUS$ 0.00085US$ 0.85

Cost examples at the Free plan price:

JobRowsCost
One molecule, default cap30US$ 0.03
One molecule (the measured run)50US$ 0.05
One manufacturer's catalogue300US$ 0.30
20 molecules, 50 rows each1,000US$ 1.00
Daily check of 100 packs for a month3,000US$ 3.00

Nothing else is charged: no start fee, no per-run fee, no separate proxy bill, and nothing for a run that finds no match.

Speed and reliability

Measured on the Apify platform:

RunInputRows deliveredTime
2026-09-10, build 0.1.2{"termoOuEan": "dipirona", "uf": "SP", "maxItems": 50}5031 s
2026-09-23, build 0.1.8{"termoOuEan": "dipirona", "uf": "SP", "maxItems": 50}5035 s

Across the Actor's public history the run success rate is 100%, 5 successful runs out of 5, measured on 2026-09-15.

How the run works:

  • It always reads the current month's CMED price list, so a new month is picked up with no change on your side.
  • It stops at your maxItems.
  • If the price list is missing or unreadable, or the term matches nothing, the run raises an error saying which of those happened, never a green run with an empty dataset.

Use it from code, no-code tools and AI agents

Python

from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("scrapewise/anvisa-precos-cmed").call(run_input={
"termoOuEan": "dipirona",
"uf": "SP",
"maxItems": 50,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item["ean"], item["produto"], item.get("pmc"))

Node.js

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });
const run = await client.actor('scrapewise/anvisa-precos-cmed').call({
termoOuEan: '7896714261515',
uf: 'SP',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items[0]);

HTTP API

POST https://api.apify.com/v2/acts/scrapewise~anvisa-precos-cmed/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN with the input JSON as the body returns the rows directly. Add &format=csv for a spreadsheet instead of JSON.

n8n, Make, Zapier and Google Sheets

Use the Apify app or node: pick "Run Actor", choose scrapewise/anvisa-precos-cmed, paste the input and map the dataset rows into a sheet, a database or a Slack message. In Apify Console you can attach a Schedule and a webhook to a saved task: one run per month, after CMED publishes the new file.

AI agents (MCP)

Add the Apify MCP server to Claude, ChatGPT, Cursor or any MCP client with this Actor as a tool:

https://mcp.apify.com/?tools=scrapewise/anvisa-precos-cmed

The agent sends termoOuEan and uf and reads the rows back. Because termoOuEan has a default, a call with an empty input still returns rows instead of erroring out.

FAQ

What exactly are PF and PMC?

PF, Preço Fábrica, is the ceiling a manufacturer or importer may charge a distributor, a hospital or a pharmacy. PMC, Preço Máximo ao Consumidor, is the ceiling a pharmacy may charge the person buying the box. Both are set by CMED and both are legal maximums, not a survey of what is actually charged.

Why does the ceiling change from state to state?

Because ICMS, the Brazilian state sales tax, is charged at a different rate in each state, and PMC is published once per rate. uf picks which of those columns is copied into pmc.

Is pmc the price a pharmacy actually charges?

No. It is the maximum a pharmacy is allowed to charge. Real shelf prices are usually below it, and the gap varies by chain, city and promotion. Comparing a retail price against pmc is what makes the pair useful, but do not treat one as the other.

Why is pmc empty on some rows?

Because the presentation is for hospital use only (restricaoHospitalar: true), and CMED publishes no consumer ceiling for those. pf is still filled. Until build 0.1.8 (2026-09-23) the Actor read CMED's public procurement file, which has no PMC column, so older runs came back with pf and pmc empty; that is fixed.

Which state codes can I send?

Any of the 27 two-letter Brazilian state codes. Each maps to its standard ICMS rate, returned in aliquotaIcms; an unknown code falls back to 18%. Send aliquotaIcms when your product has a reduced rate in that state.

Can I download the whole CMED table in one run?

Not by design: every run returns the presentations matching one term. To cover a wide portfolio, run one term per molecule or manufacturer in parallel through the API and merge the datasets.

How often does the source change?

CMED publishes a new file every month and the name changes with it. The Actor discovers the current link at run time, so a monthly schedule keeps working without edits.

Why are the output field names in Portuguese?

They mirror the column names in the official spreadsheet: produto, laboratorio, apresentacao, pf, pmc. Keeping the source names means a row can be checked against the official file with no translation table in between. This page explains each one in English, and renaming them in your pipeline is one line of code.

Does this contain personal data?

No. Every row describes a product: barcode, name, manufacturer, pack description and the two ceiling prices. There is no patient, no prescriber, no prescription and no purchase. It must not be used for anything that tracks an individual person's treatment.

The file is published by CMED on a public federal government page, with no login and no paywall, precisely so the market knows the legal ceiling. The Actor downloads that public file and filters it. You remain responsible for what you do with the data; if in doubt, ask a lawyer.

What happens if the ANVISA page is down or changes layout?

The run raises an error saying which step failed: link not found, a non-200 response for the file, or a header row that no longer contains "PRODUTO" and "EAN 1". It never finishes green with an empty dataset, and undelivered rows are not charged. Run it again later, and if the layout really changed, open an issue.

How do I limit how much a run costs?

Set maxItems. That number times the per-row price of your plan is the hard ceiling. Apify Console also lets you set a maximum total charge in the run options.

How do I schedule a monthly refresh?

Save a task with your term and state and attach an Apify Schedule for a few days after the start of the month, when the new file is up. Add a webhook to push the rows into your database.

What is this useful for if I am not in Brazil?

Brazil is one of the largest pharmaceutical markets in the world and one of the few that publishes a full legal ceiling price list every month. That is a clean input for international reference pricing, market access and launch pricing, portfolio mapping, and as a regulated baseline against retail prices you collect elsewhere.

Limitations

  • pf and pmc came back empty in the one measured run, for the reason explained above. The identification fields did not.
  • One search term per run, no wildcard and no regular expression, and accents must follow the source.
  • Only the columns listed in the field table. Active ingredient, ATC class, registration number, therapeutic class, hospital restriction flags and the other PMC tax brackets are not returned today.
  • Only the current month's file: build your own history by scheduling the Actor and keeping coletado_em.
  • The state you ask for picks a column but is not written back into the row.
  • Up to 200,000 rows of the file are read per run.
  • Something broke or a field is missing? Open an issue on the Issues tab.

If this Actor saves you time, a short review on the Store page helps other people find it.

Changelog

  • 2026-09-15: README rewritten, with a field table measured on a real run, a competitor table measured on the public Apify API the same day, input guide, integration snippets and FAQ. The empty pf and pmc are recorded as an open issue.
  • 2026-09-14: examples and prefills moved to São Paulo / SP; the required field termoOuEan got a default value so calls with an empty input from the API and from MCP clients work; icon published.
  • 2026-09-13: Store price ladder by plan published (US$ 0.95 per 1,000 on Bronze, 0.90 on Silver, 0.85 on Gold and above, Free stays at US$ 1.00) and a task example added.
  • 2026-09-10: published in the Apify Store. Build 0.1.2 is the one measured on this page; the current build is 0.1.3.
  • 2026-09-05: dataset and output schemas added, SDK 4, first build and run on the platform.
  • 2026-09-04: first working version, after three fixes against the real source: the file is .xlsx and not .csv; its name changes every month, so the URL is discovered at run time instead of hardcoded; the header row sits below roughly 53 lines of legal notes and is now found dynamically.