> ## 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](/docs/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 for every request in a workspace instead of adding `security.mask` to each call.

## 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>

At least one `mask` value is required. The [What each value masks](/docs/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](/docs/ai-gateway/features/plugins/pii-redaction#workspace-level-redaction) behaves.

## Apply per routing rule

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

## Combine with security.mask

A request that carries `security.mask` has those values merged with the plugin's before the trace is written, so the two compose rather than override. The plugin is the way to mask traffic that omits `security.mask`, because only the plugin can be set for a whole workspace. See [Coverage](/docs/ai-gateway/features/security#coverage).

## 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](/docs/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](/docs/ai-studio/observability/trace-evaluations#trace-scrubbing-and-evaluator-data).
* It does not redact PII before the provider sees it. Use [PII Redaction](/docs/ai-gateway/features/plugins/pii-redaction) for that.

## Supported endpoints

The `plugins` entry is accepted on the same endpoints as the other plugins; see [Supported endpoints](/docs/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 any request the **AI Gateway** traces, including deployment invokes and traffic matched by a routing rule.
