에러 코드 & 트러블슈팅

Book Print API가 반환하는 HTTP 상태 코드, errorCode 카탈로그, 응답 shape, 트러블슈팅을 안내합니다.

HTTP 상태 코드

Book Print API가 사용하는 HTTP 상태 코드 카탈로그입니다. 같은 HTTP 상태라도 도메인 의미에 따라 구체적인 errorCode가 달라지므로, 클라이언트 분기는 HTTP 상태가 아니라 errorCode 하세요.

코드설명비고
200성공요청이 정상적으로 처리됨
201리소스 생성 성공새 리소스가 생성됨 (예: 주문, 도서)
400잘못된 요청필드 검증 실패, 잘못된 파라미터 등
401인증 실패API Key가 없거나 유효하지 않음
402충전금 부족잔액이 부족하여 주문 결제 불가
403권한 없음해당 리소스에 대한 접근 권한 없음 / 환경 불일치
404리소스 없음요청한 리소스를 찾을 수 없음
409충돌리소스 상태 충돌, Idempotency 락 타임아웃
422처리 불가동일 Idempotency-Key + 다른 요청 본문, PDF 생성 실패
429Rate Limit 초과요청 빈도 제한 초과(Retry-After 헤더 동봉)
500서버 에러서버 내부 오류
501Sandbox 미지원Sandbox 환경에서 의도적으로 차단된 엔드포인트 호출 (Live 전용)

에러 응답 형식

모든 실패 응답은 6필드 고정 shape으로 반환됩니다. errorCode·errors·fieldErrors항상 존재하므로 클라이언트에서 null 체크 없이 바로 접근할 수 있습니다.

필드타입역할
successboolean실패 응답은 항상 false
errorCodestring기계 분기용 식별자. ERR_* 형식. HTTP 상태 기반 기본값이 자동 주입되어 항상 존재
messagestringHTTP 상태 영어 라벨 ("Bad Request", "Not Found", "Forbidden" 등). 사용자 표시용 아님
dataobject | null기본 null. 일부 에러는 진단 객체 포함(예: 402 {required, balance, currency})
errorsstring[]사용자 표시용 한글 상세 메시지 배열. 항상 배열(비어 있으면 [])
fieldErrorsobject[]필드 단위 구조화 에러 배열. 항상 배열(해당 없으면 [])
사용자에게 표시할 한글은 errors[0]을 사용하세요. message는 영어 라벨이므로 사용자 노출에 부적합합니다. 클라이언트 분기는 errorCode + 필요 시 fieldErrors[].constraint로 하세요.
기본 shape (실패 응답 6필드)
{
  "success": false,
  "errorCode": "ERR_NOT_FOUND",
  "message": "Not Found",
  "data": null,
  "errors": ["해당 주문을 찾을 수 없습니다"],
  "fieldErrors": []
}

fieldErrors 항목 구조

필드 단위 검증 실패는 fieldErrors 배열의 각 항목이 아래 5필드를 가집니다. field·message는 항상 존재하며, 나머지 3개는 값이 있을 때만 포함됩니다.

필드타입설명
fieldstring에러 발생 필드명 (중첩은 점 표기)
messagestring한글 설명
currentValueany요청에 담겨 온 실제 값(있을 때만)
requiredValueany요구 값 또는 허용 범위(단일 값 또는 {min, increment} 객체)
constraintstring제약 종류 enum: required / min / max / increment / enum / pattern

errorCode 카탈로그

파트너에게 반환되는 errorCode 21종(Generic 8 + Specific 13)의 한눈 매핑입니다. 각 코드의 응답 예시·처리 가이드는 아래 errorCode 케이스 상세에서 확인하세요.

HTTPerrorCode카테고리발생 조건주요 발생 엔드포인트재시도
400ERR_VALIDATION_FAILEDGeneric일반 검증 실패 (Specific 코드 없을 때 기본값)모든 POST·PATCH·PUT (요청 본문/파라미터 검증)X
400ERR_MALFORMED_REQUESTGeneric요청 형식 오류 (필드 누락, null 등)모든 엔드포인트X
400ERR_INSUFFICIENT_PAGESSpecific최소 페이지 미달 (pageCount < pageMin)POST /books/{bookUid}/finalizationX
400ERR_PAGECOUNT_INVALIDSpecific최대 초과 또는 증분 규칙 위반POST /books/{bookUid}/finalization, /contentsX
400ERR_FINALIZE_PREREQ_UNMETSpecificfinalize 전제조건 미충족 (PDF 미업로드, DRAFT 아님 등)POST /books/{bookUid}/finalizationX
400ERR_CREATION_TYPE_UNSUPPORTEDSpecific책의 creationType과 호출 API가 호환되지 않음표지/내지/사진/PDF 추가 (cover·contents·photos·pdf-cover·pdf-contents)X
401ERR_UNAUTHORIZEDGeneric인증 실패 (API Key 누락·무효 등)모든 엔드포인트X
402ERR_INSUFFICIENT_CREDITSpecific충전금 잔액 부족 (datarequired·balance·currency 동봉)POST /orders, POST /orders/estimateX
403ERR_FORBIDDENGeneric권한 부족 (다른 파트너 자원 접근)모든 자원 접근 엔드포인트X
403ERR_ENV_MISMATCHSpecific호출 도메인(sandbox/live)과 대상 리소스의 환경 불일치책·사진·PDF 자원 접근X
404ERR_NOT_FOUNDGeneric리소스 미존재모든 단건 조회/수정/삭제 엔드포인트X
404ERR_PDF_NOT_UPLOADEDSpecificPDF 다운로드 시 업로드형 PDF가 디스크에 없음 (그룹 A — PDF_UPLOAD/MIX 내지)GET /books/{bookUid}/pdf-cover, /pdf-contentsX
409ERR_CONFLICTGeneric리소스 상태 충돌 (PDF 재등록), Idempotency 락 타임아웃POST /books/{bookUid}/pdf-cover, /pdf-contents, 모든 [Idempotent] 엔드포인트일부 O
409ERR_PDF_NOT_GENERATEDSpecificPDF 다운로드 시 책 최종화 호출 전 (그룹 B — TEMPLATE/MIX 표지)GET /books/{bookUid}/pdf-cover, /pdf-contentsO (finalize 후)
409ERR_PDF_PENDINGSpecificPDF 다운로드 시 백그라운드 생성 진행 중 (그룹 B)동일 (그룹 B)O (간격 두고)
422ERR_IDEMPOTENCY_KEY_MISMATCHSpecific동일 Idempotency-Key로 다른 요청 본문 전송[Idempotent] 적용 엔드포인트 (POST /books, /cover, /contents, /finalization, /orders, /orders/{uid}/cancel 등)X
422ERR_PDF_GENERATION_FAILEDSpecificPDF 다운로드 시 백그라운드 생성 실패 (그룹 B). 클라이언트 자체 해결 불가GET /books/{bookUid}/pdf-cover, /pdf-contents (그룹 B)X (고객지원)
429ERR_TOO_MANY_REQUESTSGenericRate Limit 초과 (Retry-After 헤더 동봉)모든 엔드포인트O (Retry-After 후)
500ERR_INTERNAL_ERRORGeneric서버 내부 오류 (미처리 예외 폴백)모든 엔드포인트O (Backoff)
500ERR_PDF_FILE_MISSINGSpecificPDF 다운로드 시 생성 완료(pdfStatus=2 COMPLETED)인데 디스크에 파일 부재 (그룹 B — 서버 결함)GET /books/{bookUid}/pdf-cover, /pdf-contents (그룹 B)X (고객지원)
501ERR_SANDBOX_UNSUPPORTEDSpecificSandbox 환경에서 의도적으로 차단된 엔드포인트 (Live 전용)현재 파트너 노출 엔드포인트 중 0건 (관리자 전용 결제 확인 한정)X (Live로)

엔드포인트별 환경(Sandbox/Live) 호출 가능 여부는 환경 매트릭스를 참조하세요. Retry 전략·Backoff·Idempotency 결합 등 운영 패턴은 에러 핸들링 & Retry 전략을 참조하세요.

errorCode 케이스 상세

errorCode별로 발생 조건·응답 예시·처리 가이드를 정리합니다. 응답 받았을 때 errorCode로 검색하여 해당 카드를 참조하세요.

ERR_VALIDATION_FAILED · HTTP 400 · Generic

일반 검증 실패. 필수 필드 누락·잘못된 값·형식 불일치 등 Specific 코드가 더 구체적이지 않은 모든 검증 실패에서 반환됩니다. fieldErrors 배열에서 field·constraint를 확인하여 사용자에게 구체 수정 안내를 제공하세요. 재시도 불가 — 요청 본문 수정 필요.

400 ERR_VALIDATION_FAILED
{
  "success": false,
  "errorCode": "ERR_VALIDATION_FAILED",
  "message": "Bad Request",
  "data": null,
  "errors": ["입력값을 확인해 주세요"],
  "fieldErrors": [
    {
      "field": "title",
      "message": "필수 항목입니다",
      "constraint": "required"
    }
  ]
}

ERR_MALFORMED_REQUEST · HTTP 400 · Generic

요청 본문 형식 자체 오류. JSON 파싱 실패, 잘못된 Content-Type, 필수 헤더 누락 등 ModelBinding 단계에서 거부된 요청. 재시도 불가 — 요청 형식 수정 필요.

400 ERR_MALFORMED_REQUEST
{
  "success": false,
  "errorCode": "ERR_MALFORMED_REQUEST",
  "message": "Bad Request",
  "data": null,
  "errors": ["요청 형식이 올바르지 않습니다"],
  "fieldErrors": []
}

ERR_INSUFFICIENT_PAGES · HTTP 400 · Specific

finalize 직전 최소 페이지 미달 감지. fieldErrorspageCountcurrentValue·requiredValue·constraint: "min"이 구조화되어 있어 UI에 바로 매핑 가능합니다. 처리: 사용자에게 "최소 N페이지 필요" 안내 후 콘텐츠 추가하여 재시도.

400 ERR_INSUFFICIENT_PAGES
{
  "success": false,
  "errorCode": "ERR_INSUFFICIENT_PAGES",
  "message": "Bad Request",
  "data": null,
  "errors": ["최소 페이지 미달: 현재 10p, 최소 24p"],
  "fieldErrors": [
    {
      "field": "pageCount",
      "message": "최소 24 페이지가 필요합니다",
      "currentValue": 10,
      "requiredValue": 24,
      "constraint": "min"
    }
  ]
}

ERR_PAGECOUNT_INVALID · HTTP 400 · Specific

최대 페이지 초과 또는 증분 규칙 위반(예: 짝수 단위만 허용). fieldErrorsconstraintmax / increment 구분. 처리: pageMin~pageMax 범위와 pageIncrement 단위 확인 후 재시도.

400 ERR_PAGECOUNT_INVALID — increment 위반
{
  "success": false,
  "errorCode": "ERR_PAGECOUNT_INVALID",
  "message": "Bad Request",
  "data": null,
  "errors": ["페이지 수는 2의 배수여야 합니다"],
  "fieldErrors": [
    {
      "field": "pageCount",
      "message": "2의 배수만 허용됩니다",
      "currentValue": 25,
      "requiredValue": { "min": 24, "increment": 2 },
      "constraint": "increment"
    }
  ]
}

ERR_FINALIZE_PREREQ_UNMET · HTTP 400 · Specific

finalize 전제조건 미충족 — PDF 미업로드(PDF_UPLOAD 책), DRAFT 상태 아님 등. 다중 필드가 미충족인 경우 fieldErrors에 모두 누적되며, 하나라도 충족되면 해당 항목은 제외됩니다. 처리: fieldErrors에서 누락 항목별로 준비 단계 완료 후 재시도.

400 ERR_FINALIZE_PREREQ_UNMET — 표지/내지 PDF 미업로드
{
  "success": false,
  "errorCode": "ERR_FINALIZE_PREREQ_UNMET",
  "message": "Bad Request",
  "data": null,
  "errors": [
    "coverPdf: 표지 PDF가 업로드되지 않았습니다",
    "contentsPdf: 내지 PDF가 업로드되지 않았습니다"
  ],
  "fieldErrors": [
    {
      "field": "coverPdf",
      "message": "표지 PDF가 업로드되지 않았습니다",
      "requiredValue": "uploaded",
      "constraint": "required"
    },
    {
      "field": "contentsPdf",
      "message": "내지 PDF가 업로드되지 않았습니다",
      "requiredValue": "uploaded",
      "constraint": "required"
    }
  ]
}

ERR_CREATION_TYPE_UNSUPPORTED · HTTP 400 · Specific

책의 creationType(TEMPLATE/PDF_UPLOAD/MIX_COVER_TEMPLATE)과 호출 API가 호환되지 않을 때 (예: PDF_UPLOAD 책에 POST /cover 템플릿 호출). 재시도 불가 — 책 생성 시 creationType 또는 호출 API 변경 필요. 자세한 호환성은 창작 방식을 참조하세요.

400 ERR_CREATION_TYPE_UNSUPPORTED
{
  "success": false,
  "errorCode": "ERR_CREATION_TYPE_UNSUPPORTED",
  "message": "Bad Request",
  "data": null,
  "errors": ["이 책의 creationType(PDF_UPLOAD)에서는 사진 업로드를 지원하지 않습니다"],
  "fieldErrors": []
}

ERR_UNAUTHORIZED · HTTP 401 · Generic

Authorization 헤더 누락, Bearer 접두사 누락, 폐기·만료된 API Key. 환경 불일치(Sandbox Key로 Live URL 호출 등)는 401이 아니라 403 ERR_ENV_MISMATCH로 분기됩니다. 재시도 불가Authorization: Bearer <API Key> 형식 확인, 포털에서 Key 상태 확인 후 새 요청.

401 ERR_UNAUTHORIZED
{
  "success": false,
  "errorCode": "ERR_UNAUTHORIZED",
  "message": "Unauthorized",
  "data": null,
  "errors": ["인증이 필요합니다"],
  "fieldErrors": []
}

ERR_INSUFFICIENT_CREDIT · HTTP 402 · Specific

주문 생성 시 충전금 잔액 부족. 이 에러는 예외적으로 data에 진단 객체(required·balance·currency)가 들어있어 충전 UI로 바로 안내할 수 있습니다. 재시도 불가 — 파트너 포털에서 충전 후 새 요청.

402 ERR_INSUFFICIENT_CREDIT
{
  "success": false,
  "errorCode": "ERR_INSUFFICIENT_CREDIT",
  "message": "Insufficient Credit",
  "data": {
    "required": 5500,
    "balance": 1820.00,
    "currency": "KRW"
  },
  "errors": ["잔액이 부족합니다. 필요: 5500, 잔액: 1820.00"],
  "fieldErrors": []
}

ERR_FORBIDDEN · HTTP 403 · Generic

본인 소유가 아닌 자원에 접근하려 한 경우. 재시도 불가 — 자원 소유권 확인 후 본인 자원으로 재요청.

403 ERR_FORBIDDEN
{
  "success": false,
  "errorCode": "ERR_FORBIDDEN",
  "message": "Forbidden",
  "data": null,
  "errors": ["해당 리소스에 대한 권한이 없습니다"],
  "fieldErrors": []
}

ERR_ENV_MISMATCH · HTTP 403 · Specific

Sandbox 도메인에서 Live 리소스를 접근하거나 그 반대인 경우. 401(잘못된 키)과 명확히 구분되므로 클라이언트는 "도메인 재선택"만 안내하면 됩니다. 재시도 불가api-sandbox.sweetbook.comapi.sweetbook.com 중 키에 맞는 쪽으로 새 요청.

403 ERR_ENV_MISMATCH
{
  "success": false,
  "errorCode": "ERR_ENV_MISMATCH",
  "message": "Forbidden",
  "data": null,
  "errors": [
    "환경 불일치: 호출 도메인과 API Key의 환경(sandbox/live)이 일치하지 않습니다. 키에 맞는 도메인으로 재시도하세요."
  ],
  "fieldErrors": []
}

ERR_NOT_FOUND · HTTP 404 · Generic

요청한 리소스(도서, 주문, 사진 등)를 찾을 수 없음. errors[0] 문구로 어떤 리소스가 누락됐는지 식별 가능합니다. 재시도 불가 — 생성 응답에서 받은 UID가 맞는지, 같은 환경에서 조회하는지 확인.

404 ERR_NOT_FOUND — 도서 조회
{
  "success": false,
  "errorCode": "ERR_NOT_FOUND",
  "message": "Not Found",
  "data": null,
  "errors": ["책을 찾을 수 없습니다: bk_xxx"],
  "fieldErrors": []
}

참고: PDF 다운로드 시 그룹 A(PDF_UPLOAD/MIX 내지)에서 파일이 없는 경우는 더 구체적인 ERR_PDF_NOT_UPLOADED가 반환됩니다.

ERR_PDF_NOT_UPLOADED · HTTP 404 · Specific

PDF 다운로드 시 업로드형 PDF가 디스크에 없음. 그룹 A(PDF_UPLOAD cover/contents + MIX_COVER_TEMPLATE 내지)에서만 발생. 재시도 불가POST /books/{bookUid}/pdf-cover 또는 /pdf-contents로 PDF 업로드 후 새 요청.

404 ERR_PDF_NOT_UPLOADED (그룹 A)
{
  "success": false,
  "errorCode": "ERR_PDF_NOT_UPLOADED",
  "message": "Not Found",
  "data": null,
  "errors": ["PDF 파일이 업로드되지 않았습니다."],
  "fieldErrors": []
}

ERR_CONFLICT · HTTP 409 · Generic

두 가지 상황에서 반환됩니다.

① 리소스 이미 존재 (재시도 불가)

PDF 업로드 POST(신규 등록 전용)를 이미 등록된 책에 다시 호출. 교체하려면 PUT 메서드를 사용하세요. 같은 요청을 재시도해도 같은 결과.

409 ERR_CONFLICT — PDF 표지 POST 중복
{
  "success": false,
  "errorCode": "ERR_CONFLICT",
  "message": "Conflict",
  "data": null,
  "errors": ["표지 PDF가 이미 등록되어 있습니다. 교체하려면 PUT 메서드를 사용하세요."],
  "fieldErrors": []
}

② Idempotency 락 타임아웃 (재시도 가능)

동일한 Idempotency-Key동시 요청이 들어와 선행 요청의 분산 락이 잡혀 있는 경우. 첫 요청이 완료되기를 기다렸다가 같은 키로 재시도하면 캐시된 응답이 반환됩니다. 상세는 멱등성 (Idempotency) 참조.

409 ERR_CONFLICT — Idempotency 락 타임아웃
{
  "success": false,
  "errorCode": "ERR_CONFLICT",
  "message": "Conflict",
  "data": null,
  "errors": ["동일한 요청이 처리 중입니다. 잠시 후 다시 시도하세요."],
  "fieldErrors": []
}

참고: 같은 키로 다른 본문을 보낸 경우는 409가 아니라 422 ERR_IDEMPOTENCY_KEY_MISMATCH로 반환됩니다.

ERR_PDF_NOT_GENERATED · HTTP 409 · Specific

PDF 다운로드 시 책 최종화(POST /finalization) 호출 전. 그룹 B(TEMPLATE cover/contents + MIX_COVER_TEMPLATE 표지)에서만 발생. 처리: POST /books/{bookUid}/finalization 호출 후 재시도.

409 ERR_PDF_NOT_GENERATED (그룹 B)
{
  "success": false,
  "errorCode": "ERR_PDF_NOT_GENERATED",
  "message": "Conflict",
  "data": null,
  "errors": ["책 최종화 전이라 PDF가 존재하지 않습니다."],
  "fieldErrors": []
}

ERR_PDF_PENDING · HTTP 409 · Specific

PDF 다운로드 시 백그라운드 생성 진행 중. 그룹 B에서만 발생. 처리: 일정 간격(예: 10초~수십 초) 후 재시도. 응답에는 Retry-After 헤더가 포함되지 않으므로 클라이언트가 자체 대기 간격을 결정해야 합니다. 무한 폴링 금지 — 횟수·총 대기 시간 제한 필수.

409 ERR_PDF_PENDING (그룹 B)
{
  "success": false,
  "errorCode": "ERR_PDF_PENDING",
  "message": "Conflict",
  "data": null,
  "errors": ["PDF 생성이 진행 중입니다. 잠시 후 다시 시도해 주세요."],
  "fieldErrors": []
}

ERR_IDEMPOTENCY_KEY_MISMATCH · HTTP 422 · Specific

같은 Idempotency-Key이전과 다른 요청 본문을 보낸 경우. 재시도는 반드시 동일 키 + 동일 본문으로만 가능합니다. 재시도 불가 — 본문이 달라져야 한다면 새 키 발급 후 새 요청.

422 ERR_IDEMPOTENCY_KEY_MISMATCH
{
  "success": false,
  "errorCode": "ERR_IDEMPOTENCY_KEY_MISMATCH",
  "message": "Unprocessable Entity",
  "data": null,
  "errors": [
    "동일한 Idempotency-Key에 서로 다른 요청 본문이 사용되었습니다. 같은 키는 같은 본문에만 재사용 가능합니다."
  ],
  "fieldErrors": []
}

ERR_PDF_GENERATION_FAILED · HTTP 422 · Specific

PDF 다운로드 시 백그라운드 생성 실패. 그룹 B에서만 발생. 클라이언트 자체 해결 불가 — 사용자에게 실패를 안내하고 고객지원팀 문의 권장. 재시도해도 같은 결과.

422 ERR_PDF_GENERATION_FAILED (그룹 B — 생성 실패)
{
  "success": false,
  "errorCode": "ERR_PDF_GENERATION_FAILED",
  "message": "Error",
  "data": null,
  "errors": ["PDF 생성에 실패했습니다. 고객지원팀에 문의해 주세요."],
  "fieldErrors": []
}

ERR_TOO_MANY_REQUESTS · HTTP 429 · Generic

정책별(auth/general/upload) 요청 한도 초과. 응답 본문과 함께 Retry-After 헤더(초 단위)가 동봉됩니다. 처리: Retry-After 헤더 값만큼 대기 후 재시도. 정책 상세는 Rate Limiting 가이드 참고.

429 ERR_TOO_MANY_REQUESTS (헤더 포함)
HTTP/1.1 429 Too Many Requests
Retry-After: 60
Content-Type: application/json; charset=utf-8

{
  "success": false,
  "errorCode": "ERR_TOO_MANY_REQUESTS",
  "message": "Too Many Requests",
  "data": null,
  "errors": ["요청 한도를 초과했습니다. Retry-After 헤더 값만큼 대기 후 재시도하세요."],
  "fieldErrors": []
}

ERR_INTERNAL_ERROR · HTTP 500 · Generic

서버에서 미처리 예외가 발생한 경우의 폴백 응답. 내부 정보 유출 방지를 위해 일반 메시지만 반환되며, 일시적 오류일 수 있습니다. 처리: 짧은 간격(예: 1~2초) 후 Backoff로 재시도. 지속 발생 시 고객지원팀 문의.

500 ERR_INTERNAL_ERROR
{
  "success": false,
  "errorCode": "ERR_INTERNAL_ERROR",
  "message": "Internal Server Error",
  "data": null,
  "errors": ["서버 오류가 발생했습니다"],
  "fieldErrors": []
}

ERR_PDF_FILE_MISSING · HTTP 500 · Specific

PDF 다운로드 시 생성 완료 상태(pdfStatus=2 COMPLETED)인데 디스크에 파일이 부재. 서버 결함으로 클라이언트 자체 해결 불가. 처리: 사용자에게 실패 안내 + 고객지원팀 문의. 재시도해도 같은 결과.

500 ERR_PDF_FILE_MISSING (그룹 B — 서버 결함)
{
  "success": false,
  "errorCode": "ERR_PDF_FILE_MISSING",
  "message": "Internal Server Error",
  "data": null,
  "errors": ["PDF 파일이 존재하지 않습니다. 고객지원팀에 문의해 주세요."],
  "fieldErrors": []
}

ERR_SANDBOX_UNSUPPORTED · HTTP 501 · Specific

Sandbox 환경에서 의도적으로 차단된 엔드포인트(예: 외부 결제망 호출) 호출. Live 환경 전용 액션이며, Sandbox에서는 실 결제 등 외부 부수효과 방지를 위해 차단. 엔드포인트별 환경 호출 가능 여부는 환경 매트릭스 참조.

재시도 주의: HTTP 501은 일반적으로 "서버 미구현"으로 해석되지만, 본 케이스는 의도적 미지원이라 재시도해도 동일 결과입니다. 자동 재시도 로직에서 제외하세요.

501 ERR_SANDBOX_UNSUPPORTED
{
  "success": false,
  "errorCode": "ERR_SANDBOX_UNSUPPORTED",
  "message": "Not Implemented",
  "data": null,
  "errors": ["이 엔드포인트는 sandbox 환경에서 지원되지 않습니다"],
  "fieldErrors": []
}

PDF 다운로드 — 출처별 응답 분기 (그룹 A·B)

GET /books/{bookUid}/pdf-cover·GET /books/{bookUid}/pdf-contents는 책의 creationType에 따라 응답이 두 그룹으로 분기됩니다. 클라이언트는 errorCode로 분기해야 하며, HTTP 상태만으로 판단하면 의도와 다른 동작이 됩니다.

자세한 분기 표는 Books — PDF 기반 / Books — 템플릿 기반 페이지의 PDF 다운로드 섹션을 참조하세요.

자주 묻는 질문 (FAQ)

QHTTP 상태 코드로 분기해도 되나요?
A권장하지 않습니다. 같은 400도 ERR_INSUFFICIENT_PAGES·ERR_PAGECOUNT_INVALID·ERR_FINALIZE_PREREQ_UNMET·ERR_VALIDATION_FAILED 등으로 세분화되어 있어, errorCode로 분기해야 정확한 사용자 안내가 가능합니다.
Q응답 메시지 문자열을 includes()로 파싱해 분기해도 되나요?
A금지합니다. errors[0]·message 문구는 다국어화·표현 정비로 언제든 변경될 수 있습니다. 분기는 errorCode + fieldErrors[].constraint 조합으로만 하세요.
QSandbox Key로 Live URL을 호출하면?
A403 ERR_ENV_MISMATCH가 반환됩니다. 401(키 무효)과 구분되므로 클라이언트는 "도메인만 맞춰서 재시도"하면 됩니다. Sandbox Key는 api-sandbox.sweetbook.com, Live Key는 api.sweetbook.com에서만 사용 가능합니다.
Q같은 Idempotency-Key로 다른 본문을 보내면?
A422 ERR_IDEMPOTENCY_KEY_MISMATCH가 반환됩니다. 재시도는 반드시 원본과 동일한 본문 + 동일 키로만 가능합니다. 본문이 달라져야 한다면 새로운 키를 발급하세요.
QAPI Key가 노출되면?
A즉시 파트너 포털에서 해당 API Key를 폐기하고 새 Key를 재발급하세요. 노출된 Key로 발생한 피해는 복구가 어려울 수 있으므로 빠른 대응이 중요합니다.