# Governance services | Chersus

## Governance 4

```
curl -X POST https://api.chersus.com/v1/run \
  -H "Authorization: Bearer chrs_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "type": "text",
      "value": "Contact Jane Doe at jane.doe@example.com about invoice #4821."
    },
    "pipeline": [
      { "id": "redact", "service": "governance.pii.redact" }
    ]
  }'
```

```
const res = await fetch("https://api.chersus.com/v1/run", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CHERSUS_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    input: {
      type: "text",
      value: "Contact Jane Doe at jane.doe@example.com about invoice #4821.",
    },
    pipeline: [{ id: "redact", service: "governance.pii.redact" }],
  }),
});

const data = await res.json();
```

```
import os

import requests

res = requests.post(
    "https://api.chersus.com/v1/run",
    headers={"Authorization": f"Bearer {os.environ['CHERSUS_KEY']}"},
    json={
        "input": {
            "type": "text",
            "value": "Contact Jane Doe at jane.doe@example.com about invoice #4821.",
        },
        "pipeline": [{"id": "redact", "service": "governance.pii.redact"}],
    },
)

data = res.json()
```
200 · 26ms · 61 chars
```
{
  "trace_id": "chs_01J9X4Q7K2M8N3P5R6T7V8W9X0",
  "status": "completed",
  "output": {
    "type": "text",
    "value": "Contact [REDACTED] at [REDACTED] about invoice #4821."
  },
  "results": {
    "redact": { "kind": "transform", "status": "ok", "changes": 2 }
  },
  "usage": {
    "billed": [
      { "unit": "characters", "quantity": 61, "steps": ["redact"] }
    ]
  },
  "audit": { "region": "eu-nl-1", "retention": "none", "total_ms": 26 }
}
```

Use `governance.pii.redact` before text leaves your system: support tickets, log lines, LLM prompts, or anything you forward to a third party. The service replaces names, email addresses, phone numbers, and ID-like strings with stable placeholders, so downstream tools still see consistent sentence structure.

The service takes two params: `entities` (default `["name", "email", "id"]`) and `mask` (default `"[REDACTED]"`). Redaction is one-way. When you need the original values back later, use `governance.pii.tokenize` instead; it returns reversible tokens.
KINDtransformMODELRoblox/roblox-pii-classifier-v2LICENSEApache 2.0LANGUAGESMultilingualREGION26 EU cities
```
curl -X POST https://api.chersus.com/v1/run \
  -H "Authorization: Bearer chrs_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "type": "text",
      "value": "Contact Jane Doe at jane.doe@example.com about invoice #4821."
    },
    "pipeline": [
      { "id": "tokenize", "service": "governance.pii.tokenize" }
    ]
  }'
```

```
const res = await fetch("https://api.chersus.com/v1/run", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CHERSUS_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    input: {
      type: "text",
      value: "Contact Jane Doe at jane.doe@example.com about invoice #4821.",
    },
    pipeline: [{ id: "tokenize", service: "governance.pii.tokenize" }],
  }),
});

const data = await res.json();
```

```
import os

import requests

res = requests.post(
    "https://api.chersus.com/v1/run",
    headers={"Authorization": f"Bearer {os.environ['CHERSUS_KEY']}"},
    json={
        "input": {
            "type": "text",
            "value": "Contact Jane Doe at jane.doe@example.com about invoice #4821.",
        },
        "pipeline": [{"id": "tokenize", "service": "governance.pii.tokenize"}],
    },
)

data = res.json()
```
200 · 26ms · 61 chars
```
{
  "trace_id": "chs_01J9X4Q7K2M8N3P5R6T7V8W9X1",
  "status": "completed",
  "output": {
    "type": "text",
    "value": "Contact <PII_1> at <PII_2> about invoice #4821."
  },
  "results": {
    "tokenize": {
      "kind": "transform",
      "status": "ok",
      "changes": 2,
      "map": { "<PII_1>": "Jane Doe", "<PII_2>": "jane.doe@example.com" }
    }
  },
  "usage": {
    "billed": [
      { "unit": "characters", "quantity": 61, "steps": ["tokenize"] }
    ]
  },
  "audit": { "region": "eu-nl-1", "retention": "none", "total_ms": 26 }
}
```

Use `governance.pii.tokenize` when processing must continue on the data but the raw values have to leave your trust boundary first. The classic case: ship tokenized text to an LLM, then restore the values afterwards with `governance.pii.detokenize`. The service replaces each PII value with a stable token like `<PII_1>`, and the same value gets the same token throughout one payload. The token-to-value map comes back once, in the same response.

Store the map on your side. Tokenization is stateless: Chersus keeps neither the map nor a key. The audit trace stays hash-only and never includes the map.
KINDtransformMODELRoblox/roblox-pii-classifier-v2LICENSEApache 2.0LANGUAGESMultilingualREGION26 EU cities
```
curl -X POST https://api.chersus.com/v1/run \
  -H "Authorization: Bearer chrs_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "type": "text",
      "value": "Contact <PII_1> at <PII_2> about invoice #4821."
    },
    "pipeline": [
      {
        "id": "restore",
        "service": "governance.pii.detokenize",
        "params": {
      "map": { "<PII_1>": "Jane Doe", "<PII_2>": "jane.doe@example.com" }
        }
      }
    ]
  }'
```

```
const res = await fetch("https://api.chersus.com/v1/run", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CHERSUS_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    input: { type: "text", value: "Contact <PII_1> at <PII_2> about invoice #4821." },
    pipeline: [
      {
        id: "restore",
        service: "governance.pii.detokenize",
        params: { map: { "<PII_1>": "Jane Doe", "<PII_2>": "jane.doe@example.com" } },
      },
    ],
  }),
});

const data = await res.json();
```

```
import os

import requests

res = requests.post(
    "https://api.chersus.com/v1/run",
    headers={"Authorization": f"Bearer {os.environ['CHERSUS_KEY']}"},
    json={
        "input": {"type": "text", "value": "Contact <PII_1> at <PII_2> about invoice #4821."},
        "pipeline": [
            {
                "id": "restore",
                "service": "governance.pii.detokenize",
                "params": {
      "map": {"<PII_1>": "Jane Doe", "<PII_2>": "jane.doe@example.com"}
                },
            }
        ],
    },
)

data = res.json()
```
200 · 1ms · 47 chars
```
{
  "trace_id": "chs_01J9X4Q7K2M8N3P5R6T7V8W9X2",
  "status": "completed",
  "output": {
    "type": "text",
    "value": "Contact Jane Doe at jane.doe@example.com about invoice #4821."
  },
  "results": {
    "restore": { "kind": "transform", "status": "ok", "changes": 2 }
  },
  "usage": {
    "billed": [
      { "unit": "characters", "quantity": 47, "steps": ["restore"] }
    ]
  },
  "audit": { "region": "eu-nl-1", "retention": "none", "total_ms": 1 }
}
```

The inverse of `governance.pii.tokenize`. Pass the tokenized text plus the map you stored, as `params.map`, and the service restores the original values. Deterministic replacement, no model. It replaces only the tokens it finds in the map; unknown tokens pass through untouched, so a partially lost map degrades gracefully instead of failing.

Keep the token map in the same security zone as the original data. A map that travels with the tokenized text is as good as shipping the PII itself.
KINDtransformMODELnone (deterministic)LICENSEn/aLANGUAGESAny languageREGION26 EU cities
```
curl -X POST https://api.chersus.com/v1/run \
  -H "Authorization: Bearer chrs_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "type": "text",
      "value": "Certainly. I have emailed the invoice to jane.doe@example.com as you asked."
    },
    "pipeline": [
      { "id": "leak", "service": "governance.output.leak-check" }
    ]
  }'
```

```
const res = await fetch("https://api.chersus.com/v1/run", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CHERSUS_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "input": {
      "type": "text",
      "value": "Certainly. I have emailed the invoice to jane.doe@example.com as you asked."
    },
    "pipeline": [
      {
        "id": "leak",
        "service": "governance.output.leak-check"
      }
    ]
  }),
});

const data = await res.json();
```

```
import os

import requests

res = requests.post(
    "https://api.chersus.com/v1/run",
    headers={"Authorization": f"Bearer {os.environ['CHERSUS_KEY']}"},
    json={
      "input": {
        "type": "text",
        "value": "Certainly. I have emailed the invoice to jane.doe@example.com as you asked."
      },
      "pipeline": [
        {
          "id": "leak",
          "service": "governance.output.leak-check"
        }
      ]
    },
)

data = res.json()
```
200 · 75 chars
```
{
  "trace_id": "chs_01J9X4Q7K2M8N3P5R6T7V8W9XB",
  "status": "completed",
  "output": {
    "type": "text",
    "value": "Certainly. I have emailed the invoice to jane.doe@example.com as you asked."
  },
  "results": {
    "leak": {
        "kind": "classify",
        "status": "ok",
        "verdict": "flag",
        "score": 0.96,
        "labels": [
          "email"
        ]
      }
  },
  "usage": {
    "billed": [
      { "unit": "characters", "quantity": 75, "steps": ["leak"] }
    ]
  },
  "audit": { "region": "eu-nl-1", "retention": "none" }
}
```

Run `governance.output.leak-check` on what a model produced, not on what a user sent. It is the same PII detector as `governance.pii.redact`, pointed the other way: at an answer, before that answer reaches the person who asked. A model with private context in its prompt can quote that context back, and this catches it.

A `flag` means the output carries personal data, and `labels` names the entity types found. Gate on the verdict, or chain `governance.pii.redact` behind it to strip the values and return the answer anyway.
KINDclassifyMODELRoblox/roblox-pii-classifier-v2LICENSEApache 2.0LANGUAGESMultilingualREGION26 EU cities
## Start redacting in minutes.

Create an account, copy your key, make your first run before your coffee cools.
[Request access](/en/signup/)[Read the chaining guide](/en/docs/chaining/)