Books API — PDF 기반

파트너가 제작한 PDF 파일(표지·내지)을 직접 업로드하여 책을 생성하는 방식의 API 레퍼런스입니다. 템플릿 바인딩이 아닌 PDF 직접 업로드 흐름과 각 엔드포인트의 정확한 스펙을 다룹니다.

템플릿 방식(creationType="TEMPLATE")은 Books — 템플릿 기반 페이지를 참고하세요. 실제 호출 흐름을 단계별 따라 하기로 보려면 PDF 업로드 시나리오를 참고하세요.
모든 Books API는 인증이 필요합니다. API Key를 Authorization: Bearer {YOUR_API_KEY} 헤더로 제공하세요. 자세한 인증 안내는 인증 가이드를 참고하세요.

이 방식이 적합한 경우

  • 이미 자체 제작한 PDF 파일이 있는 경우
  • 인쇄용 PDF를 직접 디자인 도구(InDesign, Illustrator 등)로 제작하는 경우
  • 레이아웃·폰트·이미지를 파트너가 완전히 제어하고 싶은 경우

지원 creationType

creationType표지내지비고
PDF_UPLOADPDF 직접 업로드PDF 직접 업로드이 페이지의 기본 흐름
MIX_COVER_TEMPLATE템플릿 바인딩PDF 직접 업로드표지 추가는 Books — 템플릿 기반POST /books/{bookUid}/cover 사용

TEMPLATE 방식은 표지·내지 모두 템플릿 바인딩으로 진행하며, 이 페이지의 PDF 업로드 엔드포인트(/pdf-cover, /pdf-contents)는 사용할 수 없습니다.Books — 템플릿 기반을 참고하세요.

책 생성

POST/books

새로운 책을 생성합니다. 생성 직후 status="draft" 상태이며, 이후 PDF 업로드와 최종화 단계를 거쳐 주문 가능 상태로 진입합니다.

Request Body

필드타입필수설명
titlestringO책 제목 (1~255자)
bookSpecUidstringO판형 UID (예: SQUAREBOOK_HC). BookSpecs API로 조회
creationTypestringO"PDF_UPLOAD" 또는 "MIX_COVER_TEMPLATE". 그 외 값은 400 에러
pageCountintegerO내지 페이지 수. PDF 방식은 필수. 업로드할 내지 PDF의 실제 페이지 수와 정확히 일치해야 함 (불일치 시 내지 업로드 단계에서 400)
specProfileUidstringSpecProfile UID (선택, 일반적으로 미사용). 사용자별 판형 프로파일이 사전 등록된 경우에만 사용. 제공 시 해당 프로필과 연결, 유효하지 않으면 400
externalRefstring파트너 외부 참조 식별자 (최대 100자). 파트너 시스템의 고유 ID 매핑용
이 단계에서는 빈 책만 생성됩니다. 응답으로 받은 bookUid를 사용해 표지·내지 PDF 업로드와 최종화를 순차적으로 진행해야 주문 가능한 상태(finalized)가 됩니다.
Idempotency-Key 지원: POST /booksIdempotency-Key 헤더를 지원합니다. 동일한 키로 재요청해도 책이 중복 생성되지 않으므로, 네트워크 오류 등 재시도 상황에 활용하세요. 재시도가 캐시된 응답으로 처리된 경우 응답 헤더에 X-Idempotent-Replayed: true가 포함됩니다. 자세한 동작은 멱등성 가이드를 참고하세요.

Request 예시

Request body (PDF_UPLOAD)
{
  "title": "PDF 업로드 샘플",
  "bookSpecUid": "SQUAREBOOK_HC",
  "creationType": "PDF_UPLOAD",
  "pageCount": 24,
  "externalRef": "PARTNER-ORDER-001"
}
Request body (MIX_COVER_TEMPLATE)
{
  "title": "혼합 방식 샘플",
  "bookSpecUid": "SQUAREBOOK_HC",
  "creationType": "MIX_COVER_TEMPLATE",
  "pageCount": 24,
  "externalRef": "PARTNER-ORDER-002"
}
Request
curl -X POST 'https://api-sandbox.sweetbook.com/v1/books' \
  -H 'Authorization: Bearer {YOUR_API_KEY}' \
  -H 'Idempotency-Key: unique-request-id-001' \
  -H 'Content-Type: application/json' \
  -d '{
    "title": "PDF 업로드 샘플",
    "bookSpecUid": "SQUAREBOOK_HC",
    "creationType": "PDF_UPLOAD",
    "pageCount": 24,
    "externalRef": "PARTNER-ORDER-001"
  }'

응답 필드

필드타입설명
bookUidstring생성된 책의 UID
pageMetaobject페이지 제약 메타. currentPageCount·pageMin·pageMax·pageIncrement·isValid 5개 필드

Response 예시

Response (201 Created)
{
  "success": true,
  "message": "책 생성 완료",
  "data": {
    "bookUid": "bk_2h4L********",
    "pageMeta": {
      "currentPageCount": 24,
      "pageMin": 24,
      "pageMax": 200,
      "pageIncrement": 2,
      "isValid": true
    }
  }
}

pageMeta: PDF_UPLOAD·MIX_COVER_TEMPLATE 방식은 책 생성 시 pageCount를 입력받으므로 currentPageCount가 입력값과 동일하게 설정됩니다(예: pageCount: 24currentPageCount: 24). TEMPLATE 방식은 0으로 초기화됩니다. isValidpageMin ≤ currentPageCount ≤ pageMax 및 증분 규칙 만족 여부를 나타내며, 페이지 제약만 판정하고 표지·내지 PDF 업로드 여부는 별도입니다.

HTTP 상태 코드

코드errorCode설명
201 Created책 생성 성공
400 Bad RequestERR_VALIDATION_FAILEDtitle/bookSpecUid/creationType 누락 또는 허용되지 않은 값, PDF 방식인데 pageCount 누락, 잘못된 specProfileUid
401 UnauthorizedERR_UNAUTHORIZED인증 실패
422 Unprocessable EntityERR_IDEMPOTENCY_KEY_MISMATCH같은 Idempotency-Key로 다른 본문 전송
429 Too Many RequestsERR_TOO_MANY_REQUESTS요청 빈도 제한 초과 — Rate Limiting 가이드 참고
500 Internal Server ErrorERR_INTERNAL_ERROR서버 오류

본 엔드포인트의 주요 검증 실패 메시지(400 ERR_VALIDATION_FAILED):

  • creationType 누락 또는 허용되지 않은 값 — errors[0]: "유효하지 않은 creationType: <값> (허용: TEMPLATE, PDF_UPLOAD, MIX_COVER_TEMPLATE)"
  • PDF 방식(PDF_UPLOAD · MIX_COVER_TEMPLATE)인데 pageCount 누락 — errors[0]: "creation_type=<값>는 pageCount(내지 페이지수)가 필수입니다."

응답 6필드 shape, 다른 errorCode, 처리 가이드는 에러 코드 & 트러블슈팅을 참조하세요.

PDF 파일 요건

표지·내지 PDF 업로드 시 PDF 형식·크기·페이지 수가 동기 검증됩니다. 업로드 단계에서 차단되는 항목(hard fail)과 업로드는 성공하지만 주문 단계에서 차단되는 항목(soft warning)이 구분됩니다. 업로드 전에 아래 요건을 충족하는지 확인하세요.

판형별 PDF 규격

정확한 PDF 규격(너비·높이 mm)은 판형(BookSpec)마다 다릅니다. 구조는 커버 타입(소프트/하드)에 따라 다음과 같이 분기되며, 실제 값은 GET /book-specs 또는 파트너 포털에서 확인하세요.

커버 타입표지 규격 구조내지 규격 구조
소프트커버고정 크기 단일 객체 (책등 두께 무관)고정 크기
하드커버페이지 수 범위별 배열 — 책등 두께에 따라 너비 가변고정 크기

허용 오차

허용 오차는 판형의 pdfSize 정의값을 기준으로 적용됩니다. 대부분의 판형은 정의값과 정확히 일치(오차 0mm)하도록 설정되어 있습니다. 안전한 인쇄 품질을 위해 PDF 제작 시 다음 권고 마진 내로 제작하는 것을 권장합니다.

항목권고 마진 (제작 시)
소프트커버 표지 (너비·높이)±1mm 이내
하드커버 표지 너비±2mm 이내 (책등 두께 보정 여유)
하드커버 표지 높이±1mm 이내
내지 (너비·높이)±1mm 이내

실제 허용치는 판형마다 다를 수 있습니다. 정의값 정확 일치를 목표로 제작하되, 위 권고 마진 내라면 일반적으로 안전합니다. 검증 실패 시 응답의 errors 배열에 실제 측정값과 허용 규격이 함께 표기됩니다.

공통 제약 (검증 실패 시 업로드 차단 — Hard Fail)

  • 파일 형식: PDF (시그니처 %PDF- 확인)
  • 파일 크기: 500MB 이하 (요청 크기 제한과 동일)
  • PDF 구조 무결성: 손상되거나 파싱 불가능한 PDF는 차단
  • 표지 페이지 수: 1페이지 고정
  • 내지 페이지 수: 책 생성 시 지정한 pageCount와 정확히 일치
  • PDF 크기(mm): 위 표의 권고 마진 내

페이지 수 권장 사항 (업로드는 성공, 주문 시 차단 — Soft Warning)

책 생성 시 지정한 pageCount가 판형의 페이지 규칙을 벗어나도 PDF 업로드 자체는 성공합니다. 응답의 warnings 배열에 경고가 포함되며, 주문 생성 시 400 에러로 차단됩니다.

규칙설명참고 (SQUAREBOOK_HC)
페이지 수 범위pageCount가 판형의 pageMin ~ pageMax 사이24 ~ 130
페이지 수 배수pageCountpageIncrement의 배수2의 배수 (24, 26, 28, …)

예를 들어 SQUAREBOOK_HC에서 pageCount=23으로 책을 생성하면 23p PDF 업로드는 성공하지만,pageIncrement=2의 배수가 아니므로 주문 단계에서 거부됩니다. 책 생성 시점부터 판형 범위 내·배수 조건을 충족하도록 지정하세요.

PDF 규격 예시 — 하드커버 (BookSpec.pdfSize)
{
  "cover": [
    { "minPage": 24, "maxPage": 64, "width": 544, "height": 288 },
    { "minPage": 65, "maxPage": 130, "width": 550, "height": 288 }
  ],
  "inner": { "width": 249, "height": 254 }
}
PDF 규격 예시 — 소프트커버 (BookSpec.pdfSize)
{
  "cover": { "width": 332, "height": 216 },
  "inner": { "width": 148, "height": 210 }
}

400 ERR_VALIDATION_FAILED: PDF 규격 검증 실패 시 errors 배열에 위반 항목이 모두 포함됩니다 (예: "내지 PDF 페이지수 불일치: 올바른 페이지수 24p, 업로드된 페이지수 30p", "PDF 너비 불일치: 실제 148.0mm, 허용 규격 249mm (+/-1mm)", "PDF 높이 불일치: 실제 210.0mm, 허용 규격 254.0mm (+/-1mm)"). LAYFLAT 제본은 페이지수 메시지에 책 페이지 환산값이 괄호로 부가됩니다(예: "... (책 페이지 환산: 올바른 페이지수 16p, 업로드된 페이지수 20p)"). 응답 shape 상세는 에러 코드 & 트러블슈팅 — ERR_VALIDATION_FAILED를 참조하세요.

표지 PDF

표지 PDF는 1페이지 고정입니다. 신규 등록(POST), 교체(PUT), 다운로드(GET) 세 가지 엔드포인트를 제공합니다. 업로드/교체 동작은 동일한 검증을 거치며 응답 본문 구조도 같습니다 (HTTP 상태 코드와 메시지만 다름).

creationType="MIX_COVER_TEMPLATE" 책의 표지는 PDF가 아닌 템플릿으로 생성됩니다. 해당 책에 PDF 표지 업로드 시도 시 400 에러가 반환됩니다. 표지는 Books — 템플릿 기반POST /books/{bookUid}/cover를 사용하세요.

공통 응답 필드 (POST · PUT)

필드타입설명
bookUidstring대상 책 UID
kindstring"cover" 고정
validboolean검증 성공 여부 (성공 시 true)
pageMetaobject책의 페이지 제약 메타. currentPageCount·pageMin·pageMax·pageIncrement·isValid 5필드 (v1.2 C04에서 pageCount 정수 필드 대체). 표지 PDF는 1페이지 고정이므로 본 응답에서는 의 페이지 제약을 반환합니다.
pdfSizeMmobject{ width, height } mm 단위 측정값
messagesarray검증 실패 시 에러 메시지 (성공 시 빈 배열)
warningsarray경고 메시지 (표지는 일반적으로 비어있음, 내지에 주로 사용)
bookStatusinteger | null현재 책 상태 (정수). 1(DRAFT, 작성 중) / 2(FINALIZED, 최종화 완료). 검증 실패 시 null이 반환될 수 있습니다. 책 목록 조회(GET /books) 응답의 status 필드는 같은 값을 문자열(draft/finalized)로 반환합니다. 표지·내지 PDF 업로드 후 POST /books/{bookUid}/finalization을 호출하면 12로 전환됩니다
urlstring | null업로드된 PDF 다운로드 URL (검증 성공 시만 채움, 실패 시 null). 호출 도메인(api-sandbox / api)을 기준으로 자동 결정됨

HTTP 상태 코드 (POST · PUT 공통)

코드POST 신규PUT 교체
200 OK교체 성공
201 Created등록 성공
400 Bad RequestPDF 검증 실패, 잘못된 creationType, 제작 확정된 주문 존재(PUT)
401 Unauthorized인증 실패 (ERR_UNAUTHORIZED)
403 Forbidden본인 소유가 아닌 책 (ERR_FORBIDDEN) / Sandbox 도메인에서 Live 책 또는 그 반대 (ERR_ENV_MISMATCH) — 아래 케이스 박스 참고
404 Not Found교체 대상 표지 PDF가 등록되어 있지 않음
409 Conflict이미 표지 PDF가 등록되어 있음
429 Too Many Requests업로드 Rate Limit 초과 — Rate Limiting 가이드 참고
500 Internal Server Error서버 오류
환경 불일치(400): Sandbox에서 만든 책을 Live 도메인으로 호출(또는 반대)할 때 발생합니다. 책의 isTest 값(true=Sandbox / false=Live)과 호출 도메인이 일치해야 합니다.
{ "success": false, "message": "Invalid Operation", "errors": ["환경 불일치: 이 책은 sandbox 환경에서 생성되었습니다. sandbox 도메인에서 호출하세요."] }

표지 PDF 신규 등록

POST/books/{bookUid}/pdf-cover

표지 PDF를 최초로 등록합니다. 이미 등록된 상태에서 호출하면 409 Conflict가 반환되며, 이 경우 PUT으로 교체해야 합니다. 검증은 동기로 수행되어 응답 본문에 결과가 포함됩니다.

Request — multipart/form-data

필드위치타입필수설명
bookUidpathstringO대상 책 UID
fileform-datafile (application/pdf)O표지 PDF 파일 (1페이지 고정)

업로드 Rate Limit은 upload 정책(API Key 단위 200 req/분)이 적용됩니다. Rate Limiting 가이드 참고.

Request 예시

Request
curl -X POST 'https://api-sandbox.sweetbook.com/v1/books/{bookUid}/pdf-cover' \
  -H 'Authorization: Bearer {YOUR_API_KEY}' \
  -F 'file=@hardcover24.pdf;type=application/pdf'

Response 예시

Response (201 Created)
{
  "success": true,
  "message": "cover PDF가 저장되었습니다",
  "data": {
    "bookUid": "bk_2h4L********",
    "kind": "cover",
    "valid": true,
    "pdfSizeMm": { "width": 544, "height": 288 },
    "messages": [],
    "warnings": [],
    "bookStatus": 1,
    "url": "https://api-sandbox.sweetbook.com/v1/books/bk_2h4L********/pdf-cover",
    "pageMeta": {
      "currentPageCount": 24,
      "pageMin": 24,
      "pageMax": 200,
      "pageIncrement": 2,
      "isValid": true
    }
  }
}

409 ERR_CONFLICT: 이미 등록된 표지에 POST 재호출 시 — errors[0]: "표지 PDF가 이미 등록되어 있습니다. 교체하려면 PUT 메서드를 사용하세요." 응답 shape 상세는 에러 코드 & 트러블슈팅 — ERR_CONFLICT를 참조하세요.

표지 PDF 교체

PUT/books/{bookUid}/pdf-cover

이미 등록된 표지 PDF를 교체합니다. 등록되지 않은 상태에서 호출하면 404가 반환되며, 이 경우 POST로 신규 등록해야 합니다.

제작 확정 이후 교체 차단: 책에 연결된 주문 아이템 중 제작 확정(CONFIRMED) 이상 상태가 하나라도 있으면 PDF 교체가 차단됩니다(400). 인쇄 단계에 진입한 후의 PDF 변경을 방지하기 위함입니다. 자세한 주문 상태는 주문 상태 흐름을 참고하세요.

Request — multipart/form-data

신규 등록(POST)과 동일한 파라미터를 사용합니다.

Request 예시

Request
curl -X PUT 'https://api-sandbox.sweetbook.com/v1/books/{bookUid}/pdf-cover' \
  -H 'Authorization: Bearer {YOUR_API_KEY}' \
  -F 'file=@hardcover24-v2.pdf;type=application/pdf'

Response 예시

Response (200 OK)
{
  "success": true,
  "message": "cover PDF가 교체되었습니다",
  "data": {
    "bookUid": "bk_krW7********",
    "kind": "cover",
    "valid": true,
    "pdfSizeMm": { "width": 544, "height": 288 },
    "messages": [],
    "warnings": [],
    "bookStatus": 1,
    "url": "https://api-sandbox.sweetbook.com/v1/books/bk_krW7********/pdf-cover",
    "pageMeta": {
      "currentPageCount": 24,
      "pageMin": 24,
      "pageMax": 200,
      "pageIncrement": 2,
      "isValid": true
    }
  }
}

주요 에러: 404 ERR_NOT_FOUND 등록되지 않은 상태에서 PUT 호출 (errors[0]: "표지 PDF가 등록되어 있지 않습니다. 신규 등록은 POST 메서드를 사용하세요.") · 400 ERR_VALIDATION_FAILED 제작 확정 이후 교체 시도 (errors[0]: "제작 확정된 주문이 있어 PDF 교체가 불가합니다."). 응답 shape 상세는 에러 코드 & 트러블슈팅을 참조하세요.

표지 PDF 다운로드

GET/books/{bookUid}/pdf-cover

저장된 표지 PDF를 다운로드합니다. 정상 응답은 JSON이 아닌 application/pdf 바이너리 스트림입니다.

표지 PDF의 응답은 책의 creationType에 따라 분기됩니다.
  • PDF_UPLOAD (그룹 A — 사용자 업로드): 업로드된 파일 존재 여부만 검사. 파일이 있으면 200, 없으면 404.
  • MIX_COVER_TEMPLATE (그룹 B — 백그라운드 생성): 책 최종화 후 백엔드가 표지를 PDF로 렌더링. pdfStatus에 따라 200 / 409 / 422 / 500 분기.

응답 매트릭스

그룹 A — PDF_UPLOAD 책의 표지
파일 상태HTTP응답 형식errorCode
디스크에 존재200application/pdf 바이너리 스트림
디스크에 부재 (업로드 미완)404JSONERR_PDF_NOT_UPLOADED
그룹 B — MIX_COVER_TEMPLATE 책의 표지
책 상태HTTP응답 형식errorCode
책 최종화 전 (PDF 생성 미시작)409JSONERR_PDF_NOT_GENERATED
PDF 생성 진행 중409JSONERR_PDF_PENDING
PDF 생성 실패422JSONERR_PDF_GENERATION_FAILED
생성 완료 + 파일 부재 (서버 결함)500JSONERR_PDF_FILE_MISSING
생성 완료 + 파일 존재200application/pdf 바이너리 스트림

공통 사전 검증

케이스HTTPerrorCode
책 미존재404ERR_NOT_FOUND
본인 소유가 아닌 책403ERR_FORBIDDEN
환경 불일치 (Sandbox/Live 도메인 ↔ 책의 환경 불일치)403ERR_ENV_MISMATCH
kind 경로 오류 (/pdf-cover·/pdf-contents 외 호출)400ERR_MALFORMED_REQUEST
책의 creationType이 PDF 조회를 지원하지 않음400ERR_CREATION_TYPE_UNSUPPORTED

클라이언트 권장 행동

  • ERR_PDF_NOT_UPLOADED (그룹 A): 해당 kind의 PDF를 업로드.
  • ERR_PDF_NOT_GENERATED (그룹 B): POST /books/{bookUid}/finalization 호출 후 재시도.
  • ERR_PDF_PENDING (그룹 B): 일정 간격(예: 10초~수십 초) 후 재시도. 무한 폴링 금지. 본 응답에는 Retry-After 헤더가 포함되지 않으므로 클라이언트가 자체 대기 간격을 결정해야 합니다.
  • ERR_PDF_GENERATION_FAILED (그룹 B): 클라이언트 자체 해결 불가 — 사용자에게 실패 안내 + 고객지원팀 문의.
  • ERR_PDF_FILE_MISSING (그룹 B): 서버 측 결함 — 고객지원팀 문의.

URL은 응답 본문이 아닌 표지 업로드 응답의 data.url 필드를 통해 확인할 수 있으며, 호출 도메인(api-sandbox.sweetbook.com / api.sweetbook.com)이 자동 적용됩니다.

Request 예시

Request — 파일로 저장
curl -o cover.pdf \
  'https://api-sandbox.sweetbook.com/v1/books/{bookUid}/pdf-cover' \
  -H 'Authorization: Bearer {YOUR_API_KEY}'

출처별 errorCode 분기: creationType에 따라 그룹 A(PDF_UPLOAD·MIX 내지 — 404 ERR_PDF_NOT_UPLOADED) / 그룹 B(TEMPLATE·MIX 표지 — 409 ERR_PDF_NOT_GENERATED·ERR_PDF_PENDING·422 ERR_PDF_GENERATION_FAILED·500 ERR_PDF_FILE_MISSING). 응답 예시·처리 가이드는 에러 코드 & 트러블슈팅 — PDF 다운로드 분기를 참조하세요.

내지 PDF

내지 PDF는 책 생성 시 지정한 pageCount와 페이지 수가 정확히 일치해야 합니다. 표지와 마찬가지로 신규 등록(POST), 교체(PUT), 다운로드(GET) 세 엔드포인트를 제공하며, 응답 본문 구조는 표지와 동일합니다.

creationType="MIX_COVER_TEMPLATE" 책의 내지는 PDF 업로드를 사용합니다 (표지는 템플릿). 따라서 이 섹션의 내지 엔드포인트는 PDF_UPLOAD·MIX_COVER_TEMPLATE 두 방식 모두에서 사용됩니다.

공통 응답 필드 (POST · PUT)

구조는 표지 PDF의 공통 응답 필드와 동일합니다 (bookUid / kind / valid / pageMeta / pdfSizeMm / messages / warnings / bookStatus / url). 내지의 경우 kind 값이 "contents"이고, 업로드 PDF의 페이지 수는 책 생성 시 지정한 pageCount와 정확히 일치해야 합니다 (불일치 시 400).

HTTP 상태 코드 (POST · PUT 공통)

표지와 동일합니다. POST 신규는 201 Created (이미 등록 시 409), PUT 교체는 200 OK (미등록 시 404, 제작 확정 후 400).환경(Sandbox/Live) 불일치 시 400도 표지와 동일하게 적용됩니다 — 표지 섹션의 환경 불일치 안내 박스를 참고하세요.

내지 PDF 신규 등록

POST/books/{bookUid}/pdf-contents

내지 PDF를 최초로 등록합니다. 책 생성 시 지정한 pageCount와 PDF의 실제 페이지 수가 정확히 일치하지 않으면 400으로 차단됩니다.

Request — multipart/form-data

필드위치타입필수설명
bookUidpathstringO대상 책 UID
fileform-datafile (application/pdf)O내지 PDF 파일 (페이지 수 = 책의 pageCount)

경고(warnings) 발생 조건 — 업로드는 성공, 주문 시 차단

업로드 자체는 성공하지만 응답의 warnings 배열에 메시지가 포함되며, 이후 주문 생성 시 400으로 차단됩니다.

  • 페이지 수가 판형의 pageMin 미만
  • 페이지 수가 판형의 pageMax 초과
  • 페이지 수가 판형의 pageIncrement의 배수가 아님

Request 예시

Request
curl -X POST 'https://api-sandbox.sweetbook.com/v1/books/{bookUid}/pdf-contents' \
  -H 'Authorization: Bearer {YOUR_API_KEY}' \
  -F 'file=@hardcontents24.pdf;type=application/pdf'

Response 예시

Response (201 Created)
{
  "success": true,
  "message": "contents PDF가 저장되었습니다",
  "data": {
    "bookUid": "bk_2h4L********",
    "kind": "contents",
    "valid": true,
    "pdfSizeMm": { "width": 249, "height": 254 },
    "messages": [],
    "warnings": [],
    "bookStatus": 1,
    "url": "https://api-sandbox.sweetbook.com/v1/books/bk_2h4L********/pdf-contents",
    "pageMeta": {
      "currentPageCount": 24,
      "pageMin": 24,
      "pageMax": 200,
      "pageIncrement": 2,
      "isValid": true
    }
  }
}

pageMeta.currentPageCount는 내지 PDF 실제 페이지 수를 반영합니다. 기존 pageCount 필드는 v1.2에서 제거됐으며 pageMeta.currentPageCount로 대체됐습니다.

주요 에러: 400 ERR_VALIDATION_FAILED 페이지 수 불일치 (errors[0]: "내지 PDF 페이지수 불일치: 올바른 페이지수 24p, 업로드된 페이지수 30p". LAYFLAT 제본은 책 페이지 환산값이 괄호로 부가) · 409 ERR_CONFLICT 이미 등록됨 (errors[0]: "내지 PDF가 이미 등록되어 있습니다. 교체하려면 PUT 메서드를 사용하세요."). 응답 shape 상세는 에러 코드 & 트러블슈팅을 참조하세요.

내지 PDF 교체

PUT/books/{bookUid}/pdf-contents

등록된 내지 PDF를 교체합니다. 표지 교체와 동일하게 제작 확정(CONFIRMED) 이후에는 차단됩니다. 교체 시에도 책 생성 시 지정한 pageCount와 일치해야 합니다 (책의 pageCount는 변경되지 않음).

내지 페이지 수를 바꾸려면 책의 pageCount를 변경해야 합니다. 그러나 pageCount는 책 생성 시 확정되며 이후 수정 API가 제공되지 않습니다 — 페이지 수가 다른 책은 새로 생성하세요.

Request — multipart/form-data

신규 등록(POST)과 동일한 파라미터를 사용합니다.

Request 예시

Request
curl -X PUT 'https://api-sandbox.sweetbook.com/v1/books/{bookUid}/pdf-contents' \
  -H 'Authorization: Bearer {YOUR_API_KEY}' \
  -F 'file=@hardcontents24-v2.pdf;type=application/pdf'

Response 예시

Response (200 OK)
{
  "success": true,
  "message": "contents PDF가 교체되었습니다",
  "data": {
    "bookUid": "bk_2h4L********",
    "kind": "contents",
    "valid": true,
    "pdfSizeMm": { "width": 249, "height": 254 },
    "messages": [],
    "warnings": [],
    "bookStatus": 1,
    "url": "https://api-sandbox.sweetbook.com/v1/books/bk_2h4L********/pdf-contents",
    "pageMeta": {
      "currentPageCount": 24,
      "pageMin": 24,
      "pageMax": 200,
      "pageIncrement": 2,
      "isValid": true
    }
  }
}

404 ERR_NOT_FOUND: 등록되지 않은 상태에서 PUT 호출 — errors[0]: "내지 PDF가 등록되어 있지 않습니다. 신규 등록은 POST 메서드를 사용하세요." 응답 shape 상세는 에러 코드 & 트러블슈팅 — ERR_NOT_FOUND를 참조하세요.

내지 PDF 다운로드

GET/books/{bookUid}/pdf-contents

저장된 내지 PDF를 다운로드합니다. 정상 응답은 JSON이 아닌 application/pdf 바이너리 스트림입니다.

내지 PDF는 PDF_UPLOAD·MIX_COVER_TEMPLATE 두 방식 모두 사용자 업로드(그룹 A)이므로 응답 분기는 동일합니다 — 업로드된 파일 존재 여부만 검사하여 200 또는 404를 반환합니다.

응답 매트릭스 (그룹 A)

파일 상태HTTP응답 형식errorCode
디스크에 존재200application/pdf 바이너리 스트림
디스크에 부재 (업로드 미완)404JSONERR_PDF_NOT_UPLOADED

공통 사전 검증

케이스HTTPerrorCode
책 미존재404ERR_NOT_FOUND
본인 소유가 아닌 책403ERR_FORBIDDEN
환경 불일치403ERR_ENV_MISMATCH
kind 경로 오류400ERR_MALFORMED_REQUEST
책의 creationType이 PDF 조회를 지원하지 않음400ERR_CREATION_TYPE_UNSUPPORTED

Request 예시

Request — 파일로 저장
curl -o contents.pdf \
  'https://api-sandbox.sweetbook.com/v1/books/{bookUid}/pdf-contents' \
  -H 'Authorization: Bearer {YOUR_API_KEY}'

404 ERR_PDF_NOT_UPLOADED: 내지 PDF 미업로드 (그룹 A) — errors[0]: "PDF 파일이 업로드되지 않았습니다." 응답 shape·다른 errorCode·처리 가이드는 에러 코드 & 트러블슈팅 — ERR_PDF_NOT_UPLOADED를 참조하세요.

책 최종화

POST/books/{bookUid}/finalization

표지·내지 PDF 업로드를 마친 뒤 이 엔드포인트를 호출해 책을 최종화합니다. 호출 시 책의 statusdraft에서 finalized로 전환되어 주문 가능 상태가 됩니다.

사전 조건: 표지·내지 PDF가 모두 업로드되어 있어야 합니다. 한쪽이라도 누락되면 400 에러가 반환됩니다.
전환 결과: 호출 성공 시 statusdraftfinalized로, pdfStatusnull2(COMPLETED)로 전환됩니다.
주문 시 PDF_READY 자동 승격: PDF 방식으로 finalize된 책은 PDF가 이미 준비된 상태이므로, 주문 생성 시 일반 흐름의 PAID(20) 단계를 거치지 않고 즉시 PDF_READY(25)로 진입합니다. 자세한 주문 상태 흐름은 주문 상태 흐름을 참고하세요.

Request

요청 본문은 비어 있습니다. 다만 IIS 환경 특성상 Content-Length: 0 헤더가 필요합니다 (없으면 411 Length Required).

Request 예시

Request
curl -X POST 'https://api-sandbox.sweetbook.com/v1/books/{bookUid}/finalization' \
  -H 'Authorization: Bearer {YOUR_API_KEY}' \
  -H 'Content-Length: 0'

응답 필드

필드타입설명
resultstring처리 결과. "created"(첫 finalize 성공) / "updated"(이미 finalized 상태에서 멱등 응답)
pageMetaobject페이지 제약 메타. currentPageCount(책의 내지 페이지 수, PDF 방식은 책 생성 시 지정한 값과 동일) + pageMin·pageMax·pageIncrement·isValid 필드 포함
finalizedAtdatetime최종화 완료 시각 (ISO 8601)

이미 FINALIZED 상태에서 다시 호출하면 200 OK + message: "이미 최종화된 책입니다" + result: "updated"로 멱등 응답합니다 (실제 상태 재변경은 일어나지 않음).

Response 예시

Response (201 Created — 첫 finalize)
{
  "success": true,
  "message": "책 최종화 완료",
  "data": {
    "result": "created",
    "pageMeta": {
      "currentPageCount": 24,
      "pageMin": 24,
      "pageMax": 200,
      "pageIncrement": 2,
      "isValid": true
    },
    "finalizedAt": "2026-04-22T07:46:24.099Z"
  }
}
Response (200 OK — 이미 finalized 상태에서 재호출)
{
  "success": true,
  "message": "이미 최종화된 책입니다",
  "data": {
    "result": "updated",
    "pageMeta": {
      "currentPageCount": 24,
      "pageMin": 24,
      "pageMax": 200,
      "pageIncrement": 2,
      "isValid": true
    },
    "finalizedAt": "2026-04-22T07:46:24.099Z"
  }
}

전제조건별 에러코드 매핑

finalize 호출 시 전제조건을 충족하지 못하면 아래 표대로 errorCode + fieldErrors가 반환됩니다. 클라이언트는 fieldErrors[].field·fieldErrors[].constraint로 누락 항목을 식별해 사용자에게 안내하세요.

전제조건errorCodefieldErrors[].fieldconstraint
책이 DRAFT 상태가 아님 (공통)ERR_FINALIZE_PREREQ_UNMETstatusenum
표지 PDF 미업로드 (PDF_UPLOAD 전용)ERR_FINALIZE_PREREQ_UNMETcoverPdfrequired
내지 PDF 미업로드 (PDF_UPLOAD · MIX_COVER_TEMPLATE 공통)ERR_FINALIZE_PREREQ_UNMETcontentsPdfrequired
페이지 수 < pageMinERR_INSUFFICIENT_PAGESpageCountmin
페이지 수 > pageMaxERR_PAGECOUNT_INVALIDpageCountmax
페이지 증분 규칙 위반ERR_PAGECOUNT_INVALIDpageCountincrement

여러 전제조건이 동시에 깨지면 fieldErrors에 항목들이 함께 반환됩니다(예: 표지·내지 PDF 둘 다 없으면 두 항목 모두 포함). 응답 예시는 위 페이지 제약 위반 에러 섹션과 케이스 C(ERR_FINALIZE_PREREQ_UNMET 다중 필드)를 참조하세요.

pageMeta.isValid 사용 시 주의:
  • isValid페이지 수 제약(pageMin·pageMax·pageIncrement) 판정합니다.
  • 표지·내지 PDF 업로드 여부, 책 상태(DRAFT 여부) 등 다른 전제조건은 finalize 호출 시 별도로 검증되므로 isValid: true여도 ERR_FINALIZE_PREREQ_UNMET이 반환될 수 있습니다.
  • finalize 가능 여부 최종 확정은 POST /finalization 호출 결과로만 가능합니다. isValid는 사전 UI 안내(예: "아직 N페이지 부족") 용도로만 사용하세요.

HTTP 상태 코드

코드errorCode설명
200 OK이미 finalized 상태의 책에 재호출한 경우 (멱등 응답, message: "이미 최종화된 책입니다", result: "updated")
201 Created최종화 신규 성공
400 Bad RequestERR_FINALIZE_PREREQ_UNMET / ERR_INSUFFICIENT_PAGES / ERR_PAGECOUNT_INVALID전제조건 미충족 (위 매핑 표 참고)
401 UnauthorizedERR_UNAUTHORIZED인증 실패
404 Not FoundERR_NOT_FOUND책 없음
411 Length RequiredContent-Length: 0 헤더 누락
500 Internal Server ErrorERR_INTERNAL_ERROR서버 오류

book.pdfStatus 값

책 조회(GET /books) 응답에 포함되는 pdfStatus 필드는 PDF 처리 상태를 나타내는 정수값입니다. 파트너는 일반적으로 책의 status 필드만 참조하면 충분하며, pdfStatus는 PDF 준비 완료 여부를 직접 확인하고 싶을 때 부가 정보로 활용할 수 있습니다.

의미발생 시점
null미생성/미업로드 (초기 상태)책 생성 직후 또는 표지·내지 PDF만 업로드한 상태 (finalize 미호출)
2COMPLETED (PDF 준비 완료)finalize 호출 후. PDF 방식은 즉시 2로 전환됨
9FAILED (처리 실패)처리 실패 시. PDF 방식에서는 일반적으로 발생하지 않음 (사용자가 PDF를 직접 제공하므로 렌더링 실패 경로가 없음)

400 ERR_FINALIZE_PREREQ_UNMET: 표지/내지 PDF 미업로드 등 전제조건 미충족. 위의 전제조건별 에러코드 매핑 표가 정확한 매핑을 제공하며, 표지만 업로드되고 내지가 없으면 fieldErrorscontentsPdf만, 반대면 coverPdf만 포함됩니다. 응답 예시(다중 fieldErrors)와 처리 가이드는 에러 코드 & 트러블슈팅 — ERR_FINALIZE_PREREQ_UNMET를 참조하세요.

책 목록 조회

GET/books

파트너가 생성한 책 목록을 조회합니다. 다양한 쿼리 파라미터로 필터링할 수 있으며, 페이지네이션을 지원합니다. 응답에는 PDF 방식·템플릿 방식 책이 모두 포함되며, creationType 필드로 구분할 수 있습니다.

Query 파라미터

파라미터타입기본값설명
bookUidstring특정 책 UID로 단건 조회
statusstring책 상태 필터. draft / finalized / deleted(일반 파트너 조회 결과에서는 삭제된 책이 자동 제외되므로 빈 결과)
pdfStatusstringPDF 상태 필터. 숫자 값(2 COMPLETED / 9 FAILED) 또는 null 문자열(PDF 미생성 책) 허용. PDF 방식 책 중 finalize 완료된 것만 조회 시 pdfStatus=2(COMPLETED) 활용
specProfileUidstringSpecProfile UID로 필터
createdFromstring생성일 시작 (ISO 8601, 예: 2026-01-01)
createdTostring생성일 종료 (ISO 8601)
limitinteger20조회할 항목 수 (1~100)
offsetinteger0건너뛸 항목 수 (≥0)

페이지네이션 동작과 응답 구조(data.books 배열 + data.pagination 객체)는 페이지네이션 가이드를 참고하세요.

Request 예시

Request
curl -X GET 'https://api-sandbox.sweetbook.com/v1/books?limit=5' \
  -H 'Authorization: Bearer {YOUR_API_KEY}'
Request — finalize 완료된 PDF 책만 조회
curl -X GET 'https://api-sandbox.sweetbook.com/v1/books?status=finalized&pdfStatus=2&limit=20' \
  -H 'Authorization: Bearer {YOUR_API_KEY}'

응답 필드

필드타입설명
bookUidstring책 고유 UID
accountUidstring책 소유 계정 UID
titlestring책 제목
authorstring | null저자명 (선택)
statusstring책 상태 — enum 문자열로 반환. "draft"(작성 중, 내부값 1) / "finalized"(최종화 완료, 내부값 2) / "deleted"(삭제됨, 내부값 9). PDF 업로드 응답의 bookStatus는 같은 값을 정수로 반환합니다
pageCountinteger내지 페이지 수 (PDF 방식은 책 생성 시 지정한 값, TEMPLATE은 자동 계산)
bookSpecUidstring판형 UID
specProfileUidstring | nullSpecProfile UID
creationTypestringTEMPLATE / PDF_UPLOAD / MIX_COVER_TEMPLATE
createdAtdatetime책 생성 시각 (ISO 8601)
updatedAtdatetime마지막 수정 시각
externalRefstring | null파트너 외부 참조 식별자
isTestbooleanSandbox 환경 책 여부
pdfStatusinteger | nullPDF 처리 상태 (정수). null(미생성) / 2(COMPLETED, 준비 완료) / 9(FAILED, 실패). 자세한 의미는 위 책 최종화 → book.pdfStatus 값 표 참고
pdfCreatedAtdatetime | nullPDF 파일이 마지막으로 갱신된 시각 (업로드/교체/finalize 시 갱신)
pdfRequestedAtdatetime | nullPDF 요청 시각 (PDF 방식은 일반적으로 null)
thumbnailStatusinteger | null책 페이지 썸네일 처리 상태. null(NONE, 미생성) / 1(PENDING, 생성 진행 중) / 2(COMPLETED, 생성 완료) / 9(FAILED, 생성 실패)

Response 예시

Response (200 OK)
{
  "success": true,
  "message": "성공",
  "data": [
    {
      "bookUid": "bk_2h4L********",
      "accountUid": "u_b4b9********************",
      "title": "PDF 업로드 샘플",
      "author": null,
      "status": "finalized",
      "pageCount": 24,
      "bookSpecUid": "SQUAREBOOK_HC",
      "specProfileUid": null,
      "creationType": "PDF_UPLOAD",
      "createdAt": "2026-04-22T07:45:05.759Z",
      "updatedAt": "2026-04-22T07:46:24.099Z",
      "externalRef": "PARTNER-ORDER-001",
      "isTest": true,
      "pdfStatus": 2,
      "pdfCreatedAt": "2026-04-22T07:46:24.000Z",
      "pdfRequestedAt": null,
      "thumbnailStatus": null
    },
    {
      "bookUid": "bk_5EdC********",
      "title": "DRAFT 상태 PDF 책",
      "status": "draft",
      "creationType": "PDF_UPLOAD",
      "pageCount": 24,
      "pdfStatus": null,
      "pdfCreatedAt": null
      /* ... 나머지 필드 생략 ... */
    }
  ],
  "pagination": {
    "total": 15,
    "limit": 5,
    "offset": 0,
    "hasNext": true
  }
}

HTTP 상태 코드

코드설명
200 OK조회 성공
400 Bad Requestlimit/offset 범위 위반 등 파라미터 오류
401 Unauthorized인증 실패
500 Internal Server Error서버 오류

책 단건 조회

GET/books/{bookUid}

특정 책의 상세 정보를 조회합니다. v1.2에 신설된 RESTful 단건 조회 엔드포인트로, 편집 화면 진입이나 현재 페이지 수 제약 확인에 사용합니다. 응답에 pageMeta가 포함되어 "아직 N페이지 부족" 같은 힌트를 UI에 즉시 반영할 수 있습니다.

Path 파라미터

파라미터타입필수설명
bookUidstringO조회할 책 UID

Request 예시

Request
curl -X GET 'https://api-sandbox.sweetbook.com/v1/books/{bookUid}' \
  -H 'Authorization: Bearer {YOUR_API_KEY}'

응답 필드

필드타입설명
bookUidstring책 UID
accountUidstring책을 생성한 계정의 UID (파트너 본인 계정)
titlestring책 제목
bookSpecUidstring책 규격 UID
bookSpecNamestring규격 이름 (예: "A5 소프트커버 포토북")
specProfileUidstring | nullSpecProfile UID (사용 시)
creationTypestringTEMPLATE / PDF_UPLOAD / MIX_COVER_TEMPLATE
statusinteger1=작성 중(DRAFT) / 2=최종화 완료(FINALIZED). status1인 책은 주문을 생성할 수 없으며, POST /books/{bookUid}/finalization을 호출해 2로 전이해야 합니다. 목록 조회(GET /books)는 동일 값을 문자열("draft" / "finalized")로 반환합니다
coverTemplateUidstring | null템플릿 방식에서 바인딩된 표지 템플릿 UID. PDF 방식은 null
externalRefstring | null파트너 외부 참조 식별자
isTestbooleanSandbox 환경의 책이면 true
pageMetaobject페이지 제약 메타. currentPageCount·pageMin·pageMax·pageIncrement·isValid 5개 필드
createdAtdatetime생성 시각 (ISO 8601)
updatedAtdatetime최종 수정 시각 (ISO 8601)

Response 예시

Response (200 OK)
{
  "success": true,
  "message": "성공",
  "data": {
    "bookUid": "bk_2h4L********",
    "accountUid": "u_b4b9********************",
    "title": "PDF 업로드 샘플",
    "bookSpecUid": "SQUAREBOOK_HC",
    "bookSpecName": "고화질 스퀘어북 (하드커버)",
    "specProfileUid": null,
    "creationType": "PDF_UPLOAD",
    "status": 1,
    "coverTemplateUid": null,
    "externalRef": "PARTNER-ORDER-001",
    "isTest": true,
    "pageMeta": {
      "currentPageCount": 24,
      "pageMin": 24,
      "pageMax": 200,
      "pageIncrement": 2,
      "isValid": true
    },
    "createdAt": "2026-04-22T03:00:00.000Z",
    "updatedAt": "2026-04-22T04:00:00.000Z"
  }
}

HTTP 상태 코드

상태 코드errorCode설명
200 OK조회 성공
401 UnauthorizedERR_UNAUTHORIZED인증 실패
403 ForbiddenERR_FORBIDDEN다른 파트너의 책 접근 시도
403 ForbiddenERR_ENV_MISMATCHSandbox 도메인에서 Live 책 조회(또는 반대)
404 Not FoundERR_NOT_FOUND책 UID가 존재하지 않음

단건 조회 vs 목록 조회 (bookUid 필터) 차이

기존 목록 조회의 bookUid 필터(GET /books?bookUid=...)와 본 단건 조회는 의미·응답 타입·권한 처리가 다릅니다. 용도에 맞게 선택하세요.

항목GET /books/{uid} (단건)GET /books?bookUid=... (목록 필터)
의미론RESTful 리소스 단건 조회목록 조회 + bookUid 동등 필터 (결과 0~1건)
응답 data 타입객체배열 + pagination 메타
응답 필드상세 필드 + pageMeta, bookSpecName, coverTemplateUid 등 편집 화면용 풀셋목록용 요약 필드 (pageCount 유지, pageMeta 없음)
결과 없을 때404 ERR_NOT_FOUND200 + 빈 배열
다른 파트너의 책403 ERR_FORBIDDEN200 + 빈 배열 (필터 결과)
환경 불일치 (sandbox/live)403 ERR_ENV_MISMATCH빈 배열 (필터에 환경 적용)
status 필드 타입숫자 (1/2)문자열 ("draft"/"finalized")
주 용도책 편집 페이지 진입, 상세 패널 렌더링, finalize 전 상태 확인목록/검색 UI, 페이지네이션, 여러 조건 조합 필터링
  • 책 UID를 알고 있고 상세 정보(특히 pageMeta)가 필요하면 → 단건 조회
  • 존재 여부만 빠르게 확인하거나 여러 조건과 조합해야 하면 → 목록 조회
  • 없는 책과 권한 없는 책을 명확히 구별해야 하면 → 단건 조회 (목록은 둘 다 빈 배열로 동일)

404 ERR_NOT_FOUND: 존재하지 않는 bookUiderrors[0]: "책을 찾을 수 없습니다: bk_xxx". 응답 shape 상세는 에러 코드 & 트러블슈팅 — ERR_NOT_FOUND를 참조하세요.

페이지 제약 위반 에러

내지 PDF 업로드·최종화·내지 템플릿 추가 시 페이지 제약을 위반하면 아래 3종 에러 중 하나가 반환됩니다. fieldErrors[0].constraint로 어떤 제약이 위반됐는지 분기할 수 있습니다. 전체 에러 체계 상세는 에러 코드 & 트러블슈팅을 참고하세요.

  • ERR_INSUFFICIENT_PAGES (constraint: "min") — 최소 페이지 미달
  • ERR_PAGECOUNT_INVALID (constraint: "max") — 최대 페이지 초과
  • ERR_PAGECOUNT_INVALID (constraint: "increment") — 증분 규칙 위반. requiredValue{min, increment} 객체 형태

응답 예시(fieldErrors 배열에 currentValue·requiredValue·constraint 포함)는 errors 페이지의 각 errorCode 카드를 참조하세요: ERR_INSUFFICIENT_PAGES, ERR_PAGECOUNT_INVALID.

책 삭제

DELETE/books/{bookUid}

책을 삭제 처리합니다. 물리적 삭제가 아닌 소프트 삭제(상태값 변경)로 처리되어, 이후 목록 조회 결과에서 제외됩니다. 업로드한 PDF 파일은 별도 정리되지 않고 보관 상태로 남으며, 책 자체에 대한 추가 작업(업로드/교체/finalize/주문)은 모두 차단됩니다.

멱등 동작: 이미 삭제된 책에 다시 호출해도 200 OK를 반환합니다 (재실패하지 않음).
상태 제약 없음: draft·finalized 어느 상태에서도 삭제 가능합니다 (단 본인 소유 책에 한함).

Path 파라미터

파라미터타입필수설명
bookUidstringO삭제할 책 UID

Request 예시

Request
curl -X DELETE 'https://api-sandbox.sweetbook.com/v1/books/{bookUid}' \
  -H 'Authorization: Bearer {YOUR_API_KEY}'

응답 필드

필드타입설명
bookUidstring삭제된 책 UID
statusstring삭제 처리 결과 ("deleted")

Response 예시

Response (200 OK)
{
  "success": true,
  "message": "책이 삭제되었습니다",
  "data": {
    "bookUid": "bk_2h4L********",
    "status": "deleted"
  }
}

HTTP 상태 코드

코드설명
200 OK삭제 성공 (이미 삭제된 책에 대한 재호출 포함)
400 Bad RequestbookUid 형식 오류
401 Unauthorized인증 실패
403 Forbidden본인 소유가 아닌 책
404 Not Found책 없음
500 Internal Server Error서버 오류

404 ERR_NOT_FOUND: 존재하지 않는 bookUid — 응답 shape 상세는 에러 코드 & 트러블슈팅 — ERR_NOT_FOUND를 참조하세요.