Sanitext

Detect and redact dates with the DATE label

Sanitext detects dates with its DATE label, returning each match as a span with byte start and end offsets, a confidence score, and the matched text from POST /v1/detect. POST /v1/redact replaces every date span with [DATE]. It finds numeric, written, and relative dates across 30-plus languages.

Dates are quiet identifiers. A birth date, an admission date, or a contract date can re-identify a person when joined with other data. Sanitext finds dates in free text and masks them so you can ship logs, prompts, and documents with less exposure.

What counts as a date?

The DATE label covers any text that names a point or period in time. Sanitext does not need a fixed format. It reads the surrounding words to decide what is a real date.

This includes calendar dates, written-out dates, and relative phrases. It also catches partial dates like a month and year or a standalone year when the context makes the meaning clear.

  • —Numeric dates: 2025-06-17, 17/06/2025, 06.17.2025
  • —Written dates: June 17, 2025, 17 de junio de 2025
  • —Partial dates: June 2025, Q3 2024, the year 1998
  • —Relative dates: yesterday, last Tuesday, three days ago
  • —Date ranges: from May 1 to May 14

How does date detection work?

Send your text to POST /v1/detect. Sanitext returns an entities array. Each date is one object with the label DATE, a start and end byte offset, a confidence score from 0 to 1, and the exact matched text.

Byte offsets are positions in the UTF-8 encoded string, not character indexes. This matters for accented and non-Latin text where one character can take several bytes. Use the offsets to slice, highlight, or replace the date in place.

Set an optional threshold in the request body to drop low-confidence matches. The default is 0.5. Raise it to reduce false positives, lower it to catch more borderline dates. To mask instead of inspect, call POST /v1/redact and each date span comes back as [DATE].

What date formats and edge cases are handled?

Dates are ambiguous by nature, so review output against your own data before production use. Sanitext is a data-minimization aid, not an anonymization guarantee.

Day-month-day order is the classic trap. 03/04/2025 can be March 4 or April 3 depending on locale. Sanitext flags the span as a DATE either way, since the goal is to find and mask it, not to parse its calendar value.

  • —Ordering: handles DMY, MDY, and ISO YMD as one DATE span
  • —Times: a clock time alone (14:30) is not a DATE; a full datetime is split per label
  • —Numbers that look like dates: invoice or ID numbers may match; raise the threshold or verify
  • —Embedded dates: a date inside a URL or filename may be caught by the DATE or URL label
  • —Two-digit years: 17/06/25 is detected, but confirm the century in your domain

Does it detect dates in other languages?

Yes. Sanitext runs one multilingual model that finds dates across 30-plus languages, including Spanish, French, German, Dutch, Portuguese, and Italian. Written month names, locale-specific separators, and connector words like de or der are handled.

The model runs on our own Cloudflare infrastructure, so your text never goes to a third-party LLM. We log counts and timings only, not the raw text or the dates it contains.

POST /v1/detect → response

# request
curl https://api.sanitext.app/v1/detect \
  -H "Authorization: Bearer pf_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text":"Born June 17, 1990. Last seen yesterday.","threshold":0.5}'

# response
{ "entities": [
    { "label": "DATE", "start": 5, "end": 18,
      "score": 0.98, "text": "June 17, 1990" },
    { "label": "DATE", "start": 30, "end": 39,
      "score": 0.91, "text": "yesterday" } ],
  "count": 2, "ms": 27 }

# POST /v1/redact on the same text returns:
{ "redacted": "Born [DATE]. Last seen [DATE].",
  "entities": [ ... ], "count": 2, "ms": 24 }

FAQ

How do I redact every date in a block of text?+

Call POST /v1/redact with your text. Sanitext finds each date and replaces the span with [DATE], returning the masked string plus the entities array and a count. No format hints are needed; it handles numeric, written, and relative dates.

Are date offsets in bytes or characters?+

Byte offsets in the UTF-8 string. Each DATE entity has start and end byte positions. For accented or non-Latin text, slice on bytes, not character indexes, so the boundaries line up with the matched date exactly.

Does Sanitext tell March 4 from April 3?+

No. Sanitext detects and labels the text as a DATE but does not resolve its calendar value, so ambiguous orders like 03/04/2025 are still masked. If you need a parsed date, parse the matched text yourself after detection.

Can detecting dates make my data anonymous?+

No. Redacting dates is a data-minimization aid, not anonymization or a compliance guarantee. Dates often combine with other fields to re-identify people, so review output and pair date redaction with names, addresses, and IDs.

Redact dates in 60 seconds

Sign up free for 300K characters, no card. Drop the DATE label into your pipeline and mask dates before they reach logs or an LLM. See the docs to start.

Get your free API key