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

# Redaction vault: a compliance-safe copy of every call transcript, with an audit of what was removed

> How the write-time redaction vault produces a redacted copy of your finalized call transcript — its artifact shape on the call record's metadata, the audit of removed categories, the webhook that signals it is ready, and how to scope it by category. Read this before you build a PHI/PCI-safe QA export.

# Redaction vault

Regulated tenants — healthcare, fintech, government — need to retain call transcripts for quality review without storing the PHI/PII values those transcripts contain. The **redaction vault** produces that copy: when a call's transcript finalizes, Orbit runs a deterministic pattern-matching engine over it, replaces regulated values with sentinel markers, and stores the result as a `redaction_vault` artifact on the call record, together with a typed audit of exactly what was removed. Read this page before you build a QA export that must not carry PHI/PCI.

## What the vault is

The vault is a **write-time compliance copy pipeline**. It runs after a call's transcript finalizes, as one of the post-finalize side channels on the [recording lifecycle](/concepts/recording-lifecycle). Two properties make it trustworthy for an audit:

* **Deterministic, not probabilistic.** The engine is fixed pattern matching — the same redaction primitive Orbit uses everywhere PII is stripped — not an LLM judgment. The same transcript always yields the same redacted copy, and every removed span is counted and typed.
* **Opt-in per tenant.** The vault runs only when you enable it under **Compliance → Recording redaction vault** in your organization settings (`settings.compliance.recording_redaction_vault.enabled`). A settings read failure fails closed: the vault stays disabled rather than risking an incomplete copy.

When the vault is off, nothing happens and the raw transcript is your only copy. When it is on, the redacted artifact appears on the call record shortly after the transcript finalizes.

## The artifact contract

The vault persists its result at `redaction_vault` on the call record's metadata:

```json theme={null}
{
  "status": "redacted",
  "redacted_at": "2026-03-08T12:12:00Z",
  "transcript_redacted": "Agent: May I have your card number? Caller: Yes, it's [CREDIT_CARD_REDACTED]. Agent: I'll also send a receipt to [EMAIL_REDACTED].",
  "audio_redaction_segments": [
    { "start_ms": 18400, "end_ms": 21250, "category": "credit_card" },
    { "start_ms": 31900, "end_ms": 34100, "category": "email" }
  ],
  "audit": {
    "total_redactions": 2,
    "by_category": [
      { "type": "credit_card", "count": 1 },
      { "type": "email", "count": 1 }
    ],
    "compliance_topics": ["pci", "pii"],
    "policy_categories": null
  }
}
```

Field by field:

| Field                      | Meaning                                                                                                                                                                                                                                                      |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `status`                   | Always `"redacted"` on a completed artifact.                                                                                                                                                                                                                 |
| `redacted_at`              | ISO-8601 time the copy was sealed.                                                                                                                                                                                                                           |
| `transcript_redacted`      | The full transcript with every detected span replaced by a sentinel (for example `[CREDIT_CARD_REDACTED]`). Safe to export for QA.                                                                                                                           |
| `audio_redaction_segments` | Millisecond ranges in the recording audio where detected values are spoken — a playback or export pipeline mutes or beeps these ranges. Empty when word-level timings are unavailable on the call. Each entry is timings plus a category — never raw values. |
| `audit.total_redactions`   | Count of spans replaced across all categories.                                                                                                                                                                                                               |
| `audit.by_category`        | Per-category counts, only categories with at least one match. Category vocabulary: `credit_card`, `ssn`, `email`, `e164_phone`, `us_phone`, `ipv4`, `ipv6`.                                                                                                  |
| `audit.compliance_topics`  | The regulatory surface hit: `pci` when cardholder data matched, `pii` for identifier patterns. Ordered PCI first.                                                                                                                                            |
| `audit.policy_categories`  | The category list you configured (see below), or `null` when the vault redacted every category. The audit names its own scope.                                                                                                                               |

Two deliberate design choices to rely on:

1. **The raw transcript is untouched.** The vault adds a copy; it never edits or replaces the original `transcript` on the call record. Deleting the raw values is a destructive retention-policy decision, and it belongs to the retention pipeline (`recording.retention_deleted` — see the [recording lifecycle](/concepts/recording-lifecycle)), not to an additive redaction step.
2. **The audit never carries what it removed.** Counts and categories are typed; the redacted values themselves never appear in the artifact, the logs, or the webhook payload. The raw transcript remains the only place the original values exist.

## Where it sits in the lifecycle

The vault fires after the recording and transcript finalize — it does not block any of them. It sits in the **post-finalize side channels** row of the [recording lifecycle](/concepts/recording-lifecycle) event table, alongside QC (`recording.qc_failed`), auto-chaptering (`recording.chapters.ready`), and the retention pre-notification (`recording.retention_deleted`). Like those, it never changes the recording's lifecycle state; it reacts to the finished artifact. The capture path itself is the [call recording pipeline](/concepts/call-recording-pipeline).

## What to branch on

Subscribe to `recording.redaction_vault.ready` to know when a call's redacted copy exists:

```json theme={null}
{
  "type": "recording.redaction_vault.ready",
  "data": {
    "call_id": "call_abc123",
    "total_redactions": 12,
    "by_category": [
      { "type": "credit_card", "count": 4 },
      { "type": "email", "count": 8 }
    ],
    "compliance_topics": ["pci", "pii"],
    "policy_categories": ["email", "phone"],
    "audio_redaction_segments": [
      { "start_ms": 18400, "end_ms": 21250, "category": "credit_card" }
    ],
    "timestamp": "2026-03-08T12:12:00Z"
  }
}
```

Integration rules:

* **`call_id`** is the join key — read the artifact off the call record's `redaction_vault` metadata after this event arrives.
* **`total_redactions` and `by_category`** are counts and categories only; treat a nonzero total as "a sanitized copy exists," never as a list of values.
* **`audio_redaction_segments`** is the muting map for playback exports: mute or beep each listed millisecond range before the audio leaves your control. An empty list means no timing data was available — the redacted transcript still stands, but the raw audio needs your own handling.
* **`compliance_topics`** tells you which regulatory surface the audit touched; route recordings tagged `pci` to your cardholder-data process and `pii` to your general identifier process.

The full payload contract is in the [webhook events reference](/reference/webhook-events).

## Scoping by category

Enable the vault and it redacts every category by default. You can narrow it — a healthcare reviewer might bleep SSNs and emails while keeping phone numbers from the sanitized copy, for example — by setting a category list under the same vault settings:

| Category key  | Covers                     |
| ------------- | -------------------------- |
| `credit_card` | Cardholder data (PCI)      |
| `ssn`         | US social security numbers |
| `email`       | Email addresses            |
| `phone`       | E.164 and US phone numbers |
| `ip_address`  | IPv4 and IPv6 addresses    |

Unknown entries are dropped, and a policy that resolves to nothing valid falls back to redacting everything — a malformed stored policy can never leave regulated values in the compliance copy. The artifact's `audit.policy_categories` records the exact scope each copy was produced under.

## Tenant posture, stated precisely

The vault is a **tenant-owned control, not a compliance guarantee**. Enabling it gives you a deterministic, auditable sanitized copy of each call transcript; it does not by itself satisfy HIPAA, PCI-DSS, GDPR, or any other framework — what those frameworks require of your organization is your determination, and Orbit does not make it for you. Decide which categories to redact, when to export the redacted copy, and whether and when the raw transcript and audio are purged (retention). Orbit provides the control; the posture is yours.

One distinction matters when you design the posture: the redaction vault is **persisted-copy** redaction — it seals a sanitized transcript on the call record at write time. It is separate from the **LLM-prompt redaction gate** (`settings.privacy.pii_redaction_in_llm`), which strips PII only from text sent into AI processing. The two are independent gates: one protects what the platform stores for you, the other protects what flows to a model. A HIPAA or PCI posture usually wants both, and neither implies the other.

## Common pitfalls

1. **Exporting the raw transcript for QA.** The redacted copy exists precisely so reviewers never need the raw one. Point QA exports at `redaction_vault.transcript_redacted`, and keep raw-transcript access behind your own role gate.
2. **Treating the vault as deletion.** The artifact is additive — the raw transcript survives until your retention policy purges it. If your posture requires the raw copy to disappear, schedule that through retention, not through this vault.
3. **Playing back raw audio to reviewers.** The audio segment list is the deterministic half of audio masking: mute or beep the listed ranges on the playback surface before reviewers hear it. Until you do, the redacted transcript and the playable audio tell two different stories.
4. **Assuming the event without enabling the control.** `recording.redaction_vault.ready` fires only when the vault is opted in. If you subscribed but never enabled the setting, no artifacts and no events appear — check the compliance settings first.
5. **Enabling the vault and expecting historical calls to copy.** The vault runs at write time, when a transcript finalizes. It seals copies for calls recorded after you enable it; it does not retroactively process your archive.

With the artifact contract clear, the per-event payload fields live in the [webhook events reference](/reference/webhook-events), and the lifecycle slot the event occupies is on the [recording lifecycle](/concepts/recording-lifecycle) page.
