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.
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, 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.
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.
{
"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-supportresolves to the latest active version at request time.customer-support@3is 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.
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 has every field.