# Zimbabwe MCAZ Registered Medicines (`a-g-d/zw-mcaz`) Actor

Registered human, veterinary and complementary medicines from the Medicines Control Authority of Zimbabwe (MCAZ) as English-keyed JSON: registration number, trade and generic names, ingredients, strength, form, route, supply class, applicant, manufacturers and ISO dates.

- **URL**: https://apify.com/a-g-d/zw-mcaz.md
- **Developed by:** [Aloever Dulay](https://apify.com/a-g-d) (community)
- **Categories:** E-commerce, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 product records

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Zimbabwe MCAZ Registered Medicines

The public registers of medicines authorised in **Zimbabwe** by the **Medicines Control
Authority of Zimbabwe (MCAZ)**, as clean JSON with English keys: registration number, trade
and generic names, active ingredients, strength, dosage form, route, legal supply class,
applicant, principal, manufacturers with their countries, and ISO registration and expiry
dates. Human, veterinary and complementary medicines, about 4,060 registrations on
2026-10-21:

| `categories`    | Register                                                   | Medicines |
| --------------- | ---------------------------------------------------------- | --------- |
| `human`         | Human medicines                                            | 3,171     |
| `veterinary`    | Veterinary medicines                                       | 399       |
| `complementary` | Complementary medicines (vitamins, herbal and supplements) | 491       |

All three registers take about 20 seconds.

### Who needs this

- **Pharmaceutical companies, distributors and importers** checking which products are
  registered in Zimbabwe, who holds each registration, who makes it and when it expires.
- **Market-access and regulatory-affairs teams** watching competitors' registrations,
  new approvals (`registeredSince`) and upcoming expiries (`expiringBefore`).
- **Procurement, tender and supply-chain teams, NGOs and donors** verifying that a product
  and its manufacturer are registered before buying or shipping.
- **Veterinary and agricultural suppliers** working with the veterinary register.
- **Pharmacovigilance, research and journalism** studying what is registered, by whom and
  from which countries.
- **AI agents and automations** that need one stable schema instead of a web grid.

### Input

| Field                 | Type    | Default   | Description                                                                                         |
| --------------------- | ------- | --------- | --------------------------------------------------------------------------------------------------- |
| `categories`          | array   | all three | Which registers to read: `human`, `veterinary`, `complementary`.                                    |
| `tradeName`           | string  | `""`      | Trade (brand) name contains this text, any case (`myclav`).                                         |
| `genericName`         | string  | `""`      | Generic name or an active ingredient contains this text, any case (`paracetamol`).                  |
| `registrationNumber`  | string  | `""`      | Registration number contains this text, ignoring spaces and case (`2026/`, `CM0385`).               |
| `manufacturer`        | string  | `""`      | A manufacturer's company name contains this text, any case (`cipla`). Addresses are not searched.   |
| `applicant`           | string  | `""`      | Applicant (registration holder) company name contains this text, any case (`caps`).                 |
| `supplyCategory`      | string  | `""`      | Legal supply class contains this text, any case (`household remedies`, `pharmacy`, `9th schedule`). |
| `registeredSince`     | string  | `""`      | Registered on or after this date (`YYYY-MM-DD`).                                                    |
| `expiringBefore`      | string  | `""`      | Registration expires before this date (`YYYY-MM-DD`).                                               |
| `maxItemsPerCategory` | integer | `100`     | Stop each register after this many medicines (1-10,000).                                            |
| `proxyConfiguration`  | object  | no proxy  | Optional Apify Proxy, if the register is unreachable from Apify's network.                          |

Filters combine with AND. The register itself filters on trade name, generic name,
manufacturer and registration date, so those searches take one request per register
(a search for "paracetamol" in all three takes about 5 seconds); every filter is also
checked on each medicine before it is stored.

### Output

One dataset item per registered medicine. Text is kept as the register publishes it with
the whitespace tidied; dates are ISO (`YYYY-MM-DD`). The Output tab on this page documents
every field, with one table view per register, and a run summary (`OUTPUT`) reports per
register what was stored, how many rows were read and why it stopped.

A real human medicine (2026-10-21):

```json
{
  "category": "human",
  "applicationId": "000036",
  "registrationNumber": "72/22.3/27",
  "tradeName": "EUCORUB",
  "genericName": "UNICORN CAMPHOR RUB",
  "activeIngredients": ["UNICORN CAMPHOR RUB"],
  "strength": "15.56; 0.61; 2.77; 0.16; 0.12; 0.62G",
  "dosageForm": "OINTMENT",
  "route": "TOPICAL",
  "supplyCategory": "HOUSEHOLD REMEDIES (H.R.)",
  "applicant": "ZIMBABWE PHARMACEUTICALS HEALTHCARE",
  "principal": "ZIMBABWE PHARMACEUTICALS HEALTHCARE",
  "manufacturer": "ECOMED MANUFACTURING (PVT) LTD",
  "manufacturers": [
    { "name": "ECOMED MANUFACTURING (PVT) LTD", "country": "Zimbabwe" },
    { "name": "ZIMBABWE PHARMACEUTICALS HEALTHCARE", "country": "Zimbabwe" }
  ],
  "registeredAt": "1972-04-13",
  "expiresAt": "2027-12-31",
  "registrationStatus": "active",
  "sourceUrl": "https://onlineservices.mcaz.co.zw/onlineregister/Medicines",
  "fetchedAt": "2026-10-20T22:25:12.187Z"
}
```

A real veterinary medicine (the register's principal value carries a street address, so
`principal` is `null`):

```json
{
  "category": "veterinary",
  "applicationId": "V00037",
  "registrationNumber": "80/80.12.10/9015",
  "tradeName": "VALBAZEN FOR CATTLE",
  "genericName": "ALBENDAZOLE",
  "activeIngredients": ["ALBENDAZOLE"],
  "strength": "7.5%",
  "dosageForm": "SUSPENSION",
  "route": null,
  "supplyCategory": "VETERINARY MEDICINES (GENERAL DEALER), V.M.G.D.",
  "applicant": "ZOETIS SOUTH AFRICA (PTY) LTD",
  "principal": null,
  "manufacturer": "PFIZER LABS PTY LTD",
  "manufacturers": [
    { "name": "PFIZER LABS PTY LTD", "country": "South Africa" },
    { "name": "CHEMICAL PROCESS TECHNOLOGIES (PTY) LTD", "country": "South Africa" }
  ],
  "registeredAt": "1980-10-17",
  "expiresAt": "2027-12-31",
  "registrationStatus": "active",
  "sourceUrl": "https://onlineservices.mcaz.co.zw/onlineregister/Medicines",
  "fetchedAt": "2026-10-20T22:25:26.548Z"
}
```

A real complementary medicine:

```json
{
  "category": "complementary",
  "applicationId": "CMA008",
  "registrationNumber": "2017/CM0002",
  "tradeName": "CALMETTES NITE 45 MG",
  "genericName": "VALERIAN",
  "activeIngredients": ["VALERIAN"],
  "strength": "45MG",
  "dosageForm": "TABLET",
  "route": "ORAL",
  "supplyCategory": "CMGS",
  "applicant": "ABBOTT LABORATORIES SA (PTY) LTD",
  "principal": "ABBOTT LABORATORIES SA (PTY) LTD",
  "manufacturer": "VEMEDIA MANUFACTURING",
  "manufacturers": [
    { "name": "VEMEDIA MANUFACTURING", "country": "Netherlands" },
    { "name": "WIEWELHOVE GMBH", "country": "Germany" },
    { "name": "DRAGENOPHARM APOTHEKER PUSCHL", "country": "Germany" }
  ],
  "registeredAt": "2017-02-20",
  "expiresAt": "2027-12-31",
  "registrationStatus": "active",
  "sourceUrl": "https://onlineservices.mcaz.co.zw/onlineregister/Medicines",
  "fetchedAt": "2026-10-20T22:25:28.320Z"
}
```

Notes on the fields:

- **`manufacturers`** lists every manufacturer the register names, as company name and
  country only (see Data and privacy). `manufacturer` is the first name in that list.
- **`supplyCategory`** is the legal supply class ("PRESCRIPTION PREPARATIONS 9TH SCHEDULE,
  (P.P.)", "PHARMACY MEDICINES (P.)", "HOUSEHOLD REMEDIES (H.R.)", "CMGS" for complementary
  medicines…), not the register the medicine comes from (that is `category`).
- **`strength`** lists one value per ingredient for combinations, separated by "; ", often
  with the unit on the last value only, as published.
- **`dosageForm`** and **`route`** come from the register's "Forms" value ("TABLET,
  COATED; ORAL"); `route` is `null` when the register gives only a form.
- **Dates** are calendar dates as the register stores them, with no time or zone added.
- **`registrationStatus`** is worked out by the actor: `active` while `expiresAt` is today
  or later (today in Zimbabwe), `expired` after it, `null` for the few registrations without
  an expiry date (35 on 2026-10-21). The register lists the registrations it holds; on
  2026-10-21 every dated one was active.
- **`sourceUrl`** is the MCAZ online register of medicines. Its grid loads rows through the
  register's own data service, so the link opens the register, not the product.

### Pricing

Pay per event:

| Event            | Charged for                                     |
| ---------------- | ----------------------------------------------- |
| `product-record` | Each registered medicine stored in the dataset. |

Apify's standard run-start event covers starting the actor. Medicines are stored first and
charged after, so you never pay for data you did not receive. When your spending limit runs
out, the run stops cleanly and never stores an unpaid medicine.

### Data source and politeness

- **Source:** the MCAZ online register of medicines at
  `https://onlineservices.mcaz.co.zw/onlineregister/Medicines`, linked from the authority's
  website ("Online Registers"). The actor asks the register for rows the way its own grid
  does, 500 per request; nine requests cover all three registers. No login, no captcha;
  the certificate is always verified.
- **Only medicines:** the actor reads the medicines registers and nothing else on the site
  (not the registers of persons, premises or institutions).
- **robots.txt:** the authority's website allows everything; the register host publishes no
  rules. The actor still
  - waits **at least 1.5 seconds** after each request ends before the next one starts
    (retries included; a constant, not an input),
  - sends **one request at a time**, reading the registers one after another,
  - identifies itself honestly as `zw-mcaz-actor/0.1 (+https://apify.com/a-g-d/zw-mcaz)`,
  - asks only for the rows it needs: 10 medicines per register take one request each.
- **Measured on 2026-10-21:** 10 medicines per register in 5 seconds (3 requests); all
  three whole registers (4,061 medicines) in 19 seconds (9 requests, about 240 KB per
  500-row page); a "paracetamol" search 121 medicines in 6 seconds; everything registered
  since 2026-01-01, 374 medicines, in 6 seconds.
- **Resilience:** connection errors, timeouts, HTTP 5xx and 429, and error answers are
  retried with exponential backoff and jitter inside a run-wide budget. A refusal, a
  challenge page or a changed answer stops that register with a clear message rather than
  working around it. **One register failing does not stop the others**: their medicines are
  stored, the run summary names the register that failed and why, and the run fails only
  when every requested register fails.
- **Run timeout:** the default run timeout is 30 minutes, far more than the registers need.
  If a run would still outlast its timeout (for example a shorter one you set), the actor
  stops requesting 20 seconds before it, keeps everything stored and ends SUCCEEDED with a
  status message saying so.
- **Terms:** the MCAZ website's footer reads "Copyright © 2026 MCAZ" and the register's
  "© 2025 MCAZ - Medicines Control Authority of Zimbabwe". Its privacy policy covers visitor
  logs, cookies and personal information MCAZ collects; it does not mention automated access
  or reuse, and no terms-of-use page exists. The register is published so the public can
  check which medicines are authorised. Check MCAZ's terms for your own use of the data.

### Data and privacy

The register publishes product and company data. The actor outputs only the fields listed
above, an allowlist, and treats the three company columns strictly, because the register
writes street addresses into them:

- **Manufacturers: name and country only.** Each manufacturer entry in the register reads
  "COMPANY NAME, street, city, COUNTRY". The actor keeps the text before the first comma as
  the name and the last part as the country, but only when it is a country name on the
  ISO 3166 list; everything in between (street, plot, P.O. box, city, postal code) is
  dropped.
- **Fail closed.** A company name (manufacturer, applicant or principal) that contains a
  digit, an e-mail address, a phone number or an address word (street, road, avenue, plot,
  P.O. box, industrial estate, district…) is output as `null` instead of being cut.
  On 2026-10-21 this nulled 25 of 4,727 manufacturer names, 26 applicants and 60 principals.
- **Never output:** any e-mail address, phone number or street address; any text value
  that contains an e-mail address or a phone number is output as `null`.
- **Only the medicines registers are read.** The actor never requests the site's registers
  of persons or premises.
- Company names can include a place that is part of the registered name ("KRKA D.D, NOVO
  MESTO") or a country; these are kept as published.

### Limitations

- **Which medicines are listed is the register's choice.** The register lists the
  registrations MCAZ holds; it does not publish suspended, cancelled or historical ones.
- **Totals change.** New registrations are added continuously (4,054 rows on 2026-10-13,
  4,062 on 2026-10-17); a run is a snapshot.
- **One duplicate.** The register lists one human medicine twice (application id M227); the
  actor stores each application id once per register.
- **Data quality is the register's.** Typos, units missing from strengths and trade names
  equal to the generic name are kept as published; manufacturer countries the register
  misspells beyond recognition, or leaves out, are `null`.

# Changelog

This Actor's version history is a separate document: https://apify.com/a-g-d/zw-mcaz/changelog.md

# Actor input Schema

## `categories` (type: `array`):

Which MCAZ registers to read. They are read one after another; one register failing does not stop the others.

## `tradeName` (type: `string`):

The trade (brand) name contains this text, any case, e.g. "myclav". Leave empty for all.

## `genericName` (type: `string`):

The generic name or an active ingredient contains this text, any case, e.g. "paracetamol". Leave empty for all.

## `registrationNumber` (type: `string`):

The registration number contains this text, ignoring spaces and case, e.g. "2026/" or "CM0385". Leave empty for all.

## `manufacturer` (type: `string`):

A manufacturer's company name contains this text, any case, e.g. "cipla". Addresses are not searched. Leave empty for all.

## `applicant` (type: `string`):

The applicant (registration holder) company name contains this text, any case, e.g. "caps". Leave empty for all.

## `supplyCategory` (type: `string`):

The legal supply class contains this text, any case, e.g. "household remedies", "pharmacy medicines" or "9th schedule". Leave empty for all.

## `registeredSince` (type: `string`):

Only medicines registered on or after this date (YYYY-MM-DD). The register applies this filter itself.

## `expiringBefore` (type: `string`):

Only medicines whose registration expires before this date (YYYY-MM-DD). The whole register is read.

## `maxItemsPerCategory` (type: `integer`):

Stop each register after storing this many medicines (1 to 10,000). All three whole registers take about 20 seconds.

## `proxyConfiguration` (type: `object`):

Optional. Use Apify Proxy if the MCAZ register is unreachable from Apify's network.

## Actor input object example

```json
{
  "categories": [
    "human",
    "veterinary",
    "complementary"
  ],
  "tradeName": "",
  "genericName": "",
  "registrationNumber": "",
  "manufacturer": "",
  "applicant": "",
  "supplyCategory": "",
  "registeredSince": "",
  "expiringBefore": "",
  "maxItemsPerCategory": 10,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `medicines` (type: `string`):

One item per registered medicine matching the input: category, application id, registration number, trade and generic names, active ingredients, strength, dosage form, route, supply category, applicant, principal, manufacturers (name and country), registration and expiry dates, registration status, source page and fetch time. The dataset has one table view per category.

## `summary` (type: `string`):

The OUTPUT record: per category, whether it succeeded, why it stopped, medicines stored, pages and rows read, duplicates skipped, and the error when a category failed; plus requests and bytes per category.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "categories": [
        "human",
        "veterinary",
        "complementary"
    ],
    "maxItemsPerCategory": 10,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("a-g-d/zw-mcaz").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "categories": [
        "human",
        "veterinary",
        "complementary",
    ],
    "maxItemsPerCategory": 10,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("a-g-d/zw-mcaz").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "categories": [
    "human",
    "veterinary",
    "complementary"
  ],
  "maxItemsPerCategory": 10,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call a-g-d/zw-mcaz --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,a-g-d/zw-mcaz"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/LGaseBLYvvy4MY5dt/builds/EuEd3HEJwGg2BZF0o/openapi.json
