---
title: "Privacy shield · intentic sandbox API"
description: "What personal data is kept from model providers, and the record of what was masked. Every route in the privacy shield group of the intentic sandbox API."
url: "https://intentic.dev/api/privacy/"
---

Agent setup

# Privacy shield

What personal data is kept from model providers, and the record of what was masked

**On this page (8 sections)**

- [The privacy shield and what it covers](#privacy-status)
- [Change the privacy shield](#privacy-setPolicy)
- [What the privacy shield did lately](#privacy-log)
- [Read tokens back to their values](#privacy-reveal)
- [The name lists the shield finds names by](#privacy-dictionary)
- [The datasets taught to the shield](#privacy-sources)
- [Teach the shield a dataset's values](#privacy-learn)
- [Forget a taught dataset](#privacy-forget)

The shield replaces names, numbers and other personal data with tokens before a request reaches a provider you have not trusted, and puts the real values back on the way out. These routes read its state and replace its policy, which only the owner may do; read the log of what it masked; look a word up in the name dictionary; and list, teach and forget the datasets of known values it masks wherever they appear.

8 calls. Pick one to open it, or use the list on the right.

**GET`/privacy/shield` The privacy shield and what it covers**

Whether personal data is kept from untrusted model providers, which providers are trusted, which local readers are installed, and how many values it has learned.

### What you send

Nothing. Call it as it is.

### What comes back

| Field | Type |
| --- | --- |
| `policy` | object |
| `mode` Whether the shield is off, only… | "off" | "watch" | "on" |
| `trusted` Providers that may read personal data… | string[] |
| `classes` Which kinds of personal data are… | "person-name" | "national-id" | "tax-id" | "identity-document" … (9)[] |
| `images` What an image bound for an… | "mask" | "allow" |
| `names` How names are found | "dictionary" | "model" |
| `allow` Values never masked: your own company,… | string[] |
| `conversations` Providers that may read one conversation's… | object[] |
| `conversationId` | string |
| `provider` Provider id, as the trusted list… | string |
| `known` Values taught from your datasets, matched… | integer |
| `tokens` Values the shield has given a… | integer |
| `readers` | object |
| `ocr` The local text reader (PaddleOCR) that… | boolean |
| `model` A local named-entity model for names… | boolean |
| `providers` | object[] |
| `id` Provider id, as the trusted list… | string |
| `label` | string |
| `shieldable` Its runtime can be put behind… | boolean |
| `local` It runs on this machine, so… | boolean |

Try it answered in this tab

curl

```bash
curl "$SANDBOX/privacy/shield" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.privacy.status();
```

**POST`/privacy/shield` Change the privacy shield**

Replaces the policy whole. Turning the shield on puts every turn that starts from then on, whose runtime can be shielded, behind the gateway, and refuses the turns that cannot be shielded on an untrusted provider; a turn already running keeps the route it started with. A change to what is masked or trusted holds from the next model request.

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `mode` Whether the shield is off, only… | "off" | "watch" | "on" | body |
| `trusted` Providers that may read personal data… | string[] | body |
| `classes` Which kinds of personal data are… | "person-name" | "national-id" | "tax-id" | "identity-document" … (9)[] | body |
| `images` What an image bound for an… | "mask" | "allow" | body |
| `names` How names are found | "dictionary" | "model" | body |
| `allow` Values never masked: your own company,… | string[] | body |
| `conversations` Providers that may read one conversation's… | object[] | body |
| `conversationId` required | string | body |
| `provider` required Provider id, as the trusted list… | string | body |

### What comes back

| Field | Type |
| --- | --- |
| `ok` Always true | true |

Try it answered in this tab

curl

```bash
curl -X POST "$SANDBOX/privacy/shield" \
 -H "x-intentic-control: $INTENTIC_TOKEN" \
 -H "content-type: application/json" \
 -d '{"mode":"off","trusted":["…","…"],"classes":["person-name","national-id"],"images":"mask","names":"dictionary","allow":["…","…"],"conversations":[{"conversationId":"nightly-changelog","provider":"claude"},{"conversationId":"release-notes","provider":"claude"}]}'
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.privacy.setPolicy({
 "mode": "off",
 "trusted": [
 "…",
 "…"
 ],
 "classes": [
 "person-name",
 "national-id"
 ],
 "images": "mask",
 "names": "dictionary",
 "allow": [
 "…",
 "…"
 ],
 "conversations": [
 {
 "conversationId": "nightly-changelog",
 "provider": "claude"
 },
 {
 "conversationId": "release-notes",
 "provider": "claude"
 }
 ]
});
```

**GET`/privacy/log` What the privacy shield did lately**

Each model request the gateway handled: which provider, whether it was trusted, how many of each kind of personal data it found, and the tokens it gave with the masked text around them. Never the values.

### What you send

Nothing. Call it as it is.

### What comes back

| Field | Type |
| --- | --- |
| `at` When, as an ISO timestamp | string |
| `conversationId` | string |
| `provider` | string |
| `trusted` | boolean |
| `action` | "masked" | "watched" | "passed" | "refused" |
| `counts` How many of each kind were… | object |
| `images` Images the shield changed: personal data… | integer |
| `documents` Documents replaced by their masked text | integer |
| `protocol` Which wire format the request spoke | string |
| `detail` Why it was refused, when it… | string |
| `replacements` The first values replaced in what… | object[] |
| `token` The token the value became, as… | string |
| `class` | "person-name" | "national-id" | "tax-id" | "identity-document" … (9) |
| `excerpt` The masked text around the token… | string |
| `image` Found in an image's text, so… | boolean |

Try it answered in this tab

curl

```bash
curl "$SANDBOX/privacy/log" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.privacy.log();
```

**POST`/privacy/reveal` Read tokens back to their values**

The value each token stands for, from the vault, so the owner can check what the shield masked and spot a value it should have left alone. Only the owner may ask; a token the vault never gave out is left out.

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `tokens` required | string[] | body |

### What comes back

A plain value rather than an object. The example below is the whole of it.

Try it answered in this tab

curl

```bash
curl -X POST "$SANDBOX/privacy/reveal" \
 -H "x-intentic-control: $INTENTIC_TOKEN" \
 -H "content-type: application/json" \
 -d '{"tokens":["ict_9wQ4rTz8kLmN3pXbV7hJ","ict_9wQ4rTz8kLmN3pXbV7hJ"]}'
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.privacy.reveal({
 "tokens": [
 "ict_9wQ4rTz8kLmN3pXbV7hJ",
 "ict_9wQ4rTz8kLmN3pXbV7hJ"
 ]
});
```

**GET`/privacy/dictionary` The name lists the shield finds names by**

Every list the dictionary holds (first names, surnames, words that are names only beside other evidence, titles), how many words each has and where they come from. With a query, what the dictionary makes of it as a name, and for one word the listed words starting with it.

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `query` A word, the start of one,… | string | query |

### What comes back

| Field | Type |
| --- | --- |
| `lists` | object[] |
| `id` Stable id of the list | string |
| `kind` What a word on it says… | "first-name" | "surname" | "ambiguous" | "title" … (5) |
| `languages` The languages its words come from | "pl" | "en"[] |
| `count` How many words it holds | integer |
| `matching` inflected: matched in every grammatical form… | "inflected" | "as-written" |
| `source` Where the words come from: the… | string |
| `url` The source's page, where it has… | string |
| `license` | string |
| `totals` Distinct words across the first-name lists,… | object |
| `firstNames` | integer |
| `surnames` | integer |
| `matches` | object[] |
| `word` | string |
| `lists` Ids of the lists holding it | string[] |
| `lookup` | object |
| `text` The query as a name is… | string |
| `found` Whether the dictionary alone masks it… | boolean |
| `words` | object[] |
| `word` | string |
| `firstName` A listed first name, in this… | boolean |
| `surname` A listed surname, in this form… | boolean |
| `surnameForm` Shaped like a Polish surname (-ski,… | boolean |
| `ambiguous` Also an ordinary word, so found… | boolean |
| `never` Never taken as part of a… | boolean |

Try it answered in this tab

curl

```bash
curl "$SANDBOX/privacy/dictionary" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.privacy.dictionary();
```

**GET`/privacy/known` The datasets taught to the shield**

Each source values were taught from, and how many. The values themselves are never sent back.

### What you send

Nothing. Call it as it is.

### What comes back

| Field | Type |
| --- | --- |
| `source` Where the values came from, as… | string |
| `count` | integer |
| `at` When they were last taught | string |

Try it answered in this tab

curl

```bash
curl "$SANDBOX/privacy/known" \
 -H "x-intentic-control: $INTENTIC_TOKEN"
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.privacy.sources();
```

**POST`/privacy/known` Teach the shield a dataset's values**

Each value is masked wherever it appears from now on, in every form it is written, whether or not the detectors would have found it. Teaching only ever masks more, so the agent may do it.

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `source` required Where the values came from: a… | string | body |
| `values` required | object[] | body |
| `value` required | string | body |
| `class` required | "person-name" | "national-id" | "tax-id" | "identity-document" … (9) | body |

### What comes back

| Field | Type |
| --- | --- |
| `added` | integer |
| `known` | integer |

Try it answered in this tab

curl

```bash
curl -X POST "$SANDBOX/privacy/known" \
 -H "x-intentic-control: $INTENTIC_TOKEN" \
 -H "content-type: application/json" \
 -d '{"source":"…","values":[{"value":"…","class":"person-name"},{"value":"…","class":"national-id"}]}'
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.privacy.learn({
 "source": "…",
 "values": [
 {
 "value": "…",
 "class": "person-name"
 },
 {
 "value": "…",
 "class": "national-id"
 }
 ]
});
```

**POST`/privacy/known/forget` Forget a taught dataset**

Stops matching the values taught from one source. Tokens already given to them still resolve, so earlier conversations keep reading right.

### What you send

| Field | Type | Where |
| --- | --- | --- |
| `source` required | string | body |

### What comes back

| Field | Type |
| --- | --- |
| `forgotten` | integer |

Try it answered in this tab

curl

```bash
curl -X POST "$SANDBOX/privacy/known/forget" \
 -H "x-intentic-control: $INTENTIC_TOKEN" \
 -H "content-type: application/json" \
 -d '{"source":"…"}'
```

TypeScript

```typescript
import { sandbox } from "@intentic/sandbox-client";

const result = await sandbox.privacy.forget({
 "source": "…"
});
```

More in Agent setup

[Previous ← Safety policy](https://intentic.dev/api/safety/)
