pii · Guide
Getting started
Install the package, and run a synchronous pattern-tier call in under a minute in either language. The dictionary and NER tiers need one more line each.
1. Install
The pattern and pattern+dictionary tiers have zero dependencies in both languages. The pattern+dictionary+ner and pattern+ner-verified tiers need an ONNX runtime to execute the bundled model — the model file itself ships inside the package, nothing is downloaded.
| Language | Package | Import | Requires |
|---|---|---|---|
| JavaScript / Node | @cognipeer/pii | CommonJS require | Node.js 18+ |
| Python | cognipeer-pii | cognipeer_pii | Python 3.9+ |
npm install @cognipeer/pii # pattern + dictionary tiers, zero deps
npm install onnxruntime-node # add for pattern+dictionary+ner / pattern+ner-verifiedpip install cognipeer-pii # pattern + dictionary tiers, zero deps
pip install "cognipeer-pii[ner]" # add onnxruntime + numpy for the NER tiersNode 18+ or Python 3.9+. The JS package's main is plain CommonJS (src/index.js); the Python distribution cognipeer-pii imports as cognipeer_pii.
2. Your first detection
The synchronous detect/redact/mask calls only ever run the pattern tier (L1) — no dictionary, no model, no await needed:
const pii = require('@cognipeer/pii');
const result = pii.detect('e-postam ahmet@example.com, IBAN: TR330006100519786457841326');
console.log(result.findings.map((f) => [f.category, f.value]));
// [['email', 'ahmet@example.com'], ['iban', 'TR330006100519786457841326']]
pii.mask('TC kimlik no: 12345678950, e-postam ahmet@example.com').outputText;
// 'TC kimlik no: [TC_KIMLIK], e-postam [EMAIL]'import cognipeer_pii as pii
result = pii.detect("e-postam ahmet@example.com, IBAN: TR330006100519786457841326")
print([(f["category"], f["value"]) for f in result["findings"]])
# [('email', 'ahmet@example.com'), ('iban', 'TR330006100519786457841326')]
pii.mask("TC kimlik no: 12345678950, e-postam ahmet@example.com")["outputText"]
# 'TC kimlik no: [TC_KIMLIK], e-postam [EMAIL]'Only defaultEnabled categories run unless you pass your own categories map — see Categories for which 11 of the 31 built-in categories are on by default, and why the other 20 are opt-in.
3. Opting into the dictionary tier
Finding person/organization/location needs the built-in Turkish gazetteer, which only runs behind the Async functions:
const result = await pii.detectAsync(
"Ahmet Yılmaz, Cognipeer Teknoloji A.Ş.'de çalışıyor.",
{ detection: { mode: 'pattern+dictionary' } },
);result = await pii.detect_async(
"Ahmet Yılmaz, Cognipeer Teknoloji A.Ş.'de çalışıyor.",
detection={"mode": "pattern+dictionary"},
)4. pattern+ner-verified: pattern findings, judged by the CNN
This is the mode recommended for Turkish production use (see Model & benchmarks). It reruns fusion with the bundled char-CNN in front of the same candidates, and — for every category the model has a counterpart for — asks it whether the exact span agrees, pulling the score up or down instead of only ever reinforcing it:
const verified = await pii.detectAsync(text, {
detection: { mode: 'pattern+ner-verified' },
});verified = await pii.detect_async(text, detection={"mode": "pattern+ner-verified"})This mode defaults minConfidence to 0.4 when you set none (every other mode defaults to 0), and needs onnxruntime-node / onnxruntime installed — a missing runtime degrades to the dictionary tier with a note in result.degraded rather than throwing. See Detection modes for the full fusion math (agreeWeight, checksumFloor, contextFloor, dictionaryFloor, nerOnlyWeight, nerOnlyNumberWeight) and Categories for which categories the judge can score at all.
Where to go next
- Detection modes — every mode, the judge's math, and latency per mode.
- Categories — all 31 built-in categories, languages, defaults, and validators.
- Redaction & tokens —
tokenizeText/detokenizeText, mask strategies, and the finding shape. - JavaScript API and Python API — the full function and option reference.

