PDF 업로드 시나리오

파트너가 직접 제작한 PDF를 업로드해 책을 만들고 주문까지 완료하는 전체 흐름입니다. 표지·내지 PDF 업로드 후 POST /books/{bookUid}/finalization으로 책을 최종화하면 FINALIZED 상태가 되고, 주문 생성 시 즉시 PDF_READY 상태로 진입합니다.

개요

호출 시퀀스

  • 책 생성creationType=PDF_UPLOAD, pageCount 지정
  • 표지 PDF 업로드 + 내지 PDF 업로드 (순서 무관)
  • 책 최종화POST /books/{bookUid}/finalization 호출로 책을 FINALIZED 상태로 전환
  • 주문 생성 — finalize 후 주문 시 즉시 PDF_READY 상태 진입
  • 주문 상태 추적 — 웹훅으로 배송 진행 수신

사용 케이스

이미 자체 편집 도구로 PDF를 직접 제작하고 있거나, 템플릿 기반 렌더링 없이 파트너 쪽에서 최종 레이아웃을 제어하고 싶을 때 사용합니다.

예시 환경

이 페이지의 모든 curl 예시는 아래 값을 기준으로 작성되어 있습니다. 코드 블록 우측 상단의 Sandbox / Live 탭으로 환경이 전환됩니다.

복붙해서 실행할 때는 {YOUR_API_KEY}를 본인 API Key로, {bookUid} 플레이스홀더를 실제 값으로 교체하세요.

항목예시 값
판형 UID (bookSpecUid)SQUAREBOOK_HC (하드커버 243×248mm)
페이지 수 (pageCount)24
표지 PDFhardcover24.pdf (544×288mm, 24p 기준)
내지 PDFhardcontents24.pdf (249×254mm, 24p)

PDF 준비 요건

업로드 시 PDF 크기·페이지 수·파일 무결성이 동기 검증됩니다. 검증 실패 시 400 에러로 업로드가 차단됩니다.

판형별 PDF 규격

이 페이지의 예시는 SQUAREBOOK_HC(하드커버) 기준 고정 규격을 사용합니다 (위 예시 환경 블록 참조). 다른 판형의 PDF 규격은 파트너 포털에서 확인하세요. 커버 타입(하드/소프트)에 따라 규격 규칙이 다릅니다.

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

허용 오차

항목허용 오차
소프트커버 표지 (너비·높이 공통)±1mm
하드커버 표지 너비 (width)±2mm
하드커버 표지 높이 (height)±1mm
내지 크기 (너비·높이 공통)±1mm

제본 타입별 내지 PDF 형식

제본 타입내지 PDF 형식업로드 PDF 페이지수
PUR (예: SQUAREBOOK_HC, PHOTOBOOK_A4_SC)단면 (page-by-page)book.pageCount 그대로
LAYFLAT (예: SQUAREBOOK_LAYFLAT_HC)펼침면 (spread, 좌·우 펼침)book.pageCount / 2

표지 PDF는 제본 타입과 관계없이 항상 펼침면 1페이지(앞표지 + 책등 + 뒤표지 한 장)입니다.book.pageCount·bookSpec.pageMin·bookSpec.pageMax·bookSpec.pageIncrement는 모두 책 페이지 단위로 저장됩니다. 업로드 검증 시점에만 PDF 페이지수로 환산됩니다.

공통 제약 (업로드 차단)

  • 파일 크기: 500MB 이하
  • 파일 형식: PDF (시그니처 %PDF- 확인)
  • PDF 구조 무결성: 손상/파싱 실패 시 업로드 차단
  • 내지 페이지 수: 책 생성 시 pageCount정확히 일치해야 함 (LAYFLAT은 pageCount / 2 PDF 페이지 — 불일치 시 400)
  • PDF 크기: 허용 오차 내 (위 표 참조)

페이지 수 주의사항 (업로드는 성공, 주문 시 차단)

책 생성 시 지정한 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 규격 구조 — 하드커버 예시 (파트너 포털에서 제공)
{
  "cover": [
    { "minPage": 24, "maxPage": 64, "width": 544, "height": 288 },
    { "minPage": 65, "maxPage": 130, "width": 550, "height": 288 }
  ],
  "inner": { "width": 249, "height": 254 }
}
PDF 규격 구조 — 소프트커버 예시 (파트너 포털에서 제공)
{
  "cover": { "width": 332, "height": 216 },
  "inner": { "width": 148, "height": 210 }
}

1. 책 생성

POST/books

PDF 업로드 방식으로 책을 생성합니다. creationType="PDF_UPLOAD"pageCount(내지 페이지 수)를 지정하는 것이 템플릿 기반 방식과의 차이점입니다.

Request Body

필드타입필수설명
titlestringO책 제목 (1~255자)
bookSpecUidstringO판형 UID
creationTypestringO"TEMPLATE" / "PDF_UPLOAD" / "MIX_COVER_TEMPLATE" 중 하나. PDF 업로드 방식에선 "PDF_UPLOAD" 지정
pageCountinteger-내지 페이지 수 (단페이지 기준). creationType=PDF_UPLOAD 또는 MIX_COVER_TEMPLATE일 때 필수
externalRefstring-파트너 외부 참조 식별자 (최대 100자). 파트너 시스템의 고유 ID를 저장하는 용도

상태 전이: (없음)DRAFT(편집중). 응답에서 받은 bookUid를 이후 모든 단계에서 사용합니다.

Idempotency-Key 지원: POST /books 요청 시 Idempotency-Key 헤더를 제공하면 동일한 키로 재요청해도 책이 중복 생성되지 않습니다. 네트워크 오류 등으로 인한 재시도 시 활용하세요.

에러 응답

상황상태 코드응답 메시지
creationType=PDF_UPLOAD인데 pageCount 누락400creation_type=PDF_UPLOAD는 pageCount(내지 페이지수)가 필수입니다.
유효하지 않은 creationType400유효하지 않은 creationType: INVALID_TYPE (허용: TEMPLATE, PDF_UPLOAD, MIX_COVER_TEMPLATE)
책 생성
curl -X POST 'https://api-sandbox.sweetbook.com/v1/books' \
  -H 'Authorization: Bearer {YOUR_API_KEY}' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: unique-request-id-001' \
  -d '{
    "title": "PDF 업로드 샘플",
    "bookSpecUid": "SQUAREBOOK_HC",
    "creationType": "PDF_UPLOAD",
    "pageCount": 24,
    "externalRef": "PARTNER-ORDER-001"
  }'
Response (201 Created)
{
  "success": true,
  "message": "책 생성 완료",
  "data": {
    "bookUid": "bk_3lOO********"
  }
}

2. 표지 PDF 업로드

POST/PUT/books/{bookUid}/pdf-cover

표지 PDF를 업로드하고 동기 검증합니다. 메서드에 따라 동작이 분리되어 있습니다.

  • POST신규 등록 전용. 이미 등록되어 있으면 409 Conflict
  • PUT교체 전용. 등록되어 있지 않으면 404 Not Found

교체 실패 시 기존 파일 보존 — PUT 요청의 검증이 실패해도, 이미 성공적으로 업로드되어 있던 파일은 그대로 유지됩니다.

Request (multipart/form-data)

필드타입필수설명
filefile (application/pdf)O표지 PDF 파일 (1페이지 고정)

응답 필드

필드타입설명
validboolean검증 통과 여부
pageCountintegerPDF의 실제 페이지 수 (표지는 1)
pdfSizeMmobjectPDF 실제 크기 (width, height, mm 단위)
messagesstring[]안내 메시지 배열
warningsstring[]경고 메시지 배열
bookStatusinteger책의 현재 상태. 1=DRAFT(편집중) / 2=FINALIZED(최종화)
urlstring업로드된 PDF 조회 URL

에러 응답

상황상태 코드응답 메시지
POST 호출 시 표지 PDF가 이미 등록됨409표지 PDF가 이미 등록되어 있습니다. 교체하려면 PUT 메서드를 사용하세요.
PUT 호출 시 표지 PDF가 등록되어 있지 않음404표지 PDF가 등록되어 있지 않습니다. 신규 등록은 POST 메서드를 사용하세요.
PDF 크기 불일치400PDF 너비 불일치: 실제 148.0mm, 허용 규격 249mm (+/-1mm)
표지 신규 등록 (POST)
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 (201 Created)
{
  "success": true,
  "message": "cover PDF uploaded successfully",
  "data": {
    "bookUid": "bk_3lOO********",
    "kind": "cover",
    "valid": true,
    "pageCount": 1,
    "pdfSizeMm": { "width": 544, "height": 288 },
    "messages": [],
    "warnings": [],
    "bookStatus": 1,
    "url": "https://api-sandbox.sweetbook.com/v1/books/bk_3lOO********/pdf-cover"
  }
}
표지 교체 (PUT)
curl -X PUT 'https://api-sandbox.sweetbook.com/v1/books/{bookUid}/pdf-cover' \
  -H 'Authorization: Bearer {YOUR_API_KEY}' \
  -F 'file=@hardcover24.pdf;type=application/pdf'
Response (200 OK)
{
  "success": true,
  "message": "cover PDF replaced successfully",
  "data": {
    "bookUid": "bk_3lOO********",
    "kind": "cover",
    "valid": true,
    "pageCount": 1,
    "pdfSizeMm": { "width": 544, "height": 288 },
    "messages": [],
    "warnings": [],
    "bookStatus": 1,
    "url": "https://api-sandbox.sweetbook.com/v1/books/bk_3lOO********/pdf-cover"
  }
}

3. 내지 PDF 업로드

POST/PUT/books/{bookUid}/pdf-contents

내지 PDF를 업로드합니다. 실제 페이지 수가 책 생성 시 지정한 pageCount정확히 일치해야 합니다 (불일치 시 400).

  • POST신규 등록 전용. 이미 등록되어 있으면 409 Conflict
  • PUT교체 전용. 등록되어 있지 않으면 404 Not Found

Request (multipart/form-data)

필드타입필수설명
filefile (application/pdf)O내지 PDF 파일. 페이지 수가 pageCount와 일치해야 함

응답 필드

표지 업로드와 동일한 구조 (kind"contents"). 응답 필드 상세는 2. 표지 PDF 업로드 섹션 참조.

에러 응답

상황상태 코드응답 메시지
POST 호출 시 내지 PDF가 이미 등록됨409내지 PDF가 이미 등록되어 있습니다. 교체하려면 PUT 메서드를 사용하세요.
PUT 호출 시 내지 PDF가 등록되어 있지 않음404내지 PDF가 등록되어 있지 않습니다. 신규 등록은 POST 메서드를 사용하세요.
PDF 크기 불일치400PDF 너비 불일치: 실제 148.0mm, 허용 규격 249mm (+/-1mm)
내지 PDF 페이지 수 불일치400내지 PDF 페이지수 불일치: 올바른 페이지수 24p, 업로드된 페이지수 30p (LAYFLAT은 책 페이지 환산값 부가)
내지 신규 등록 (POST)
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 (201 Created)
{
  "success": true,
  "message": "contents PDF uploaded successfully",
  "data": {
    "bookUid": "bk_3lOO********",
    "kind": "contents",
    "valid": true,
    "pageCount": 24,
    "pdfSizeMm": { "width": 249, "height": 254 },
    "messages": [],
    "warnings": [],
    "bookStatus": 1,
    "url": "https://api-sandbox.sweetbook.com/v1/books/bk_3lOO********/pdf-contents"
  }
}
내지 교체 (PUT)
curl -X PUT 'https://api-sandbox.sweetbook.com/v1/books/{bookUid}/pdf-contents' \
  -H 'Authorization: Bearer {YOUR_API_KEY}' \
  -F 'file=@hardcontents24.pdf;type=application/pdf'
Response (200 OK)
{
  "success": true,
  "message": "contents PDF replaced successfully",
  "data": {
    "bookUid": "bk_3lOO********",
    "kind": "contents",
    "valid": true,
    "pageCount": 24,
    "pdfSizeMm": { "width": 249, "height": 254 },
    "messages": [],
    "warnings": [],
    "bookStatus": 1,
    "url": "https://api-sandbox.sweetbook.com/v1/books/bk_3lOO********/pdf-contents"
  }
}

4. 책 최종화

POST/books/{bookUid}/finalization

표지·내지 PDF가 모두 업로드된 후 호출합니다. 호출 성공 시 책의 statusdraftfinalized로, pdfStatusnull2(COMPLETED)로 전환되어 주문 가능 상태가 됩니다.

최종화 호출이 누락되면 주문이 차단됩니다
표지·내지 PDF 업로드 후 이 엔드포인트를 호출해야 책이 FINALIZED 상태가 됩니다. 호출 누락 시 주문 생성은 400 ERR_FINALIZE_PREREQ_UNMET으로 차단됩니다.
Request
curl -X POST 'https://api-sandbox.sweetbook.com/v1/books/{bookUid}/finalization' \
  -H 'Authorization: Bearer {YOUR_API_KEY}' \
  -H 'Content-Length: 0'

상세 응답 필드·에러 분기·재호출 멱등 동작은 Books — PDF 기반 → 책 최종화를 참고하세요.

5. 주문 생성

POST/orders

책이 FINALIZED(최종화) 상태인 경우에만 주문 생성이 가능합니다. PDF 업로드 방식의 책은 PDF가 이미 준비되어 있으므로 주문 생성 시점에 즉시 PDF_READY 상태로 진입합니다.

주문 전 금액 확인이 필요하면 POST /orders/estimate를 먼저 호출하세요. 충전금 잔액 부족 시 402 Insufficient Credit이 반환됩니다.

필드 상세는 Orders API 레퍼런스 참조.

Idempotency-Key 지원: POST /orders 요청 시 Idempotency-Key 헤더를 제공하면 동일한 키로 재요청해도 주문이 중복 생성되지 않습니다. 네트워크 오류 등으로 인한 재시도 시 활용하세요.

에러 응답

상황상태 코드응답 메시지
DRAFT(편집중) 상태 책을 주문 시도400Book이 FINALIZED 상태가 아닙니다: bk_588b********
충전금 부족402잔액이 부족합니다. 필요: 3420, 잔액: 760.00
주문 생성
curl -X POST 'https://api-sandbox.sweetbook.com/v1/orders' \
  -H 'Authorization: Bearer {YOUR_API_KEY}' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: unique-request-id-002' \
  -d '{
    "items": [{ "bookUid": "{bookUid}", "quantity": 1 }],
    "shipping": {
      "recipientName": "김영수",
      "recipientPhone": "010-0000-0000",
      "postalCode": "06134",
      "address1": "서울시 강남구 테헤란로 100",
      "address2": "101호",
      "memo": ""
    },
    "externalRef": "PARTNER-ORDER-001"
  }'
Response (402) — 충전금 부족
{
  "success": false,
  "message": "Insufficient Credit",
  "data": {
    "required": 3420,
    "balance": 760.00,
    "currency": "KRW"
  },
  "errors": [
    "잔액이 부족합니다. 필요: 3420, 잔액: 760.00"
  ]
}
Response (201 Created) — 즉시 PDF_READY
{
  "success": true,
  "message": "주문이 생성되었습니다",
  "data": {
    "orderUid": "or_7Bjt********",
    "accountName": "김영수",
    "accountOrganizationName": null,
    "externalRef": "PARTNER-ORDER-001",
    "orderStatus": "PDF_READY",
    "orderStatusDisplay": "PDF준비완료",
    "isTest": true,
    "totalProductAmount": 100.00,
    "totalShippingFee": 3000,
    "totalPackagingFee": 0,
    "totalAmount": 3100.00,
    "paidCreditAmount": 3410,
    "creditBalanceAfter": 98250.00,
    "recipientName": "김영수",
    "recipientPhone": "010-0000-0000",
    "postalCode": "06134",
    "address1": "서울시 강남구 테헤란로 100",
    "address2": "101호",
    "shippingMemo": "",
    "trackingNumber": null,
    "trackingCarrier": null,
    "cancelReason": null,
    "refundAmount": null,
    "orderedAt": "2026-04-15T06:16:49.813Z",
    "paidAt": "2026-04-15T06:16:49.813Z",
    "cancelledAt": null,
    "shippedAt": null,
    "deliveredAt": null,
    "createdAt": "2026-04-15T06:16:49.813Z",
    "items": [
      {
        "itemUid": "oi_34CN********",
        "bookUid": "bk_3lOO********",
        "bookTitle": "PDF 업로드 샘플",
        "bookSpecUid": "SQUAREBOOK_HC",
        "bookSpecName": "고화질 스퀘어북 (하드커버)",
        "quantity": 1,
        "pageCount": 24,
        "unitPrice": 100.00,
        "itemAmount": 100.00,
        "itemStatus": "PDF_READY",
        "itemStatusDisplay": "PDF준비완료",
        "trackingNumber": null,
        "trackingCarrier": null,
        "shippedAt": null,
        "createdAt": "2026-04-15T06:16:49.813Z"
      }
    ]
  }
}

6. 주문 상태 추적

주문이 생성된 이후 제작·배송 진행은 웹훅 이벤트로 수신합니다. PDF 업로드 방식 주문은 PDF_READY에서 시작하며, 이후 상태 전이 체계는 주문 상태 흐름 페이지 참조.

PDF 다운로드 (선택)

GET/books/{bookUid}/pdf-cover
GET/books/{bookUid}/pdf-contents

업로드한 PDF를 다시 다운로드합니다. 인증 필요. 성공 시 Content-Type: application/pdf 바이너리 스트림이 반환됩니다.

한쪽만 업로드된 상태에서도 해당 파일은 다운로드 가능합니다.

에러 응답

상황상태 코드응답 메시지
파일이 존재하지 않음404PDF 파일이 존재하지 않습니다.
권한 없음403해당 책에 대한 권한이 없습니다.
표지 다운로드
curl -o cover.pdf 'https://api-sandbox.sweetbook.com/v1/books/{bookUid}/pdf-cover' \
  -H 'Authorization: Bearer {YOUR_API_KEY}'
내지 다운로드
curl -o contents.pdf 'https://api-sandbox.sweetbook.com/v1/books/{bookUid}/pdf-contents' \
  -H 'Authorization: Bearer {YOUR_API_KEY}'