> ## Documentation Index
> Fetch the complete documentation index at: https://sidenet.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Guardrails

> Safety checks that run on every turn of an agent — personal data, content moderation, prompt injection and more — each set to warn or to block.

A guardrail is a check that runs on every turn of an agent, before the
message reaches the model or before the answer reaches the user. Turn one on
and it either **warns** (the violation is recorded, the turn goes on) or
**blocks** (the turn stops and the chat shows why). An agent with no
guardrails behaves exactly as before.

## The six guardrails

| Kind | Runs on | What it catches | Judge |
| - | - | - | - |
| `pii` | user message, optionally the answer | personal data: emails, phone numbers, card numbers, government ids… | yes |
| `moderation` | user message, optionally the answer | hate, harassment, violence, sexual content, self-harm | yes |
| `prompt_injection` | user message | jailbreaks, "ignore your instructions", attempts to pull tool or system data out | yes |
| `system_prompt_scrub` | the answer | the agent quoting its own instructions or internal configuration back | yes |
| `language` | user message | messages outside the target language(s) | yes |
| `unicode` | user message | control characters, odd whitespace, look-alike characters | no |

**Judge** means a small, fast model reads the content and decides. The five
judge-backed guardrails cost one short model call per turn each (two for a
kind that runs on both sides). `unicode` is a pure text transform and costs
nothing.

## Warn or block

`mode` says what happens when a guardrail fires:

* **`warn`** (the default) records the violation and lets the turn continue.
  Use it first: it tells you how often a guardrail would fire on real
  traffic, and the threshold you want, before anyone is refused.
* **`block`** ends the turn. The user sees a clear sentence naming the
  guardrail — *"This message was blocked by the agent's content moderation
  guardrail."* — followed by the judge's own reason. No answer is produced,
  no follow-up suggestions are offered, and the violation is recorded the
  same way.

`block` is also **fail-closed**: if the judge model itself cannot answer
(an outage, an invalid response), the turn stops rather than letting
unchecked content through. In `warn` mode a judge failure lets the message
through and logs the failure.

### In between: redact, rewrite, translate

Some guardrails can do something more useful than warning or refusing. Set
`options.strategy` and the guardrail takes that action instead:

| Kind | `strategy` | What happens |
| - | - | - |
| `pii` | `redact` | the personal data is masked before the model sees it (or before the user sees the answer) |
| `pii`, `moderation`, `prompt_injection`, `system_prompt_scrub` | `filter` | the offending message is dropped from the turn |
| `prompt_injection` | `rewrite` | the judge rewrites the message to neutralise the attack while keeping what the user actually asked |
| `language` | `translate` | the message is translated into the first target language |
| `language` | `detect` | the language is recorded on the message, nothing else |
| `system_prompt_scrub` | `redact` | the quoted instructions are replaced in the answer |

With a strategy set, `mode` no longer picks the action — it only decides what
a judge failure does (`block` = stop the turn, `warn` = let it through) and
how the violation is recorded.

## Turning guardrails on

Guardrails live on the agent version, like tools and memory: edit the draft,
publish, activate.

```bash theme={null}
curl -X PATCH https://api.sidenet.ai/v1/agents/AGENT_ID/draft \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "guardrails": [
      { "kind": "prompt_injection", "mode": "block" },
      { "kind": "moderation", "mode": "block",
        "options": { "categories": ["hate", "harassment", "violence"], "threshold": 0.7 } },
      { "kind": "pii", "mode": "warn",
        "options": { "strategy": "redact", "detection_types": ["email", "phone", "credit-card"] } },
      { "kind": "unicode" }
    ]
  }'
```

One entry per kind. `enabled: false` keeps an entry but switches it off;
`"guardrails": null` removes them all. A bad entry — an unknown kind, an
option that belongs to another kind, a threshold outside 0–1 — is rejected
with a 400 so a typo never saves as a guardrail that silently does nothing.

In the Studio, guardrails are a section of the agent editor: a switch per
kind, a warn/block toggle, and the options below.

### Options

Every option is optional.

| Option | Kinds | Meaning |
| - | - | - |
| `threshold` | judge-backed | Confidence (0–1) above which the guardrail fires. Defaults: `pii` 0.6, `moderation` 0.5, `prompt_injection` and `language` 0.7. Raise it to fire less. |
| `model` | judge-backed | The judge model, as a `provider/model` slug. The default is a small, fast model — classification does not need the agent's own model. |
| `instructions` | judge-backed | Custom instructions for the judge, up to 4000 characters, replacing the built-in ones. |
| `strategy` | see above | An action other than warn or block. |
| `stage` | `pii`, `moderation` | `input` (the user's message, the default), `output` (the agent's answer) or `both`. |
| `detection_types` | `pii`, `prompt_injection` | Which categories to look for, e.g. `["email", "phone", "credit-card", "ssn"]` or `["injection", "jailbreak", "system-override"]`. |
| `redaction_method` | `pii`, `system_prompt_scrub` | `mask` (asterisks, the default), `placeholder`, `remove`; `pii` also takes `hash`. |
| `categories` | `moderation` | Which categories count, e.g. `["hate", "harassment", "violence"]`. |
| `target_languages` | `language` | Names or ISO codes, e.g. `["French", "fr"]`. Default English. |
| `min_text_length` | `language` | Messages shorter than this are not checked (short text detects badly). Default 10. |
| `custom_patterns` | `system_prompt_scrub` | Extra phrases (regular expressions) that count as instruction leakage. |
| `placeholder_text` | `system_prompt_scrub` | What replaces a redacted passage when `redaction_method` is `placeholder`. |
| `strip_control_chars`, `collapse_whitespace`, `preserve_emojis`, `trim` | `unicode` | Each on by default. |

Input guardrails check **only the message that just arrived**: earlier
messages were checked when they arrived, and a long thread would otherwise
cost one judge call per message per turn.

## Cost

The judge-backed guardrails bill the organization's dedicated **LLM
Judges** group — the same group that pays for [LLM scorers](/docs/experiments)
— never the customer group the conversation runs under. Their spend shows
up in that group's usage, tagged as guardrail spend, and counts against its
own monthly cap. See [Traces, cost and billing groups](/docs/observability).

The call is short (the message plus a one-line verdict) but it is made on
every turn and adds its latency before the answer starts, so prefer `warn`
with a sensible threshold over several guardrails in `block` mode, and keep
output-side checks for the agents that need them: an answer is checked
sentence by sentence as it streams, which is several judge calls per turn.

If the organization has no LLM Judges key, judge-backed guardrails are
**skipped** and the skip is reported as a warning on the agent's rebuild
report and in the server log. The agent still builds and answers. `unicode`
is unaffected.

## What gets recorded

Every time a guardrail fires, blocking or not, the violation is:

* **logged** on the server with the guardrail, the agent version, the thread
  and the trace, and
* **written on the turn's trace** as span metadata (`guardrailViolations`,
  with `guardrailBlocked` and `guardrailViolationCount`), so a trace can be
  found and read by what tripped it.

On the chat stream a blocked turn carries a `data-tripwire` part (which
guardrail fired, and the reason) followed by an `error` part with the sentence
the user sees. The Chat SDK shows the error; a custom client can read the
data part to render something richer.

<Note>
  Guardrails are checks on **messages**: what the user typed and what the agent
  answers. They do not inspect tool results, and they do not replace
  [approvals](/docs/approvals), which gate what the agent is allowed to *do*.
</Note>

## Where next

<CardGroup cols={2}>
  <Card title="Approvals" icon="hand" href="/docs/approvals">
    Pause before a tool writes, charges or sends.
  </Card>

  <Card title="Experiments and scorers" icon="flask" href="/docs/experiments">
    Grade answers after the fact with the same judge group.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.