# Rwanda FDA Registered Human Medicines (`a-g-d/rw-fda`) Actor

The Rwanda FDA Human Medicines Drug Register as English-keyed JSON: registration number and series, brand and generic names, ingredients, strength, form, pack size, shelf life, manufacturer and country, marketing authorisation holder, local representative and ISO dates.

- **URL**: https://apify.com/a-g-d/rw-fda.md
- **Developed by:** [Aloever Dulay](https://apify.com/a-g-d) (community)
- **Categories:** E-commerce, Other
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 94.1% 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

## Rwanda FDA Registered Human Medicines

The **Human Medicines Drug Register** of the **Rwanda Food and Drugs Authority (Rwanda FDA)**
as clean JSON with English keys: registration number and series, brand and generic names,
active ingredients, strength, dosage form, pack size, shelf life, manufacturer and its
country, marketing authorisation holder, local technical representative, ISO registration
and expiry dates, and registration status. About 2,600 registered products; the whole
register takes under 10 seconds.

### Who needs this

- **Pharmaceutical companies, distributors and importers** checking which products are
  registered in Rwanda, 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.
- **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 page.

### Input

| Field                | Type    | Default  | Description                                                                                     |
| -------------------- | ------- | -------- | ----------------------------------------------------------------------------------------------- |
| `brandName`          | string  | `""`     | Brand (trade) name contains this text, any case (`besicor`).                                    |
| `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 (`HBP-MA`, `FDA-HMP-MA-2360`). |
| `manufacturer`       | string  | `""`     | Manufacturer's company name contains this text, any case (`cipla`). Addresses are not searched. |
| `holder`             | string  | `""`     | Marketing authorisation holder or local agent contains this text, any case (`sanofi`).          |
| `country`            | string  | `""`     | Manufacturer's country contains this text, any case (`india` matches `INDIA` and `India`).      |
| `dosageForm`         | string  | `""`     | Dosage form contains this text, any case (`tablet`, `injection`).                               |
| `registeredSince`    | string  | `""`     | Registered on or after this date (`YYYY-MM-DD`).                                                |
| `expiringBefore`     | string  | `""`     | Registration expires before this date (`YYYY-MM-DD`).                                           |
| `includeExpired`     | boolean | `true`   | Keep registrations whose expiry date has passed (the register lists them in a grace period).    |
| `maxItems`           | integer | `100`    | Stop after storing this many products (1-10,000).                                               |
| `proxyConfiguration` | object  | no proxy | Optional Apify Proxy, if the Rwanda FDA site is unreachable from Apify's network.               |

Filters combine with AND. The register is one web page with no search of its own, so every
run reads the page once and the actor applies the filters to each product before storing it.

### Output

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

A real product:

```json
{
  "registrationNumber": "Rwanda FDA-HMP-MA-2217",
  "registrationSeries": "HMP",
  "brandName": "ZINNIA P",
  "genericName": "Levonorgestrel 0.15mg + Ethinylestradiol 0.03mg",
  "activeIngredients": ["Levonorgestrel 0.15mg", "Ethinylestradiol 0.03mg"],
  "strength": "150mcg + 30mcg",
  "dosageForm": "tablets",
  "dosageFormNormalized": "tablets",
  "packSize": "28 Tablets",
  "shelfLife": "36 Months",
  "shelfLifeMonths": 36,
  "manufacturer": "MYLAN LABORATORIES LIMITED",
  "manufacturerCountry": "India",
  "holder": "MYLAN LABORATORIES LIMITED",
  "localRepresentative": "Pyramid Pharma Limited",
  "registeredAt": "2025-02-04",
  "expiresAt": "2030-02-03",
  "registrationStatus": "active",
  "sourceUrl": "https://monitoring.rwandafda.gov.rw/register/hmdr/",
  "fetchedAt": "2026-10-21T22:23:46.444Z"
}
```

Notes on the fields:

- **`registrationSeries`** is `HMP` for human medicinal products (`Rwanda FDA-HMP-MA-NNNN`),
  `HBP` for human biological products such as vaccines and insulins
  (`Rwanda FDA-HBP-MA-NNNN`), and `legacy` for the older number formats
  (`RWANDA-FDA25/HM/0373/0034` and others).
- **`activeIngredients`** splits the generic name at "+", ";" and a "/" between two names
  ("TENOFOVIR/LAMIVUDINE"); a "/" inside a strength ("250mg/5ml") does not split.
- **`dosageForm`** and **`manufacturerCountry`** are as published: the register writes the
  same form or country in many spellings ("Tablets", "TABLETS"; "INDIA", "India").
  `dosageFormNormalized` is the form in lower case, for grouping and filtering.
- **`shelfLifeMonths`** is the leading number of the free-text `shelfLife` ("36 Months",
  "36", "24 month"); a bare number is months.
- **`holder`** is the marketing authorisation holder (MAH) or local agent; the register's
  "MAH / Local Agent" column often continues with an address and contact details, which
  are never output (see Data and privacy).
- **`registrationStatus`** is worked out by the actor: `active` while `expiresAt` is today
  or later (today in Rwanda) or unknown, `expired` after it. The register keeps expired
  registrations listed during a grace period; set `includeExpired` to `false` to leave
  them out.
- **Duplicates.** A few registration numbers appear twice on the page for different
  products; both are kept. A row that repeats another's registration number, brand and
  strength (ignoring case and spacing) is stored once.

### Pricing

Pay per event:

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

Apify's standard run-start event covers starting the actor. Products 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 product.

### Data source and politeness

- **Source:** the Rwanda FDA Human Medicines Drug Register page,
  `https://monitoring.rwandafda.gov.rw/register/hmdr/`, linked from the authority's
  "Products repositories" page. The page holds the whole register (about 7 MB, about
  0.7 MB compressed); its search box filters rows in the browser.
- **One request per run.** The actor downloads the page once, compressed, and reads it as
  it arrives. When `maxItems` is reached and no filter is set, it stops the download early:
  10 products read about 16 KB.
- **Only the register:** the actor never requests the product-leaflet or recall pages or
  anything else on the site. No login, no captcha; the certificate is always verified.
- It identifies itself honestly as `rw-fda-actor/0.1 (+https://apify.com/a-g-d/rw-fda)`.
- **robots.txt:** the register host publishes no rules; the authority's main site only
  turns away a list of named bots.
- **Measured runs:** the prefill (10 products) in 4 seconds; the whole register, 2,610
  products, in 7 seconds; a "paracetamol" search, 138 products, in 5 seconds; everything
  registered since 2026-01-01, 177 products, in 7 seconds.
- **Resilience:** connection errors, timeouts, HTTP 5xx and 429, redirects, cut-off pages
  and answers that are not the register page are retried with exponential backoff and
  jitter inside a run-wide budget, each attempt reading the page from the top. A refusal, a
  challenge page or a changed table stops the run with a clear message rather than working
  around it or storing wrong data.
- **Run timeout:** the default run timeout is 10 minutes, far more than a run needs. If a
  run would still outlast its timeout (for example a shorter one you set), the actor stops
  reading 20 seconds before it, stores every product read so far and ends SUCCEEDED with a
  status message saying so.
- **Terms:** the Rwanda FDA websites carry a copyright footer ("©2026 Rwanda Food and Drug
  Authority"); their "Terms" and "Privacy" footer links lead nowhere, no terms-of-use page
  exists, and the national privacy policy they link to does not mention automated access or
  reuse. The register is published so the public can check which medicines are authorised.
  Check Rwanda FDA'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 company columns strictly, because the register writes
addresses, phone numbers and e-mail addresses (some of them named people's work addresses)
into them:

- **MAH / Local Agent: the company name only.** The actor keeps the text before the first
  address or contact label ("Address", "Adresse", "Country", "Pays", "Tel", "Telephone",
  "Fax", "E-mail", "Plot", "P.O. Box"…, also when glued to the name), comma, semicolon or
  line break, after a leading "(Company) Name:" label. The rest of the cell is never output.
  A comma followed only by a legal form ("COMBINO PHARM MALTA, LTD") does not end the name.
- **Manufacturer:** the same rule, after joining a name the register splits across lines.
- **Local technical representative:** passed through only under the same test below.
- **Fail closed.** A company name that still contains a digit, an e-mail address, a phone
  number or an address word (street, road, avenue, plot, P.O. box, floor, building,
  house…) is output as `null` instead of being cut further. On the whole register this
  leaves 613 distinct holder names and nulls the holder of 26 products.
- **Never output:** any e-mail address, phone number or street address; any other text
  value that contains an e-mail address or a phone number is output as `null`.
- Company names can include a place that is part of the registered name ("SANDOZ GmbH
  KUNDL", "CIPLA LTD/INDIA"); these are kept as published.

### Limitations

- **Which products are listed is the register's choice.** The page lists the human
  medicines Rwanda FDA has registered, expired ones in their grace period included; it does
  not cover veterinary products, medical devices or premises.
- **Totals change.** New registrations are added as they are granted; a run is a snapshot.
- **Data quality is the register's.** Typos, spelling variants and missing cells are kept as
  published; a holder or manufacturer the register writes with an address and no clear
  separator may be `null`.

# Changelog

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

# Actor input Schema

## `brandName` (type: `string`):

The brand (trade) name contains this text, any case, e.g. "besicor". 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. "HBP-MA" or "FDA-HMP-MA-2360". Leave empty for all.

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

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

## `holder` (type: `string`):

The marketing authorisation holder (MAH) or local agent company name contains this text, any case, e.g. "sanofi". Addresses are not searched. Leave empty for all.

## `country` (type: `string`):

The manufacturer's country as published contains this text, any case, e.g. "india" (matches "INDIA" and "India"). Leave empty for all.

## `dosageForm` (type: `string`):

The dosage form contains this text, any case, e.g. "tablet" or "injection". Leave empty for all.

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

Only products registered on or after this date (YYYY-MM-DD).

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

Only products whose registration expires before this date (YYYY-MM-DD).

## `includeExpired` (type: `boolean`):

Keep registrations whose expiry date has passed (the register lists them in a grace period). Turn off for active registrations only.

## `maxItems` (type: `integer`):

Stop after storing this many products (1 to 10,000). The whole register, about 2,600 products, takes under half a minute.

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

Optional. Use Apify Proxy if the Rwanda FDA site is unreachable from Apify's network.

## Actor input object example

```json
{
  "brandName": "",
  "genericName": "",
  "registrationNumber": "",
  "manufacturer": "",
  "holder": "",
  "country": "",
  "dosageForm": "",
  "registeredSince": "",
  "expiringBefore": "",
  "includeExpired": true,
  "maxItems": 10,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `products` (type: `string`):

One item per registered product matching the input: registration number and series, brand and generic names, active ingredients, strength, dosage form, pack size, shelf life, manufacturer and its country, marketing authorisation holder, local technical representative, registration and expiry dates, registration status, source page and fetch time.

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

The OUTPUT record: whether the run succeeded, why it stopped, products stored and matched, register rows read, the total the page reports, duplicates skipped, and the bytes and retries of the one request.

# 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 = {
    "maxItems": 10,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("a-g-d/rw-fda").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 = {
    "maxItems": 10,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("a-g-d/rw-fda").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 '{
  "maxItems": 10,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call a-g-d/rw-fda --silent --output-dataset

```

## MCP server setup

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

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/YNHlx7okl3Fc6tq0n/builds/y1f56mwAqMmnytAQG/openapi.json
