> For the complete documentation index, see [llms.txt](https://uclix.gitbook.io/run-ai-rca-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://uclix.gitbook.io/run-ai-rca-docs/ko/api.md).

# API 레퍼런스

> **관점:** 레퍼런스 — HTTP 표면(surface). **이 문서에서 다루는 것:** Backend 엔드포인트 · Agent 엔드포인트 · 웹훅 accept/ignore 시맨틱.

**이 문서는 누구를 위한가:** 연동을 시험하는 운영자와 client를 만드는 개발자를 위한 문서입니다. 엔드포인트는 요청을 받거나 기록을 돌려주는 하나의 HTTP 주소입니다. 알림 접수는 webhook, 사건 조회는 incident, 진행 상태는 analysis run부터 보면 됩니다. 도구가 모든 필드를 알아야 할 때는 OpenAPI를 사용하세요.

```mermaid
flowchart LR
  W[Alertmanager webhook] --> I[Incident와 alert API]
  I --> A[Analyze와 analysis-run API]
  A --> E[Events/SSE와 dashboard]
  K[Knowledge API] --> I
  H[Agent health] --> A
```

## OpenAPI 계약

Backend는 GitBook 호환 **OpenAPI 3.0.3** 계약을 `GET /api/v1/openapi.json`으로 제공합니다. API 포털, 생성형 client, Scalar 또는 Swagger UI 같은 interactive renderer의 기준으로 사용하세요. 현재 계약은 Backend route map을 제공하며, Knowledge operation은 요청 schema와 lifecycle 응답 코드를 상세히 정의합니다.

배포된 RCA URL의 `/api-docs`를 열면 내장 Scalar 레퍼런스를 볼 수 있습니다. 같은 origin의 계약을 읽고 **Try it**으로 요청을 직접 보냅니다. Scalar 계정이나 hosted Scalar 서비스는 사용하지 않습니다.

## 엔드포인트

### 작업에 따라 엔드포인트 고르기

사건을 보려면 incident/alert 엔드포인트를 읽고, 새 조사를 요청하려면 analyze 엔드포인트를 사용하며, 브라우저에 실시간 갱신이 필요하면 events 엔드포인트를 사용합니다. 아래의 상세 목록은 계속해서 권위 있는 route 레퍼런스입니다.

Backend:

* `POST /webhook/alertmanager`
* `GET /api/v1/openapi.json`
* `GET /api/v1/incidents?view=active|archived|trash` (`status`, `severity`, `final_decision`, `q`로도 필터 가능. `sort=activity|started`와 `order=asc|desc`로 정렬)
* `GET /api/v1/incidents/{id}`
* `POST /api/v1/incidents/{id}/analyze`
* `POST /api/v1/incidents/{id}/cancel`
* `POST /api/v1/incidents/{id}/rca-correction`
* `POST /api/v1/incidents/{id}/rca-pin`
* `POST /api/v1/incidents/{id}/reverify`
* `POST /api/v1/incidents/{id}/resolve`
* `POST /api/v1/incidents/{id}/archive`
* `POST /api/v1/incidents/{id}/unarchive`
* `POST /api/v1/incidents/{id}/restore`
* `POST /api/v1/incidents/bulk`
* `DELETE /api/v1/incidents/trash`
* `DELETE /api/v1/incidents/{id}`
* `DELETE /api/v1/incidents/{id}?permanent=true`
* `GET /api/v1/incidents/{id}/feedback`
* `POST /api/v1/incidents/{id}/feedback`
* `POST /api/v1/incidents/{id}/vote`
* `POST /api/v1/incidents/{id}/comments`
* `PUT /api/v1/incidents/{id}/comments/{comment_id}`
* `DELETE /api/v1/incidents/{id}/comments/{comment_id}`
* `GET /api/v1/alerts`
* `GET /api/v1/alerts/{id}`
* `GET /api/v1/alerts/{id}/feedback`
* `POST /api/v1/alerts/{id}/feedback`
* `POST /api/v1/alerts/{id}/vote`
* `POST /api/v1/alerts/{id}/comments`
* `PUT /api/v1/alerts/{id}/comments/{comment_id}`
* `DELETE /api/v1/alerts/{id}/comments/{comment_id}`
* `POST /api/v1/embeddings/search`
* `GET /api/v1/analysis-runs`
* `GET /api/v1/analysis-runs/{id}/evaluation?author=...`
* `PUT /api/v1/analysis-runs/{id}/evaluation?author=...`
* `GET /api/v1/knowledge-candidates?status=...`
* `GET /api/v1/knowledge-candidates/{id}`
* `POST /api/v1/knowledge-candidates/{id}/decision`
* `DELETE /api/v1/knowledge-candidates/{id}`
* `GET /api/v1/knowledge-packages?include_retired=true|false`
* `GET /api/v1/knowledge-packages/{id}`
* `POST /api/v1/knowledge-packages/{id}/retire`
* `GET /api/v1/knowledge/families`
* `GET /api/v1/knowledge/runtime-snapshot`
* `GET /api/v1/knowledge/probe-metrics`
* `POST /api/v1/analysis-runs/{id}/progress`
* `GET /api/v1/stats/recurrence?days=7`
* `GET /api/v1/stats/llm-spend?days=7`
* `GET /api/v1/stats/kpi?days=7`
* `GET /api/v1/events`
* `POST /api/v1/chat`
* `GET /api/v1/chat/conversations`
* `DELETE /api/v1/chat/conversations/{id}`

`POST /webhook/alertmanager`는 `status`, `alerts`, `accepted`, `ignored` 카운트와 함께 HTTP 202를 반환합니다. severity가 `info` 또는 `information`인 알림은 ignored로 집계되며, 인시던트, 알림, SSE 이벤트, 분석 실행(analysis run)을 생성하지 않습니다.

`GET /api/v1/incidents`는 기본적으로 active 인시던트 뷰를 반환합니다. 보관된 인시던트는 `view=archived`, 휴지통 보존 기간 안의 soft delete 인시던트는 `view=trash`를 사용합니다. 목록은 `status`, `severity`, `final_decision`, `q`(자유 텍스트) 필터도 받습니다. 유효하지 않은 view 값은 HTTP 400을 반환합니다. 목록 페이지네이션의 `total`은 선택한 view 기준으로 계산됩니다.

목록이 페이지 단위라 정렬은 서버에서 수행합니다. `sort=activity`(기본)는 `last_activity_at`, `sort=started`는 `fired_at` 기준이며 각각 `order=desc`(기본) 또는 `order=asc`를 받습니다. `last_activity_at`은 발생·알림 해소·분석 시작 중 가장 최근 시각이므로, 방금 시작된 분석은 별도 분기 없이 자기 타임스탬프로 목록 최상단에 올라옵니다. 플래핑 윈도우의 기준 시각은 별도 필드이며 분석으로 갱신되지 않습니다.

인시던트 라이프사이클 액션:

* `POST /api/v1/incidents/{id}/cancel`은 진행 중인 분석 실행의 취소를 요청합니다 — 실행 중이면 `run_id`와 함께 HTTP 202 `cancel_requested`, 아니면 HTTP 200 `not_analyzing`.
* `POST /api/v1/incidents/{id}/rca-correction`은 운영자 RCA 정정을 새 분석 실행으로 기록합니다 — HTTP 201. `summary`와 카탈로그의 `root_cause_family`가 필요하며, `actions`는 선택 사항입니다.
* `POST /api/v1/incidents/{id}/rca-pin`은 `pinned` 불리언 바디로 최신 운영자 정정을 고정/해제합니다 — HTTP 200.
* `POST /api/v1/incidents/{id}/reverify`는 고정된 운영자 정정을 새 증거로 재검증합니다 — HTTP 202.
* `POST /api/v1/incidents/{id}/resolve`는 RCA에 대한 운영자의 최종 승인을 토글합니다. `user_approved_at`을 설정하거나 비우며, `status`와 `resolved_at`은 변경하지 않습니다. 이 둘은 Alertmanager 기준 인시던트 상태로 유지됩니다. 유사 인시던트 메모리는 이 승인 이후에만 적재됩니다.
* `POST /api/v1/incidents/{id}/archive`는 데이터를 삭제하지 않고 active 목록에서 인시던트를 숨깁니다. 같은 조건의 새 알림이 들어오면 자동으로 unarchive됩니다.
* `POST /api/v1/incidents/{id}/unarchive`는 보관된 인시던트를 active 뷰로 되돌립니다.
* `DELETE /api/v1/incidents/{id}`는 인시던트를 휴지통으로 soft delete하고 active 매칭 인덱스에서 제거합니다. backfill, 대시보드, 채팅 폴백, 메모리 검색은 삭제된 인시던트를 사용하지 않습니다.
* `POST /api/v1/incidents/{id}/restore`는 매칭 인덱스를 더 새 인시던트가 선점하지 않은 경우 soft delete 인시던트를 복구합니다.
* `DELETE /api/v1/incidents/{id}?permanent=true`는 인시던트와 연결된 알림, 임베딩, 피드백, 코멘트, 분석 실행을 영구 삭제합니다.

## Knowledge candidate 결정

모든 knowledge lifecycle 액션은 같은 엔드포인트를 사용합니다. `{candidate_id}`에는 candidate 목록 또는 상세 API가 반환한 값을 넣으세요. `actor`와 `note`는 선택적인 감사 필드입니다.

```http
POST /api/v1/knowledge-candidates/{candidate_id}/decision
Content-Type: application/json
```

```json
{
  "action": "shadow",
  "actor": "on-call@example.com",
  "note": "이 probe template은 활성화 전에 관찰합니다."
}
```

| `action`   | 가능한 상태                       | 결과                                              |
| ---------- | ---------------------------- | ----------------------------------------------- |
| `shadow`   | candidate가 pending           | 검증 후 관찰용 non-active package를 만듭니다.              |
| `activate` | candidate가 shadow            | 해당 package를 runtime snapshot에 활성화합니다.           |
| `approve`  | candidate가 pending           | 검증 후 즉시 active package를 만듭니다.                   |
| `reject`   | candidate가 pending 또는 shadow | candidate를 거절하며, shadow package는 retired 처리합니다. |

모든 액션의 요청 본문은 같고 `action`만 바뀝니다. `approve`와 `shadow`는 상태 전환 전에 Agent validator를 호출합니다. 성공한 `shadow`, `activate`, `approve` 응답에는 `candidate`와 `package`가 함께 있고, pending candidate의 성공한 `reject` 응답에는 `candidate`가 있습니다. 잘못된 action은 400, validator 거절은 422, 허용되지 않는 lifecycle 전환은 409를 반환합니다.

Candidate 생성에는 두 가지 증거 경로가 있습니다. 기본 경로는 완전한 trace-v3 ledger를 요구합니다. 즉, family가 일치하는 selected/supported 가설 1개, 최소 두 source group의 canonical supporting evidence, 연계된 probe 실행이 필요합니다. Ledger가 불완전한 경우에는 출력 harness가 `supported`이고, root-cause claim이 snapshot family와 일치하며, 모든 supporting evidence가 canonical이고 반증이 없고 supporting evidence가 비어 있지 않을 때만 `harness_claim` 경로를 사용할 수 있습니다. 이 경로는 의도적으로 source group 1개와 probe 실행 0개를 허용하며, compiled `probe_template_ids`는 `null`이 아닌 `[]`로 전달됩니다. 감사를 위해 payload에 `evidence_source: "harness_claim"`과 `provenance.promotion_path: "harness_claim"`이 기록됩니다.

평가를 저장하면 해당 run과 analysis hash에 대해 candidate 검증이 다시 실행됩니다. 여전히 유효하지 않은 candidate는 `validation_failed` 상태를 유지하지만 최신 `validation_error`와 `updated_at`으로 갱신됩니다. 적격해진 candidate는 `ready_for_review`로 돌아오며, 활성화 전에는 여전히 명시적인 candidate decision이 필요합니다.

`DELETE /api/v1/knowledge-candidates/{id}`는 리뷰 큐에 남은 죽은 행을 정리합니다. 정리 목적 전용이라 `validation_failed`와 `rejected`에서만 허용되고, 살아 있는 상태이거나 아직 은퇴하지 않은 package를 소유한 candidate는 409로 거부됩니다 — 런타임 스냅샷이 서빙 중인 행을 잃는 일은 없습니다. case 링크와 감사 이벤트는 같은 트랜잭션에서 함께 삭제됩니다. candidate id는 내용에서 파생되므로, 같은 지식을 다시 만들어내는 평가가 있으면 행도 다시 생성됩니다.

## Bulk incident lifecycle action

여러 인시던트에 같은 lifecycle action을 적용하려면 다음을 호출합니다:

```http
POST /api/v1/incidents/bulk
Content-Type: application/json
```

```json
{
  "incident_ids": ["INC-...", "INC-..."],
  "action": "archive"
}
```

`action`은 `archive`, `unarchive`, `restore`, `trash`, `delete_permanently` 중 하나입니다. 응답에는 처리된 ID가 포함됩니다. 휴지통의 모든 인시던트를 영구 삭제하려면 `DELETE /api/v1/incidents/trash`를 호출하며, 응답에는 `deleted_count`가 포함됩니다.

## Package retire

package를 명시적으로 retire할 때는 `action` 없이 같은 선택 감사 필드를 보냅니다.

```http
POST /api/v1/knowledge-packages/{package_id}/retire
Content-Type: application/json
```

```json
{
  "actor": "on-call@example.com",
  "note": "더 새로운 package로 대체되었습니다."
}
```

`GET /api/v1/stats/recurrence?days=N`은 최근 `N`일 재발 통계를 반환합니다. `days`는 기본값 7이며 1..90 범위로 클램프됩니다.

```json
{
  "data": {
    "days": 7,
    "rate": 0.5,
    "total": 4,
    "recurred": 2,
    "daily": [{"date": "2026-07-06", "total": 1, "recurred": 1, "rate": 1}]
  }
}
```

`GET /api/v1/stats/llm-spend?days=N`은 analysis-run `metadata.llm_usage`를 토큰, 호출 수, 실패 호출 수, 추정 USD 비용, 일별 버킷, 모델별 breakdown으로 집계합니다. 조회 기간은 1..90일 범위입니다. 여기에 더해 `hosted_estimates`(같은 실측 토큰량을 Anthropic·OpenAI·Google 공시 요율로 환산한 비용. 입력과 출력을 따로 계산)와 `fx`(USD/KRW 환율, 갱신 시각, 환율 피드에 도달하지 못해 설정된 fallback을 쓰는 중이면 `usd_krw_is_fallback`)를 반환합니다.

`GET /api/v1/stats/kpi?days=N`은 time-to-RCA와 time-to-resolve의 평균/p50/p90, 일별 버킷을 반환합니다. time-to-RCA는 인시던트별 최초 성공 완료 시각을 사용하므로 이후 재분석이 기준선을 덮어쓰지 않습니다.

`POST /api/v1/analysis-runs/{id}/progress`는 실행 상태가 `analyzing`인 동안 에이전트의 진행 이벤트를 받습니다. 백엔드는 항목을 `metadata.progress_log`에 최대 200개까지 append하고, 수락한 각 항목을 SSE `analysis.progress`로 broadcast합니다. 완료/실패 실행도 누적된 progress log를 보존합니다.

인시던트 응답은 Alertmanager 상태를 `status` / `resolved_at`으로, 운영자 최종 승인을 `user_approved_at`으로 노출합니다. `AnalysisRun` 응답은 선택 사항인 `metadata`를 포함합니다. 에이전트가 usage 데이터를 반환하면 LLM 토큰 계측값은 `metadata.llm_usage`에 저장됩니다. 인시던트 상세 응답은 최신 실행의 usage를 `token_usage`로 노출하고, UI의 최근 유사 발생 카운트에 쓰이는 `similar_recent_count`를 포함합니다.

인시던트 상세에는 최신 RCA의 `analysis_run_id`, `analysis_hash`, 선택적 `harness`, 선택적 `ontology_reasoning`도 포함됩니다. evaluation GET은 현재 hash와 일치하는 평가만 반환하고, PUT은 현재 browser actor의 평가를 upsert합니다. 재분석된 RCA에 과거 평가가 붙지 않도록 stale hash는 HTTP 400으로 거절합니다.

`GET /api/v1/events`는 named SSE 이벤트를 내보냅니다. 인시던트 archive, unarchive, delete, restore, 수동 permanent delete 변경은 `incident.updated`를 발행하므로 다른 대시보드 세션이 active, archived, trash 뷰를 갱신할 수 있습니다. 분석 라이프사이클 이벤트에는 `analysis.started`, `analysis.progress`, `analysis.completed`가 포함됩니다. progress 이벤트는 `run_id`, `phase`, 선택 사항인 collector/hypothesis 필드, confidence 스냅샷, timestamp를 포함합니다.

Agent:

* `POST /analyze`
* `POST /summarize-incident`
* `POST /chat` 현재 인시던트, 알림, 증거, 피드백, 유사 RCA 메모리에 기반한 컨텍스트 인지형(context-aware) RCA 채팅
* `GET /healthz`는 프로세스/런타임 상태와 `collectors: {active, unknown}`를 반환합니다. `unknown`은 `COLLECTORS`에 제공된 인식할 수 없는 이름이며, 수집기 상태가 아니라 구성 가시성 정보입니다.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://uclix.gitbook.io/run-ai-rca-docs/ko/api.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
