> ## Documentation Index
> Fetch the complete documentation index at: https://docs.frostwolf.app/llms.txt
> Use this file to discover all available pages before exploring further.

# POST /v1/cloak/detect

> Find personal data in a text and return where it is.

Finds personal data and returns a type, a category, a score, and a range for each entity. It never returns the matched value and it rewrites nothing. The caller already holds the text, so the caller cuts the ranges itself.

## Request

<ParamField body="text" type="string" required>
  The text. At most 12,000 characters. A longer text is refused with `400`, never truncated.
</ParamField>

<ParamField body="entities" type="string[]">
  Entity types to detect. Defaults to every type except `location` and `date`. An unknown type is a `400`.
</ParamField>

<ParamField body="min_confidence" type="number" default="0.5">
  Lowest score to accept, from 0 to 1.
</ParamField>

```bash theme={null}
curl https://api.frostwolf.app/v1/cloak/detect \
  -H "Authorization: Bearer fw_sk_..." \
  -H "Content-Type: application/json" \
  -d '{"text": "Contact jane@example.com", "entities": ["email"]}'
```

## Response

<ResponseField name="entities" type="object[]">
  <Expandable title="properties">
    <ResponseField name="type" type="string">One of the [24 entity types](/cloak/entity-types).</ResponseField>
    <ResponseField name="category" type="string">`pii`, `phi`, `pci`, or `credential`.</ResponseField>
    <ResponseField name="start" type="integer">Inclusive, in UTF-16 code units.</ResponseField>
    <ResponseField name="end" type="integer">Exclusive, in UTF-16 code units.</ResponseField>
    <ResponseField name="confidence" type="number">The detector's score.</ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="scanned_chars" type="integer">
  Characters in the submitted text.
</ResponseField>

<ResponseField name="taxonomy_version" type="string">
  Identity of the type mapping, so a change is auditable.
</ResponseField>

<ResponseField name="ner" type="object">
  `{ ran: true, latency_ms }`.
</ResponseField>

```json theme={null}
{
  "entities": [
    { "type": "email", "category": "pii", "start": 8, "end": 24, "confidence": 1 }
  ],
  "scanned_chars": 24,
  "taxonomy_version": "2026.09.30",
  "ner": { "ran": true, "latency_ms": 41.5 }
}
```

## Entities never overlap

The detector may label one region several ways. Overlapping detections are merged into their union, and the merged entity takes the type of the strongest member. A region is never reported twice.

## Failure

There is no fail-open path. When detection is not configured the route answers `503 not_configured`, and when the detector does not answer, or answers with something that cannot be trusted, it answers `503 unavailable`. A clean-looking response after a failed check would report a payload as free of personal data that nobody looked at.

The response is not cacheable, and nothing about the request is recorded.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.