# 에러

실패 응답:

```json
{
  "success": false,
  "message": "No active score-sharing consent for this client and purpose",
  "errorCode": "SW2300",
  "data": null
}
```

## 에러코드 표

| errorCode | 이름 | 의미 | 대응 |
|---|---|---|---|
| `SW2102` | INVALID_API_KEY | 헤더 누락/키 불일치 | 헤더·키 확인, 재시도 금지 |
| `SW2101` | PARTNER_CLIENT_SUSPENDED | 클라이언트 정지 | 운영팀 문의 |
| `SW2300` | NO_CONSENT | 활성 동의 없음 | `POST /fi/consent/requests`로 동의 요청 |
| `SW2301` | CONSENT_REVOKED | 동의 철회됨 | 재동의 요청 |
| `SW2302` | CONSENT_EXPIRED | 동의 만료됨 | 재동의 요청 |
| `SW2303` | CONSENT_NOT_FOUND | 동의 영수증 없음 | receiptId 확인 |
| `SW2304` | PARTNER_FORBIDDEN | 범위(scope) 권한 없음 | 계약 범위 확인 |
| `SW2305` | FI_SUBJECT_NOT_FOUND | 연결된 주체 없음 | pairwiseSub 확인 |
| `SW1001` | VALIDATION_ERROR | 입력 검증 실패 — 배치 100건 초과, 필수 필드 누락, `/fi/decision/evaluate`의 `productCode` 형식 위반(`[A-Z0-9_]` 1~40자가 아님), 조회 구간 초과(history 365일 / usage 92일) 등 | 요청 수정, 재시도 금지 |
| `SW1004` | RATE_LIMIT_EXCEEDED | 속도 제한(60 req/min) 초과 | `Retry-After`만큼 대기 후 재시도 |

주체 존재 비공개: 라이브에서 동의 없음·철회·만료·주체 없음은 FI가 구분할 수 없도록 동일 라벨로
처리될 수 있습니다(배치는 항상 단일 `DENIED`). 거부 응답으로 가입 여부를 추론할 수 없습니다.

## HTTP 상태와 재시도 정책

| HTTP | 상황 | 재시도 |
|---|---|---|
| 200 | 정상(verify의 valid=false 포함) | — |
| 4xx (429 제외) | 요청 자체 문제 | 재시도 금지 |
| 429 | 속도 제한 | `Retry-After: <seconds>`(최소 1)만큼 대기 후 재시도, 최대 3회 권장 |
| 5xx | 일시적 서버 오류 | 지수 백오프(1s→2s→4s), 최대 3회 권장 |

```
HTTP/1.1 429 Too Many Requests
Retry-After: 12
```

공식 SDK(Java/TypeScript/Python)는 이 정책을 내장합니다.

## 사유코드는 에러가 아님

사유코드는 정상 점수 응답 안에서 점수 수준의 이유를 설명하는 데이터입니다
(카탈로그 31종, 응답당 최대 4건, 영향 순 랭킹). 여신 거절 사유 고지 등에 활용됩니다.
