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

# Trace: compliance guardrails

> Score every agent call against compliance rule packs, get a tamper-evident scorecard per call, and read your org's exposure, with one config PUT and four read endpoints.

**Trace** is the compliance and guardrails layer for your voice agents. Every
scanned call gets a deterministic **scorecard**: which rules fired, which
requirements were satisfied, what was redacted, and a verdict (`PASS`, `WARN`,
`FAIL`), with plain-English reasons and cited regulations, sealed with a
tamper-evident `audit_hash`. A second, asynchronous layer adds **semantic
findings** (model-judged concerns deterministic rules can't catch, like
indirect opt-outs or hallucination-vs-knowledge-base); those are advisory and
never block.

<Note>
  Trace is in **beta** and **free during beta** (metered, billed \$0). It
  defaults to **on, in `warn` mode**, for every org, so calls are already being
  scored, this guide is about configuring it deliberately and reading the
  results. Findings are informational and not legal advice.
</Note>

You need a key with `trace:configure` (to manage config and rule packs) and
`trace:read` (to read results). Add scopes in the
[console](https://console.pyai.com).

## Step 1, configure Trace

One `PUT` sets the org-wide default; add `?agent_id=` (or wrap the body as
`{ "agent_id", "config" }`) to override per agent:

```bash theme={null}
curl -X PUT https://api.pyai.com/v1/trace/config \
  -H "Authorization: Bearer $PYAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "enabled": true,
    "rule_packs": {
      "tcpa": { "enabled": true },
      "pii":  { "enabled": true }
    },
    "guardrails": {
      "mode": "warn",
      "block_pii": { "patterns": ["ssn", "credit_card"] },
      "mandatory_disclosures": [
        { "text": "This call may be recorded.", "trigger": "call_start" }
      ]
    }
  }'
```

The response is the stored config with a content-addressed `ETag`, the runtime
pins it, so a config change takes effect on the next pull. `GET
/v1/trace/config` reads it back (omit `agent_id` for the org default).

### Pick a mode

| Mode            | Behavior                                                |
| --------------- | ------------------------------------------------------- |
| `warn`          | Log and score only. Never touches the call. Start here. |
| `modify`        | Redact PII and inject missing disclosures inline.       |
| `block`         | Suppress non-compliant output.                          |
| `human_handoff` | Escalate the call to a human.                           |

Every mode is **fail-open**: if anything in the pipeline errors, the call
continues and the gap is recorded, compliance tooling never takes your agents
down.

## Step 2, know your rule packs

Built-in packs cover **TCPA**, **HIPAA**, **PII**, and **brand voice**. List
what's available (built-ins plus your tenant's custom packs):

```bash theme={null}
curl https://api.pyai.com/v1/trace/rule-packs \
  -H "Authorization: Bearer $PYAI_API_KEY"
```

Pin a specific version in config with `"tcpa": { "enabled": true, "version":
"v3" }`, or omit `version` to track the latest active. You can also upload your
own pack in the Trace DSL (`POST /v1/trace/rule-packs` with `pack_id`,
`version`, and `rules[]`); custom packs are scoped to your org and can never
shadow a built-in.

## Step 3, read the results

All four reads are cursor-paginated and newest-first.

**Exposure summary**, the dashboard headline: interactions scanned, the share
with a compliance gap, per-rule exposure ranking, and the verdict mix over a
trailing window:

```bash theme={null}
curl "https://api.pyai.com/v1/trace/exposure?window_days=30" \
  -H "Authorization: Bearer $PYAI_API_KEY"
```

**Interactions**, one scorecard row per call. Filter by `verdict`
(`PASS`/`WARN`/`FAIL`) or `agent_id`:

```bash theme={null}
curl "https://api.pyai.com/v1/trace/interactions?verdict=FAIL&limit=20" \
  -H "Authorization: Bearer $PYAI_API_KEY"
```

**Interaction detail**, the full evidence view for one `call_id`: findings with
reasons and cited regulations, satisfied requirements, redactions, gate health,
the verdict, and the tamper-evident `audit_hash`:

```bash theme={null}
curl "https://api.pyai.com/v1/trace/interactions/<call_id>" \
  -H "Authorization: Bearer $PYAI_API_KEY"
```

**Violations**, every fired rule across scorecards, for drill-down. Filter by
`rule_id`, `severity` (`low`/`medium`/`high`/`critical`), or `interaction_id`:

```bash theme={null}
curl "https://api.pyai.com/v1/trace/violations?severity=critical" \
  -H "Authorization: Bearer $PYAI_API_KEY"
```

**Findings**, the async semantic layer (advisory, kept separate from the
hash-chained violations). Filter by `check_id`, `action`, or `severity`; the
compliance-officer alerts feed is `action=escalate` and/or
`severity=critical`:

```bash theme={null}
curl "https://api.pyai.com/v1/trace/findings?action=escalate" \
  -H "Authorization: Bearer $PYAI_API_KEY"
```

## The console view

The **Compliance / Trace** tab in the [console](https://console.pyai.com)
renders the same data, Overview (exposure), Interactions (scorecards), and
Alerts (escalated findings), no code required.

## Metering

Trace meters `trace.minutes`, the scanned audio minutes of calls where Trace is
enabled, on top of the underlying product's own rate. During the beta it bills
at \$0. See [pricing & metering](/pricing-and-metering).

## Next steps

<CardGroup cols={2}>
  <Card title="Trace API reference" href="/api-reference">Full request/response schemas for every `/v1/trace/*` endpoint.</Card>
  <Card title="Post-call extraction" href="/guides/post-call-extraction">Pull structured data out of completed calls.</Card>
  <Card title="Conversation intelligence" href="/guides/conversation-intelligence">Recap: summaries and CRM sync for your calls.</Card>
  <Card title="Errors & limits" href="/errors-and-limits">Error codes, pagination, and idempotency conventions.</Card>
</CardGroup>
