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

# Response format

> The Guard API response: the top-level action, per-part input_results, and detected_items for PII and Topic.

A successful call returns **HTTP 200** with a top-level `action` and a per-content-part breakdown in `input_results`. Starfort returns the Guardian's response body **verbatim** — no wrapper, no field reshaping.

## The action model

The middle state depends on the policy type:

* **PII** policies return `PASS` / `MASK` / `BLOCK`.
* **Topic** policies return `PASS` / `CHECK` / `BLOCK`, where **`CHECK`** flags a `controversial` topic for review.

**API callers receive `CHECK` directly** — unlike the Desktop Agent and Proxy Server, which enforce `CHECK` as `PASS`. The root `action` is the **highest severity** across everything detected: `BLOCK` > `MASK` > `CHECK` > `PASS`. See [Actions](/en/v1.2/concepts/actions-pass-mask-block).

## Top-level

| Field           | Type   | Notes                                                                      |
| --------------- | ------ | -------------------------------------------------------------------------- |
| `action`        | string | `PASS` \| `MASK` \| `BLOCK` — the **highest severity** across all results. |
| `input_results` | array  | One entry per inspected content part. Empty when nothing was inspected.    |

Each `input_results[]` entry:

| Field                    | Notes                                                     |
| ------------------------ | --------------------------------------------------------- |
| `index`                  | Position of the content part in `messages[].content`.     |
| `type`                   | `text`, `image`, `audio`, `video`, `document`, `archive`. |
| `identifier`             | File name for file parts; otherwise `null`.               |
| `action`                 | This part's action.                                       |
| `processed_content`      | On `MASK`: the masked text. On `PASS`/`BLOCK`: `null`.    |
| `processed_content_type` | MIME type of `processed_content` when present.            |
| `results`                | Per-policy results (see below).                           |

## MASK example (PII)

```json theme={null}
{
  "action": "MASK",
  "input_results": [{
    "index": 0, "type": "text", "identifier": null, "action": "MASK",
    "processed_content": "제 번호는 [PHONE_NUMBER_1] 이고 이메일은 [EMAIL_1] 입니다.",
    "processed_content_type": "text",
    "results": [{
      "policy_name": "PII Masking Policy", "policy_type": "PII", "action": "MASK",
      "detected_items": [
        { "rule_type": "regex", "rule_id": 15, "rule_name": "phone_number:_korea_mobile_all_separators",
          "action": "MASK", "confidence": 1, "mask_word": "PHONE_NUMBER_1",
          "matched_text": "010-2543-2513", "alert_message": "휴대전화번호 감지됨" },
        { "rule_type": "regex", "rule_id": 18, "rule_name": "email:_email_address",
          "action": "MASK", "confidence": 1, "mask_word": "EMAIL_1",
          "matched_text": "jane@acme.co.kr", "alert_message": "이메일 주소 감지됨" }
      ]
    }]
  }]
}
```

**Masking token format:** `[<MASK_WORD>_<n>]`, numbered per occurrence (`[PHONE_NUMBER_1]`, `[PHONE_NUMBER_2]`, …).

## BLOCK example (Topic)

```json theme={null}
{
  "action": "BLOCK",
  "input_results": [{
    "index": 0, "type": "text", "identifier": null, "action": "BLOCK",
    "processed_content": null, "processed_content_type": null,
    "results": [{
      "policy_name": "Topic Policy", "policy_type": "TOPIC", "action": "BLOCK",
      "detected_items": [
        { "rule_id": "WPN", "rule_name": "무기", "action": "BLOCK",
          "confidence": 1, "classification": "unsafe", "alert_message": "…" }
      ]
    }]
  }]
}
```

## `detected_items` — PII vs. Topic

The fields differ by policy type:

| Field                                   | PII                           | Topic                                                              |
| --------------------------------------- | ----------------------------- | ------------------------------------------------------------------ |
| `rule_type`                             | `ner` \| `regex` \| `keyword` | —                                                                  |
| `rule_id`                               | integer                       | string topic code (e.g. `WPN`)                                     |
| `rule_name`                             | rule name                     | topic title                                                        |
| `classification`                        | —                             | `safe` (→ PASS) \| `controversial` (→ CHECK) \| `unsafe` (→ BLOCK) |
| `mask_word`                             | present (MASK)                | —                                                                  |
| `matched_text`                          | the matched span              | —                                                                  |
| `action`, `confidence`, `alert_message` | yes                           | yes                                                                |

<Note>
  Read the top-level `action` first. On `MASK`, send `processed_content` onward instead of the original. On `BLOCK`, do not call your model. See [Actions](/en/v1.2/concepts/actions-pass-mask-block).
</Note>

## `PASS` always means "analyzed, nothing detected"

A `PASS` with empty `results` is never ambiguous: it means the Guardian **completed analysis and found nothing** — not that it failed to analyze. A request the Guardian cannot analyze returns an **HTTP error** instead of a degraded 200 (Guardian fail-closed), so a failure can never be mistaken for a clean result. See [Errors & states](/en/v1.2/api/errors).
