npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

sertify-id

v1.0.1

Published

Indonesian product compliance checker — BPOM, Halal (BPJPH), and SNI (BSN) in one library

Downloads

17

Readme

sertify-id

npm version License: MIT TypeScript

Indonesian product compliance checker — query BPOM, Halal (BPJPH), and SNI (BSN) databases from a single TypeScript library.

🇮🇩 Search across ~30M Halal certificates, BPOM food & drug registrations, and 9,000+ SNI-certified products — no API keys required.

Installation

npm install sertify-id
yarn add sertify-id
pnpm add sertify-id

Quick Start

import { checkProduct } from 'sertify-id';

// Check all sources at once (parallel)
const result = await checkProduct({ query: 'Indomie Goreng' });

console.log('Halal:', result.halal?.data.length, 'certificates');
console.log('BPOM:', result.bpom?.data.length, 'registrations');
console.log('SNI:', result.sni?.data.length, 'standards');

API Reference

searchHalal(options?) — BPJPH Halal Certificates

Search the BPJPH Halal certificate database (~30M records).

import { searchHalal } from 'sertify-id';

const result = await searchHalal({
  namaProduk: 'Susu Ultra',   // Product name (optional)
  noSertifikat: 'BPJPH-123',  // Certificate number (optional)
  pelakuUsaha: 'PT Indofood', // Business name (optional)
  page: 1,                     // Page number, default 1
  size: 20,                    // Results per page, default 10
});

Options:

| Field | Type | Default | Description | |----------------|----------|---------|--------------------------| | namaProduk | string | — | Product name to search | | noSertifikat | string | — | Certificate number | | pelakuUsaha | string | — | Business/operator name | | page | number | 1 | Page number (1-indexed) | | size | number | 10 | Results per page |


searchBPOM(options?) — BPOM Product Registration

Search the BPOM food & drug registration database.

import { searchBPOM } from 'sertify-id';

// Search a specific category
const result = await searchBPOM({
  query: 'Paracetamol',
  category: 'obat',     // Product category
  page: 1,
  limit: 10,
});

// Search all categories
const all = await searchBPOM({ query: 'Vitamin C', category: 'all' });

Options:

| Field | Type | Default | Description | |------------|-------------------------------------------------------------|-------------------|--------------------------| | query | string | — | Search query | | category | 'obat' \| 'obat-tradisional' \| 'obat-kuasi' \| 'suplemen' \| 'kosmetik' \| 'pangan-olahan' \| 'all' | 'pangan-olahan' | Product category | | page | number | 1 | Page number | | limit | number | 10 | Results per page |

Categories:

| Category | ID | Description | |----------------------|----|----------------------| | obat | 01 | Drugs | | obat-tradisional | 02 | Traditional Medicine | | obat-kuasi | 03 | Quasi-drugs | | suplemen | 04 | Supplements | | kosmetik | 05 | Cosmetics | | pangan-olahan | 06 | Processed Food |


searchSNI(options?) — BSN SNI Certification

Search the BSN SNI (Indonesian National Standard) product database (~9,000 active records).

import { searchSNI } from 'sertify-id';

const result = await searchSNI({
  namaProduk: 'Air Mineral',     // Product name (optional)
  merk: 'Aqua',                  // Brand (optional)
  noSNI: 'SNI 3553:2015',       // SNI number (optional)
  offset: 0,                      // Pagination offset, default 0
  limit: 20,                      // Max results, default 20
});

Options:

| Field | Type | Default | Description | |--------------|----------|---------|--------------------------| | namaProduk | string | — | Product name to search | | merk | string | — | Brand name | | noSNI | string | — | SNI standard number | | offset | number | 0 | Pagination offset | | limit | number | 20 | Max results to return |


checkProduct(options) — Check All Sources

Query multiple sources in parallel and get a unified result.

import { checkProduct } from 'sertify-id';

const result = await checkProduct({
  query: 'Indomie Goreng',
  sources: ['halal', 'bpom', 'bsn'],  // default: all three
  bpomCategory: 'pangan-olahan',       // optional BPOM override
});

Options:

| Field | Type | Default | |----------------|------------------------------------|----------------------------| | query | string | (required) | | sources | Array<'halal' \| 'bpom' \| 'bsn'> | ['halal', 'bpom', 'bsn'] | | bpomCategory | BPOMCategory | 'all' (when bpom in sources) |


Types

All result objects follow a consistent pattern:

// Every result has a `success` flag and `error` field
interface HalalResult {
  success: boolean;
  data: HalalProduct[];
  total: number;
  page: number;
  totalPages: number;
  error?: string;
}

interface SNIResult {
  success: boolean;
  data: SNIProduct[];
  total: number;
  error?: string;
}

interface BPOMResult {
  success: boolean;
  data: BPOMProduct[];
  total: number;
  filtered: number;
  category: string;
  error?: string;
}

Error Handling

import { SertifyError, searchHalal } from 'sertify-id';

try {
  const result = await searchHalal({ namaProduk: 'test' });
  // ...
} catch (err) {
  if (err instanceof SertifyError) {
    console.log(`Error from ${err.source}: ${err.message}`);
    console.log(`Code: ${err.code}, Status: ${err.status}`);
  }
}

Note: Individual search functions catch errors internally and return { success: false, error: "..." } instead of throwing. Only the convenience functions and direct HTTP errors throw SertifyError.

Custom Rate Limiting

The library uses a global rate limiter (max 2 concurrent requests) and automatic retry with exponential backoff (3 retries for 5xx errors).

import { checkProduct } from 'sertify-id';

// All requests go through the rate limiter automatically
// No manual throttling needed for normal usage
const result = await checkProduct({ query: 'Susu' });

How It Works

| Source | API Auth | Method | Records | |--------|----------|--------|---------| | BPJPH (Halal) | None | GET | ~30M certificates | | BSN (SNI) | None | POST JSON | ~9,000 active products | | BPOM | CSRF + session | POST form | Per category |

  • No API keys required — all APIs are publicly accessible.
  • BPOM requires session management (CSRF token extracted from the page). This is handled automatically with caching and auto-refresh.
  • Rate limiting prevents overwhelming the government servers (max 2 concurrent requests).
  • Retry logic with exponential backoff handles transient server errors gracefully.

⚠️ Disclaimer

This library accesses publicly available government databases via publicly available endpoints used by the official websites (cekbpom.pom.go.id, prod-api-si.halal.go.id, bangbeni.bsn.go.id). These services are subject to change without notice.

  • Data accessed — All data retrieved is publicly searchable on the respective government websites.
  • Read-only — This library performs only read (GET/POST) operations. No data is modified, deleted, or written.
  • Rate-limited — Requests are intentionally throttled (max 2 concurrent) to avoid overloading government servers.
  • Educational use — Intended for prototyping, educational, and personal verification purposes.

Use at your own risk. For production or commercial use, consider reaching out to the respective institutions (BPOM, BPJPH, BSN) to inquire about official API access.

Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feat/my-feature
  3. Make your changes
  4. Run npm run build to verify TypeScript compilation
  5. Run npm test to verify tests pass
  6. Commit and push
  7. Open a Pull Request

License

MIT © Arga Wicaksono