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

# RTB audience safety gate: COPPA compliance checks

> Enforces COPPA compliance by detecting child-directed inventory signals and blocking bids whose creative categories fall into an unsafe content type list.

The audience safety gate detects child-directed inventory in the bid request and then checks every bid in the response for creative categories that are inappropriate for that audience. This protects you from COPPA violations and brand safety incidents that arise when adult-oriented or regulated-content creatives reach under-13 inventory.

## Usage

```typescript theme={null}
import { createEngine, gates } from "@pecta/core";

const engine = createEngine({
  gates: [
    gates.rtb.tmaxGuard({ bufferMs: 15 }),
    gates.rtb.audienceSafety(),
    // ...
  ],
  timeout: 15,
});
```

## How child-directed inventory is detected

The gate inspects the request (`ctx.input`) for any of the following signals:

* `regs.coppa === 1` — the request explicitly declares COPPA applicability
* `app.cat` contains `IAB13` — the app's content category is children's content
* `site.cat` contains `IAB13` — the site's content category is children's content
* `app.bundle` contains any of the keywords: `kids`, `child`, `children`, `toddler`, `preschool`, `baby`

If none of these signals are present, the gate returns `skipped: true` immediately. No bids are inspected and the remaining pipeline continues normally.

## Unsafe categories

When inventory is flagged as child-directed, the gate checks every `bid.cat[]` entry against the following default unsafe categories:

| IAB category                | Content type                  |
| --------------------------- | ----------------------------- |
| `IAB7-39`                   | Substance abuse               |
| `IAB8-5`                    | Beer                          |
| `IAB8-18`                   | Wine                          |
| `IAB14-1`                   | Dating                        |
| `IAB25`                     | Non-standard content          |
| `IAB25-1` through `IAB25-7` | Non-standard content subtypes |
| `IAB26`                     | Illegal content               |
| `IAB26-1` through `IAB26-4` | Illegal content subtypes      |

If any bid carries one of these categories, the gate fails with the offending category name:

```json theme={null}
{
  "name": "rtb.audience-safety",
  "passed": false,
  "reason": "child-directed inventory served unsafe category: IAB8-5",
  "latency_ms": 1
}
```

## Options

<ParamField path="unsafeCategories" type="string[]">
  Replace the default unsafe category set entirely. When provided, only the categories you list are considered unsafe. Pass an empty array to effectively disable the category check while keeping the COPPA detection logic.
</ParamField>

<ParamField path="extraKidBundleHints" type="string[]">
  Additional substrings to match against `app.bundle` when detecting child-directed inventory. Matched case-insensitively. For example, `["junior", "playground"]` would flag bundles like `com.example.junior-app`.
</ParamField>

<ParamField path="name" type="string" default="rtb.audience-safety">
  Override the gate's name in evaluation results and telemetry.
</ParamField>

## Example: COPPA request with unsafe bid

```json theme={null}
{
  "regs": { "coppa": 1 },
  "imp": [{ "id": "imp-001", "bidfloor": 0.20 }]
}
```

A bid response carrying a beer creative category:

```json theme={null}
{
  "seatbid": [
    {
      "bid": [
        {
          "id": "bid-1",
          "impid": "imp-001",
          "price": 0.30,
          "cat": ["IAB8-5"]
        }
      ]
    }
  ]
}
```

The gate detects `regs.coppa = 1`, finds `IAB8-5` in the bid's `cat` array, and fails.

<Warning>
  If you override `unsafeCategories` with your own list, the defaults are completely replaced. Make sure your list covers all content types that are inappropriate for minors under your applicable regulations.
</Warning>

<Tip>
  Use `extraKidBundleHints` to catch proprietary app naming conventions that the default keyword list does not cover. Bundle matching is substring-based, so `"jr"` would match both `com.kids.jr.app` and `com.junior.games`.
</Tip>
