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

# Trace Scrubbing

> Mask selected fields in stored traces using the trace_scrubbing plugin in the AI Gateway.

The `trace_scrubbing` **plugin** selects what the **AI Gateway** writes to stored traces. It changes only the stored copy, never the live request, the response, or the payload the provider receives. See [Trace Data Masking](/ai-gateway/features/security) for the per-request `security` field, which feeds the same masking.

## Use cases

* Keeping prompt content, model output, or template variables out of trace storage without changing what the model receives.
* Retaining latency, token, and cost data on a trace while removing the text that produced it.
* Enforcing one masking policy across a workspace instead of adding `security.mask` to each call, on the routes listed under [Supported endpoints](#supported-endpoints).

## Comparison to Trace Data Masking

**Trace Scrubbing** (this page) and [Trace Data Masking](/ai-gateway/features/security) both decide what the **AI Gateway** writes to a stored trace. They mask the same fields with the same code, so what differs is not what gets masked but where the mask is set and who can change it.

**What is the same**

* Both accept `input`, `output`, `system`, `metadata`, `variables`, or `all`.
* Both blank or remove those fields from the stored trace only. The live request, the response, the payload the provider receives, and the data [**Guardrails**](/ai-gateway/configuration/guardrail-rules) and [**Evaluators**](/ai-studio/optimize/evaluators) check are untouched.
* A request that sends both is merged: the masks add up, and neither side removes a mask the other set.

**What differs**

| | `security.mask` on a request | `trace_scrubbing` plugin |
| - | - | - |
| Where it is set | In the request's `security` block | In the request's `plugins` array, on a [routing rule](/ai-gateway/configuration/routing-rules#plugins), on an [MCP gateway](/ai-gateway/mcp-portal/mcp-gateways), or for the whole workspace under [**Settings** > **Plugins**](#enable-for-a-workspace) |
| Applies without the caller sending it | No. A request that omits the field is traced in full unless the workspace, a rule, or a gateway adds masks | Yes for the workspace, routing-rule, and MCP-gateway placements; a request-scoped `plugins` entry still needs the caller |
| Can a request loosen it | Not applicable: the caller sets it, so it can change or drop it per request | No. A request can add masks but cannot remove one set by the workspace, a rule, or a gateway |
| Endpoints it reaches | Every endpoint where it is applied, including `deployments/invoke`. [/classify](/ai-gateway/features/classify) ignores it, and `images/edits` and `moderations` accept it without applying it | The same endpoints, plus `/classify` and deployment invokes when set on the workspace or a routing rule, and the tool-call traces an MCP gateway stores; `images/edits`, `moderations`, and the `/responses` WebSocket and `/responses/compact` routes traces stay unmasked; see [Coverage](/ai-gateway/features/security#coverage) |
| Empty selection | Allowed, and masks nothing | A request entry with no `mask` values is accepted and masks nothing; a routing-rule or MCP-gateway placement rejects one. A workspace toggle with no values selected masks everything |

**Which to use**: `security.mask` suits a caller protecting its own traffic, at the cost of sending the field on every request. `trace_scrubbing` suits a policy that must hold for everyone, because an admin sets it once for the workspace, a rule, or a gateway and no caller can opt out.

## Quick start

Add a `trace_scrubbing` entry to the `plugins` array with at least one `mask` value.

<CodeGroup>
  ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
  curl -X POST https://my.orq.ai/v3/router/chat/completions \
    -H "Authorization: Bearer $ORQ_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "openai/gpt-5.4-mini",
      "messages": [{ "role": "user", "content": "Summarize the open ticket." }],
      "plugins": [{ "id": "trace_scrubbing", "mask": ["input", "output"] }]
    }'
  ```

  ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  import OpenAI from 'openai';

  const client = new OpenAI({
    apiKey: process.env.ORQ_API_KEY,
    baseURL: 'https://my.orq.ai/v3/router',
  });

  const response = await client.chat.completions.create({
    model: 'openai/gpt-5.4-mini',
    messages: [{ role: 'user', content: 'Summarize the open ticket.' }],
    // @ts-ignore - orq.ai extension
    plugins: [{ id: 'trace_scrubbing', mask: ['input', 'output'] }],
  });
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
  from openai import OpenAI
  import os

  client = OpenAI(
      api_key=os.environ.get("ORQ_API_KEY"),
      base_url="https://my.orq.ai/v3/router",
  )

  response = client.chat.completions.create(
      model="openai/gpt-5.4-mini",
      messages=[{"role": "user", "content": "Summarize the open ticket."}],
      extra_body={"plugins": [{"id": "trace_scrubbing", "mask": ["input", "output"]}]},
  )
  ```
</CodeGroup>

Give the entry at least one `mask` value: a routing-rule or MCP-gateway placement rejects an entry with none. A request-scoped entry with no values is accepted by the runtime and masks nothing. The [What each value masks](/ai-gateway/features/security#what-each-value-masks) table lists the accepted values and what each one removes from a stored trace.

## Enable for a workspace

Turn on **Trace Scrubbing** under **Settings** > **Plugins** to apply a mask to every request, without passing a `plugins` array on each call. Once the toggle is on, a <Icon icon="sliders" /> icon appears next to it; click it to choose the surfaces to mask. Enabling the plugin without choosing any masks everything.

<Frame caption="The Trace Scrubbing configuration panel, with every trace surface selected.">
  <img src="https://mintcdn.com/orqai/XVjQcyKNye_91OkM/images/trace-scrubbing-configuration.png?fit=max&auto=format&n=XVjQcyKNye_91OkM&q=85&s=9f589c195ab146752673d68e405391e8" alt="Trace Scrubbing configuration panel listing All trace content, System, Input, Output, Metadata, and Variables, each with a description and a selected checkbox." width="822" height="586" data-path="images/trace-scrubbing-configuration.png" />
</Frame>

The workspace setting is a floor, not a default. The masks a request sends are added to the workspace's masks, and `all` wins over any narrower selection, so a request can mask more but never less. This matches how workspace-level [PII redaction](/ai-gateway/features/plugins/pii-redaction#workspace-level-redaction) behaves.

## Apply per routing rule

Attach **Trace Scrubbing** to a [routing rule](/ai-gateway/configuration/routing-rules#plugins) to mask traffic that matches the rule, with the fields chosen on the rule. An [MCP gateway](/ai-gateway/mcp-portal/mcp-gateways) takes the same plugin for the tool-call traces it stores.

## What it does not do

* It does not remove anything from the live request or response, or from the payload the provider receives.
* It does not change the data an [Evaluator](/ai-studio/optimize/evaluators) or Guardrail processes: the check still receives the original runtime input, output, instructions, and variables, and only the persisted span is scrubbed. See [Trace scrubbing and evaluator data](/ai-studio/observability/trace-evaluations#trace-scrubbing-and-evaluator-data).
* It does not redact PII before the provider sees it. Use [PII Redaction](/ai-gateway/features/plugins/pii-redaction) for that.

<Note>
  Scrubbing removes the masked values from the stored trace rather than hiding them from view, so the request cannot be debugged from those fields afterwards. Where diagnosis matters, keep an unsanitised copy elsewhere or narrow the mask to the fields that must not be stored.
</Note>

## Supported endpoints

The `plugins` entry is accepted on the same endpoints as the other plugins; see [Supported endpoints](/ai-gateway/features/plugins/overview#supported-endpoints). The workspace setting and a routing-rule attachment reach further: their mask is written to the stored trace of a request whose handler records masking options, including deployment invokes and [/classify](/ai-gateway/features/classify), plus the tool-call traces an [MCP gateway](/ai-gateway/mcp-portal/mcp-gateways) stores. A route that records none is never scrubbed, whatever the placement: `images/edits`, `moderations`, and the `/responses` WebSocket and `/responses/compact` routes.


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