응답 형식
json
{
"error": {
"code": "VALIDATION_FAILED",
"message": "Field 'amount' must be a positive integer.",
"details": [
{ "path": "amount", "issue": "must be >= 1" }
],
"requestId": "req_4f29ab..."
}
}문의 시 requestId를 함께 전달하면 1분 내 로그 조회가 가능합니다.
전체 코드 매트릭스
| HTTP | Code | 의미 |
|---|---|---|
| 400 | VALIDATION_FAILED | 요청 본문/쿼리 파라미터 검증 실패 |
| 401 | CLOUD_API_KEY_INVALID | API Key 누락 또는 잘못됨 |
| 401 | CLOUD_API_KEY_REVOKED | 관리자가 회수한 키 |
| 401 | WEBHOOK_SIGNATURE_INVALID | Webhook HMAC 서명 불일치 |
| 403 | CLOUD_MODULE_NOT_ENABLED | 플랜에 포함되지 않은 모듈 호출 |
| 403 | SCOPE_INSUFFICIENT | API Key에 해당 작업 권한 없음 |
| 404 | RESOURCE_NOT_FOUND | 존재하지 않는 리소스 |
| 409 | RESOURCE_CONFLICT | 중복 생성, 동시 수정 충돌 |
| 422 | BUSINESS_RULE_VIOLATION | 비즈니스 제약 위반(예: 음수 입찰) |
| 429 | RATE_LIMITED | 초당 요청 한도 초과 |
| 429 | QUOTA_EXCEEDED | 월 quota 초과 |
| 500 | INTERNAL_ERROR | 서버 내부 오류 (재시도 권장) |
| 503 | SERVICE_UNAVAILABLE | 점검 또는 일시적 의존 장애 |
Quota / Rate Limit 처리 패턴
typescript
try {
await client.notify.send({ ... });
} catch (e: any) {
if (e.code === 'RATE_LIMITED') {
const retryAfter = Number(e.headers['retry-after'] ?? 1);
await new Promise(r => setTimeout(r, retryAfter * 1000));
return retry();
}
if (e.code === 'QUOTA_EXCEEDED') {
notifyOps('quota exhausted: ' + e.details);
return;
}
throw e;
}검증 오류
VALIDATION_FAILED는 항상 details[] 배열에 path/issue를 포함합니다. i18n이 필요하면 클라이언트에서 code 기준으로 자체 번역하세요(서버는 영문 메시지만 제공).
서버 오류 (5xx)
5xx는 멱등성이 보장되는 요청(GET, PUT, 명시적 idempotency-key가 있는 POST)에 한해 exponential backoff(최대 5회)로 재시도하는 것을 권장합니다.