에러
실패 응답은 표준 봉투에 success=false와 errorCode로 표현됩니다.
{
"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 | 동의 영수증(receipt) 없음 | 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
Content-Type: application/json
{ "success": false, "message": "Rate limit exceeded", "errorCode": "SW1004", "data": null }
공식 SDK(Java/TypeScript/Python)는 이 정책을 내장하고 있습니다:
429는
Retry-After 존중 재시도(최대 3회), 5xx는 지수 백오프, 4xx(429 제외)는 재시도하지 않습니다.사유코드(reason code)와 에러의 구분
사유코드는 에러가 아닙니다. 정상 점수 응답 안에서 "점수가 왜 이 수준인지"를 설명하는 데이터입니다(카탈로그 31종, 응답당 최대 4건, 영향 순 랭킹). 여신 거절 사유 고지(adverse action notice) 등에 활용할 수 있습니다. 전체 카탈로그는 운영팀에서 제공하는 카탈로그 문서를 참조하세요.