한국형 통합 문서 파서

# 한국형 통합 문서 파서 API HWP·HWPX·PDF·DOCX·PPTX·XLSX·이미지·HTML 등 19종 문서를 단일 API 한 호출로 마크다운·텍스트·JSON으로 변환해요. 라우터가 형식을 자동 감지해 최적 백엔드에 분기하고, 필요하면 한국어 OCR·개인정보 마스킹·기밀 등급까지 한 호출에 묶어 처리합니다. - **모델 ID**: `doc` - **Base URL**: `https://api.corepin.ai` - **버전**: `doc-2026.06` ## 1. 엔드포인트 | Method | Path | 인증 | 단가 | 설명 | |---|---|:-:|---:|---| | POST | `/v1/doc/parse` | ✓ | 2원 / 페이지 | 문서 1개 → 마크다운/텍스트/JSON | | POST | `/v1/doc/parse/batch` | ✓ | 1원 / 페이지 | 여러 문서 일괄 (최대 100개, 50% 할인) | | POST | `/v1/doc/parse/async` | ✓ | 1원 / 페이지 | 비동기 대용량 — 단일 호출 최대 2,000페이지, 결과는 폴링으로 받기 | | POST | `/v1/doc/parse/async/init` | ✓ | — | 대용량 path — 업로드용 PUT URL 발급 (≤500 파일·5,000p) | | POST | `/v1/doc/parse/async/upload` | ✓ | 1원 / 페이지 | 대용량 path — 업로드 완료 후 잡 제출 | | GET | `/v1/doc/parse/async/{job_id}` | ✓ | — | async 작업 상태·결과 조회 | | GET | `/v1/doc/parse/async` | ✓ | — | 내 async 작업 목록 (최근 50개) | | DELETE | `/v1/doc/parse/async/{job_id}` | ✓ | — | 대기 중인 async 작업 취소 | | POST | `/v1/doc/diff` | ✓ | 2원 / 페이지 | 두 문서 신구대조표 (A·B 페이지 합산) | | POST | `/v1/doc/fill` | ✓ | 2원 / 페이지 | 양식 자동 채우기 — HWPX template + JSON → 채워진 HWPX | | POST | `/v1/doc/markdown-to` | ✓ | 2원 / 페이지 | 마크다운 → HWPX·DOCX·PDF 통합 역변환 (Notion 인쇄 수준 미려) | | GET | `/v1/doc/formats` | ✓ | — | 지원 형식 + 라우터 백엔드 정보 | | GET | `/v1/doc/version` | ✓ | — | 모델 버전 | 응답 시간: 단건 0.3–3초 · 표 자동 정밀 모드 발동 시 4–18초 · 배치 1–30초 · 스캔 PDF (OCR fallback) 페이지당 +1.5초. ## 2. POST `/v1/doc/parse` 요청은 `multipart/form-data`입니다. **Request 필드**: | 필드 | 타입 | 기본 | 설명 | |---|---|---|---| | `file` | binary | (필수) | 문서 파일. 19종 형식, 최대 50MB. | | `output_format` | string | `markdown` | 응답 형식. `text` / `markdown` / `html` / `json` 중 선택. | | `pii_mask` | bool | `false` | 본문 자동 개인정보 마스킹. 기본가에 **+5원 / 호출** (문서 1건당 한 번). | | `dlp_grade` | bool | `false` | 자동 보안 등급·유형 분류. 기본가에 **+20원 / 호출** (문서 1건당 한 번). | | `ocr_fallback` | bool | `true` | 스캔 PDF 자동 감지 시 한국어 OCR. 기본가에 **+2원 / 페이지 — OCR한 페이지만** (그 페이지는 2원+2원=**4원**, 글자 페이지는 2원 그대로). | | `moderation_check` | bool | `false` | 본문 유해발화 자동 감지. 기본가에 **+5원 / 호출** (문서 1건당 한 번). | | `mental_health_check` | bool | `false` | 본문 정신건강 위험 신호 감지. 기본가에 **+10원 / 호출** (문서 1건당 한 번). | | `pptx_ocr` | bool | `false` | PPTX 슬라이드 안 이미지에 박힌 텍스트 자동 OCR. 기본가에 **+2원 / 이미지 — OCR한 이미지만**. 기본 PPTX 파서는 슬라이드 텍스트 박스만 읽고 다이어그램·스크린샷 안 텍스트는 못 봐요. 이 옵션이 켜지면 슬라이드별로 picture shape를 모아 한국어 OCR 1위 모델로 cascade 호출해요. | | `pii_categories` | string | `""` | **`pii_mask=true`일 때만.** 마스킹할 PII 카테고리 화이트리스트 (콤마 구분, 예: `kr_rrn,private_phone`). 지정한 카테고리만 마스킹하고 나머지는 평문으로 둬요. 비우면 전체. 코드 목록은 `GET /v1/pii/categories`. | | `dlp_grades` | string | `""` | **`dlp_grade=true`일 때만.** 보고할 보안 등급 화이트리스트 (콤마 구분, 예: `CONFIDENTIAL,RESTRICTED`). 분류된 등급이 목록 밖이면 `grade`가 `null`로 와요. 비우면 전체. 코드는 `GET /v1/dlp/grades`. | | `dlp_types` | string | `""` | **`dlp_grade=true`일 때만.** 보고할 보안 유형 화이트리스트 (콤마 구분, 예: `CONTRACT,HR`). 목록에 든 유형만 `types`에 남겨요. 비우면 전체. 코드는 `GET /v1/dlp/types`. | | `moderation_labels` | string | `""` | **`moderation_check=true`일 때만.** 보고할 유해발화 라벨 화이트리스트 (콤마 구분, 예: `M07,M08`). 목록 라벨만 `labels`에 남기고 `blocked`도 그 기준으로 재계산해요. 비우면 전체. | | `mental_health_axes` | string | `""` | **`mental_health_check=true`일 때만.** 알림 대상 정신건강 축 화이트리스트 (콤마 구분, 예: `MH01,MH10`). 목록 축의 신호만 `flagged_axes`에 남겨요 (`risk_level`은 정보용으로 그대로). 비우면 전체. 코드는 `GET /v1/mental_health/axes`. | > **대상 화이트리스트 (테넌트별 호출 단위 설정).** 테넌트별 필터 정책을 자체 시스템에서 관리하고 코어핀엔 호출마다 파라미터로 넘기는 통합(예: WorksAI)을 위한 옵션이에요. 위 5개 필드는 해당 모델이 켜졌을 때만 의미가 있고, **비우면 기존처럼 전체 대상**으로 동작해요. 알 수 없는 코드를 넣으면 `422 invalid_whitelist`로 즉시 거부돼요(오타 조기 발견). 모델 추론 자체는 항상 전체 대상으로 수행되므로 **추가 비용은 없어요** — 화이트리스트는 응답에 담길 결과만 좁혀요. **지원 형식**: | 카테고리 | 확장자 | 백엔드 | |---|---|---| | 한국 표준 | `.hwp` (3.0/5.x) · `.hwpx` · `.hwpml` | 한국 공무 표준 처리 | | Microsoft | `.docx` · `.pptx` · `.xlsx` | 외산 표준 처리 | | Microsoft (구버전) | `.doc` · `.xls` (97-2003) | 구버전 바이너리 — `.doc` 본문 텍스트, `.xls` 시트별 표 | | PDF | `.pdf` | 텍스트 추출 + 스캔본 자동 OCR | | 이미지 | `.jpg` · `.png` · `.heic` · `.tif` · `.webp` · `.bmp` | 한국어 OCR | | 텍스트·웹 | `.html` · `.epub` · `.rtf` · `.csv` · `.tsv` · `.md` · `.txt` | 텍스트 추출 | **Response 필드**: | 필드 | 타입 | 설명 | |---|---|---| | `text` | string | 본문 (마크다운 마커 제거된 plain text) | | `markdown` | string | `output_format=markdown`/`html`/`json`일 때 — 헤더·표·리스트 보존 마크다운 | | `html` | string | `output_format=html`일 때 — 마크다운을 HTML 변환 (table·fenced_code·sane_lists 확장) | | `blocks` | array | `output_format=json`일 때 — IR 블록 배열 (paragraph/heading/table/list) | | `pii_applied` | object | `pii_mask=true`일 때 — `{applied, span_count}` | | `dlp_classification` | object | `dlp_grade=true`일 때 — `{grade, grade_confidence, types}`. `dlp_grades` 화이트리스트를 줬고 분류 등급이 그 목록 밖이면 `grade`/`grade_confidence`는 `null`. `dlp_types` 화이트리스트는 `types`를 그 목록으로 좁혀요. | | `moderation` | object | `moderation_check=true`일 때 — `{labels, label_names, blocked, raw, confidence, genre_suppressed?}` | | `mental_health` | object | `mental_health_check=true`일 때 — `{risk_level, recommended_action, flagged_axes, genre_suppressed?}` | | `auto_escalated` | bool | 표가 감지되어 자동 정밀 모드로 처리된 경우 `true`. 추가 비용 없음. | | `meta.model_id` | string | `doc` | | `meta.model_version` | string | 모델 버전 (예: `doc-2026.05`) | | `meta.processing_time_ms` | float | 서버 처리 시간 (ms) | | `meta.request_id` | string | 요청 추적 ID | | `meta.page_count` | int | 청구 단위 페이지 수 | | `meta.file_format` | string | 감지된 파일 형식 (`hwp`/`pdf`/`docx` 등) | | `meta.needed_ocr` | bool | OCR fallback 발동 여부 | | `meta.ocr_pages_used` | int | OCR 호출된 페이지 수 | | `meta.warnings` | array | 사용자 알림 (스캔 PDF 감지 등) | | `meta.quota_remaining` | int | 잔여 호출 수 (후불 계정은 `null`) | **예시 — HWP 공문**: ```bash curl -X POST https://api.corepin.ai/v1/doc/parse \ -H "Authorization: Bearer $COREPIN_API_KEY" \ -F "file=@공문.hwp" \ -F "output_format=markdown" ``` ```json { "text": "발 신: 행정안전부 / ...", "markdown": "## 발신\n행정안전부\n\n## 수신\n각 시·도\n\n| 항목 | 내용 |\n|---|---|\n| 시행일 | 2026-05-16 |", "meta": { "model_id": "doc", "model_version": "doc-2026.05", "processing_time_ms": 642.1, "request_id": "abc...", "page_count": 2, "file_format": "hwp", "needed_ocr": false, "ocr_pages_used": 0, "warnings": [], "quota_remaining": 98 } } ``` **예시 — 스캔 PDF 자동 OCR**: ```bash curl -X POST https://api.corepin.ai/v1/doc/parse \ -H "Authorization: Bearer $COREPIN_API_KEY" \ -F "file=@옛판결문_스캔본.pdf" \ -F "output_format=text" ``` 응답의 `meta.needed_ocr=true` + `meta.warnings`에 "스캔 PDF로 감지 — 한국형 OCR로 다시 처리해요." 표시. **예시 — 개인정보 마스킹 + 기밀 등급**: ```bash curl -X POST https://api.corepin.ai/v1/doc/parse \ -H "Authorization: Bearer $COREPIN_API_KEY" \ -F "file=@계약서.pdf" \ -F "output_format=markdown" \ -F "pii_mask=true" \ -F "dlp_grade=true" ``` ```json { "text": "계약자: ●●●...", "markdown": "## 계약서\n\n- 계약자: ●●●\n- 주민등록번호: ●●●●●●-●●●●●●●", "pii_applied": {"applied": true, "span_count": 7}, "dlp_classification": { "grade": "CONFIDENTIAL", "grade_confidence": 0.93, "types": ["CONTRACT", "CUSTOMER"] }, "meta": { "model_id": "doc", "page_count": 4, "warnings": ["개인정보 자동 마스킹 적용 (7건)", "보안 등급 자동 분류: CONFIDENTIAL"], ... } } ``` **예시 — 대상 화이트리스트 (주민번호·전화만 마스킹, 정신건강은 자살/자해 축만 알림)**: ```bash curl -X POST https://api.corepin.ai/v1/doc/parse \ -H "Authorization: Bearer $COREPIN_API_KEY" \ -F "file=@상담기록.pdf" \ -F "pii_mask=true" -F "pii_categories=kr_rrn,private_phone" \ -F "mental_health_check=true" -F "mental_health_axes=MH01,MH02" ``` ```json { "markdown": "상담자: 홍●● (●●●●●●-●●●●●●●, ●●●-●●●●-●●●●)", "pii_applied": {"applied": true, "span_count": 2}, "mental_health": { "risk_level": "moderate", "recommended_action": "...", "flagged_axes": [{"axis": "MH01", "name_ko": "자살 사고", "level": "moderate"}] } } ``` 화이트리스트에 든 카테고리/축만 응답에 반영돼요. 이름(`홍●●`)은 `private_person`이 화이트리스트에 없어 평문으로 남고, `MH05`(정신증) 같은 다른 축 신호는 감지돼도 `flagged_axes`에서 빠져요. ## 3. POST `/v1/doc/parse/batch` 여러 문서를 한 번에 처리. 요청은 `multipart/form-data`, `file` 필드를 여러 번 첨부하세요. **Request 필드**: | 필드 | 타입 | 기본 | 설명 | |---|---|---|---| | `file` | binary (반복) | (필수) | 문서 1~100개. 각 최대 50MB. | | `output_format` | string | `markdown` | `text` / `markdown` / `json`. | | `pii_mask` | bool | `false` | 모든 파일에 적용. | | `dlp_grade` | bool | `false` | 모든 파일에 적용. | | `ocr_fallback` | bool | `true` | 모든 파일에 적용. | | `moderation_check` · `mental_health_check` · `pptx_ocr` | bool | `false` | sync와 동일. 모든 파일에 적용. | | `pii_categories` · `dlp_grades` · `dlp_types` · `moderation_labels` · `mental_health_axes` | string | `""` | sync `/v1/doc/parse`와 동일한 대상 화이트리스트 (콤마 구분). 배치 내 모든 파일에 같은 화이트리스트가 적용돼요. | **Response**: ```json { "results": [ {"filename": "doc1.pdf", "text": "...", "markdown": "...", "page_count": 3, "file_format": "pdf"}, {"filename": "doc2.hwp", "text": "...", "markdown": "...", "page_count": 5, "file_format": "hwp"}, {"filename": "broken.xlsx", "error": {"code": "parser_failed", "message": "..."}} ], "meta": { "model_id": "doc", "model_version": "doc-2026.05", "processing_time_ms": 4123.7, "page_count": 8, "file_count": 3, "unit_price_krw": 2, "quota_remaining": 92 } } ``` 페이지 단위 실패 시 그 파일만 `{"filename": "...", "error": {...}}`로 표시되고, 나머지는 정상 결과를 받아요. ```bash curl -X POST https://api.corepin.ai/v1/doc/parse/batch \ -H "Authorization: Bearer $COREPIN_API_KEY" \ -F "file=@a.pdf" -F "file=@b.docx" -F "file=@c.hwp" \ -F "output_format=markdown" ``` ## 4. POST `/v1/doc/parse/async` — 대용량 비동기 배치 한도 (100파일·페이지 합산 ~340p)를 넘는 대용량 RAG 인덱싱 같은 작업용. 즉시 `job_id`가 돌아오고 실제 처리는 백그라운드 작업에서 이루어져요. 결과는 GET으로 폴링해서 받으세요. **Request 필드** (`/v1/doc/parse/batch`와 동일, 단일 호출 한도만 달라요): | 필드 | 타입 | 기본 | 설명 | |---|---|---|---| | `file` | binary (반복) | (필수) | 문서 1~100개. 각 최대 50MB. **단일 호출 페이지 합계 ≤ 2,000.** | | `output_format` | string | `markdown` | `text` / `markdown` / `html` / `json`. | | `pii_mask` | bool | `false` | 모든 파일에 적용. 파일당 +5원 / 호출. | | `dlp_grade` | bool | `false` | 모든 파일에 적용. 파일당 +20원 / 호출. | | `ocr_fallback` | bool | `true` | 모든 파일에 적용. +2원 / 페이지 — OCR한 페이지만 (그 페이지는 4원). | | `moderation_check` | bool | `false` | 모든 파일에 적용. 파일당 +5원 / 호출. | | `mental_health_check` | bool | `false` | 모든 파일에 적용. 파일당 +10원 / 호출. | | `pptx_ocr` | bool | `false` | PPTX 안 이미지 OCR. +2원 / 이미지 — OCR한 이미지만. | | `pii_categories` · `dlp_grades` · `dlp_types` · `moderation_labels` · `mental_health_axes` | string | `""` | sync `/v1/doc/parse`와 동일한 대상 화이트리스트 (콤마 구분). 잡 전체에 적용돼요. | **Response — 202 Accepted (제출 직후)**: ```json { "job_id": "34d5a0514bdf46a2819540c11f5ac8f8", "status": "queued", "file_count": 12, "status_url": "/v1/doc/parse/async/34d5a0514bdf46a2819540c11f5ac8f8", "meta": { "model_id": "doc", "model_version": "doc-2026.05", "request_id": "req_abc...", "unit_price_krw": 2, "max_pages_per_job": 2000 } } ``` **폴링** — `GET /v1/doc/parse/async/{job_id}`: ```json { "job_id": "34d5a05...", "status": "processing", "file_count": 12, "completed_files": 5, "page_count": 47, "ocr_pages_used": 0, "submitted_at": "2026-05-18T03:42:11Z", "started_at": "2026-05-18T03:42:13Z", "finished_at": null, "output_format": "markdown" } ``` `status`가 `done`으로 바뀌면 `results` 배열이 추가돼요 (배치 응답과 같은 모양 — 파일별 `text`/`markdown` 또는 `error`). `failed`면 잡 전체 실패 사유가 `error` 필드에 들어가요. 폴링 권장 간격 5초, 점진 증가 60초까지. **작업 보관**: 24시간 (완료·실패·취소 잡 모두). 그 후 자동 삭제. **취소** — 아직 시작 안 한 (status=queued) 잡만 DELETE로 취소 가능. processing 중인 잡은 끝까지 처리돼요. ```bash # 제출 curl -X POST https://api.corepin.ai/v1/doc/parse/async \ -H "Authorization: Bearer $COREPIN_API_KEY" \ -F "file=@big1.pdf" -F "file=@big2.pdf" -F "file=@big3.pdf" \ -F "output_format=markdown" -F "pii_mask=true" # 상태 폴링 curl https://api.corepin.ai/v1/doc/parse/async/$JOB_ID \ -H "Authorization: Bearer $COREPIN_API_KEY" # 내 잡 목록 curl https://api.corepin.ai/v1/doc/parse/async \ -H "Authorization: Bearer $COREPIN_API_KEY" # 취소 (queued만) curl -X DELETE https://api.corepin.ai/v1/doc/parse/async/$JOB_ID \ -H "Authorization: Bearer $COREPIN_API_KEY" ``` 청구: 페이지당 1원 (batch와 동일 50% 할인). 옵션(pii_mask·dlp_grade·ocr_fallback·moderation_check·mental_health_check·pptx_ocr)은 sync 경로와 동일 단가로 기본가에 추가돼요. ### 4.1 대용량 path — `/v1/doc/parse/async/init` + `/v1/doc/parse/async/upload` (≤5,000p, ≤500 파일) 기본 path (위) 한도는 100 파일·2,000 페이지지만, 직접 업로드 path는 한 잡당 **500 파일·5,000 페이지**까지 가능해요. 동작 순서: 1. `POST /v1/doc/parse/async/init`으로 업로드용 PUT URL N개 받음 2. 클라이언트가 각 URL에 HTTP PUT으로 파일을 직접 업로드 3. `POST /v1/doc/parse/async/upload`로 `key` list와 옵션 제출 → `job_id` 4. 이후 GET / DELETE는 기본 path와 같은 엔드포인트 사용 (`/v1/doc/parse/async/{job_id}`) ```bash # 1. init — 업로드용 PUT URL 발급 curl -s -X POST https://api.corepin.ai/v1/doc/parse/async/init \ -H "Authorization: Bearer $COREPIN_API_KEY" \ -H "Content-Type: application/json" \ -d '{"count": 3, "content_types": ["application/pdf","application/pdf","application/pdf"]}' # → {"upload_id":"...","uploads":[{"key":"...","put_url":"https://...","expires_in":3600}, ...]} # 2. 각 파일을 PUT URL로 직접 업로드 curl -X PUT "$PUT_URL" -H "Content-Type: application/pdf" --data-binary @big1.pdf # 3. 잡 제출 curl -X POST https://api.corepin.ai/v1/doc/parse/async/upload \ -H "Authorization: Bearer $COREPIN_API_KEY" \ -H "Content-Type: application/json" \ -d '{"items":[{"key":"...","filename":"big1.pdf"},{"key":"...","filename":"big2.pdf"}],"output_format":"markdown","pii_mask":true}' ``` 옵션은 기본 path와 동일하되, 이 path는 **JSON body** 라 대상 화이트리스트를 콤마 문자열이 아니라 **배열**로 넣어요 — `pii_categories` · `dlp_grades` · `dlp_types` · `moderation_labels` · `mental_health_axes` (각각 `["kr_rrn","private_phone"]` 형태). 의미·검증(미지 코드 422)·과금(추가 비용 0)은 sync `/v1/doc/parse`와 동일. 예: `{"items":[...],"pii_mask":true,"pii_categories":["kr_rrn","private_phone"],"mental_health_check":true,"mental_health_axes":["MH01","MH10"]}`. 단가·동시 부하 제한·취소 동작은 기본 path와 완전히 동일. ## 5. POST `/v1/doc/diff` 두 문서 신구대조표. A·B 두 파일 모두 파싱한 뒤 본문 unified diff를 마크다운 코드 펜스로 반환합니다. **Request 필드**: | 필드 | 타입 | 설명 | |---|---|---| | `file_a` | binary | 이전 문서 | | `file_b` | binary | 새 문서 | **Response**: ```json { "summary": { "a_pages": 3, "b_pages": 3, "added_lines": 12, "removed_lines": 8, "format_a": "hwp", "format_b": "hwpx" }, "diff_markdown": "```diff\n--- 공문_v1.hwp\n+++ 공문_v2.hwpx\n@@ ... @@\n- 시행일: 2026-05-10\n+ 시행일: 2026-05-16\n```", "meta": { "model_id": "doc", "total_pages": 6, "request_id": "...", "quota_remaining": 88 } } ``` 청구: A 문서 페이지 + B 문서 페이지 합산 (2원/페이지). ### 위양성 안내 — `genre_suppressed` `moderation` · `mental_health` 응답의 `genre_suppressed: true`는 본문이 업무용 문서(시방서·계약서·견적서·공고문 등)로 추정된다는 신호예요. 같은 응답의 `blocked: true` / `risk_level: acute`는 false positive 가능성이 높으니, 자동 차단 대신 사람 검토 큐로 분기 처리하세요. 모델 raw 결과는 그대로 노출됩니다. ## 6. POST `/v1/doc/fill` HWP·HWPX·DOCX 양식의 빈칸을 key/value JSON으로 자동 채워서 같은 형식으로 반환. **Request 필드** (`multipart/form-data`): | 필드 | 타입 | 기본 | 설명 | |---|---|---|---| | `file` | binary | (필수) | 양식 파일 (`.hwpx` 권장, `.hwp`/`.docx` 가능). | | `fields` | string | (실 fill 시 필수) | 채울 필드 JSON. 예: `{"성명":"홍길동","전화":"010-1234-5678"}`. | | `output_format` | string | `hwpx` | `hwpx` (한글 호환 권장) / `markdown`. | | `dry_run` | bool | `false` | true면 채우지 않고 양식의 빈 필드 목록만 JSON으로 반환 (무료). | **Response**: - 실제 fill: `application/octet-stream` (HWPX) 또는 `text/markdown`. 메타 정보는 응답 헤더: - `X-Corepin-Page-Count` · `X-Corepin-Template-Format` · `X-Corepin-Output-Format` - `X-Corepin-Fields-Filled` / `X-Corepin-Fields-Missing` (채워진/누락 필드 수) - `dry_run=true`: JSON `{"fields": [{"name": "성명"}, ...], "meta": {...}}` ```bash # 1. 빈 필드 목록만 (무료) curl -X POST https://api.corepin.ai/v1/doc/fill \ -H "Authorization: Bearer $COREPIN_API_KEY" \ -F "file=@신청서.hwpx" -F "dry_run=true" # 2. 실제 채우기 curl -X POST https://api.corepin.ai/v1/doc/fill \ -H "Authorization: Bearer $COREPIN_API_KEY" \ -F "file=@신청서.hwpx" \ -F 'fields={"성명":"홍길동","전화":"010-1234-5678"}' \ -o 결과.hwpx ``` 청구: `dry_run`은 무료. 실제 fill은 양식 페이지당 2원. ## 7. POST `/v1/doc/markdown-to` 마크다운 본문을 **HWPX · DOCX · PDF** 셋 중 하나로 역변환. 헤딩 1~6 위계, 표, 코드블록, 인용, 리스트, 강조·인라인 코드, 링크, 수평선까지 마크다운 문법을 노션 인쇄 수준의 미려한 서식으로 보존해요. **Request 필드** (`multipart/form-data` + query): | 필드 | 타입 | 기본 | 설명 | |---|---|---|---| | `format` (query) | string | `hwpx` | 출력 형식 — `hwpx` / `docx` / `pdf`. | | `file` | binary | — | 마크다운 파일 (`.md` / `.markdown`, UTF-8). | | `markdown` | string | — | `file` 미사용 시 raw 마크다운 텍스트. | | `filename` | string | `output` | 응답 파일명. 확장자는 `format` 에 맞춰 자동 보정. | `file` 과 `markdown` 둘 중 하나는 반드시 채워야 해요. **Response**: format 에 맞춘 바이너리. Content-Type 자동 설정: | format | Content-Type | |---|---| | `hwpx` | `application/hwp+zip` (macOS 한컴 호환 ZIP) | | `docx` | `application/vnd.openxmlformats-officedocument.wordprocessingml.document` (Word 호환) | | `pdf` | `application/pdf` (A4 paged-media, 페이지 번호 포함) | 메타 헤더: - `X-Corepin-Output-Format` — 응답 format (`hwpx` / `docx` / `pdf`) - `X-Corepin-Page-Count` · `X-Corepin-Model-Version` · `X-Corepin-Request-Id` - `Content-Disposition` 에 RFC 5987 한국어 파일명 (UTF-8 escape) ```bash # 1. PDF로 (가장 미려, A4 paged-media) curl -X POST 'https://api.corepin.ai/v1/doc/markdown-to?format=pdf' \ -H "Authorization: Bearer $COREPIN_API_KEY" \ -F "file=@보고서.md" \ -F "filename=2026Q1보고서" \ -o 보고서.pdf # 2. DOCX로 (Microsoft Word 호환) curl -X POST 'https://api.corepin.ai/v1/doc/markdown-to?format=docx' \ -H "Authorization: Bearer $COREPIN_API_KEY" \ -F "file=@보고서.md" \ -o 보고서.docx # 3. HWPX로 (한컴 한글 호환) curl -X POST 'https://api.corepin.ai/v1/doc/markdown-to?format=hwpx' \ -H "Authorization: Bearer $COREPIN_API_KEY" \ -F "file=@보고서.md" \ -o 보고서.hwpx # 4. raw 텍스트로 curl -X POST 'https://api.corepin.ai/v1/doc/markdown-to?format=pdf' \ -H "Authorization: Bearer $COREPIN_API_KEY" \ -F "markdown=# 제목 본문" \ -o output.pdf ``` 청구: 추정 페이지당 2원 (parse 와 동일 단가, format 무관). 한 호출 최대 마크다운 **10MB**. PDF 는 워커당 동시 4건 제한 (OOM 방어, 평균 0.5–2.5초). ### 7.1 이미지 embedding (`![alt](url)`) 마크다운 이미지 노드 (`![alt](url)`) 를 본문 안에 실제 그림으로 박아드려요. | format | data:image/...;base64,... | http(s):// URL | 비고 | |---|---|---|---| | `pdf` | ✅ embed | ✅ embed | WeasyPrint native 지원 | | `docx` | ✅ embed | ✅ embed | python-docx inline picture (5인치 폭, 비율 유지) | | `hwpx` | ❌ 무시 (텍스트만) | ❌ 무시 | kordoc upstream 한계 | 지원 이미지 형식 — PNG · JPEG · GIF · BMP (DOCX/PDF 공통). ICO/SVG 등 비표준은 DOCX 에서 placeholder 텍스트 `[이미지: alt]` 로 폴백. 이미지 fetch · decode 안전 cap: - 한 이미지당 최대 **10MB** (base64 decode 후 / 또는 HTTP 응답 본문). - HTTP 이미지 fetch timeout **10초**, follow redirects ON. - `file://` · 상대경로 · 빈 URL → 무시 (SSRF 가드). HWPX 에 이미지가 꼭 필요하면 DOCX 로 받아서 HWP 편집 프로그램에서 「다른 이름으로 저장 → HWPX」 한 번 거치면 변환돼요. ### 7.2 응답 헤더 | 헤더 | 예시 | 의미 | |---|---|---| | `Content-Type` | `application/pdf` | format 별 자동 | | `Content-Disposition` | `attachment; filename="output.pdf"; filename*=UTF-8''2026Q1%EB%B3%B4%EA%B3%A0%EC%84%9C.pdf` | RFC 5987 한국어 파일명 | | `X-Corepin-Output-Format` | `pdf` | 응답 format | | `X-Corepin-Page-Count` | `4` | 추정 페이지 수 (청구 기준) | | `X-Corepin-Model-Version` | `doc-2026.05` | 모델 버전 | | `X-Corepin-Request-Id` | `30201913a9...` | 요청 추적 ID | ## 8. GET `/v1/doc/formats` ```bash curl https://api.corepin.ai/v1/doc/formats \ -H "Authorization: Bearer $COREPIN_API_KEY" ``` 지원하는 19종 형식 목록 + 라우터 백엔드 매핑 + 제약 (최대 크기·배치 수) 반환. ## 9. 오류 응답 | HTTP | code | 의미 | |---|---|---| | 400 | `empty_file` | 업로드된 파일이 비어 있음 | | 400 | `empty_markdown` | (markdown-to) 변환할 마크다운이 비어 있음 | | 400 | `invalid_output_format` | `output_format`이 text/markdown/json이 아님 | | 400 | `unsupported_format` | 지원하지 않는 파일 형식 · 또는 (markdown-to) `format` 이 hwpx/docx/pdf 가 아님 | | 400 | `invalid_encoding` | (markdown-to) 마크다운이 UTF-8 인코딩이 아님 | | 400 | `encrypted_document` | 암호·DRM 문서 — 잠금 해제 필요 | | 400 | `too_many_files` | 배치 호출에 100개 초과 | | 401 | `missing_api_key` / `invalid_api_key` | 인증 실패 | | 413 | `file_too_large` | 50MB 초과 | | 413 | `markdown_too_large` | (markdown-to) 마크다운이 50MB 초과 | | 429 | `rate_limited` / `concurrency_limit` | 속도 한도 초과 | | 429 | `quota_active_jobs` | (async 전용) 같은 API 키의 동시 진행 async 잡 한도 초과 (default 3). `Retry-After: 60` | | 502 | `parser_failed` | 문서 파싱 실패 | | 502 | `conversion_failed` / `conversion_invalid` | (markdown-to) 변환 실패 또는 결과가 올바른 바이너리가 아님 | | 503 | `parser_not_installed` | 백엔드 미설치 (운영 측 알림) | | 503 | `node_not_installed` / `script_not_installed` | (markdown-to) Node.js 또는 변환 스크립트 미설치 | | 503 | `weasyprint_not_installed` | (markdown-to pdf) WeasyPrint 엔진 미설치 | | 503 | `docx_not_installed` | (markdown-to docx) python-docx 미설치 | | 503 | `queue_full` | (async 전용) 전체 async 큐가 가득 (default 20). `Retry-After: 120` | | 504 | `parser_timeout` / `conversion_timeout` | 처리 시간 초과 | 공통 오류 응답·재시도 안내는 [빠른 시작 §6](/docs/quickstart) 참고. ## 10. 코드 예제 ### Python ```python import requests # 어떤 문서든 한 호출 with open("입력.{확장자}", "rb") as f: r = requests.post( "https://api.corepin.ai/v1/doc/parse", headers={"Authorization": f"Bearer {YOUR_KEY}"}, files={"file": f}, data={ "output_format": "markdown", "pii_mask": "true", # 옵션: 개인정보 자동 마스킹 "dlp_grade": "true", # 옵션: 자동 보안 등급 "ocr_fallback": "true", # 옵션: 스캔본 자동 OCR (기본 ON) }, timeout=120, ) r.raise_for_status() data = r.json() print(data["markdown"]) ``` ### Node.js ```javascript import fs from "fs"; import FormData from "form-data"; const form = new FormData(); form.append("file", fs.createReadStream("계약서.pdf")); form.append("output_format", "markdown"); form.append("pii_mask", "true"); const r = await fetch("https://api.corepin.ai/v1/doc/parse", { method: "POST", headers: { Authorization: `Bearer ${process.env.COREPIN_API_KEY}`, ...form.getHeaders() }, body: form, }); const out = await r.json(); console.log(out.markdown); ``` ### 배치 — 한 번에 100개 파일 ```python import requests files = [("file", open(p, "rb")) for p in ["a.pdf", "b.docx", "c.hwp"]] r = requests.post( "https://api.corepin.ai/v1/doc/parse/batch", headers={"Authorization": f"Bearer {YOUR_KEY}"}, files=files, data={"output_format": "markdown"}, timeout=300, ) for item in r.json()["results"]: if "error" in item: print(item["filename"], item["error"]) else: print(item["filename"], "→", len(item["markdown"]), "chars") ``` ## 11. 단가 정리 | 항목 | 단가 | |---|---:| | 기본 (단건) | 2원 / 페이지 | | 배치 (≤100개 파일) | 1원 / 페이지 (50% 할인) | | 비동기 대용량 (≤2,000페이지) | 1원 / 페이지 (50% 할인) | | 신구대조표 | 2원 / 페이지 (A·B 합산) | | 옵션 `pii_mask` | + 5원 / 호출 | | 옵션 `dlp_grade` | + 20원 / 호출 | | 옵션 `ocr_fallback` (스캔 감지 시) | + 2원 / 페이지 (OCR한 페이지만 · 그 페이지 4원) | | **표 자동 감지 → 정밀 모드** (PDF/DOCX/PPTX) | **+0원** (기본 2원에 포함) | | 옵션 `moderation_check` | + 5원 / 호출 | | 옵션 `mental_health_check` | + 10원 / 호출 | | 옵션 `pptx_ocr` (PPTX 슬라이드 이미지 OCR) | + 2원 / 이미지 (OCR한 이미지만) | | `/v1/doc/fill` (양식 채우기) | 2원 / 페이지 | | `/v1/doc/fill?dry_run=true` (필드 목록만) | 무료 | | `/v1/doc/markdown-to` (HWPX·DOCX·PDF 역변환) | 2원 / 페이지 | 무료 한도 100페이지/월. 후불 정산은 매월 1일 09:00 KST.