Apify Indonesian Cosmetics Inteligence
Under maintenancePricing
Pay per usage
Apify Indonesian Cosmetics Inteligence
Under maintenancePricing
Pay per usage
Rating
0.0
(0)
Developer
Andrew E
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
4 days ago
Last modified
Categories
Share
Indonesian Cosmetics Intelligence — Apify Actor
MVP Actor for targeted cosmetics intelligence from the public BPOM Cek Produk registry.
Instead of attempting to scrape the entire cosmetics registry on every run, this Actor is designed for recurring watchlists such as:
- monitor selected cosmetics brands;
- monitor selected registrants / companies;
- search selected products or BPOM registration numbers;
- watch composition / ingredient keywords supported by BPOM search;
- compare the result with the previous run and classify records as
NEW,CHANGED, orUNCHANGED.
Source: Badan Pengawas Obat dan Makanan Republik Indonesia (BPOM), public Cek Produk website. This Actor is an independent integration and is not affiliated with or endorsed by BPOM.
What this MVP does
- Opens the current Produk Kosmetika page with Playwright.
- Uses the visible BPOM filter UI instead of relying on undocumented private endpoints.
- Scrapes list results and, optionally, attempts to open the product detail dialog.
- Normalizes results into a stable JSON structure.
- Deduplicates products by BPOM registration number (NIE).
- Optionally compares records with a persistent snapshot stored in a named Apify Key-Value Store.
- Outputs records to the default Apify Dataset.
Example input
{"brands": ["SOMETHINC", "SKINTIFIC"],"registrants": [],"productNames": [],"registrationNumbers": [],"compositions": [],"maxItemsPerQuery": 100,"maxPagesPerQuery": 20,"includeDetails": true,"detectChanges": true,"emit": "changes","stateStoreName": "indonesian-cosmetics-intelligence-state","stateKey": "competitor-watchlist","requestDelayMs": 500}
Example output
{"eventType": "NEW","registrationNumber": "NA18260123456","productName": "Example Brightening Serum","brand": "EXAMPLE","registrant": "EXAMPLE COSMETICS, PT","packaging": "Botol 20 mL","dosageForm": "Cairan","composition": "...","issuedDate": "2026-08-28","expiryDate": "2029-08-28","status": "Aktif","category": "Kosmetika","source": "BPOM RI - Cek Produk","sourceUrl": "https://cekbpom.pom.go.id/produk-kosmetika","matchedBy": {"type": "brand","value": "EXAMPLE"},"detectedAt": "2026-09-02T05:00:00.000Z","changedFields": []}
Actual detail fields depend on what the BPOM interface exposes for the record at runtime. The Actor keeps list-level fields even when the detail dialog cannot be parsed.
Change detection
When detectChanges is enabled, the Actor stores a snapshot in the named Key-Value Store:
SNAPSHOT_<stateKey>
On the next successful run:
- record absent from previous snapshot →
NEW; - same NIE, different normalized fingerprint →
CHANGED; - same fingerprint →
UNCHANGED.
The MVP deliberately does not mark a missing result as REMOVED/REVOKED. A product may disappear from a query because of filtering, pagination limits, or a temporary source issue; calling that a regulatory removal would be unsafe. A future version should implement removal detection only with a verified complete snapshot strategy.
If any query job fails, the snapshot is not replaced. This prevents a partial failed run from becoming the next baseline.
Why Playwright?
The current BPOM product table is rendered dynamically. This Actor interacts with the public UI rather than hard-coding an undocumented internal endpoint. The tradeoff is higher compute use, but the MVP is easier to understand and more resilient to backend endpoint changes.
Deploy to Apify
Install the Apify CLI, log in, and from this folder run:
$apify push
You can also create an Actor in Apify Console and upload/push this repository.
Run locally
Requirements: Docker or a local Node.js environment with a compatible Playwright browser.
With Apify CLI:
$apify run
The sample input is included in:
storage/key_value_stores/default/INPUT.json
Production recommendations before publishing to Apify Store
- Start with low
maxItemsPerQueryand one browser concurrency. - Validate the BPOM site's applicable access/use rules before commercial scale-up.
- Add a proxy strategy only when legitimately needed; do not use it to defeat access controls.
- Add monitoring/alerts for selector changes.
- Add tests based on saved, legally obtained HTML fixtures.
- Keep
includeDetails=falsefor high-volume list discovery and run a second enrichment pass only for new records. - Consider a two-stage architecture for lower cost: discovery → detail enrichment.
Suggested roadmap
v0.1 — included here
- BPOM cosmetics watchlists
- brand / registrant / product / NIE / composition queries
- structured dataset
- detail-dialog enrichment (best effort)
- persistent change detection
v0.2
- BPOM Public Warning / dangerous cosmetics feed
- explicit
WARNING_ADDEDevents - webhook-friendly compact event dataset
v0.3
- scheduled competitor watch presets
- richer trend aggregation (registrations per brand / month)
- separate
discoverandenrichmodes to reduce browser cost
v1.0 — Indonesian Cosmetics Intelligence
- BPOM registry + BPOM public warnings
- marketplace product/pricing connectors where permitted
- cross-source product/entity resolution
- competitor launch radar
- market trend aggregates
- API-friendly product intelligence layer
Important scope note
A BPOM registration record is regulatory registry data; it should not be represented as a guarantee that a marketplace listing is genuine, safe for a specific person, or identical to the registered item. Matching a listing to BPOM data requires additional product-identity checks.