Books API — 템플릿 기반

SweetBook 템플릿에 이미지·텍스트를 바인딩하여 책을 생성하는 방식의 API 레퍼런스입니다. 표지·내지 페이지를 템플릿 단위로 추가하고, 명시적인 최종화(finalize) 호출로 주문 가능 상태로 전환합니다.

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

이 방식이 적합한 경우

  • SweetBook이 제공하는 표지·내지 템플릿을 활용하고 싶은 경우
  • 이미지·텍스트만 입력하고 레이아웃은 템플릿에 맡기는 경우
  • 여러 페이지를 다양한 템플릿(갤러리/베이스 레이어/간지/발행면 등)으로 조합하고 싶은 경우

지원 creationType

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

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

책 생성

POST/books

새로운 책을 생성합니다. 생성 직후 status="draft" 상태이며, 이후 표지·내지 추가와 명시적인 최종화 단계를 거쳐 주문 가능 상태로 진입합니다.

Request Body

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

Request 예시

Request body (TEMPLATE)
{
  "title": "일기장 샘플",
  "bookSpecUid": "SQUAREBOOK_HC",
  "creationType": "TEMPLATE",
  "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": "일기장 샘플",
    "bookSpecUid": "SQUAREBOOK_HC",
    "creationType": "TEMPLATE",
    "externalRef": "PARTNER-ORDER-001"
  }'

응답 필드

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

Response 예시

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

pageMeta: TEMPLATE 방식은 생성 직후 currentPageCount=0, isValid=false로 시작합니다. 콘텐츠 추가(POST /books/{bookUid}/contents) 호출에 따라 자동 증가합니다. MIX_COVER_TEMPLATE은 요청의 pageCount 값이 currentPageCount로 반영됩니다. isValid는 페이지 제약만 판정하며, finalize 가능 여부는 표지·내지 존재 여부 등 다른 조건도 포함되므로 POST /finalization 호출로 최종 확인하세요.

HTTP 상태 코드

코드errorCode설명
201 Created책 생성 성공
400 Bad RequestERR_VALIDATION_FAILEDtitle/bookSpecUid/creationType 누락 또는 허용되지 않은 값, MIX 방식인데 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)"
  • MIX_COVER_TEMPLATE인데 pageCount 누락 — errors[0]: "creation_type=MIX_COVER_TEMPLATE는 pageCount(내지 페이지수)가 필수입니다."

TEMPLATEpageCount가 필요 없으므로 누락해도 에러가 발생하지 않으며, 값을 포함해도 서버에서 무시됩니다(실제 저장값은 0). 응답 6필드 shape, 다른 errorCode, 처리 가이드는 에러 코드 & 트러블슈팅을 참조하세요.

표지 추가

POST/books/{bookUid}/cover

지정한 표지 템플릿에 이미지·텍스트를 바인딩하여 책의 표지를 생성합니다. 이미지는 위 이미지 처리 → 이미지 전달 방식 섹션의 3가지 방식 중 어느 것으로든 제공할 수 있고, 한 요청에서 혼용도 가능합니다.

표지는 한 번만 등록 가능합니다. 이미 표지가 등록된 책에 다시 호출하면 400 에러가 반환됩니다. 표지를 변경하려면 책을 새로 생성하세요.
creationType="MIX_COVER_TEMPLATE" 책의 표지도 이 엔드포인트를 사용합니다 (표지는 템플릿, 내지는 PDF). 단 creationType="PDF_UPLOAD" 책에는 사용할 수 없습니다 (그 경우 Books — PDF 기반POST /pdf-cover 사용).

Request — multipart/form-data

필드위치타입필수설명
bookUidpathstringO대상 책 UID
templateUidformstringO표지 템플릿 UID. Templates API에서 templateKind=cover로 조회
parametersformstring (JSON)템플릿 파라미터 (텍스트 값, 이미지 URL, 서버 파일명, $upload 플레이스홀더 포함). 템플릿이 요구하는 변수에 따라 필수성 결정
(이미지 필드명)form-datafile템플릿의 이미지 변수명($변수명$)과 동일한 이름으로 multipart 파일 첨부 (예: coverPhoto=@front.jpg)

템플릿의 변수 목록과 필수 여부는 Templates API의 템플릿 상세 조회로 확인할 수 있습니다. 템플릿 구조와 바인딩 동작 원리는 템플릿 구조와 바인딩을 참고하세요.

Idempotency-Key 지원: Idempotency-Key 헤더를 함께 보내면 동일한 키로 재요청해도 표지가 중복 추가되지 않습니다. 자세한 동작은 멱등성 가이드를 참고하세요.

Request 예시

Request — 파일 업로드 방식
curl -X POST 'https://api-sandbox.sweetbook.com/v1/books/{bookUid}/cover' \
  -H 'Authorization: Bearer {YOUR_API_KEY}' \
  -F 'templateUid=79yjMH3qRPly' \
  -F 'coverPhoto=@front.jpg' \
  -F 'parameters={"title":"나의 하루 기록","dateRange":"26.01 - 26.04","coverPhoto":"$upload"}'
Request — URL 방식
curl -X POST 'https://api-sandbox.sweetbook.com/v1/books/{bookUid}/cover' \
  -H 'Authorization: Bearer {YOUR_API_KEY}' \
  -F 'templateUid=79yjMH3qRPly' \
  -F 'parameters={"title":"나의 하루 기록","coverPhoto":"https://example.com/front.jpg"}'
Request — 사전 업로드 서버 파일명 방식
curl -X POST 'https://api-sandbox.sweetbook.com/v1/books/{bookUid}/cover' \
  -H 'Authorization: Bearer {YOUR_API_KEY}' \
  -F 'templateUid=79yjMH3qRPly' \
  -F 'parameters={"title":"나의 하루 기록","coverPhoto":"photo250105143052123.JPG"}'

응답 필드

필드타입설명
resultstring처리 결과. "inserted" 고정
pageMetaobject페이지 제약 메타 (참고용 — 표지는 카운트에 미포함)

Response 예시

Response (201 Created)
{
  "success": true,
  "message": "표지가 생성되었습니다",
  "data": {
    "result": "inserted",
    "pageMeta": {
      "currentPageCount": 0,
      "pageMin": 24,
      "pageMax": 200,
      "pageIncrement": 1,
      "isValid": false
    }
  }
}

표지는 내지 카운트(currentPageCount)에 포함되지 않으므로 표지 추가 후에도 값이 변하지 않습니다. pageMeta는 현재 내지 상태를 보고용으로 함께 노출됩니다.

HTTP 상태 코드

코드errorCode설명
201 Created표지 신규 등록 성공
400 Bad RequestERR_VALIDATION_FAILED / ERR_CREATION_TYPE_UNSUPPORTEDtemplateUid 누락, 필수 이미지 파라미터 누락, parameters JSON 파싱 실패, 이미 표지 등록됨("이미 표지가 존재합니다"), PDF_UPLOAD 책에 사용 시 차단 등
401 UnauthorizedERR_UNAUTHORIZED인증 실패
404 Not FoundERR_NOT_FOUND책 또는 템플릿 없음
429 Too Many RequestsERR_TOO_MANY_REQUESTS업로드 Rate Limit 초과 — Rate Limiting 가이드 참고
500 Internal Server ErrorERR_INTERNAL_ERROR서버 오류

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

  • 이미 표지가 등록됨 — errors[0]: "이미 표지가 존재합니다"
  • 필수 이미지 파라미터 누락 — errors[0]: "필수 이미지 파라미터 '<name>' (<설명>)이 제공되지 않았습니다. form-data에 파일을 첨부하거나 parameters에 URL 또는 서버 파일명을 제공해야 합니다."

파라미터 이름(예: coverPhoto)과 설명(예: 앞표지 메인 사진)은 템플릿에 따라 달라집니다. Templates API에서 해당 템플릿의 필수 변수 목록을 먼저 확인하세요. 응답 6필드 shape, 다른 errorCode, 처리 가이드는 에러 코드 & 트러블슈팅을 참조하세요.

콘텐츠(내지) 추가

POST/books/{bookUid}/contents

지정한 콘텐츠(내지) 템플릿에 이미지·텍스트를 바인딩하여 페이지를 추가합니다. 한 번 호출에 한 콘텐츠가 추가되며, 여러 페이지를 만들려면 반복 호출합니다. 이미지 전달 방식은 위 이미지 처리 → 이미지 전달 방식 섹션과 동일합니다.

creationType="PDF_UPLOAD" · "MIX_COVER_TEMPLATE" 책에는 이 엔드포인트를 사용할 수 없습니다. 두 방식은 내지를 PDF로 업로드합니다 (Books — PDF 기반POST /pdf-contents 사용).

Request — multipart/form-data

필드위치타입필수설명
bookUidpathstringO대상 책 UID
templateUidformstringO콘텐츠/간지/발행면 템플릿 UID. Templates API에서 templateKind=content/divider/publish로 조회
parametersformstring (JSON)템플릿 파라미터. 갤러리 등 다수 이미지를 받는 변수는 배열로 전달 가능 (예: "galleryPhotos": ["url1", "url2"])
breakBeforequerystring페이지 나누기 방식. page(새 페이지) / column(새 단) / none(이어붙기). 기본값은 템플릿 종류에 따라 다름 (content: none, divider/publish: page). 위 외 값은 400 에러
(이미지 필드명)form-datafile템플릿의 이미지 변수명($변수명$)과 동일한 이름으로 multipart 파일 첨부

템플릿 종류와 변수 정보는 Templates API에서, 레이아웃 동작 원리(이어붙기 vs 새 페이지)는 레이아웃 동작 원리를 참고하세요. 갤러리 템플릿(다수 이미지 배치)은 갤러리 템플릿을 참고하세요.

Idempotency-Key 지원: 콘텐츠 추가도 Idempotency-Key 헤더로 중복 추가를 방지할 수 있습니다. 자세한 동작은 멱등성 가이드를 참고하세요.

Request 예시

Request — 파일 업로드 방식 (단일 이미지)
curl -X POST 'https://api-sandbox.sweetbook.com/v1/books/{bookUid}/contents?breakBefore=page' \
  -H 'Authorization: Bearer {YOUR_API_KEY}' \
  -F 'templateUid=46VqZhVNOfAp' \
  -F 'photo=@image1.jpg' \
  -F 'parameters={"monthNum":"04","dayNum":"14","diaryText":"오늘의 일기","photo":"$upload"}'
Request — URL 방식
curl -X POST 'https://api-sandbox.sweetbook.com/v1/books/{bookUid}/contents' \
  -H 'Authorization: Bearer {YOUR_API_KEY}' \
  -F 'templateUid=46VqZhVNOfAp' \
  -F 'parameters={"monthNum":"04","dayNum":"14","diaryText":"오늘의 일기","photo":"https://example.com/photo.jpg"}'
Request — 갤러리(배열) URL 방식
curl -X POST 'https://api-sandbox.sweetbook.com/v1/books/{bookUid}/contents' \
  -H 'Authorization: Bearer {YOUR_API_KEY}' \
  -F 'templateUid={GALLERY_TEMPLATE_UID}' \
  -F 'parameters={"date":"2026-04-22","galleryPhotos":["https://example.com/1.jpg","https://example.com/2.jpg","https://example.com/3.jpg"]}'

응답 필드

필드타입설명
resultstring처리 결과. "inserted"(새 페이지 신규 추가) / "updated"(같은 페이지 범위 내 기존 콘텐츠가 있어 left→right로 이동하거나 교체되어 저장됨)
breakBeforestring실제로 적용된 페이지 나누기 값 (요청 값 또는 템플릿별 기본값)
pageNuminteger이번 콘텐츠가 배치된 페이지 번호 (1부터 시작)
pageSidestring페이지 방향. "left" / "right"
pageMetaobject페이지 제약 메타 객체. currentPageCount(누적 내지 페이지 수 — 제본 방식에 따라 계산, 같은 pageNum 안에서 left/right만 채우는 호출은 증가하지 않을 수 있음. 산출 방식 상세는 레이아웃 동작 원리 참고) + pageMin·pageMax·pageIncrement·isValid 필드 포함

Response 예시

Response (201 Created — 새 페이지 추가)
{
  "success": true,
  "message": "내지가 생성되었습니다",
  "data": {
    "result": "inserted",
    "breakBefore": "page",
    "pageNum": 1,
    "pageSide": "right",
    "pageMeta": {
      "currentPageCount": 1,
      "pageMin": 24,
      "pageMax": 200,
      "pageIncrement": 1,
      "isValid": false
    }
  }
}
Response (200 OK — 같은 페이지 범위에 이어 배치)
{
  "success": true,
  "message": "내지가 갱신되었습니다",
  "data": {
    "result": "updated",
    "breakBefore": "none",
    "pageNum": 2,
    "pageSide": "right",
    "pageMeta": {
      "currentPageCount": 2,
      "pageMin": 24,
      "pageMax": 200,
      "pageIncrement": 1,
      "isValid": false
    }
  }
}

HTTP 상태 코드

코드errorCode설명
200 OK같은 페이지 범위 내 기존 콘텐츠에 이어 배치되어 저장된 경우 (응답 메시지 Content updated successfully, result: "updated")
201 Created새 페이지에 콘텐츠 신규 추가 (응답 메시지 Content created successfully, result: "inserted")
400 Bad RequestERR_VALIDATION_FAILED / ERR_CREATION_TYPE_UNSUPPORTEDtemplateUid 누락, 필수 이미지 파라미터 누락, parameters JSON 파싱 실패, 잘못된 breakBefore 값, 이미 최종화된 책("이미 최종화된 책입니다. 콘텐츠를 추가할 수 없습니다."), 삭제된 책, PDF_UPLOAD/MIX_COVER_TEMPLATE 책 등
401 UnauthorizedERR_UNAUTHORIZED인증 실패
404 Not FoundERR_NOT_FOUND책 또는 템플릿 없음
429 Too Many RequestsERR_TOO_MANY_REQUESTS업로드 Rate Limit 초과 — Rate Limiting 가이드 참고
500 Internal Server ErrorERR_INTERNAL_ERROR서버 오류

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

  • 이미 최종화된 책 — errors[0]: "이미 최종화된 책입니다. 콘텐츠를 추가할 수 없습니다."
  • 필수 이미지 파라미터 누락 — errors[0]: "필수 이미지 파라미터 '<name>' (<설명>)이 제공되지 않았습니다. form-data에 파일을 첨부하거나 parameters에 URL 또는 서버 파일명을 제공해야 합니다."
  • 간지/발행면 템플릿에 잘못된 breakBeforeerrors[0]: "template_kind='divider'인 특수 페이지에서는 breakBefore='none'를 사용할 수 없습니다. 'page'만 허용됩니다."

파라미터 이름과 설명은 템플릿에 따라 달라집니다. Templates API에서 해당 템플릿의 필수 변수 목록을 먼저 확인하세요. 간지(templateKind=divider)·발행면(templateKind=publish) 템플릿은 breakBefore를 생략하거나 page만 명시해야 합니다. 일반 내지(templateKind=content)는 세 값 모두 허용됩니다. 응답 6필드 shape, 다른 errorCode, 처리 가이드는 에러 코드 & 트러블슈팅을 참조하세요.

책 최종화

POST/books/{bookUid}/finalization

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

사전 조건: 콘텐츠(내지) 페이지가 1개 이상 추가되어 있어야 하며, 누적된 실 페이지 수가 판형의 페이지 수 규칙(pageMin·pageMax·pageIncrement)을 충족해야 합니다.
전환 결과: 호출 성공 시 statusdraftfinalized로 전환됩니다 (PDF 렌더링은 시스템이 비동기로 처리). 책의 pdfStatus는 PDF 렌더링이 완료되면 2(COMPLETED)로 갱신됩니다.

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처리 결과 메시지 (아래 result 값 조건 표 참고)
pageMetaobject페이지 제약 메타. currentPageCount(최종화된 책의 내지 페이지 수, 콘텐츠 추가 결과로 자동 산출) + pageMin·pageMax·pageIncrement·isValid 필드 포함
finalizedAtdatetime최종화 완료 시각 (ISO 8601)

result 값 조건

발생 조건
"페이지를 추가하고 완료"제본 방식 PUR이며 마지막 페이지가 자동 추가되어 finalize 완료된 경우
"페이지를 추가하지 않고 완료"제본 방식 PUR이며 마지막 페이지가 이미 있어 추가 없이 finalize 완료된 경우
"완료"제본 방식이 PUR이 아닌 경우 (일반 finalize 완료)
"updated"이미 finalized 상태인 책에 finalize를 다시 호출한 경우 (멱등 응답). 실제 상태는 재변경되지 않음

파트너는 result 문자열 자체보다 응답 상태 코드(2xx)와 pageMeta.currentPageCount/finalizedAt 값으로 성공 여부를 확인하는 것을 권장합니다.

Response 예시

Response (201 Created — 신규 최종화)
{
  "success": true,
  "message": "책 최종화 완료",
  "data": {
    "result": "페이지를 추가하고 완료",
    "pageMeta": {
      "currentPageCount": 26,
      "pageMin": 24,
      "pageMax": 200,
      "pageIncrement": 1,
      "isValid": true
    },
    "finalizedAt": "2026-04-14T07:15:44.613Z"
  }
}
Response (200 OK — 이미 finalized 상태에서 재호출)
{
  "success": true,
  "message": "이미 최종화된 책입니다",
  "data": {
    "result": "updated",
    "pageMeta": {
      "currentPageCount": 26,
      "pageMin": 24,
      "pageMax": 200,
      "pageIncrement": 1,
      "isValid": true
    },
    "finalizedAt": "2026-04-14T07:15:44.613Z"
  }
}

전제조건별 에러코드 매핑

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

전제조건errorCodefieldErrors[].fieldconstraint
책이 DRAFT 상태가 아님ERR_FINALIZE_PREREQ_UNMETstatusenum
내지 콘텐츠 미추가 (0건)ERR_FINALIZE_PREREQ_UNMETcontentsrequired
페이지 수 < pageMinERR_INSUFFICIENT_PAGESpageCountmin
페이지 수 > pageMaxERR_PAGECOUNT_INVALIDpageCountmax
페이지 증분 규칙 위반ERR_PAGECOUNT_INVALIDpageCountincrement

여러 전제조건이 동시에 깨지면 fieldErrors에 항목들이 함께 반환됩니다. 응답 예시는 위 "주요 에러 응답"과 페이지 제약 위반 에러 섹션을 참조하세요.

pageMeta.isValid 사용 시 주의:
  • isValid페이지 수 제약(pageMin·pageMax·pageIncrement) 판정합니다.
  • 내지 콘텐츠 추가 여부, 책 상태(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 처리 상태를 나타내는 정수값입니다. TEMPLATE 방식은 finalize 후 시스템이 PDF를 비동기 렌더링하므로, finalize 직후엔 1(PENDING) 상태에서 2(COMPLETED)로 전환됩니다. 파트너는 일반적으로 책의 status 필드 또는 주문 상태 흐름의 PDF_READY 전환을 기준으로 처리하면 충분합니다.

의미발생 시점
null미생성 (초기 상태)책 생성 직후 또는 콘텐츠만 추가한 상태 (finalize 미호출)
1PENDING (PDF 렌더링 대기)finalize 호출 직후 (시스템이 PDF 렌더링을 시작한 상태)
2COMPLETED (PDF 준비 완료)시스템이 PDF 렌더링을 완료한 시점. 이 시점부터 주문 아이템이 PDF_READY(25)로 자동 승격됨
9FAILED (처리 실패)PDF 렌더링 실패 시 (드물게 발생). 발생 시 책을 다시 점검하거나 콘텐츠를 수정하여 재 finalize 시도

본 엔드포인트의 finalize 특화 에러:

  • 콘텐츠 미추가 상태에서 finalize 호출400 ERR_FINALIZE_PREREQ_UNMET, fieldErrors[0].field: "contents"·constraint: "required". POST /books/{bookUid}/contents로 최소 1개 이상의 내지를 추가한 뒤 finalize를 호출하세요.
  • 페이지 수 규칙 위반 — 판형의 pageMin/pageMax/pageIncrement 검증. 응답 예시는 아래 페이지 제약 위반 에러 섹션을 참조하세요.

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

이미지 처리

템플릿 표지·내지 추가 시 사용할 이미지를 어떻게 전달하고, 어떤 제약이 있는지 다룹니다. 본 묶음은 표지(POST /cover)·내지(POST /contents) 추가 단계의 사전 정보입니다.

이미지 전달 방식 (3가지, 혼용 가능)

표지·내지 추가 요청에서 이미지는 다음 3가지 방식 중 어느 것으로든 제공할 수 있고, 한 요청에서 혼용할 수도 있습니다. 템플릿의 이미지 필드명($변수명$)과 요청 필드명이 일치해야 합니다.

방식전달 위치적합한 상황
① multipart 파일 직접 첨부multipart/form-data의 파일 필드 (예: frontPhoto=@front.jpg)한 페이지에 1~2장 이미지를 즉시 업로드할 때
② URL 전달parameters JSON 안에 이미지 URL 문자열 (예: "frontPhoto": "https://...")이미지가 외부 호스팅(또는 파트너 CDN)에 이미 있는 경우
③ 사전 업로드한 서버 파일명 참조parameters JSON에 서버가 발급한 파일명 (예: photo250105143052123.JPG)여러 페이지에 같은 이미지를 반복 사용하거나, 다수 이미지를 미리 일괄 업로드해 두는 경우 (아래 사진 사전 업로드 섹션 사용)

혼합 방식과 순서 제어 ($upload 플레이스홀더)

한 요청에서 위 3가지 방식을 섞어 쓸 수 있습니다. parameters의 배열 필드에 $upload 플레이스홀더를 넣으면 multipart로 첨부한 파일이 해당 위치에 차례로 들어갑니다.

parameters 예시 (혼합 방식)
{
  "photos": [
    "$upload",
    "https://example.com/photo2.jpg",
    "photo250105143052123.JPG",
    "$upload"
  ]
}

위 예시는 첫 번째 업로드 파일 → URL 이미지 → 사전 업로드한 서버 파일 → 두 번째 업로드 파일 순으로 배치됩니다. multipart로 첨부한 파일이 $upload 등장 순서대로 매핑됩니다.

EXIF 정보

업로드된 이미지의 EXIF 정보는 항상 보존됩니다. EXIF 보존 여부를 제어하는 별도 파라미터는 제공하지 않습니다.

파일 업로드 제한 (이미지)

표지·내지 추가 요청의 multipart 파일 첨부, 사진 사전 업로드, URL 다운로드 모두에 동일한 이미지 제약이 적용됩니다.

항목제한
파일당 최대 크기50MB
지원 포맷JPEG, PNG, GIF, WebP, BMP, HEIC, HEIF
업로드 Rate Limitupload 정책 (API Key 단위 200 req/분)
URL 다운로드 타임아웃10초 (응답 없으면 400)

파일 검증

  • 매직 바이트 검증: 파일 확장자뿐만 아니라 매직 바이트(파일 시그니처)를 확인하여 실제 이미지 파일인지 검증합니다. 확장자만 변경한 파일은 거부됩니다.
  • 자동 포맷 변환: GIF·WebP는 PNG로, BMP·HEIC·HEIF는 JPG로 자동 변환되어 저장됩니다.
  • EXIF 보존: EXIF 정보는 항상 보존됩니다.

Rate Limit 초과 시 429 응답과 Retry-After 헤더가 반환됩니다. 자세한 정책은 Rate Limiting 가이드를 참고하세요.

사진 사전 업로드 [선택]

이미지를 표지·내지 추가 요청에 직접 첨부하지 않고 미리 업로드해 서버 파일명을 받아두는 보조 API입니다.표지/내지 추가 요청에 이미지를 직접 첨부(방식 ①)하거나 URL로 전달(방식 ②)한다면 이 단계는 생략 가능합니다. 여러 페이지에 같은 이미지를 반복 사용하거나, 다수 이미지를 한 번에 모아 업로드해두고 싶을 때 활용하세요.

호출 도메인 기준

사진 관련 4개 엔드포인트는 모두 API Key의 환경(Sandbox/Live)과 호출 도메인이 일치해야 합니다. 잘못된 조합으로 호출 시 403 ERR_ENV_MISMATCH가 반환됩니다.

환경도메인접근 가능 리소스
Sandboxapi-sandbox.sweetbook.com샌드박스(isTest=true) 책·사진
Liveapi.sweetbook.com라이브(isTest=false) 책·사진

권한 매트릭스

파트너 관점에서 사진 4개 엔드포인트의 호출 가능 여부입니다.

액션본인 책환경 불일치
업로드 POST /photos✅ 201❌ 403 ERR_ENV_MISMATCH
목록 GET /photos✅ 200❌ 403 ERR_ENV_MISMATCH
다운로드 GET /photos/{fileName}✅ 200❌ 403 ERR_ENV_MISMATCH
삭제 DELETE /photos/{fileName}✅ 204❌ 403 ERR_ENV_MISMATCH

사진 업로드

POST/books/{bookUid}/photos

한 번에 한 장씩 업로드하며, 응답으로 서버가 발급한 고유 파일명을 받습니다. 이후 표지·내지 추가 요청의 parameters에 이 파일명을 사용해 이미지를 참조합니다.

Request — multipart/form-data

필드위치타입필수설명
bookUidpathstringO대상 책 UID
fileform-datafileO업로드할 이미지 파일 (한 번에 1장)

제약 사항

  • 파일 크기: 50MB 이하 (초과 시 400)
  • 책당 최대 200장: 한 책에 사전 업로드할 수 있는 사진은 최대 200장입니다. 초과 전에 사진 목록 조회로 현재 수량을 확인하세요
  • 책 상태 제약: draft 상태의 책에만 업로드 가능합니다. finalized(최종화) 또는 deleted(삭제) 상태의 책에는 업로드할 수 없습니다 — 최종화 전에 필요한 사진을 모두 업로드하세요
  • 지원 포맷: JPEG · PNG · GIF · WebP · BMP · HEIC · HEIF — 그 외 형식은 400 거부. 매직 바이트로 실제 형식을 검증하므로 확장자만 바꾼 파일은 거부됨

Request 예시

Request
curl -X POST 'https://api-sandbox.sweetbook.com/v1/books/{bookUid}/photos' \
  -H 'Authorization: Bearer {YOUR_API_KEY}' \
  -F 'file=@photo1.jpg'

응답 필드

필드타입설명
fileNamestring서버가 발급한 고유 파일명. 표지·내지 추가 요청의 parameters에 이 값을 사용해 이미지를 참조하거나, 사진 다운로드 URL 경로에 직접 사용
originalNamestring업로드한 원본 파일명
sizeinteger저장된 파일 크기 (bytes)
mimeTypestringMIME 타입 (예: image/jpeg, image/png)
uploadedAtdatetime업로드 완료 시각 (ISO 8601)
isDuplicateboolean같은 책에 동일 파일(해시 기준)이 이미 업로드되어 있던 경우 true. 이때 fileName은 기존 파일의 파일명을 반환
hashstring파일 내용의 MD5 해시값 (중복 검사에 사용됨)

Response 예시

Response (201 Created)
{
  "success": true,
  "message": "Photo uploaded successfully",
  "data": {
    "fileName": "photo260423001516528.JPG",
    "originalName": "cover.jpg",
    "size": 382229,
    "mimeType": "image/jpeg",
    "uploadedAt": "2026-04-23T00:15:19.136Z",
    "isDuplicate": false,
    "hash": "1baf5077ae9f5a13787a73a08625a802"
  }
}

HTTP 상태 코드

코드errorCode설명
201 Created업로드 성공 (응답에 서버 파일명 포함)
400 Bad RequestERR_VALIDATION_FAILED파일 누락, 지원되지 않는 파일 형식, 50MB 초과 등
400 Bad RequestERR_CREATION_TYPE_UNSUPPORTEDPDF_UPLOAD 타입 책에 사진 업로드 시도 — 사진 업로드는 TEMPLATE 또는 MIX_COVER_TEMPLATE 방식에서만 지원
401 UnauthorizedERR_UNAUTHORIZED인증 실패
403 ForbiddenERR_FORBIDDEN본인 소유가 아닌 책
403 ForbiddenERR_ENV_MISMATCH호출 도메인과 API Key의 환경(Sandbox/Live) 불일치 — 호출 도메인 기준 참고
404 Not FoundERR_NOT_FOUND책 없음
500 Internal Server ErrorERR_INTERNAL_ERROR서버 오류

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

  • 400 ERR_VALIDATION_FAILED 지원되지 않는 파일 형식 — errors[0]: "지원되지 않는 파일 형식입니다: <파일명>. (확장자: <확장자>)"
  • 400 ERR_VALIDATION_FAILED 파일 크기 초과 — errors[0]: "파일 크기가 50MB를 초과합니다"
  • 400 ERR_VALIDATION_FAILED 파일 누락 — errors[0]: "파일이 없습니다"
  • 400 ERR_CREATION_TYPE_UNSUPPORTED PDF_UPLOAD 타입 책에 사진 업로드 시도 — errors[0]: "PDF_UPLOAD 타입 책에서는 지원하지 않는 API입니다."
  • 403 ERR_ENV_MISMATCH 환경 불일치 — errors[0]: "환경 불일치: 호출 도메인과 API Key의 환경(sandbox/live)이 일치하지 않습니다. 키에 맞는 도메인으로 재시도하세요."

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

사진 목록 조회

GET/books/{bookUid}/photos

해당 책에 사전 업로드한 사진 파일명 목록을 조회합니다.

Request 예시

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

응답 필드

필드타입설명
dataarray업로드된 사진 항목 배열 (아래 항목 필드 참고). list envelope 평탄화 적용 (이전 data.photosdata)
pagination.totalinteger업로드된 사진 총 개수 (이전 data.totalCountpagination.total로 이전)

사진 항목 필드 (data[])

필드타입설명
fileNamestring서버가 발급한 고유 파일명. 표지·내지 추가 요청의 parameters 또는 사진 다운로드 URL에 사용
originalNamestring원본 파일명
sizeinteger파일 크기 (bytes)
mimeTypestringMIME 타입
uploadedAtdatetime업로드 시각 (ISO 8601)
hashstring파일 내용 MD5 해시값

Response 예시

Response (200 OK)
{
  "success": true,
  "message": "Success",
  "data": [
    {
      "fileName": "photo260423001516528.JPG",
      "originalName": "cover.jpg",
      "size": 382229,
      "mimeType": "image/jpeg",
      "uploadedAt": "2026-04-23T00:15:18.977Z",
      "hash": "1baf5077ae9f5a13787a73a08625a802"
    }
  ],
  "pagination": {
    "total": 1,
    "limit": 100,
    "offset": 0,
    "hasNext": false
  }
}

HTTP 상태 코드

코드errorCode설명
200 OK조회 성공 (사진이 없으면 data 빈 배열 + pagination.total=0)
401 UnauthorizedERR_UNAUTHORIZED인증 실패
403 ForbiddenERR_FORBIDDEN본인 소유가 아닌 책
403 ForbiddenERR_ENV_MISMATCH호출 도메인과 API Key의 환경(Sandbox/Live) 불일치 — 호출 도메인 기준 참고
404 Not FoundERR_NOT_FOUND책 없음

사진 삭제

DELETE/books/{bookUid}/photos/{fileName}

사전 업로드한 사진을 삭제합니다. 응답 본문 없이 204 No Content를 반환합니다.

Path 파라미터

파라미터타입필수설명
bookUidstringO대상 책 UID
fileNamestringO삭제할 사진의 서버 파일명 (업로드 응답의 fileName)

Request 예시

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

HTTP 상태 코드

코드errorCode설명
204 No Content삭제 성공 (응답 본문 없음)
400 Bad RequestERR_VALIDATION_FAILEDbookUid 또는 fileName 형식 오류
401 UnauthorizedERR_UNAUTHORIZED인증 실패
403 ForbiddenERR_FORBIDDEN본인 소유가 아닌 책
403 ForbiddenERR_ENV_MISMATCH호출 도메인과 API Key의 환경(Sandbox/Live) 불일치 — 호출 도메인 기준 참고
404 Not FoundERR_NOT_FOUND책 또는 파일 없음
409 ConflictERR_CONFLICT책이 이미 최종화(finalized)된 상태 — 최종화 이후에는 사진 삭제가 차단됩니다

사진 다운로드

GET/books/{bookUid}/photos/{fileName}

업로드한 사진의 800px 썸네일 이미지 바이트를 반환합니다. 긴 변 기준으로 800px로 리사이즈된 썸네일이며, 원본(4000px)은 본 API로 제공되지 않습니다(내부 PDF 렌더링·인쇄 용도로만 사용). 업로드 정상 처리 여부 확인이나 사진 미리보기 UI 구성 용도로 사용하세요.

브라우저 <img src>에 직접 사용 불가합니다. 인증 헤더를 붙일 수 없기 때문입니다. 파트너 백엔드가 받아 자체 시스템에 저장·프록시해 노출하는 흐름을 권장합니다.

Path 파라미터

파라미터타입필수설명
bookUidstringO대상 책 UID
fileNamestringO다운로드할 사진의 서버 파일명

Request 예시

Request (파일로 저장)
curl 'https://api-sandbox.sweetbook.com/v1/books/{bookUid}/photos/photo260424005709732.PNG' \
  -H 'Authorization: Bearer {YOUR_API_KEY}' \
  --output photo.png

응답 헤더

헤더값 예시설명
Content-Typeimage/jpeg · image/png · image/webp저장된 원본의 MIME 타입
Content-Length58217썸네일 바이트 크기

응답 본문

800px 썸네일 이미지 바이트 (바이너리). curl --output이나 파일 스트림으로 저장해 사용하세요.

Response 예시

Response (200 OK)
HTTP/1.1 200 OK
Content-Type: image/png
Content-Length: 58217

<binary image bytes — 800px 썸네일>

HTTP 상태 코드

코드errorCode설명
200 OK다운로드 성공 (Content-Type: image/* + 이미지 바이트)
400 Bad RequestERR_VALIDATION_FAILEDbookUid 또는 fileName 형식 오류
401 UnauthorizedERR_UNAUTHORIZED인증 실패
403 ForbiddenERR_FORBIDDEN본인 소유가 아닌 책
403 ForbiddenERR_ENV_MISMATCH호출 도메인과 API Key의 환경(Sandbox/Live) 불일치 — 호출 도메인 기준 참고
404 Not FoundERR_NOT_FOUND책 또는 파일 없음 (errors: ["사진을 찾을 수 없습니다"] — 예: 삭제된 파일명)

404 ERR_NOT_FOUND: 파일 없음 (삭제된 fileName 등) — errors[0]: "사진을 찾을 수 없습니다". 응답 shape 상세는 에러 코드 & 트러블슈팅 — ERR_NOT_FOUND를 참조하세요.

PDF 다운로드

책이 최종화되어 시스템이 표지·내지를 PDF로 렌더링한 뒤에는 다음 두 엔드포인트로 인쇄용 PDF를 다운로드할 수 있습니다.

  • GET /books/{bookUid}/pdf-cover — 표지 PDF
  • GET /books/{bookUid}/pdf-contents — 내지 PDF
TEMPLATE 책의 표지·내지 PDF는 모두 책 최종화 후 백엔드가 백그라운드 큐에서 렌더링합니다(그룹 B). 따라서 POST /finalization 호출 직후에는 PDF가 아직 준비되지 않았을 수 있으며, 응답이 pdfStatus에 따라 분기됩니다 — 일정 시간 후 재시도해야 정상 다운로드가 가능합니다.

정상 응답은 JSON이 아닌 application/pdf 바이너리 스트림입니다. 그 외 케이스는 6필드 JSON 에러 응답으로 errorCode·errors·fieldErrors가 포함됩니다.

Request — 표지 PDF 다운로드
curl -o cover.pdf \
  'https://api-sandbox.sweetbook.com/v1/books/{bookUid}/pdf-cover' \
  -H 'Authorization: Bearer {YOUR_API_KEY}'
Request — 내지 PDF 다운로드
curl -o contents.pdf \
  'https://api-sandbox.sweetbook.com/v1/books/{bookUid}/pdf-contents' \
  -H 'Authorization: Bearer {YOUR_API_KEY}'

응답 매트릭스 (그룹 B)

TEMPLATE 책의 PDF 다운로드는 책 상태(pdfStatus)에 따라 다음과 같이 분기됩니다. 클라이언트는 errorCode로 분기하며 errors[0]의 한글 메시지를 사용자에게 보여줄 수 있습니다.

책 상태HTTP응답 형식errorCode클라이언트 권장 행동
책 최종화 전 (PDF 생성 미시작)409JSONERR_PDF_NOT_GENERATEDPOST /books/{bookUid}/finalization 호출 후 재시도
PDF 생성 진행 중409JSONERR_PDF_PENDING일정 간격(수 초~수십 초) 후 재시도. 무한 폴링 금지. Retry-After 헤더는 본 응답에 포함되지 않으므로 클라이언트가 자체 대기 간격을 결정해야 합니다.
PDF 생성 실패422JSONERR_PDF_GENERATION_FAILED클라이언트 자체 해결 불가 — 사용자 안내 + 고객지원팀 문의
생성 완료 + 파일 부재 (서버 결함)500JSONERR_PDF_FILE_MISSING서버 측 결함 — 고객지원팀 문의
생성 완료 + 파일 존재200application/pdf 바이너리 스트림응답 본문을 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

그룹 B 분기 응답 예시: 409 ERR_PDF_NOT_GENERATED (최종화 전) · 409 ERR_PDF_PENDING (생성 진행 중) · 422 ERR_PDF_GENERATION_FAILED (생성 실패) · 500 ERR_PDF_FILE_MISSING (서버 결함). 처리 가이드 포함 종합 안내는 에러 코드 & 트러블슈팅 — PDF 다운로드 분기를 참조하세요.

책 목록 조회

GET/books

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

Query 파라미터

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

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

응답 필드

필드타입설명
bookUidstring책 고유 UID
accountUidstring책 소유 계정 UID
titlestring책 제목
authorstring | null저자명 (선택)
statusstring책 상태 — enum 문자열로 반환. "draft"(작성 중, 내부값 1) / "finalized"(최종화 완료, 내부값 2) / "deleted"(삭제됨, 내부값 9)
pageCountinteger내지 페이지 수. TEMPLATE은 콘텐츠 추가 결과로 자동 산출 (finalize 시점에 확정), PDF 방식은 책 생성 시 지정한 값
bookSpecUidstring판형 UID
specProfileUidstring | nullSpecProfile UID
creationTypestringTEMPLATE / PDF_UPLOAD / MIX_COVER_TEMPLATE
createdAtdatetime책 생성 시각 (ISO 8601)
updatedAtdatetime마지막 수정 시각
externalRefstring | null파트너 외부 참조 식별자
isTestbooleanSandbox 환경 책 여부
pdfStatusinteger | nullPDF 처리 상태 (정수). null(미생성) / 1(PENDING, 렌더링 대기) / 2(COMPLETED, 준비 완료) / 9(FAILED, 실패). 자세한 의미는 위 책 최종화 → book.pdfStatus 값 표 참고. TEMPLATE 방식은 finalize 직후 1을 거쳐 2로 전환됩니다 (PDF 방식은 즉시 2)
pdfCreatedAtdatetime | nullPDF 파일이 마지막으로 갱신된 시각
pdfRequestedAtdatetime | null시스템이 PDF 렌더링 큐에 요청을 등록한 시각. TEMPLATE 방식은 finalize 호출 직후 시스템이 내부적으로 갱신하며, PDF 방식은 일반적으로 null을 유지합니다. 파트너가 직접 제어하는 필드가 아닙니다
thumbnailStatusinteger | null책 페이지 썸네일 처리 상태. null(NONE, 미생성) / 1(PENDING, 생성 진행 중) / 2(COMPLETED, 생성 완료) / 9(FAILED, 생성 실패)

Response 예시

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

HTTP 상태 코드

코드errorCode설명
200 OK조회 성공
400 Bad RequestERR_VALIDATION_FAILEDlimit/offset 범위 위반 등 파라미터 오류
401 UnauthorizedERR_UNAUTHORIZED인증 실패
500 Internal Server ErrorERR_INTERNAL_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_3k2S********",
    "accountUid": "u_b4b9********************",
    "title": "일기장 샘플",
    "bookSpecUid": "SQUAREBOOK_HC",
    "bookSpecName": "고화질 스퀘어북 (하드커버)",
    "specProfileUid": null,
    "creationType": "TEMPLATE",
    "status": 1,
    "coverTemplateUid": "tpl_cover_abc",
    "externalRef": "PARTNER-ORDER-001",
    "isTest": true,
    "pageMeta": {
      "currentPageCount": 18,
      "pageMin": 24,
      "pageMax": 200,
      "pageIncrement": 1,
      "isValid": false
    },
    "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를 참조하세요.

페이지 제약 위반 에러

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

  • ERR_INSUFFICIENT_PAGES (constraint: "min") — finalize 시점에 최소 페이지 미달
  • ERR_PAGECOUNT_INVALID (constraint: "max") — 콘텐츠 추가·finalize 시점에 최대 페이지 초과
  • ERR_PAGECOUNT_INVALID (constraint: "increment") — 증분 규칙 위반. requiredValue{min, increment} 객체 형태

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

책 삭제

DELETE/books/{bookUid}

책을 삭제 처리합니다. 물리적 삭제가 아닌 소프트 삭제(상태값 변경)로 처리되어, 이후 목록 조회 결과에서 제외됩니다. 표지·콘텐츠 페이지·사전 업로드한 사진은 별도 정리되지 않고 보관 상태로 남으며, 책 자체에 대한 추가 작업(표지·콘텐츠 추가/수정/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_3k2S********",
    "status": "deleted"
  }
}

HTTP 상태 코드

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

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