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

# Redact PII and PCI from a call recording, segment by segment

> Mute the seconds where a caller reads a card number and blur the frame where a screen or face shows sensitive data — build a visual-redaction region batch, post it to the recordings API, verify playback, and remove regions you no longer need.

# Redact PII and PCI from a call recording, segment by segment

A caller reads sixteen digits into your IVR. A patient names a prescription on a telehealth video visit. A participant holds an ID card to the webcam during a screen share. The recording is correct evidence of the call, but no one should ever hear or see those seconds again. The recordings API's visual-redaction surface lets you mark exactly those segments — an audio mute window here, a blurred rectangle of the video frame there — without touching the stored source artifact. This guide walks the full loop: pick the recording, define the regions, post them, verify playback, and clean up.

The full request and response shapes for every call on this page are in the [recordings API reference](/api-reference/endpoints/recordings); this guide covers the workflow between the calls.

## What redaction erases and what it preserves

A visual-redaction region is a time window plus, for video, a rectangle of the frame. On every playback surface — the dashboard player, shared links, and exports — the player renders the region over the original media: audio inside the window plays back muted, and the boxed area of the video frame renders blurred (or pixelated, mosaiced, or blacked out, per the region's `effect`).

What it preserves:

* **The source recording is immutable.** Redaction never rewrites, trims, or re-encodes the stored artifact. The regions are a separate instruction layer the player applies at render time, which is also what makes redaction safe to run on recordings under legal hold (see [Prerequisites](#prerequisites)).
* **Everything outside your regions.** A 27-second mute leaves the rest of the call fully audible; a blur box over a credit-card frame leaves the rest of the frame sharp.
* **The transcript, QC verdicts, clips, highlights, and integrity seals.** Regions live alongside those controls on the recording and do not re-run or invalidate them.

What it erases, from the viewer's perspective: the spoken content inside an audio window and the pixels inside a video box, on every surface that honors the region list. Treat the region list as the single source of truth for what a reviewer may see — anything exported before you post regions carries the un-redacted segment.

## Prerequisites

Before you start, confirm each of these:

* **A completed recording id.** Regions attach to recordings that have finished processing; a recording that is still finalizing returns `400 RECORDING_VISUAL_REDACTION_NOT_COMPLETED`. List your recordings and copy the `id` of the finished one, as in [Recording lifecycle operations](/guides/recording-lifecycle-operations).
* **Scopes.** Reads (`GET`) on this surface require `voice:read`; posting and deleting regions additionally require `voice:write`. Issue or pick an API key carrying both if you will run the whole loop.
* **Retention and legal hold.** A redaction region lives with the recording: when the retention window purges the artifact, its regions go with it, so a hold that exists to outlive your retention window also preserves whatever redaction state you left behind. A legal hold never blocks redaction and redaction never lifts a hold — the hold protects the immutable source, and your regions govern the renditions people actually watch. The hold semantics themselves, including what a hold defers and what it does not, are in [Recording integrity and legal hold troubleshooting](/troubleshooting/recording-integrity-and-legal-hold).
* **Consent and policy footing.** Which segments must be redacted, and for whom, is your policy call under your DPA/BAA and consent posture — see [DPA, BAA, and recording consent](/guides/compliance-dpa-baa-recording-consent). The API enforces the mechanics; it does not decide what is sensitive.

## Identify the recording and the regions to redact

Play the recording once end to end and note every sensitive moment as a start and end time in milliseconds from the start of the recording. There are two region shapes, and a single segment that is both (a caller reading a card number while their face is on camera) takes one entry per concern.

### Audio mute segments

An audio redaction is a pure time window: `start_ms` to `end_ms`, no rectangle. Use it for anything spoken — card numbers, dates of birth, diagnoses, passwords read aloud. Pad the window a half-second on each side; speakers trail off and the sensitive phrase rarely starts exactly on the beat you noted. Windows shorter than 100 ms are rejected as below a single frame of audio-visual content, and `end_ms` must be greater than `start_ms` and within the recording's duration.

### Screen and face region masks

A video region adds a `bbox`: `{ x, y, w, h }` as fractions of the frame, from the top-left corner, so `0.5` means halfway across (or down) whatever resolution the player renders. The box applies only inside its time window — a moving face is a short track of consecutive boxes, a static badge on screen is one box for the whole span it is visible. Pick an `effect` per region: `blur` (the default, right for faces and documents), `pixelate`, `mosaic`, or `box` (a solid black rectangle, right when the area carries no information anyone needs). Set `source` to describe how the region was found — `manual` for an operator watching playback, `face_detection` or `on_camera_pii` when a detector produced the track — and put the operator reason in `label` (200 characters max), for example `card number visible on checkout screen`.

Coordinates are clamped into the frame and rounded to six decimals on save, so pixel-perfect boxes are not required; err toward a slightly larger box. The exact accepted shape is documented under [List visual-redactions](/api-reference/endpoints/recordings#list-visual-redactions) and [Create visual-redactions](/api-reference/endpoints/recordings#create-visual-redactions) in the API reference.

## Post a redaction batch

`POST /api/v1/recordings/{id}/visual-redactions` accepts one to two hundred regions per call, and a recording holds up to five hundred regions in total. A batch is additive: posting a second region never disturbs the first, and each region comes back with its own `id` for later deletion.

Two properties make the call safe to script into a compliance pipeline:

* **Non-destructive by construction.** The batch writes only the region list on the recording; the held, sealed source artifact is the source of truth and is never mutated. Think of the regions as producing the redacted rendition at render time, not as editing the original.
* **Idempotency-friendly.** Pass an `Idempotency-Key` header when you post from an automated pipeline so a retry after a timeout replays the original response instead of doubling regions.

A `422`/`400` response names the offending field in `error.details.issues` — the usual causes are a window past the end of the recording, `end_ms` before `start_ms`, or a zero-area box.

## Worked example: a customer reads a card number on a support call

A support call ran six minutes. At 02:14 the customer starts reading their card number and finishes at 02:41; at 05:02 a checkout screen with the card on it is on camera for six seconds. That is two regions in one batch: an audio mute at 134000–161000 ms and a blur box at 302000–308000 ms.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://api.orbit.devotel.io/api/v1/recordings/rec_4d7a9c2e8b1f4a6d9e3c5b7a1f2d8e40/visual-redactions" \
    -H "X-API-Key: dv_live_sk_your_key_here" \
    -H "Content-Type: application/json" \
    -H "Idempotency-Key: redaction-batch-2026-10-12-001" \
    -d '{
      "regions": [
        {
          "start_ms": 134000,
          "end_ms": 161000,
          "bbox": { "x": 0, "y": 0, "w": 1, "h": 1 },
          "effect": "box",
          "source": "manual",
          "label": "Customer reads card number aloud"
        },
        {
          "start_ms": 302000,
          "end_ms": 308000,
          "bbox": { "x": 0.31, "y": 0.42, "w": 0.38, "h": 0.22 },
          "effect": "blur",
          "source": "manual",
          "label": "Card number visible on checkout screen"
        }
      ]
    }'
  ```

  ```typescript Node.js theme={null}
  const res = await fetch(
    'https://api.orbit.devotel.io/api/v1/recordings/rec_4d7a9c2e8b1f4a6d9e3c5b7a1f2d8e40/visual-redactions',
    {
      method: 'POST',
      headers: {
        'X-API-Key': process.env.ORBIT_API_KEY!,
        'Content-Type': 'application/json',
        'Idempotency-Key': 'redaction-batch-2026-10-12-001',
      },
      body: JSON.stringify({
        regions: [
          {
            start_ms: 134000,
            end_ms: 161000,
            bbox: { x: 0, y: 0, w: 1, h: 1 },
            effect: 'box',
            source: 'manual',
            label: 'Customer reads card number aloud',
          },
          {
            start_ms: 302000,
            end_ms: 308000,
            bbox: { x: 0.31, y: 0.42, w: 0.38, h: 0.22 },
            effect: 'blur',
            source: 'manual',
            label: 'Card number visible on checkout screen',
          },
        ],
      }),
    },
  )
  const body = await res.json()
  console.log(body.data.regions.map((r: { id: string }) => r.id))
  ```
</CodeGroup>

The response returns each region with its assigned `id`, its clamped window, and the running `total` for the recording. Keep the `id`s: they are the handles you delete with later.

## Verify the redaction

Verify twice, mechanically and by eye:

1. **List the regions.** `GET /api/v1/recordings/{id}/visual-redactions` returns the regions newest first. Check the windows match what you posted and that `total` is what you expect.

```bash cURL theme={null}
curl -X GET "https://api.orbit.devotel.io/api/v1/recordings/rec_4d7a9c2e8b1f4a6d9e3c5b7a1f2d8e40/visual-redactions" \
  -H "X-API-Key: dv_live_sk_your_key_here"
```

2. **Play it back.** Scrub to 02:14 and confirm the audio is silent through 02:41, and to 05:02 and confirm the checkout frame renders blurred inside your box and sharp outside it. The list tells you the regions are stored; playback tells you they read the way you intended. If a segment is still audible, the usual cause is a window noted too tight — post a corrected region with a wider range rather than editing the old one.

## Remove a redaction region

`DELETE /api/v1/recordings/{id}/visual-redactions/{regionId}` removes one region and returns the `remaining` count. Deleting a region makes the segment audible and visible again on every surface, immediately, because playback renders from the current region list.

That reversibility is deliberate for operators and consequential for compliance: plan who holds `voice:write` accordingly. If your policy requires that a redacted segment stay redacted, removing regions is not a self-service action — gate the delete scope to your compliance role and treat a removal request as an escalation that needs sign-off, the same posture you apply to lifting a legal hold. There is no separate "un-redact and re-blur differently" ceremony: correcting a region is delete the old one, post the corrected one, and both steps land in your audit trail.

## Production checklist

* **Wire redaction into your retention window, not after it.** Regions purge with the recording. If a record must leave your tenant redacted-only, post regions before anyone exports or shares the recording, and confirm the region list before the retention pre-notification window closes.
* **Batch by review session, key by case.** One `Idempotency-Key` per compliance case or ticket keeps retries from duplicating regions when a pipeline re-runs.
* **Expect the limits.** 200 regions per POST, 500 per recording, windows of at least 100 ms, labels of 200 characters. A long face track should be a handful of keyframed boxes, not one box per frame.
* **Audit as you go.** Every batch posted and every region removed is written to your audit log with the acting user, the recording, and the affected regions — pull those entries into your evidence binder next to the consent and hold records from [DPA, BAA, and recording consent](/guides/compliance-dpa-baa-recording-consent).
* **Keep the source as your source of truth.** Because redaction is non-destructive, a regulator or auditor entitled to the un-redacted artifact can still be served the original under your hold policy, while everyone else sees the redacted rendition. Document who may request the original and under what authority before you need the answer.
* **Cross-check related surfaces.** Transcript copies of the same call carry the same card number in text; pair this workflow with transcript redaction ([recording lifecycle concept](/concepts/recording-lifecycle)) so the spoken segment and its transcription are treated as one piece of sensitive data.


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