> For the complete documentation index, see [llms.txt](https://docs.teleskope.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.teleskope.ai/specifications/redaction-methodologies.md).

# Redaction Methodologies

Every detected element can be replaced by one of six styles. Select one with the `redactionStyle` query parameter on [v1/scrub](/the-platform/api-service/redaction-api/v1-scrub.md).

| `redactionStyle` | Replaces the value with                                                               |
| ---------------- | ------------------------------------------------------------------------------------- |
| `CLASS`          | The element label in angle brackets. The default.                                     |
| `CLASS_NUMBERED` | The element label plus an occurrence number, stable across repeats of the same value. |
| `EMPTY`          | An empty string.                                                                      |
| `MASKED`         | Asterisks, preserving a short leading prefix.                                         |
| `ENCRYPTED`      | Reversible AES-SIV ciphertext, deterministic for a given key.                         |
| `TOKENIZED`      | A format-preserving surrogate of the same shape as the original.                      |

{% hint style="warning" %}
An unrecognised `redactionStyle` is ignored rather than rejected. A misspelled value returns `200` with `CLASS` output. If a style appears not to apply, check the spelling first.
{% endhint %}

## Examples

All examples below use the same input:

```
Contact Ana Torres at ana@example.com or +1-415-555-0199
```

| Style            | Output                                                                                                               |
| ---------------- | -------------------------------------------------------------------------------------------------------------------- |
| `CLASS`          | `Contact <GIVEN> <FAMILY> at <EMAIL> or <PHONE>`                                                                     |
| `CLASS_NUMBERED` | `Contact <given_1> <family_1> at <email_1> or <phone_1>`                                                             |
| `EMPTY`          | `Contact at or`                                                                                                      |
| `MASKED`         | `Contact A** To**** at an************* or +1*************`                                                           |
| `ENCRYPTED`      | `Contact <GIVEN(3):9ec716841ed1…> <FAMILY(6):662205980d01…> at <EMAIL(15):cb7901d656e3…> or <PHONE(15):e2efe94111…>` |
| `TOKENIZED`      | `Contact <GIVEN> <FAMILY> at <EMAIL> or +1-415-256-9091`                                                             |

Ciphertext is truncated above for readability; real output carries the full hex string.

Element labels come from the [Entity Taxonomy](/specifications/data-elements/entity-taxonomy-v2.md). `CLASS` upper-cases them, `CLASS_NUMBERED` does not.

## CLASS and CLASS\_NUMBERED

`CLASS` writes `<LABEL>` for every match, so two different email addresses become two identical `<EMAIL>` tokens.

`CLASS_NUMBERED` appends an occurrence number and reuses it for repeated values, which preserves the structure of the data without revealing it:

```
Write to ana@example.com, then ana@example.com, then bo@example.com
->
Write to <email_1>, then <email_1>, then <email_2>
```

Numbering is scoped to a single response. The same address in a later request is not guaranteed the same number. For a value that stays stable across requests, use `ENCRYPTED` or `TOKENIZED`.

## EMPTY

Removes the value entirely. Surrounding characters, including the spaces on either side of the removed value, are left in place, so output can contain runs of whitespace.

## MASKED

Replaces each character with `*`, preserving a leading prefix that depends on the length of the value:

| Value length | Characters preserved |
| ------------ | -------------------- |
| 1–2          | none                 |
| 3            | first character      |
| 4 or more    | first two characters |

Length is always preserved, so a masked value still discloses how long the original was.

## ENCRYPTED

Encrypts the value with AES-SIV and emits `<LABEL(length):ciphertext>`, where `length` is the byte length of the original and `ciphertext` is hex-encoded.

```
ana@example.com  ->  <EMAIL(15):cb7901d656e33a4682eace4480bd50d72d47efa150cd8585b9d90af95db3f2>
```

Encryption is deterministic: the same input under the same key always produces the same ciphertext, which supports joins and deduplication on redacted data. It is also reversible, so treat the output as sensitive and the key as the control that makes it safe.

{% hint style="danger" %}
**Always pass your own `key`.** The `key` query parameter is not enforced, and omitting it does not fail. The service falls back to a key generated randomly when the process starts, which is never stored anywhere. Output encrypted that way cannot be decrypted by anyone, including us, and stops being reproducible as soon as the service restarts. Treat a response produced without `key` as discarded data, not as recoverable ciphertext.
{% endhint %}

Supply the key as a `key` query parameter of 32, 48, or 64 bytes, selecting AES-128, AES-192, or AES-256 respectively. Use the same key on every request whose outputs need to match.

{% hint style="warning" %}
A key of any other length returns `500`, not `400`, with a message of the form `incorrect size of key 8`.
{% endhint %}

## TOKENIZED

Replaces the value with a surrogate of the same shape: a phone number becomes a different valid phone number, an email a different well-formed email. Downstream systems that validate format continue to work on redacted data. Tokenization is deterministic for a given key, so a value maps to the same surrogate every time.

Format preservation applies to these labels only:

| Label   | v1 label       |
| ------- | -------------- |
| `email` | `EMAIL`        |
| `phone` | `PHONE_NUMBER` |
| `ip`    | `IPV4`, `IPV6` |
| `mac`   | `MAC_ADDRESS`  |

Every other element falls back to `CLASS` output. That is why `Ana Torres` appears as `<GIVEN> <FAMILY>` in the example above while the phone number is tokenized. `TOKENIZED` is not a drop-in replacement for `ENCRYPTED` when every element needs to round-trip.

Very short values cannot be tokenized either: format-preserving encryption requires a minimum input length for the character set in use, and values below it fall back to `CLASS` output.

`TOKENIZED` requires a tokenization key on the deployment. Without one, requests using this style return an error rather than unredacted content.

## Choosing a style

* Discarding the data: `EMPTY` or `CLASS`.
* Keeping shape for human review: `MASKED`.
* Counting or correlating distinct values in one payload: `CLASS_NUMBERED`.
* Joining or deduplicating across payloads, or recovering originals later: `ENCRYPTED` with your own `key`.
* Feeding redacted data to systems that validate format: `TOKENIZED`.

## Related

* [v1/scrub](/the-platform/api-service/redaction-api/v1-scrub.md) — the endpoint that applies these styles.
* [v1/classify](/the-platform/api-service/scanning-api/v1-classify.md) — detect without redacting.
* [Entity Taxonomy](/specifications/data-elements/entity-taxonomy-v2.md) — the element labels used in output.
