# 응답은 어떻게 읽습니까: unknown, null, 빈 목록, no-store

여기서 시작 · 결과는 둘이 아니라 셋입니다: 이름이 붙은 결과, 없음, 알 수 없음 — 그리고 응답이 불완전하다는 네 가지 신호

*API 가이드 · 8분 · 중급 · 개발자 · 읽기*

이 API의 모든 판정에는 세 가지 결과가 있으며, 코드는 세 가지를 모두 유지해야 합니다. **이름이 붙은 결과**(`sanctioned`, `frozen`, `severe`), **`none`**(충분한 집계 범위에서 확인했고 아무것도 찾지 못함), **`unknown`**(확인할 수 없었음)입니다. `unknown`은 결코 `none`이 아니며, 항상 `incomplete_reasons`에 이유를 밝힙니다. 응답이 보이는 것보다 부족하다는 신호가 네 가지 더 있습니다. 숫자가 있어야 할 곳의 `null`, 판정이 아니라 목록일 뿐인 빈 목록, 일부를 잃은 조회에 붙은 `Cache-Control: no-store`, 요청한 것보다 늦게 시작하는 그래프의 `window_from`입니다. 이 페이지는 정직성 계약을 분기 규칙으로 다시 쓴 것입니다.

## 코드로 본 세 가지 결과

2026-10-24에 한 제재 대상 주소의 위험 판정은 `"tier": "severe"`, `"incomplete_reasons": []`였습니다. 같은 시각 바이낸스(Binance) 핫월렛의 위험 판정은 `"tier": "unknown"`, `"incomplete_reasons": ["time_budget"]`였고, 이를 설명하는 `evidence` 행이 있었습니다. *exposure not assessed: the walk stopped on its time budget with 0 of 3 hops completed*(노출 평가 안 됨: 순회가 시간 예산에 걸려 3홉 중 0홉을 완료하고 멈춤). 둘 다 완결된 문장입니다. 첫 번째는 *하지 마십시오*라고 말하고, 두 번째는 *판단할 수 없었습니다*라고 말합니다. 두 번째를 *괜찮음*으로 처리하는 프로그램은 스캐너가 기반으로 삼는 [단 하나의 규칙](https://achivx.kr/academy/courses/first-steps/first-steps-01-what-the-scanner-is/)을 깨뜨린 것입니다.

```
risk = scan(f"/v1/addresses/{addr}/risk", chain=1)
if risk["tier"] in ("severe", "high"):
    decision = "refuse"
elif risk["tier"] == "unknown":
    decision = "escalate"          # not "allow": the reasons are in risk["incomplete_reasons"]
elif risk["tier"] == "none":
    decision = "allow"
else:                              # "low", "medium": a label or an indirect reach set it
    decision = "review"
```

`evidence` 행은 사람을 위한 것이고, 필드는 프로그램을 위한 것입니다. `detail` 텍스트가 아니라 `tier`, `flags`, `exposure`, `incomplete_reasons`로 분기하십시오.

## `incomplete_reasons`: 평가되지 않은 것

빠짐없이 고정된 순서로 나열된 목록이며, 빠진 것이 없으면 `[]`입니다. 각 값과 그 값이 요구하는 것은 다음과 같습니다.

| 이유 | 위치 | 의미 |
|---|---|---|
| `time_budget` | risk, exposure | 요청 기한 안에 머물기 위해 [노출 순회](https://achivx.kr/academy/guides/exposure-card/)가 중단되었습니다. 한산한 시점에 같은 조회를 하면 완료될 수 있습니다 — 응답은 약 10초만 유지되므로(60 대신 `Cache-Control: max-age=10`), 반복하기 전에 간격을 두십시오 |
| `frontier_cap` | risk, exposure | 한 [홉](https://achivx.kr/academy/reference/glossary/#g-hop)이 [탐색 경계 상한](https://achivx.kr/academy/courses/the-scanner-for-machines/the-scanner-for-machines-02-limits/)보다 넓었습니다. 주소의 속성이므로 매 호출마다 반복됩니다 |
| `short_history` | risk, exposure | 관측된 유입이 1달러 미만 — 평가할 것이 없습니다 |
| `ofac_list_unloaded`, `ofac_list_stale` | risk, exposure | 제재 목록이 없거나 7일보다 오래되었습니다(`sanctions_list_as_of`). [순회](https://achivx.kr/academy/reference/glossary/#g-walk)가 도달한 출발점은 그대로 유효합니다 |
| `no_accusation_labels` | risk, exposure | 해당 네트워크에 해킹 / 드레이너 / 믹서 라벨이 로드되어 있지 않습니다 |
| `coverage_pending`, `coverage_partial` | 솔라나 전용 | 주소의 기록이 아직 채워지는 중이거나, 문서화된 한도까지 채워졌습니다(`coverage_status`) |
| `freeze_history_incomplete` | risk | 발행사 로그가 소급 수집되지 않은 [동결](https://achivx.kr/academy/reference/glossary/#g-freeze-unfreeze-seize) 쌍 — 등급이 `none`일 수 없습니다 |
| `labels_unread`, `new_counterparty_unread` | risk | 조회가 끝나지 않았습니다. 응답은 `no-store`입니다 — 다시 요청하십시오 |

이유는 사실이 정한 등급을 낮추지 않습니다. 제재 대상 주소는 [순회](https://achivx.kr/academy/reference/glossary/#g-walk)가 어떻게 되었든 `severe`로 남습니다. 또한 중단된 순회 자체가 `unknown`을 뜻하지는 않습니다. 중단 전에 순회가 출발점에 도달했다면 `exposure`는 `sanctioned`, `direct` 또는 `indirect`이며 그대로 유효합니다. `truncation_reason`만 보지 말고 `exposure`를 읽으십시오.

## `null`은 *읽지 못함*, `0`은 *측정됨*

`freshness_seconds: null`은 이번 응답에서 가장 최근 전송의 경과 시간을 읽을 수 없었다는 뜻입니다 — 0도 아니고 추정치도 아닙니다. `chains_with_data: null`은 존재 여부 조사가 실행되지 않았다는 뜻이고, `[]`는 인덱싱된 어떤 네트워크에도 그 주소의 전송, 라벨, 유효한 동결 기록이 없다는 뜻입니다. [피드](https://achivx.kr/academy/courses/following-the-stablecoins/following-the-stablecoins-01-settlement-tables/)에서 `"total": null`과 `total_unavailable_reason: "timeout"`은 개수 집계가 끝나지 않았다는 뜻입니다 — 행은 실제이므로 계속 페이지를 넘기십시오. `/v1/verify`에서 `found: null`은 적어도 하나의 네트워크가 응답하지 않았다는 뜻입니다 — 다시 시도하십시오. 부정 결과가 아닙니다. `found: false`는 각 네트워크의 `chains[].sync` 시점 기준으로 모든 네트워크의 핫 윈도우에 걸친 부정 결과입니다.

다시 요청해도 채워지지 않는 `null`이 하나 있습니다. `/v1/stats/home` 또는 `/v1/stats/overview`에서 `organic_unavailable_reason`이 붙은 오가닉 수치입니다. 이는 실패한 조회가 아니라 배치의 상태입니다.

## 빈 목록은 목록일 뿐입니다

- `freeze: []` — 해당 네트워크에서는 아무것도 [동결](https://achivx.kr/academy/how-it-works/how-does-a-freeze-happen/)될 수 없다는 뜻입니다(동결 가능한 스테이블코인이 없는 네트워크의 주소 개요). *동결된 것이 없음*이 아닙니다.
- `frozen_elsewhere: []` — 다른 인덱싱된 네트워크에 유효한 동결 기록이 없다는 뜻입니다. *모든 곳에서 깨끗함*이 아닙니다.
- `freeze_proposals: []` — 공개된 [제안](https://achivx.kr/academy/guides/issuer-freezes/)이 없다는 뜻입니다. 결코 *대기 중인 것 없음*이 아닙니다([대기 중인 제안](https://achivx.kr/academy/reference/glossary/#g-pending-proposal)을 공개할지는 배포별 설정이며, 제안 목록의 `note`가 알려 줍니다).
- `items: []`인 `/v1/freezes/acts?address=` — 행이 없는 목록이지, 주소에 대한 판정이 아닙니다.
- `/approvals`에서 `worst_band: "none"`과 함께 `open: []` — 이 체인에서, 인덱싱된 로그 범위 안에서 열린 허용량이 발견되지 않았다는 뜻입니다.

주소에 대한 판정은 `/risk`에 있습니다. 목록들은 그 판정을 만든 사실입니다.

## `no-store`는 *다시 요청하라*는 뜻입니다

일부를 잃은 응답은 `Cache-Control: no-store`로 제공되며 보관되지 않습니다. 라벨을 제때 읽지 못한 판정(`labels_unread`), 최신성이 `null`인 주소 또는 동기화 응답, `total: null`인 피드 페이지, `degraded_reason`이 있는 `/graph`, `found: null`인 `/v1/verify`가 그렇습니다. *잠시 후 같은 요청은 완전할 수 있습니다.* 오류 응답과 `/v1/stats/slo`도 `no-store`이지만, 이 경우에는 재시도에 대해 아무것도 말하지 않습니다 — `503 timeout`에는 자체 `Retry-After`가 있습니다.

코드에서 `Cache-Control`을 정보로 읽으십시오.

```
const res = await fetch(`${BASE}/v1/addresses/${addr}/risk?chain=1`);
const risk = await res.json();
const cc = res.headers.get("cache-control") ?? "";
if (cc.includes("no-store")) schedule(retry, 2_000);          // a part was lost: ask again
else if (cc.includes("max-age=10")) schedule(retry, 10_000);  // the walk was cut: a quieter moment may finish it
```

## `window_from`: 그래프가 요청한 지점이 아닌 곳에서 시작할 때

`/walk`, `/graph`, 그래프 순회 스킬은 고정된 기간 동안 보관되는 일 단위 데이터를 읽습니다. `window_from`이 있으면 — 2026-10-24에 바이낸스 [순회](https://achivx.kr/academy/reference/glossary/#g-walk)는 window `all`에서 `"window_from": "2026-10-03"`으로 응답했습니다 — 응답은 지정한 기간의 시작이 아니라 그 날짜부터 만들어진 것입니다. 그래프는 그 구간만 다룬다고 읽으십시오. 거래 상대, 경로, 제재 대상 노드가 없다는 것은 그 이전에 대해 아무것도 말하지 않습니다. `window_from`이 없으면 전체 기간입니다. `/graph`에서 `edge_source: "lifetime"`은 인덱싱된 모든 날입니다.

## 솔라나: `coverage_status`는 주소의 상태입니다

솔라나(Solana)에서는 주소 개요, `risk`, `exposure`, `walk`, `graph`, `volume`에 주소별 `coverage_status`가 있습니다. `pending`(기록이 아직 채워지는 중이거나, 아직 채우기를 요청하지 않음 — 개요를 한 번 조회하면 요청됩니다) 또는 `partial`(문서화된 한도까지 채워짐, 주기적으로 다시 채워짐)입니다. 둘 다 오류가 아니며, 체인 상태도 아닙니다. 둘 다 `unknown`과 같은 부류로 취급하십시오. 또한 솔라나의 [위험 등급](https://achivx.kr/academy/concepts/risk-and-exposure/)은 결코 `none`이 아닙니다. 솔라나 [발행사 기록](https://achivx.kr/academy/guides/issuer-freezes/)은 수집되지 않으며, 모든 솔라나 [동결](https://achivx.kr/academy/how-it-works/how-does-a-freeze-happen/) 쌍은 `unknown`으로 읽히기 때문입니다.

## 모두 unknown인 결과도 결과입니다

인덱싱된 스테이블코인 기록이 없는 주소는 모든 경로에서 `unknown` 또는 빈 값으로 응답합니다. `chains_with_data: []`, `tier: "unknown"`, `short_history`입니다. 그것이 발견 사항입니다 — *이 인터페이스에는 불리한 것도, 해명이 되는 것도 없습니다* — 그리고 그 뒤에 더 깊은 엔드포인트는 없습니다. 자체 정책에 따라 결정하고, 세 가지 결과 중 무엇이었는지 로그에 남기십시오.

## Stablecoin scanner ACHIVX에서

- `incomplete_reasons: []`인 완전한 판정: [제재 대상 예시의 위험](https://stablescan.achivx.com/v1/addresses/0x098B716B8Aaf21512996dC57EB0615e2383E2f96/risk?chain=1).
- 완료할 수 없었던 판정과 그 이유, 이를 설명하는 증거 행: [바이낸스 핫월렛의 위험](https://stablescan.achivx.com/v1/addresses/0x28C6c06298d514Db089934071355E5743bf21d60/risk?chain=1)(2026-10-24에 등급은 `unknown`이었습니다. 한산한 시점에는 [순회](https://achivx.kr/academy/reference/glossary/#g-walk)가 완료될 수 있습니다).
- 스캐너 자체의 말로 된 규칙: [/agents.md](https://stablescan.achivx.com/agents.md) §4.

## 출처

- [에이전트 매뉴얼 — agents.md(버전 2026-10-05)](https://stablescan.achivx.com/agents.md)
- [REST 인터페이스의 OpenAPI 3.1 명세(API 1.4.0)](https://stablescan.achivx.com/openapi.json)
- [GET /v1/addresses/…/risk — 2026-10-24에 읽은 두 판정](https://stablescan.achivx.com/v1/addresses/0x28C6c06298d514Db089934071355E5743bf21d60/risk?chain=1)

## 더 알아보기

- [정직성 계약이란 무엇입니까?](https://achivx.kr/academy/for-agents/what-is-the-honesty-contract/)
- [정직한 숫자](https://achivx.kr/academy/concepts/honest-numbers/)
- [레슨: 페이로드에서 정직성 계약 읽기](https://achivx.kr/academy/courses/the-scanner-for-agents/the-scanner-for-agents-03-reading-the-honesty-contract/)

## 관련 질문

- [주소에 대한 위험 판정 하나를 얻으려면 어떻게 하며, 언제 unknown이 됩니까?](https://achivx.kr/academy/api/address-risk/)
- [제재 대상 또는 해킹 자금에 대한 주소의 노출을 측정하려면 어떻게 합니까?](https://achivx.kr/academy/api/address-exposure/)
- [코드에서 오류, 요청 한도, 타임아웃을 처리하려면 어떻게 합니까?](https://achivx.kr/academy/api/errors-and-limits-in-code/)

여기서 시작 · 읽기 · 2026-10-24 작성, openapi.json, agents.md 및 당일 실제 호출 기반. 구조는 인용한 것이며, 수치는 날짜 기준이고 인덱스에 따라 바뀝니다.

---

출처: https://achivx.kr/academy/api/reading-an-answer/ · 영어 원문: https://achivx.com/academy/api/reading-an-answer.html
