← Research

Find every personal detail in text, and know what it is

SporeLabs Scrub finds the names, addresses, phone numbers, emails, card numbers, passwords, login codes and API keys in text, and labels each one. Your app decides what to do with them. It is a 17M-parameter model plus rules, and runs offline on a laptop CPU, in 2.1 ms per message.

Model release · October 5, 2026

Use it now

Call the API

Create a SporeLabs account and an API key, add funds, and send your text:

curl https://sporelabs.dev/v1/scrub \
  -H "Authorization: Bearer $SPORELABS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text": "Please call Tamsin Rourke on (312) 555-3917 or email tamsin.rourke@fernmail.com.", "mode": "tag"}'
{
  "id": "scrub_...",
  "object": "scrub",
  "model": "sporelabs/scrub-v1",
  "mode": "tag",
  "results": [{
    "text": "Please call [PERSON] on [PHONE] or email [EMAIL].",
    "findings": [
      {"start": 12, "end": 25, "type": "PERSON", "text": "Tamsin Rourke"},
      {"start": 29, "end": 43, "type": "PHONE", "text": "(312) 555-3917"},
      {"start": 53, "end": 79, "type": "EMAIL", "text": "tamsin.rourke@fernmail.com"}
    ],
    "by_type": {"PERSON": ["Tamsin Rourke"], "PHONE": ["(312) 555-3917"], "EMAIL": ["tamsin.rourke@fernmail.com"]}
  }],
  "usage": {"characters": 80, "findings": 3, "cost_millicents": 4}
}

Each finding comes back with its position and type. Use them yourself, or set mode to have the text rewritten: find (default) only reports, tag swaps in the type, pseudonym swaps in a consistent stand-in, and mask swaps in *. Send up to 64 texts at once in texts.

$0.50 per million characters, paid from your SporeLabs wallet. No subscription.

Run it on your own machine

The model and rules are open on Hugging Face. The package downloads the model once; after that, nothing leaves your machine.

pip install "sporelabs-scrub @ https://huggingface.co/SporeLabs/scrub/resolve/main/package/sporelabs_scrub-0.1.1-py3-none-any.whl"
from sporelabs_scrub import Scrub

scrub = Scrub()  # downloads SporeLabs/scrub once
text = "Please call Tamsin Rourke on (312) 555-3917."
print(scrub.scrub(text, mode="tag"))  # Please call [PERSON] on [PHONE].
for f in scrub.find(text):
    print(f["type"], f["start"], f["end"], f["text"])

Or fetch the files: hf download SporeLabs/scrub --local-dir scrub

See it on one message

7 details · 7 types

Hi, it's Tamsin RourkePERSON (username tamsin_rUSERNAME). My parcel never came. I'm at 48 Quillfeather Lane, MillbrookADDRESS. Call me on (312) 555-3917PHONE or email tamsin.rourke@fernmail.comEMAIL. I paid with card 4716 2093 8851 6620CREDIT_CARD, and the login code you texted was 482913OTP.

Why the type matters

A redactor that only knows something is sensitive gives you black bars. Scrub says what each detail is, so your app can act on it:

Data map for this message: name, username, address, phone number, email, card number, login code.
In the messageTypeInto a recordStand-in
Tamsin RourkePERSONNameNovak Kariuki
tamsin_rUSERNAMEUsernamekhartigan
48 Quillfeather Lane, MillbrookADDRESSAddress02 Alder Lane, Hazel
(312) 555-3917PHONEPhone(016) 422-5022
tamsin.rourke@fernmail.comEMAILEmailzdunmore@example.net
4716 2093 8851 6620CREDIT_CARDCard ending 66204892 0894 5335 8927
482913OTPNot stored878316

Route a ticket with a card number to payments. Fill a CRM record from a free-text message. Keep a map of the personal data each system holds, ready for the day someone asks what you have on them.

Stand-ins stay consistent, so the same name gets the same stand-in every time:

BeforeHi, Rafe Okonjo here. Please send the refund to card 4024 7716 3390 5182 and update my address to 7 Pelham Mews, Ashcombe. Rafe Okonjo, (617) 555-2841

AfterHi, Hana Jablonski here. Please send the refund to card 4201 2629 5022 2583 and update my address to 3 Juniper Pine, Birch. Hana Jablonski, (390) 325-2811

Everything else stays as it was, so the text still works for analytics, search and AI.

How SporeLabs built it

Every step, from public data to the benchmark. Watch on YouTube.
  1. SporeLabs collected openly licensed text where personal details turn up: chats, text messages, code and config files.
  2. SporeLabs placed realistic made-up details into that text and labelled each with its type.
  3. SporeLabs trained a small encoder, Ettin 17M, to tag each word with its type.
  4. SporeLabs added fast rules for fixed shapes, like API keys and card numbers, and to finish partly marked details.
  5. SporeLabs tested it on documents it had never seen.

Results

SporeLabs tested Scrub and 4 other systems on the same 100 documents none of them had seen: support messages, forms, chats, logs and code.

Held-out test documents. Personal details n=504, secrets n=135. Precision is the share of findings that were a real detail. Right type is the share of all details caught and given the correct type.
SystemPersonal details caughtPasswords, keys and codes caughtPrecisionCaught with the right type
SporeLabs Scrub92.1%91.8%81.0%88.3%
OpenAI Privacy Filter77.0%85.2%77.3%52.3%
GLiNER2-PII87.3%77.0%74.1%80.0%
AWS Comprehend85.5%38.5%78.1%71.2%
Microsoft Presidio54.4%7.4%57.8%42.4%

Scrub caught the most personal details (92.1% against 87.3% for GLiNER2-PII), the most passwords, keys and codes (91.8% against 85.2% for OpenAI Privacy Filter) and the most details with the right type (88.3% against 80.0% for GLiNER2-PII).

Each finding comes back with its type. By type, on the same documents:

Share of each kind of detail caught and given the right type.
TypenSporeLabs ScrubBest other system
Names27390.1%90.8% (GLiNER2-PII)
Addresses4475.0%95.5% (AWS Comprehend)
Phone numbers5490.7%96.3% (AWS Comprehend)
Emails6196.7%96.7% (AWS Comprehend)
Usernames7288.9%73.6% (GLiNER2-PII)
Passwords1952.6%68.4% (GLiNER2-PII)
Login codes2969.0%24.1% (GLiNER2-PII)
API keys and tokens8795.4%74.7% (GLiNER2-PII)

Speed

Median time per short message (42 characters), one CPU thread on a laptop (Apple M3). The cloud API includes the network round trip.
SystemTime per message
SporeLabs Scrub2.1 ms
Microsoft Presidio3.2 ms
OpenAI Privacy Filter70.8 ms
GLiNER2-PII108.0 ms
AWS Comprehend (cloud, round trip)49 ms

More from SporeLabs Research →