sertify-id
v1.0.1
Published
Indonesian product compliance checker — BPOM, Halal (BPJPH), and SNI (BSN) in one library
Downloads
17
Maintainers
Readme
sertify-id
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-idyarn add sertify-idpnpm add sertify-idQuick 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 throwSertifyError.
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
- Fork the repository
- Create a feature branch:
git checkout -b feat/my-feature - Make your changes
- Run
npm run buildto verify TypeScript compilation - Run
npm testto verify tests pass - Commit and push
- Open a Pull Request
License
MIT © Arga Wicaksono
