# Changelog of Kenya PPB Registered Products (Medicines, Devices) (`a-g-d/ke-ppb`) Actor

- **URL**: https://apify.com/a-g-d/ke-ppb/changelog.md
- **Full Actor documentation**: https://apify.com/a-g-d/ke-ppb.md

## Changelog

All notable changes to this project are documented here. The format follows
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project adheres to
[Semantic Versioning](https://semver.org/).

### \[0.1.1] - 2026-10-12

#### Fixed

- The container build removes the base image's own `node_modules` before installing, so a
  preinstalled crawlee no longer fails the SDK's version check at start.

### \[0.1.0] - 2026-10-12

#### Added

- The Kenya Pharmacy and Poisons Board's four public product registers on
  products.pharmacyboardkenya.org: registered medicines (retention register), food
  supplements and nutritional products, retained medical devices and herbal products. One
  item per register row with English camelCase keys shared across registers: registration
  number or register ID, product name, active ingredients (split), strength, dosage form,
  route, country of origin, local or foreign, marketing authorisation holder, local
  technical representative, manufacturer, registration and expiry dates (ISO) or years,
  licence status, the food specifics (human or veterinary, application type, packaging,
  shelf life, approval), source page and fetch time.
- Filters: product name, active ingredient, registration number, company, country (the
  most selective one sent to the site's own search, the rest checked per row),
  registered since and expiring before. Filters a register does not publish stop the run
  with a clear message.
- Order: medicines newest registration first (or soonest expiry first for
  `expiringBefore`), read one year at a time with an early stop on date filters; food,
  devices and herbals newest record first.
- Privacy: company columns are output without the postal or street addresses some rows
  carry after the name; e-mail addresses and phone numbers are never output; the food
  register's visual description is not collected.
- Politeness: at least 1.5 s between requests, one connection, an honest User-Agent, rows
  requested only as needed.
- Resilience: retries with exponential backoff and jitter on connection errors, timeouts,
  5xx, 429 and answers that are not a grid, inside a run-wide backoff budget; an expired
  grid key or session is renewed once and the same page repeated; refusals, challenge
  pages and layout changes stop the run loudly; the run stops cleanly shortly before its
  timeout; optional Apify Proxy.
- Pay-per-event billing: `product-record` per stored row, charged after storing; each
  batch is planned against the remaining spending limit and the run stops cleanly when it
  runs out.
