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

# Check moderation

> Pre-check text against the moderation policy without blocking

`POST /api/v2/moderation/check`

Runs the content-moderation engine against the supplied text **without blocking**. Returns structured findings (category, severity, suggestion) so an agent can validate input before submitting it to a campaign-create or other blocking surface. Mirrors the engine that powers brief screening on `POST /campaigns`.

## Request

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://api.interchange.io/api/v2/moderation/check \
    -H "Authorization: Bearer $SCOPE3_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "text": "Reach outdoor enthusiasts in the Pacific Northwest with premium CTV inventory.",
      "direction": "input"
    }'
  ```

  ```json Output direction theme={null}
  {
    "text": "I'm sorry, I can't help with that request.",
    "direction": "output",
    "surface": "merch-agent.reply"
  }
  ```
</CodeGroup>

## Parameters

| Field       | Type   | Required | Notes                                                                                                                   |
| ----------- | ------ | -------- | ----------------------------------------------------------------------------------------------------------------------- |
| `text`      | string | Yes      | Text to evaluate (1–10,000 chars). Exceeding 10,000 chars returns a `400 VALIDATION_ERROR`                              |
| `direction` | enum   | No       | `input` runs brief/jailbreak/policy patterns; `output` runs LLM-output (refusal/identity/PII) patterns. Default `input` |
| `surface`   | string | No       | Surface label for metric attribution (1–100 chars). Default `moderation.check`                                          |

## Response

```json theme={null}
{
  "passed": false,
  "wouldBlock": true,
  "findings": [
    {
      "category": "jailbreak_attempt",
      "severity": "high",
      "suggestion": "Remove instructions that ask the system to ignore prior rules, then resubmit."
    }
  ]
}
```

| Field                   | Type    | Notes                                                                                                    |
| ----------------------- | ------- | -------------------------------------------------------------------------------------------------------- |
| `passed`                | boolean | True when no moderation patterns matched                                                                 |
| `wouldBlock`            | boolean | True when at least one finding would trigger a `422` on a blocking surface                               |
| `findings[]`            | array   | All matching findings; empty when `passed` is true. Both blocking and non-blocking findings are reported |
| `findings[].category`   | string  | Moderation category (e.g. `jailbreak_attempt`, `pii_leak`)                                               |
| `findings[].severity`   | enum    | `low`, `medium`, `high`, `critical`. `high` and above blocks at default thresholds                       |
| `findings[].suggestion` | string  | Remediation guidance for the agent to self-correct                                                       |

## Errors

* `400 VALIDATION_ERROR` — empty `text`, or `direction`/`surface` out of range.
* `401 UNAUTHORIZED` — missing or invalid API key.

See [Errors](/v2/reference/errors) for the full error contract.

## Related

<CardGroup cols={2}>
  <Card title="Activity tasks" href="/v2/storefront/activity/tasks" icon="list-check">
    All activity operations
  </Card>

  <Card title="List activity" href="/v2/storefront/activity/tasks/list-activity" icon="clock-rotate-left">
    Configuration audit feed
  </Card>

  <Card title="Errors" href="/v2/reference/errors" icon="triangle-exclamation">
    Shared error contract
  </Card>
</CardGroup>
