PII Redaction (Vietnam) API
Find and mask personal data in Vietnamese text: CCCD, tax codes, phones, bank accounts, cards, emails, BHYT, plates, names, addresses. Spans reported.
Send a text (support ticket, chat log, contract excerpt, data for an LLM) and get every piece of personal data with its type, position, confidence and reason, plus the redacted text. Detected: e-mail, Vietnamese phone numbers, CCCD (12 digits with a valid province and century code), 9-digit CMND, tax codes (MST, check digit verified), bank account numbers (after STK / tài khoản / a bank name), payment cards (Luhn and card prefix), BHXH and BHYT codes, passport numbers, vehicle plates, dates of birth (after "ngày sinh"), IPv4 addresses, person names (after a title such as anh / chị / ông / bà / "họ tên", or capitalised words starting with a Vietnamese family name) and addresses (after "địa chỉ" / "thường trú" or a street address resolved by /v1/address-parse). URLs on request.
Modes: mask (keep a few characters: 090* * 456, *******3456, N. V. A.), label ([PHONE_1], the same value keeps the same number), remove, hash (HMAC-SHA256 with your key, stable tokens for joining data sets) and pseudonym (realistic fake values of the same shape, stable for a value and key), or detect to only list the spans. Choose types with types and the threshold with min_confidence.
Built for the Personal Data Protection Law 91/2025/QH15 (in force 1 January 2026) and Decree 356/2025/NĐ-CP: sensitive marks financial and health identifiers. It is a detection aid, not a compliance guarantee: names and addresses written unusually can be missed. Nothing is stored or logged.
Parameters
| Name | In | Type | Required | Default | |
|---|---|---|---|---|---|
text | body|query | string | yes | The text to scan (max 100,000 characters). | |
mode | body|query | string | no | mask | mask, label, remove, hash, pseudonym or detect (spans only). |
types | body|query | string | no | Comma-separated: email, phone, cccd, cmnd, tax_code, bank_account, card, bhxh, bhyt, passport, plate, dob, ip, person, address, url (default: all but url). | |
key | body | string | no | Secret (8+ characters) for hash / pseudonym: HMAC-SHA256, stable per key. | |
min_confidence | body|query | number | no | 0.5 | Ignore detections below this confidence (0–1). |
mask_char | body|query | string | no | * | Character used by mask. |
Example
curl -X POST "https://apibox.io.vn/v1/vn-pii-redact" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"Khách hàng Nguyễn Văn An, CCCD 079203001234, SĐT 0909 123 456, email an.nguyen@gmail.com, STK VCB 0071000123456.","mode":"mask"}'const res = await fetch('https://apibox.io.vn/v1/vn-pii-redact', {
method: 'POST',
headers: {
Authorization: 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"text": "Khách hàng Nguyễn Văn An, CCCD 079203001234, SĐT 0909 123 456, email an.nguyen@gmail.com, STK VCB 0071000123456.",
"mode": "mask"
}),
});
const data = await res.json();
console.log(data);import requests
res = requests.post(
"https://apibox.io.vn/v1/vn-pii-redact",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={"text": "Khách hàng Nguyễn Văn An, CCCD 079203001234, SĐT 0909 123 456, email an.nguyen@gmail.com, STK VCB 0071000123456.", "mode": "mask"},
timeout=30,
)
print(res.json())<?php
$ch = curl_init('https://apibox.io.vn/v1/vn-pii-redact');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer YOUR_API_KEY', 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => '{"text":"Khách hàng Nguyễn Văn An, CCCD 079203001234, SĐT 0909 123 456, email an.nguyen@gmail.com, STK VCB 0071000123456.","mode":"mask"}',
]);
$response = curl_exec($ch);
print_r(json_decode($response, true));Response
{
"redacted": "Khách hàng N. V. A., CCCD *********234, SĐT 090* *** 456, email a********@gmail.com, STK VCB *********3456.",
"mode": "mask",
"count": 5,
"by_type": {
"person": 1,
"cccd": 1,
"phone": 1,
"email": 1,
"bank_account": 1
},
"contains_sensitive": true,
"entities": [
{
"type": "person",
"text": "Nguyễn Văn An",
"start": 11,
"end": 24,
"confidence": 0.9,
"sensitive": false,
"reason": "name after a title or \"tên\"",
"replacement": "N. V. A."
},
{
"type": "cccd",
"text": "079203001234",
"start": 31,
"end": 43,
"confidence": 0.98,
"sensitive": false,
"reason": "CCCD number (valid province and century codes)",
"replacement": "*********234"
},
{
"type": "phone",
"text": "0909 123 456",
"start": 49,
"end": 61,
"confidence": 0.95,
"sensitive": false,
"reason": "mobile number (MobiFone)",
"replacement": "090* *** 456"
},
"…"
],
"legal_basis": "Luật Bảo vệ dữ liệu cá nhân 91/2025/QH15 (hiệu lực 01/01/2026), NĐ 356/2025/NĐ-CP",
"reviewed": "2026-11-11",
"disclaimer": "Detection aid based on patterns, checksums and context words: names and addresses can be missed or over-matched. It does not by itself make processing compliant."
}
Use cases
- Mask customer data in support tickets before sharing them
- Strip personal data from chats before sending them to an LLM
- Pseudonymise exports for analytics or a third party
- Audit documents for CCCD, accounts and cards
FAQ
Is it accurate for names?
Names after a title or a "tên / họ tên" keyword are reliable; free-standing names are found when they start with a Vietnamese family name, which can also match place or street names. Check the confidence and adjust min_confidence.
Can I re-identify hashed values?
With hash or pseudonym and your own key, the same value always gives the same token, so data sets can be joined; without the key the tokens cannot be reversed. Without a key, hashes are plain SHA-256 and guessable.
Does this make me compliant?
No tool alone does. It helps minimise and de-identify data as the law requires, but legal obligations (consent, records, security) remain yours.
Related APIs
Hash Generator
Compute MD5, SHA-1, SHA-256, SHA-384, SHA-512 and CRC32 of text or files in one call, as hex or base64, with optional HMAC signing.
B64Encode / Decode
Encode or decode text as Base64, Base64URL, hex, URL encoding, HTML entities, Unicode escapes, ROT13 or binary with one simple API call.
***Password Generator
Generate cryptographically secure random passwords (4–256 chars, up to 100 at once) or check a password’s strength, entropy and estimated crack time.