# Redact personal data

> Finds personal data in text (names, email addresses, phone numbers, postal addresses, account numbers and more) and masks it, in the privacy filter's own format, with `privacy-filter` (alias `openai/privacy-filter`). `model` is optional. At most 256 inputs and a body of 192 KiB (196,608 bytes) per request. The text sent is processed in memory only: it is never written to disk or logs and never used for training.

Source: https://docs.serenityedge.ai/docs/api/edge/redact-text/

`POST https://api.serenityedge.ai/v1/redact`

Finds personal data in text (names, email addresses, phone numbers, postal addresses, account numbers and more) and masks it, in the privacy filter's own format, with `privacy-filter` (alias `openai/privacy-filter`). `model` is optional. At most 256 inputs and a body of 192 KiB (196,608 bytes) per request. The text sent is processed in memory only: it is never written to disk or logs and never used for training.

The request is billed on an estimate: `ceil(characters of all inputs / 4)` tokens, with characters counted as Unicode code points. The answer carries no `usage`. Only Serenity Edge API keys can use this route. See the [Embeddings, rerank and redaction guide](https://docs.serenityedge.ai/docs/embeddings-rerank-and-redaction#redaction).

## Request body (`application/json`)

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `model` | string | no | Optional. `privacy-filter`, or its alias `openai/privacy-filter`. When it is left out, `privacy-filter` answers. |
| `inputs` | one of string, array of string | yes | The text to redact: a string, or an array of 1 to 256 strings. The answer has the same shape: one result for a string, an array of results in input order for an array. |
| `placeholders` | boolean | no | `true` (the default) replaces each item found with a placeholder that names its category, such as `[PERSON]`, `[EMAIL]` or `[PHONE]`; `false` removes the item from the text. Default `true`. |
| `categories` | array of string | no | Look only for these categories, named as in `entity_group`: `private_person`, `private_address`, `private_email`, `private_phone`, `private_date`, `account_number`, `private_url` and `secret`. Omit it, or send an empty array, to look for every category. Write the names in lower case: a name the filter does not know (`PRIVATE_PERSON` in capitals included) is ignored without an error, so a request with only unknown names answers 200 with no spans. |

Example:

```json
{
  "inputs": "Hi, I am Ana García. Write to ana.garcia@example.com or call +34 600 000 000.",
  "placeholders": true
}
```

## Responses

### 200: For a string in `inputs`, one result: the text with each item found masked, and the items found. For an array, an array of results in input order.

Body (`application/json`): `RedactResponse`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `text` | string | yes | The input with each item found masked: replaced with its placeholder, or removed when `placeholders` is `false`. |
| `spans` | array of RedactSpan (object) | yes | One entry per item of personal data found. |
| `spans[].entity_group` | string | no | The category of the item: `private_person`, `private_address`, `private_email`, `private_phone`, `private_date`, `account_number`, `private_url` or `secret`. |
| `spans[].score` | number | no | The model's confidence, from 0 to 1. |
| `spans[].word` | string | no | The text found. |
| `spans[].start` | integer | no | Position of the item's first character in the input, counted in characters. |
| `spans[].end` | integer | no | Position just after the item's last character in the input. |
| `spans[].placeholder` | string | no | The category's tag, such as `<PRIVATE_PERSON>`. |

### 400: The request was refused: a body that is not a JSON object, a missing or invalid `inputs`, `placeholders`, `categories` or `model`, more than 256 inputs, a model served on another route, or a request the model server could not process (`The model server rejected the request. Check the input sizes and parameters.`). `param` names the field at fault when there is one.

Body (`application/json`): `ErrorResponse`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `error` | Error (object) | yes | OpenAI-style error object. |
| `error.message` | string | yes | Human-readable description of the problem. |
| `error.type` | string | yes | Error category. One of `invalid_request_error`, `authentication_error`, `permission_error`, `not_found_error`, `rate_limit_error`, `server_error`. |
| `error.code` | string or null | no | Machine-readable error code, when available. |
| `error.param` | string or null | no | The request parameter the error refers to, when applicable. |

### 401: Missing or invalid API key.

Body (`application/json`): `ErrorResponse`, the same fields as under 400.

### 403: The key is valid but cannot use this route: only Serenity Edge API keys can. Any other key, such as a key from a Serenity Star account, gets `permission_denied` with a message that names the route's API (`embeddings`, `rerank` or `redact`).

Body (`application/json`): `ErrorResponse`, the same fields as under 400.

### 404: The model id is unknown, or it is a chat or decision model, which cannot be used on this route (`model_not_found`).

Body (`application/json`): `ErrorResponse`, the same fields as under 400.

### 413: The request body is larger than this route accepts (192 KiB, 196,608 bytes, `request_too_large`).

Body (`application/json`): `ErrorResponse`, the same fields as under 400.

### 429: Rate limit exceeded, or the service is temporarily at capacity for this model. Wait for the number of seconds in the `Retry-After` header before retrying.

Header `Retry-After`: Seconds to wait before retrying.

Body (`application/json`): `ErrorResponse`, the same fields as under 400.

### 500: Unexpected server error: the model service returned an unexpected response (`upstream_error`), the request got no answer within 600 seconds (`timeout`), or an error in the gateway. Retry with backoff.

Body (`application/json`): `ErrorResponse`, the same fields as under 400.

### 503: The model service is temporarily unavailable (`upstream_unavailable`). Retry later and check the status page at https://status.serenityedge.ai.

Body (`application/json`): `ErrorResponse`, the same fields as under 400.
