# Policies | Chersus

Documentation ▾
# Policies

A policy is a workflow saved under a name: the same detects, extracts, transforms and relay, versioned. Define it once, run it by name, change it by publishing a new version.

Last updated 2026-10-24·Also as Markdown:[this page](/en/docs/policies.md)[llms.txt](/llms.txt)

A policy is a workflow saved under a name. Every application runs it by name, and you change it by publishing a new version. Nothing is edited in place.

## The shape

```
{
  "name": "customer-support",
  "description": "External support LLMs",
  "extends": "template:external-llm",
  "detect": [
    { "op": "secrets.credentials", "block": true },
    { "op": "prompt.injection", "block": true },
    "pii.entities"
  ],
  "extract": ["language.code"],
  "transform": [{ "op": "pii.tokenize", "when": ["detect.pii.entities:flagged", "high_security:true"] }],
  "conditions": { "high_security": false },
  "relay": {
    "provider": "openai",
    "model": "gpt-4.1-mini",
    "detect": [{ "op": "secrets.credentials", "block": true }]
  },
  "tokens": { "style": "angle" }
}
```

`detect`, `extract`, `transform` and `relay` are a [workflow](/en/docs/workflows/), field for field. Saving adds `name`, `extends` and the `conditions` defaults. `tokens.style` picks the bracket style of the tokens a tokenize emits. For what a relay does, see [calling your model](/en/docs/calling-your-model/#relay).

## Condition defaults

A policy declares the conditions your caller can set, each with a default. A request that does not mention one gets the default. How `when` and `by` read them is in [workflows](/en/docs/workflows/#conditions).

```
{
  "policy": "customer-support",
  "input": "Hi, I am Jane Doe. Can you check invoice #4821?",
  "conditions": { "high_security": true }
}
```

A name uses lowercase letters, digits, `-` and `_`, has no dot, and is at most 40 characters. A policy holds at most 32. A `when` or `by` with neither a request value nor a default is rejected with `unknown_condition`.

## Publish a version

```
POST /v1/policies
```

Posting a new name creates version 1. Posting an existing name creates the next version.

```
{
  "name": "customer-support",
  "version": 3,
  "ref": "customer-support@3",
  "status": "active",
  "created_at": "2026-09-13T10:12:44Z"
}
```

## Pin a version

 - `customer-support` resolves to the latest active version at request time.
 - `customer-support@3` is pinned.

Every run with a `policy` returns the pinned ref that ran, whichever form you sent. Send pinned refs from production keys. The dashboard warns when a live key sends unpinned ones.

A policy set as the gateway default in the dashboard applies to every request through the [gateway](/en/docs/calling-your-model/#gateway).

## Retire a version

```
DELETE /v1/policies/customer-support@2
```

The version is marked `retired`. A run naming it is refused with `policy_retired`, and it stays readable so audit traces still resolve. The only active version cannot be retired.

## Extend a base policy

A policy extends one parent, a template (`template:external-llm`) or one of your own (`support-base@2`). One level only.

| Field | Merge rule |
| --- | --- |
| `detect`, `extract` | The union. The child’s options win on the same operation |
| `transform` | The parent’s list, then the child’s |
| `relay` | The child’s, when it sets one, `routing` included |
| `conditions` | The union. The child’s default wins on the same name |
| `tokens` | The child’s |

The parent is frozen into the version when you create it. A later change to the parent never changes an existing version.

## Templates

```
GET /v1/templates
GET /v1/templates/external-llm
```

Chersus ships `external-llm`, `internal-llm`, `strict-pii`, `support-chat`, `rag-context` and `tool-call`. A template is a starting point you copy and own. An update reaches your policy only when you publish a new version.

## One policy per destination

Your code picks the policy for each destination. Shared rules live in one base policy the others extend.

| Where the text goes | Policy you apply |
| --- | --- |
| Internal model | `support-internal` (extracts only) |
| EU-hosted LLM | `support-eu` (tokenize PII) |
| US-hosted LLM | `support-external` (tokenize PII, block credentials) |
| Vector store | `rag-context` (redact PII and credentials) |
| CRM tool call | `crm-fields` (extract fields to a schema) |

## Read

```
GET /v1/policies
GET /v1/policies/customer-support
GET /v1/policies/customer-support@3
GET /v1/policies/customer-support/versions
```

Reading a policy returns the resolved object with the parent merged in, plus the raw definition as submitted. The [API reference](/en/docs/api-reference/) has every field.