## IP Detection

`generate.ip_detection(GenerateIPDetectionParams**kwargs)  -> GenerateIPDetectionResponse`

**post** `/generate/ip-detection`

Check prompts and/or existing assets against the team's enabled IP-detection filters, without generating anything. Advisory only: the call never blocks and nothing is stored. The payload is analyzed as ONE input set, so the answer is a single merged verdict — call the route once per item to know which item trips a filter. Videos are analyzed through their extracted frames; audio and 3d assets are returned in `skippedAssetIds` and are never checked. Available on the Enterprise plan only; a team with no enabled filter gets `evaluatedFilters: 0` and is charged nothing. Billed on the provider tokens the check sends — the prompt plus every analyzed image, once per enabled filter — with a 1 CU minimum, reported under `ipDetection.creativeUnitsCharged` and surfaced in `GET /v1/usages` as `ip-detection`.

### Parameters

- `dry_run: Optional[Literal["true", "api"]]`

  Estimate the operation instead of running it: the call returns a 269 response carrying the creative units cost. `api` estimates at the API tier.

  - `"true"`

  - `"api"`

- `project_id: Optional[str]`

  The projectId used for ownership resource management. Either to assert ownership or to set the owner of the resource(s)

- `asset_ids: Optional[Sequence[str]]`

  Asset ids to check. Videos are analyzed through their extracted first/last
  frames; audio and 3d assets are not analyzed and come back in
  `skippedAssetIds`.

- `prompts: Optional[Sequence[str]]`

  Prompts to check, analyzed as one text of 250 000 characters in total at
  most — as much as the longest prompt any model accepts. At least one prompt
  or one analyzable asset id is required.

### Returns

- `class GenerateIPDetectionResponse: …`

  Response of POST /generate/ip-detection.

  - `ip_detection: IPDetection`

    Merged verdict for the whole input set. `action` is always `allowed` or
    `flagged` — this route is advisory and blocks nothing — while
    `creativeUnitsCharged` and `analyzedImagesCount` report what was billed and
    what was actually analyzed.

    - `action: Literal["allowed", "blocked", "flagged"]`

      Whether and how detection affected the request.

      - `"allowed"`

      - `"blocked"`

      - `"flagged"`

    - `analyzed_images_count: float`

      Number of images the detectors actually analyzed — a video counts as each
      of its extracted frames, and an image that could not be read is excluded
      (and not billed). Each of them is priced once per enabled filter.

    - `creative_units_charged: float`

      IP-detection CU fee, separate from creativeUnitsCost: it follows the
      provider tokens the run sends — the prompt plus every analyzed image, once
      per enabled filter — with a 1 CU minimum per run.

    - `evaluated_filters: float`

      Number of enabled filters evaluated for this request.

    - `findings: List[IPDetectionFinding]`

      Per-filter verdicts gathered for this request.

      - `category: Literal["artist-style", "brand-trademark", "celebrity-likeness", 2 more]`

        Category of the filter that produced this verdict.

        - `"artist-style"`

        - `"brand-trademark"`

        - `"celebrity-likeness"`

        - `"custom"`

        - `"fictional-character"`

      - `confidence: float`

        Confidence score from 0 (low) to 1 (high).

      - `filter_id: str`

        Identifier of the filter that produced this verdict.

      - `filter_name: str`

        Display name of the filter that produced this verdict.

      - `flagged: bool`

        Whether this filter considered the request an IP risk.

      - `reason: str`

        Short, user-facing explanation of the verdict.

      - `entities: Optional[List[str]]`

        Named entities the filter recognized (e.g. characters, brands, people).

    - `flagged: bool`

      Whether a filter considered the inputs an IP risk. Independent of `action`:
      a request blocked because a detector errored is `blocked` and NOT flagged.

    - `has_detector_error: Optional[bool]`

      True if one or more detectors errored while evaluating this request.

  - `skipped_asset_ids: List[str]`

    Input asset ids excluded from image analysis — audio and 3d assets, or a
    video with no extractable frame. Their content was NOT checked.

### Example

```python
import os
from scenario_sdk import Scenario

client = Scenario(
    api_key=os.environ.get("SCENARIO_SDK_API_KEY"),  # This is the default and can be omitted
    api_secret=os.environ.get("SCENARIO_SDK_API_SECRET"),  # This is the default and can be omitted
)
response = client.generate.ip_detection()
print(response.ip_detection)
```

#### Response

```json
{
  "ipDetection": {
    "action": "allowed",
    "analyzedImagesCount": 0,
    "creativeUnitsCharged": 0,
    "evaluatedFilters": 0,
    "findings": [
      {
        "category": "artist-style",
        "confidence": 0,
        "filterId": "filterId",
        "filterName": "filterName",
        "flagged": true,
        "reason": "reason",
        "entities": [
          "string"
        ]
      }
    ],
    "flagged": true,
    "hasDetectorError": true
  },
  "skippedAssetIds": [
    "string"
  ]
}
```
