---
title: "Upsert privacy config for organization"
method: PUT
path: "/v1/privacy/config"
tags: ["privacy"]
---

# Upsert privacy config for organization

`PUT /v1/privacy/config`

## Request body

- PrivacyConfigUpsert — Body for ``PUT /privacy/config`` — a full config representation. Idempotent full replacement: ``audio_retention_policy`` is required for this breaking contract; other omitted fields take their defaults rather than preserving prior values (PUT semantics, not PATCH).
  - `pii_scrubbing_enabled` boolean
  - `scrub_types` string[] — PIIType enum values to scrub
  - `custom_deny_patterns` CustomDenyPattern[]
    - `name` string, required
    - `regex` string, required
    - `replacement_label` string, required
    - `description` string, nullable
    - `score` number — Presidio confidence reported for matches of this pattern. Must be >= the org's score_threshold, otherwise Presidio silently drops every match and the pattern appears broken.
  - `custom_allow_patterns` CustomAllowPattern[]
    - `name` string, required
    - `regex` string, required
    - `description` string, nullable
  - `score_threshold` number — Presidio confidence threshold
  - `audio_retention_policy` 'no_audio' | 'raw' | 'redacted', required
  - `audio_redaction_fill` 'silence' | 'tone_1khz'
  - `supported_languages` string[] — ISO-639-1 codes the org wants to scrub (subset of {en,es,fr,de,pt})
  - `default_language` string — Fallback language when detection is off or fails
  - `language_detection_enabled` boolean — Detect language per scrub call; when false default_language is always used

## Response `200`

Successful Response

- PrivacyConfigResponse
  - `id` string, uuid, required
  - `organization_id` string, uuid, required
  - `pii_scrubbing_enabled` boolean, required
  - `scrub_types` string[], required
  - `custom_deny_patterns` CustomDenyPattern[], required
    - `name` string, required
    - `regex` string, required
    - `replacement_label` string, required
    - `description` string, nullable
    - `score` number — Presidio confidence reported for matches of this pattern. Must be >= the org's score_threshold, otherwise Presidio silently drops every match and the pattern appears broken.
  - `custom_allow_patterns` CustomAllowPattern[], required
    - `name` string, required
    - `regex` string, required
    - `description` string, nullable
  - `score_threshold` number, required
  - `audio_retention_policy` 'no_audio' | 'raw' | 'redacted', required
  - `audio_redaction_fill` 'silence' | 'tone_1khz', required
  - `supported_languages` string[], required
  - `default_language` string, required
  - `language_detection_enabled` boolean, required
  - `created_at` string, date-time, required
  - `updated_at` string, date-time, required

## Other responses

- `400` — Bad request
- `401` — Authentication required
- `422` — Validation Error

---

[API](https://skmtc.net/oneloop-hq/apis/feather-api.md) · [All operations](https://skmtc.net/oneloop-hq/apis/feather-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/oneloop-hq/feather-api/revisions/9cd7291d4228/schema)
