Detect text
The protect call. Send text with a context id, get back the tokenised text and every span that was replaced.
Request
POST /v1/detect/text with Content-Type: application/json.
{
"text": "Müşteri Ayşe Demir (TCKN 12345678901) mart faturasına itiraz ediyor.",
"context_id": "ticket-48213",
"prompt_id": "turn-3",
"redaction_mode": "vault"
}
| Field | Required | Meaning |
|---|---|---|
text |
yes | The text to protect. UTF-8. The only size limit is the request body limit. |
context_id |
no | The conversation, case or job this text belongs to. With it, the same value gets the same token across calls and the result can be restored. Without it, tokens are ephemeral and nothing is stored. |
prompt_id |
no | A correlation id. Echoed back unchanged. |
redaction_mode |
no | vault (default) or fpe. See Contexts and restore. |
Unknown fields are rejected with 400.
Response
{
"document_id": "0c6b…",
"context_id": "ticket-48213",
"prompt_id": "turn-3",
"spans": [
{ "id": "…", "start": 8, "end": 18, "window_id": 0, "entity_type": "person",
"source": "model", "confidence": 0.998, "verified": true,
"cluster_id": "…", "replacement": "PERSON_kxmrqa" },
{ "id": "…", "start": 26, "end": 37, "window_id": 0, "entity_type": "national_id",
"source": "regex", "confidence": 1.0, "verified": null,
"cluster_id": "…", "replacement": "NATIONAL_ID_wbqtrz" }
],
"redacted_text": "Müşteri PERSON_kxmrqa (TCKN NATIONAL_ID_wbqtrz) mart faturasına itiraz ediyor.",
"redacted_file": null,
"stats": { "windows_processed": 1, "sources": ["model", "regex", "verifier"], "warnings": [], "cache_hit": false, "elapsed_ms": 118 }
}
Spans. start and end are byte offsets into the text you sent. entity_type is one of the classes in the detection classes table, or {"other": "<label>"} for a custom rule category. source is the layer that produced the span: regex, model, verifier or role. verified is true or false for spans the verifier scored and null for spans it did not. replacement is the token written into redacted_text. Spans that share a cluster_id are the same entity and carry the same token. The matched text itself is never returned.
Stats. windows_processed is how many detection windows the text was cut into. warnings is empty on a clean run; it carries a note when, for example, the vault was unreachable and tokens are ephemeral. cache_hit is true when identical text was submitted before in the same context.
Tokens
A vault token is the entity label, an underscore and six lowercase letters: PERSON_kxmrqa, EMAIL_dlwqzb, IBAN_hwtdmp. The letters are derived from a keyed hash of the tenant, the context, the class and the normalised value, so they are stable within a context and different across contexts and tenants. Values that differ only in case, whitespace or Turkish diacritics map to the same token.
In FPE mode the value is replaced by a format-preserving ciphertext of the same shape instead. Where that is not possible the fallback is a bracketed placeholder such as [PERSON_1].
Determinism
The same text in the same context under the same release gives the same result. Thresholds are fixed per release, model files are pinned, and the custom-rule revision is part of the cache key, so publishing a rule changes results immediately and predictably.
Failure
If any configured layer (rules, entity model, verifier, role layer) is down, times out or answers partially, the response is 503 DEPENDENCY_UNAVAILABLE and no text is returned. Text that exceeds the entity model’s 512-token sequence limit in a single window returns 422. Treat both as “do not send”.
All example values in this documentation are synthetic.