Documents

Find and redact SSNs and dates of birth in uploaded documents

Detect Social Security numbers, dates of birth and other identifiers in documents uploaded to a form, review the findings in Save & Test, then redact them with labels and send the copy on.

An intake form takes supporting documents — a Word form, a scanned PDF, a spreadsheet. Before they go to the wider team, the Social Security numbers, dates of birth, card numbers and (for New Zealand and UK patients) IRD and NHS numbers must come out. You will run Redact Document twice: first in Detect only to see what it finds, then as Redact a copy with labels.

The sample document (intake.docx, made-up values that pass the checks) reads:

text
Patient intake form
Name: Jane Example
SSN: 078-05-1120
Date of birth: 12/03/1985
Card on file: 4111 1111 1111 1111
IRD number 49-091-850 and NHS number 943 476 5919
Form received 01/10/2026.

1. Detect only

Add Redact Document after the form trigger. Set Document to {{form.supporting_documents}} (a list uses its first file; wrap the step in a Loop over {{form.supporting_documents}} with {{item}} for several), Action to Detect only (no changes), and under Information types tick, in Identity, US Social Security number and Date of birth; in Financial, Credit / debit card number; and New Zealand IRD number and UK NHS number (or choose the regions United States, United Kingdom and New Zealand to see only theirs). Keep Minimum confidence at Medium.

Detect sensitive information
{
  "type": "doc_redact",
  "label": "Find identifiers",
  "config": {
    "source": "{{form.supporting_documents}}",
    "mode": "detect_only",
    "info_types": ["us_ssn", "date_of_birth", "credit_card", "nz_ird", "uk_nhs"],
    "min_confidence": "medium"
  }
}

The canvas shows Find 5 types → detected.

2. Review the findings in Save & Test

Press Save & Test and upload the sample. The step's output lists what was found, masked, with where it is:

Find identifiers (run output)
{
  "variable": "detected",
  "mode": "detect_only",
  "found": 5,
  "counts": { "us_ssn": 1, "date_of_birth": 1, "credit_card": 1, "nz_ird": 1, "uk_nhs": 1 },
  "info_types": 5,
  "min_confidence": "medium",
  "findings": [
    { "type": "us_ssn", "label": "US Social Security number", "confidence": "high", "text": "•••-••-••••", "part": "body", "paragraph": 3, "context_snippet": "SSN: [SSN]" },
    { "type": "date_of_birth", "label": "Date of birth", "confidence": "high", "text": "••/••/••••", "part": "body", "paragraph": 4, "context_snippet": "Date of birth: [DATE_OF_BIRTH]" },
    { "type": "credit_card", "label": "Credit / debit card number", "confidence": "high", "text": "•••• •••• •••• ••••", "part": "body", "paragraph": 5, "context_snippet": "Card on file: [CREDIT_CARD]" },
    { "type": "nz_ird", "label": "New Zealand IRD number", "confidence": "high", "text": "••-•••-•••", "part": "body", "paragraph": 6, "context_snippet": "IRD number [IRD_NUMBER] and NHS number [NHS_NUMBER]" },
    { "type": "uk_nhs", "label": "UK NHS number", "confidence": "high", "text": "••• ••• ••••", "part": "body", "paragraph": 6, "context_snippet": "IRD number [IRD_NUMBER] and NHS number [NHS_NUMBER]" }
  ]
}

Each finding also has its category, source and start / end offsets (shortened here). Things to check:

  • "Form received 01/10/2026" is not there: it is a plain date, and only Date of birth is selected. A date counts as a date of birth only with DOB, date of birth or born just before it.
  • Every value is masked (•••-••-••••), here and in the run history. To see the values in the workflow (for example to compare with a record), turn on Include the values in the findings variable; the run output stays masked.
  • Something missing? A bare number with no context word ("078051120" on its own line) is low confidence: lower Minimum confidence to Low, or add the label word to the document template. Too much? Raise it to High.

To stop here and send the document to a person when anything was found, add a Condition on {{detected_count}} greater than 0, and a User Task that loops over {{detected_findings}} ({{item.label}}, {{item.page}}, {{item.context_snippet}}).

3. Redact with labels

Switch Action to Redact a copy, set Replace with to [SSN] (labels), and under Style per type set the card to Keep last 4. Keep Redacted copy at Same format so the Word file keeps its formatting.

Redact identifiers
{
  "type": "doc_redact",
  "label": "Redact identifiers",
  "config": {
    "source": "{{form.supporting_documents}}",
    "info_types": ["us_ssn", "date_of_birth", "credit_card", "nz_ird", "uk_nhs"],
    "min_confidence": "medium",
    "replacement": "label",
    "styles": { "credit_card": "partial" },
    "output": "same",
    "clear_author": true
  }
}

{{redacted_text}} is:

text
Patient intake form
Name: Jane Example
SSN: [SSN]
Date of birth: [DATE_OF_BIRTH]
Card on file: ████ ████ ████ 1111
IRD number [IRD_NUMBER] and NHS number [NHS_NUMBER]
Form received 01/10/2026.

and {{redacted_file}} is intake-redacted.docx, the same document with only those values replaced and the author properties cleared. "Jane Example" is still there: names have no syntax — add them as Words and phrases ({{form.patient_name}}) or turn on AI detection.

4. Download or send the copy

In Save & Test, the run output names the copy (redact-intake-redacted.docx); add a Log step with {{redacted_file.url}} and open the link from Logs to check the result. In the workflow, attach {{redacted_file}} to a Send Email, store it in a data table file column, or upload it with a storage connector.

Variations

  • Scanned PDFs: turn on OCR in the step (Pages without text), or redact {{document.text}} from a Read Document with OCR. The copy is a rebuilt PDF.
  • Everything at once: All high-confidence types with the regions you serve, then review Detect only findings for a few real documents before switching to redaction.
  • Keep records matchable: Replace with: Hash gives [SSN:3f9a0c21b7] — the same SSN gets the same token in every document of this workspace, without the number.
  • Spreadsheets: each finding has sheet and cell (Staff!B2); text cells are redacted in place.