Data deletion
When a customer (or their analyst acting on a documented data-subject access request) asks for their identity data to be deleted, Identity Platform anonymizes the customer row, retires face embeddings, and unlinks every sealed capture — while preserving the regulated audit trail PPATK and OJK examiners require.
This is the suite's implementation of UU PDP 27/2022 Art. 16 (right to erasure) and aligns with GDPR Art. 17 for cross-border operators.
What gets erased
| Asset | Treatment |
|---|---|
Customer.fullName | Replaced with [erased] |
Customer.nik / nikMetadata | Cleared / flagged |
Customer.email / phone / externalRef | Cleared (externalRef replaced with erased:<suffix>:<timestamp>) |
Customer.status | Flipped to archived — future verifications against this row will fail |
Customer.kycLevel | Reset to none |
FaceEnrollment.embedding | Overwritten with a 512-dim zero vector (cannot re-identify) |
FaceEnrollment.active | Flipped to false; retireReason set; sealed embedding file unlinked |
CaptureBundle.framesStoragePaths | Replaced with the __retired__ sentinel; sealed frames unlinked from disk |
KtpBundle.framesStoragePaths | Same — retired sentinel + sealed unlinks |
DeviceKey.active | All active device keys flipped to false |
What is preserved (regulated records)
| Asset | Why kept |
|---|---|
Verification rows | Regulated outcome record. Contains method + score + timestamp — no raw PII. |
TierEvent rows | KYC lifecycle audit. Contains tier transitions — no raw PII. |
AuditLog rows | Immutable per regulation. The erasure itself appends an audit row recording who/when/why. |
WebhookDelivery rows | 30-day rolling buffer; PII-bearing payloads age out per the global retention sweep. |
The position is: PII is erased, regulated outcome metadata is retained. This is the same posture an auditor expects from a regulated bank's core system — you can't unilaterally delete a verification record any more than you can delete a journal entry.
Endpoint
/api/identity/customers/{id}/erase{
"reason": "DSAR ticket #4827 — customer requested account closure + PII deletion under UU PDP Art. 16",
"caseRef": "DSAR-2026-4827"
}| Field | Required | Notes |
|---|---|---|
reason | yes | 4–500 chars. Free-text. Lands on the audit log — regulators want to see why. |
caseRef | no | Your internal ticket / DSAR / court order reference. Recommended for traceability. |
Response
{
"erased": true,
"customerId": "cus_01HXY...",
"erasedAt": "2026-05-25T08:14:22Z",
"counts": {
"enrolmentsRedacted": 2,
"captureBundlesRetired": 5,
"ktpBundlesRetired": 1,
"sealedFilesUnlinked": 18,
"sealedFilesFailed": 0
}
}sealedFilesFailed > 0 is non-fatal — the DB row is already retired so the data is no longer accessible via the application path. The sweep job retries unlinks of orphaned sealed files daily.
Error modes
| Status | Body | When |
|---|---|---|
| 400 | reason required (4-500 chars) | reason missing or out-of-range. |
| 403 | forbidden | API key lacks customers:edit scope. |
| 404 | customer not found | Wrong ID or cross-org access attempt. |
| 409 | customer already archived | Idempotent re-erasure attempt — already erased. |
| 429 | rate limit exceeded (10 per 5 min) | Per-org cap on erasures. |
Webhook
| Event | Fires when |
|---|---|
customer.erased | An erasure successfully completed. |
Subscribe if your downstream systems (CRM, billing, marketing) need to mirror the erasure.
This action is irreversible by design
Per UU PDP, erasure is a one-way operation — there is no un-erase endpoint. If the customer later signs up again with the same NIK, that's a brand-new Customer row + a fresh KYC funnel. Your application should treat erased customers as if they had never existed (status: archived).
What about NIK uniqueness?
The org-scoped NIK uniqueness constraint is enforced on active customers. An erased customer's NIK is cleared, so a future onboarding with the same NIK succeeds — it doesn't conflict with the archived row. The Verification history of the archived customer is preserved but doesn't get re-linked to the new customer.
Audit log shape
The erasure appends one row to your audit log:
{
"id": "aud_01HXY...",
"action": "customer.erased",
"actorUserId": "usr_compliance_lead_...",
"actorApiKeyId": null,
"targetType": "Customer",
"targetId": "cus_01HXY...",
"description": "Erased customer Budi Santoso per case DSAR-2026-4827 — DSAR ticket #4827 — customer requested account closure + PII deletion under UU PDP Art. 16",
"oldValue": { "kycLevel": "redacted", "fullName": "redacted" },
"newValue": { "kycLevel": "none", "status": "archived" },
"createdAt": "2026-05-25T08:14:22Z"
}Filter /api/identity/audit-log on action = customer.erased to produce a quarterly UU PDP compliance report.