사전 준비
- BIZ MORI API 키 (여기서 발급)
- 워터마크를 삽입했던 원본 파일 — 워터마크가 삽입된 결과물이 아니라 워터마크 삽입 때 보낸 파일입니다
- 검사할 파일:
- 원본이 이미지(
jpg,jpeg,png,webp,bmp,tif,tiff)라면 검사할 파일도 이미지여야 합니다. - 원본이 PDF라면 검사할 파일은 PDF이거나, 그 PDF를 캡처한 PNG·JPEG 이미지입니다.
- 원본이 이미지(
자동 발급된
sk_test_ 키를 사용하면 실제 워터마크 검출이나 크레딧 사용 없이 v3 흐름 전체를 검증할 수 있습니다. 테스트 업로드는 파일 내용을 폐기하며, 결과는 검사할 파일의 이름으로 정해집니다. _detected가 있으면 detected, 그 밖에는 undetected이고, 두 파일 중 하나라도 이름에 _fail이 있으면 주문이 실패합니다.동작 방식
- 원본 파일과 검사할 파일의 이름으로 주문을 생성합니다.
- 응답의 프리사인드 URL로 두 파일을
PUT업로드합니다. 두 파일이 모두 업로드되면 검출이 자동으로 시작되며, confirm 단계는 없습니다. GET /api/v3/orders/{orderId}를 폴링하거나 웹훅을 받아 결과를 확인합니다.- 필요하면 결과에 대한 PDF 보고서를 생성합니다.
1단계: 주문 생성
워터마크 검출 주문을 생성합니다. 주문 하나는 파일 하나를 검사하며 1크레딧을 사용합니다.files에는 항상 두 항목이 있습니다. files[0]은 원본 파일, files[1]은 검사할 파일입니다. 주문 상세에서는 같은 파일이 inputFiles[]에 role이 original, query인 항목으로 나옵니다.
같은
idempotencyKey는 같은 요청을 재시도할 때만 다시 사용하세요. 이 경우 새 주문을 만들지 않고 기존 주문을 반환합니다. 같은 키로 요청 본문이 다른 요청을 보내면 409 WATERMARK_V2_CONFLICT를 반환합니다.2단계: 두 파일 업로드
각 파일을 프리사인드uploadUrl로 PUT 업로드합니다. 스토리지로 직접 올리는 업로드이므로 Authorization 헤더는 필요 없습니다.
Content-Type 헤더는 파일 확장자에 맞는 값으로 보내야 합니다. 프리사인드 URL이 이 타입으로 서명되어 있어 다른 값을 보내면 업로드가 거부됩니다.
confirm 단계는 필요 없습니다. 두 파일이 모두 업로드되면 검출이 자동으로 시작됩니다.
일반 키의
uploadUrl은 900초 뒤에 만료됩니다. 만료되었다면 GET /api/v3/orders/{orderId}를 호출해 아직 업로드되지 않은 파일의 새 inputFiles[].uploadUrl을 받으세요. 주문 생성 후 12시간 안에 두 파일을 모두 업로드하지 않으면 주문이 failed가 됩니다. 테스트 키는 1시간 동안 유효한 https://api.bizmori.com/api/v2/test-uploads/{signedToken} URL을 받습니다. 인증 없이 같은 방식으로 PUT하면 되며, 업로드한 파일 내용은 폐기됩니다.3단계: 결과 확인
status가 complete가 될 때까지 주문을 폴링한 뒤 result를 읽으세요. 폴링 대신 웹훅을 설정하면 order.watermarkExtract.completed 또는 order.watermarkExtract.failed 이벤트를 받을 수 있습니다.
status로 주문이 끝났는지 확인한 뒤, result.detectionStatus로 결과를 읽으세요.
result.watermarkText는 삽입했던 문구입니다. 결과가detected이고, 내 계정이 직접 삽입했으며, 삽입 기록이 정확히 1건일 때만 반환됩니다. 그 밖에는null입니다.result.reportSupported는 이 결과로 PDF 보고서를 만들 수 있는지를 나타냅니다. PDF를 캡처한 이미지를 검사했다면false입니다.result.reports[]에는 이 주문에 요청한 보고서별 상태가 들어 있습니다.processingDelayed가true이면 자동 재시도가 모두 소진되어 수동 복구를 기다리는 중입니다. 주문은inProgress상태로 유지되므로 계속 폴링하거나 웹훅을 기다리세요.
웹훅 페이로드는 v2의 필드 이름을 그대로 씁니다.
order.watermarkExtract.completed는 결과를 result.detectionStatus와 같은 값의 statusCode로 알려주며, watermarkFound와 watermarkInfo.text도 함께 전달됩니다. 전체 페이로드는 웹훅을 참고하세요.4단계: PDF 보고서 생성 (선택)
result.reportSupported가 true이면 결과에 대한 PDF 보고서를 한국어(ko-KR), 영어(en-US), 일본어(ja-JP)로 만들 수 있습니다. PDF 파일의 보고서는 ko-KR만 지원합니다. 보고서는 1크레딧을 사용하며, 생성에 성공했을 때만 차감됩니다.
보고서를 요청한 뒤 status가 completed가 될 때까지 폴링하세요.
download.url은 300초 뒤 만료됩니다. 저장해 두지 말고, 보고서를 내려받을 때마다 GET /api/v3/orders/{orderId}/reports/{locale}을 다시 호출하세요. 보고서가 failed이고 failure.retryable이 true이면 POST 엔드포인트를 다시 호출해 재시도할 수 있습니다.
테스트 키에서는 결과가
detected인 테스트 주문에만 보고서를 만들 수 있습니다. 요청 즉시 completed와 1페이지짜리 샘플 PDF를 반환하며 크레딧은 사용하지 않습니다.전체 React 예제
위 내용을 모두 하나의 컴포넌트로 연결했습니다: 파일 선택 두 개, 진행률을 보여주는 업로드, 백오프 폴링,detectionStatus로 렌더링하는 결과, 보고서 버튼까지. React 외에 별도의 의존성은 없습니다.
WatermarkExtractChecker.jsx
import.meta.env.VITE_MORI_API_KEY는 Vite 문법입니다. Next.js에서는 process.env.NEXT_PUBLIC_MORI_API_KEY를, 그 밖의 번들러에서는 클라이언트 코드에 노출하는 방식을 사용하세요. crypto.randomUUID()는 보안 컨텍스트가 필요합니다. HTTPS와 localhost에서는 동작하지만 일반 HTTP로 접속한 LAN 주소에서는 동작하지 않습니다.detectionStatus, reportSupported, watermarkText만 포함되며 워터마크 ID(MID)는 포함되지 않습니다.
에러 처리
전체 에러 코드는 에러 코드 페이지를 참고하세요.
v2에서 v3로 마이그레이션
v3는 검사할 파일을 항상 원본과 비교하므로, 요청에 두 파일을 모두 지정합니다.
v2 지원 종료 후 동작 (2026년 10월 9일 09:00 KST, 00:00 UTC부터):
- 인증·권한 검사는 지금처럼 먼저 수행하므로
401,403오류는 기존과 같습니다. - 인증을 통과한 v2 워터마크 삽입·검출 요청은 live 키와
sk_test_키 모두410 Gone과{ "code": "WATERMARK_V2_API_SUNSET" }을 받습니다.Link헤더가 v3 엔드포인트를 가리키니 v3로 새로 요청하세요. - 그때까지 처리를 시작하지 않은 v2 주문은 처리되지 않고 실패로 확정됩니다. 주문 상세(
errors.errorCode)와 실패 웹훅에WATERMARK_V2_API_SUNSET과 v3 안내 메시지가 담기며, 과금되지 않고 크레딧은 복원됩니다. - 종료 시각에 이미 처리 중인 주문은 결과 기록까지 마칩니다. 이후 새로 다시 실행하지는 않습니다.
- 기존 v2 주문 조회와 이미 생성된 결과·보고서 다운로드는 기존 보존 기간 안에서 계속 이용할 수 있습니다. v2 보고서를 새로 생성하거나 재생성할 수는 없습니다.
Deprecation: true, Sunset: Fri, 09 Oct 2026 00:00:00 GMT, Link 헤더만 추가됩니다.
다음 단계
워터마크 삽입
이미지와 PDF에 비가시성 워터마크를 삽입합니다.
테스트 API 키
크레딧 사용 없이 v3 흐름을 검증합니다.
웹훅
검출이 끝나면 알림을 받습니다.
API 레퍼런스
v3 워터마크 검출 엔드포인트의 모든 필드를 확인합니다.