오류
오류 응답 형식, HTTP 상태 코드별 의미와 재시도 여부
2xx가 아닌 모든 응답은 같은 JSON 형식을 사용합니다.
{
"defined": true,
"code": "CONFLICT",
"status": 409,
"message": "Conflict",
"data": {}
}| 필드 | 설명 |
|---|---|
defined | 스펙에 정의된 오류면 true, 예상하지 못한 오류면 false입니다. false여도 형식은 같습니다. |
code | 오류 코드 문자열(아래 표). 분기 처리에는 message가 아니라 code를 사용하세요. |
status | HTTP 상태 코드와 같은 값입니다. |
message | 사람이 읽기 위한 설명입니다. 문구는 바뀔 수 있습니다. |
data | 추가 정보(선택). 현재는 402의 data.code만 정의되어 있습니다. |
POST /v1/verify의 검증 실패(코드 불일치, 만료 등)는 오류가 아니라 200 + verified: false입니다. 검증 결과를 참고하세요.
상태 코드
| 상태 | code | 주요 원인 | 재시도 |
|---|---|---|---|
| 400 | BAD_REQUEST | 요청 형식 오류, 멱등 키 누락·공백, 헤더와 본문의 멱등 키 불일치, 알 수 없는 템플릿·템플릿 변수, expiresInSec/maxAttempts/cost 범위 초과, code가 6자리 숫자가 아님, 잘못된 limit·cursor·기간 | 아니요. 요청을 고치세요. |
| 401 | UNAUTHORIZED | Authorization: Bearer 키가 없음, 형식 오류, 비활성(폐기·만료) 또는 인식할 수 없는 키 | 아니요. 키를 확인하세요. |
| 402 | PAYMENT_REQUIRED | 크레딧 부족. data.code가 INSUFFICIENT_CREDIT 또는 OVERDRAFT_LIMIT_EXCEEDED (POST /v1/issue만 해당) | 충전 후 재시도 |
| 403 | FORBIDDEN | 키에 필요한 scope가 없음, pk_ 키로 서버 전용 API 호출, pk_ 키 요청에 Origin이 없거나 허용 목록과 불일치 | 아니요. 키 설정을 확인하세요. |
| 404 | NOT_FOUND | 해당 앱에 없는 issueId(다른 앱의 것 포함) 또는 templateId | 아니요 |
| 409 | CONFLICT | 같은 멱등 키를 다른 요청 본문으로 재사용, 또는 그 키의 issue가 이미 새 발급으로 교체됨 | 아니요 |
| 500 | INTERNAL_SERVER_ERROR | 예상하지 못한 서버 오류 | 같은 멱등 키로 백오프 재시도 |
| 503 | SERVICE_UNAVAILABLE | 인증 또는 내부 의존성 일시 장애, 같은 멱등 키의 이전 요청이 아직 처리 중 | 같은 멱등 키로 백오프 재시도 |
엔드포인트별 오류 설명은 API 레퍼런스의 각 페이지에 있습니다.
처리 예제
type ApiError = {
defined: boolean;
code: string;
status: number;
message: string;
data?: { code?: "INSUFFICIENT_CREDIT" | "OVERDRAFT_LIMIT_EXCEEDED" };
};
function handleIssueError(error: ApiError) {
switch (error.code) {
case "PAYMENT_REQUIRED":
// 운영 알림: 크레딧 충전 필요 (error.data?.code)
return "잠시 후 다시 시도해 주세요.";
case "CONFLICT":
// 멱등 키를 다른 요청에 재사용했는지 확인
return "요청을 처리할 수 없습니다.";
case "SERVICE_UNAVAILABLE":
case "INTERNAL_SERVER_ERROR":
// 같은 멱등 키로 재시도 (/ko/guides/idempotency)
return "잠시 후 다시 시도해 주세요.";
default:
return "인증번호를 보낼 수 없습니다.";
}
}