> ## 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.

# 응답 형식

> Starfort Guard API 응답 스키마. 최상위 action, 파트별 input_results, PII·Topic의 detected_items를 예시 페이로드와 함께 설명합니다 (Starfort v1.4 문서)

성공적인 호출은 최상위 `action`과 콘텐츠 파트별 분석 결과인 `input_results`를 포함한 **HTTP 200**을 반환합니다. Starfort는 Guardian의 응답 본문을 **그대로** 반환합니다 — 래퍼나 필드 재구성이 없습니다.

## action 모델

action 집합은 정책 타입에 따라 다릅니다:

* **PII** 정책은 `PASS` / `MASK` / `BLOCK`을 반환합니다.
* **Topic** 정책은 **2가지 상태**입니다: `PASS` 또는 `BLOCK`을 반환합니다(`unsafe`로 분류된 토픽은 차단되고, 그 외에는 모두 통과합니다).

루트 `action`은 탐지된 모든 항목 중 **가장 높은 심각도**입니다: `BLOCK` > `MASK` > `PASS`. [Actions](/ko/v1.4/concepts/actions-pass-mask-block)를 참고하세요.

## 최상위

| 필드              | 타입     | 설명                                                      |
| --------------- | ------ | ------------------------------------------------------- |
| `action`        | string | `PASS` \| `MASK` \| `BLOCK` — 모든 결과 중 **가장 높은 심각도**입니다. |
| `input_results` | array  | 검사된 콘텐츠 파트당 하나의 항목입니다. 검사된 것이 없으면 비어 있습니다.              |

각 `input_results[]` 항목:

| 필드                       | 설명                                                                                                                                                                                         |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `index`                  | `messages[].content` 내 콘텐츠 파트의 위치입니다.                                                                                                                                                      |
| `type`                   | `text`, `image`, `audio`, `video`, `document`, `archive`.                                                                                                                                  |
| `identifier`             | 파일 파트의 경우 파일 이름. 그 외에는 `null`.                                                                                                                                                             |
| `action`                 | 해당 파트의 action입니다.                                                                                                                                                                          |
| `processed_content`      | **처리본** — Guardian이 파싱·정규화·(필요 시 OCR·디코드)한 뒤 재인코딩한 콘텐츠입니다. 전달이 일어나는 판정(`PASS` · `MASK`)에서는 항상 처리본을 담습니다 — 텍스트 파트는 문자열, 파일 파트는 base64 문자열. `BLOCK`이거나 처리본을 만들 수 없는 입력(미지원 · 처리 실패)은 `null`. |
| `processed_content_type` | `processed_content`의 콘텐츠 유형입니다 — 텍스트는 `text`, 파일류는 MIME 타입. `processed_content`가 `null`이면 `null`.                                                                                          |
| `results`                | 정책별 결과입니다(아래 참고).                                                                                                                                                                          |

## MASK 예시 (PII)

```json theme={"dark"}
{
  "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": "이메일 주소 감지됨" }
      ]
    }]
  }]
}
```

**마스킹 토큰 형식:** `[<MASK_WORD>_<n>]`, 발생 순서대로 번호가 매겨집니다(`[PHONE_NUMBER_1]`, `[PHONE_NUMBER_2]`, …).

## 처리본 전달 원칙 — 외부로 보내는 것은 항상 `processed_content`

v1.4부터 외부 AI 서비스로 나가는 콘텐츠는 호출자가 제출한 원본이 아니라, Guardian이 내용을 실제로 확인하고 재구성한 **처리본**(`processed_content`)으로 통일됩니다:

* **PASS** — 처리본을 전달합니다. 마스킹 대상이 없어 내용은 원문과 같더라도, 전달되는 것은 Guardian이 재구성한 처리본입니다.
* **MASK** — 마스킹된 처리본을 전달합니다.
* **BLOCK** — 전달이 없습니다(`processed_content`는 `null`).
* **처리본을 만들 수 없는 입력**(미지원 파일, 파싱·디코드 실패) — Guardian이 내용을 확인하지 못했으므로 `null`이며, 원본을 대신 전달해서는 안 됩니다(fail-closed).

이미지·문서·오디오처럼 OCR·디코드·파싱 변환을 거치는 입력은 처리 과정이 원본의 모든 내용을 포착한다고 보장할 수 없습니다. 처리본만 내보내면 외부로 나가는 콘텐츠가 Guardian이 실제로 확인한 표현으로 한정되어, 확인하지 못한 내용이 원본에 담겨 그대로 흘러나가는 경로가 닫힙니다.

<Note>
  **v1.3까지와 달라진 점** — v1.3까지 `processed_content`는 `MASK`일 때만 채워졌고, `PASS`는 호출자 원본이 그대로 나가는 모델이었습니다(필드는 `null`). v1.4부터는 `PASS`에서도 처리본이 채워지며, 원본 대신 처리본을 전달하는 것이 계약입니다.
</Note>

## BLOCK 예시 (Topic)

```json theme={"dark"}
{
  "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

필드는 정책 타입에 따라 다릅니다:

| 필드                                      | PII                           | Topic                               |
| --------------------------------------- | ----------------------------- | ----------------------------------- |
| `rule_type`                             | `ner` \| `regex` \| `keyword` | —                                   |
| `rule_id`                               | 정수                            | 문자열 토픽 코드(예: `WPN`)                 |
| `rule_name`                             | 규칙 이름                         | 토픽 제목                               |
| `classification`                        | —                             | `safe`(→ PASS) \| `unsafe`(→ BLOCK) |
| `mask_word`                             | 존재함(MASK)                     | —                                   |
| `matched_text`                          | 일치한 구간                        | —                                   |
| `action`, `confidence`, `alert_message` | 예                             | 예                                   |

<Note>
  최상위 `action`을 먼저 읽으세요. `PASS`와 `MASK`에서는 원본이 아니라 `processed_content`를 전달하세요(위의 처리본 전달 원칙). `BLOCK`일 때는 모델을 호출하지 마세요. [Actions](/ko/v1.4/concepts/actions-pass-mask-block)를 참고하세요.
</Note>

## `PASS`는 항상 "분석 완료, 아무것도 탐지되지 않음"을 의미합니다

`results`가 비어 있는 `PASS`는 결코 모호하지 않습니다: 이는 Guardian이 **분석을 완료했고 아무것도 발견하지 못했음**을 의미하며, 분석에 실패했다는 뜻이 아닙니다. Guardian이 분석할 수 없는 요청은 열화된 200이 아니라 **HTTP 오류**를 반환하므로(Guardian fail-closed), 실패가 깨끗한 결과로 오인될 수 없습니다. [오류 및 상태](/ko/v1.4/api/errors)를 참고하세요.
