시작하기
개요
파일 또는 URL마다 작업을 생성하고 상태를 조회한 후 ZIP을 다운로드합니다. 비동기 API이며 Pro 월간·연간만 지원합니다.
https://YOUR_API_HOST/api/open/v1YOUR_API_HOST를 API 도메인으로 바꾸세요. 아래 경로는 이 주소를 기준으로 합니다. ID와 서명 URL은 예시입니다.
인증 및 헤더
각 요청에 Authorization: Bearer와 Pro API 키를 넣으세요. API key 버튼에서 확인·재설정할 수 있습니다. 키는 sk- 뒤에 무작위 영숫자 24자이며 대소문자를 구분합니다. 로그인 JWT는 사용할 수 없습니다.
| 필드 | 유형 | 필수 | 설명 |
|---|---|---|---|
Authorization | string | 예 | Bearer와 Pro API 키. 모든 API에서 필수입니다. |
Authorization: Bearer sk-YOUR_API_KEY키는 서버에 보관하고 공개 프런트엔드·저장소·다운로드 요청에 노출하지 마세요. 다운로드는 별도의 서명 URL을 사용합니다. 재설정하면 이전 키는 즉시 무효이며 유효한 Pro 구독이 필요합니다.
전체 호출 예제
API 호스트를 바꾸고 MINERU_API_KEY와 paper.pdf를 준비하세요. 한 번 업로드하고 3초 간격으로 최대 30분 조회한 뒤 ZIP을 저장합니다. 클라이언트 대기 종료는 서버 작업을 취소하지 않으며 ID로 다시 조회할 수 있습니다. Python은 requests, Node.js는 20 이상, cURL은 Bash와 jq가 필요합니다.
# pip install requests
import os
import time
import requests
API = "https://YOUR_API_HOST/api/open/v1"
headers = {"Authorization": "Bearer " + os.environ["MINERU_API_KEY"]}
with open("paper.pdf", "rb") as source:
response = requests.post(API + "/tasks", headers=headers, files={"file": ("paper.pdf", source, "application/pdf")},
data={"force_ocr": "true", "extra_formats": '["docx","html"]'}, timeout=120)
response.raise_for_status()
body = response.json()
if body["code"] != 0:
raise RuntimeError(body["code"] + ": " + body["msg"])
task_id = body["data"]["task_id"]
deadline = time.monotonic() + 1800
while time.monotonic() < deadline:
response = requests.get(API + "/tasks/" + task_id, headers=headers, timeout=30)
response.raise_for_status()
body = response.json()
if body["code"] != 0:
raise RuntimeError(body["code"] + ": " + body["msg"])
data = body["data"]
task = data["task"]
if task["status"] == "completed":
url = data["results"].get("full_zip_url")
if not url:
raise RuntimeError("ZIP unavailable; check expires_at")
# Download separately: do not send the API key to the download host.
with requests.get(url, stream=True, timeout=120) as download:
download.raise_for_status()
with open("result.zip", "wb") as output:
for chunk in download.iter_content(1024 * 1024):
output.write(chunk)
print("Saved result.zip")
break
if task["status"] in {"failed", "expired"}:
raise RuntimeError(task["status"] + ": " + task["error"])
time.sleep(3)
else:
raise TimeoutError("Polling timed out; task ID: " + task_id)
API 인터페이스
작업 생성
/api/open/v1/tasks생성 인터페이스는 POST /api/open/v1/tasks 하나입니다. multipart/form-data로 파일을 업로드하거나 JSON으로 source_url을 제출하세요. 모두 data.task_id를 반환하고 같은 작업 조회 흐름을 사용합니다. 성공적으로 접수된 제출마다 새 작업이 생성됩니다.
화학 모드는 PDF와 이미지만 지원하며 force_ocr 및 extra_formats는 사용할 수 없습니다.
방법 1: 파일 직접 업로드
API 서버에 파일 하나를 직접 업로드하세요. multipart 경계는 HTTP 클라이언트가 설정하게 하고 Content-Type을 수동 설정하지 마세요. file과 선택적 force_ocr 및 extra_formats만 허용됩니다. 실제 크기·단위를 검증한 후 저장·대기열에 넣습니다. 별도 업로드 완료 요청은 없습니다.
본문 매개변수 · multipart/form-data
| 필드 | 유형 | 필수 | 설명 |
|---|---|---|---|
file | binary | 예 | 지원 확장자를 가진 파일 하나. |
parse_type | string (0 | 1) | 아니요 | 0: 일반 문서(기본값), 1: 화학 구조 인식.기본값: 0 |
force_ocr | string (true | false) | 아니요 | true / false; PDF에만 적용됩니다. 켜면 기존 텍스트 레이어를 무시하고 OCR을
사용하며, 끄면 자동으로 판단합니다. 다른 형식에는 영향을 주지 않습니다.기본값: false |
extra_formats | string (JSON) | 아니요 | JSON 배열 문자열. html·docx·latex만 허용됩니다.기본값: [] |
curl --fail-with-body "https://YOUR_API_HOST/api/open/v1/tasks" \
-H "Authorization: Bearer $API_KEY" \
-F '[email protected]' \
-F 'force_ocr=true' \
-F 'extra_formats=["docx","html"]'응답 필드 · 200 OK
HTTP 200은 작업 생성 성공을 의미합니다. code는 0, msg는 ok이며 data에는 task_id만 포함됩니다. 작업 조회 API에서 상태와 결과를 확인하세요.
| 필드 | 유형 | 설명 |
|---|---|---|
code | integer | 작업 생성 성공 시 0. |
data.task_id | string (UUID) | 생성 시 data.task_id로 반환되는 작업 UUID. |
msg | string | 작업 생성 성공 시 ok. |
{
"code": 0,
"data": {
"task_id": "a90e6ab6-44f3-4554-b459-b62fe4c6b436"
},
"msg": "ok"
}
방법 2: URL 제출
multipart 대신 JSON을 전송하세요. source_url은 공개 HTTP/HTTPS 문서·이미지·HTML 링크입니다. 양수 Content-Length와 헤더 또는 이름에서 판단 가능한 형식이 필요합니다. 누락·충돌·변경 시 실패합니다. 내부 주소·자격 증명 URL·압축·청크 응답은 거부하며 리디렉션은 최대 5회입니다. 생성 시 queued이며 가져오기 실패는 task.error에 표시됩니다.
본문 매개변수 · application/json
| 필드 | 유형 | 필수 | 설명 |
|---|---|---|---|
source_url | string | 예 | 공개 HTTP/HTTPS URL. 메타데이터·크기 검증 대상. |
parse_type | integer (0 | 1) | 아니요 | 0: 일반 문서(기본값), 1: 화학 구조 인식.기본값: 0 |
force_ocr | boolean | 아니요 | true / false; PDF에만 적용됩니다. 켜면 기존 텍스트 레이어를 무시하고 OCR을
사용하며, 끄면 자동으로 판단합니다. 다른 형식에는 영향을 주지 않습니다.기본값: false |
extra_formats | string[] | 아니요 | 문자열이 아닌 배열. html·docx·latex를 지정하며 Markdown·JSON은 기본
포함입니다.기본값: [] |
curl --fail-with-body "https://YOUR_API_HOST/api/open/v1/tasks" \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
--data '{"source_url":"https://example.com/paper.pdf","force_ocr":true,"extra_formats":["docx","html"]}'응답 필드 · 200 OK
HTTP 200은 작업 생성 성공을 의미합니다. code는 0, msg는 ok이며 data에는 task_id만 포함됩니다. 작업 조회 API에서 상태와 결과를 확인하세요.
| 필드 | 유형 | 설명 |
|---|---|---|
code | integer | 작업 생성 성공 시 0. |
data.task_id | string (UUID) | 생성 시 data.task_id로 반환되는 작업 UUID. |
msg | string | 작업 생성 성공 시 ok. |
{
"code": 0,
"data": {
"task_id": "a90e6ab6-44f3-4554-b459-b62fe4c6b436"
},
"msg": "ok"
}
curl --fail-with-body "https://YOUR_API_HOST/api/open/v1/tasks" \
-H "Authorization: Bearer $API_KEY" \
-F '[email protected]' \
-F 'parse_type=1'
작업 목록 조회
/api/open/v1/tasks웹 및 API 작업을 생성 시간 내림차순으로 함께 반환합니다. 각 항목은 task_id, status, credits, created_at과 file의 name, size, mime_type, source_type만 포함합니다. 상세 파일 정보, 실패 이유, 만료 시간, 결과 URL은 상세 API에서 조회하세요. page_size는 1–100, 잘못된 값은 20, page의 최소값은 1입니다.
쿼리 매개변수
| 필드 | 유형 | 필수 | 설명 |
|---|---|---|---|
page | integer | 아니요 | 1부터 시작. 잘못된 값·1 미만은 1.기본값: 1 |
page_size | integer | 아니요 | 페이지당 1–100개. 잘못된 값은 20.기본값: 20 |
search | string | 아니요 | 내 모든 작업에서 파일 이름을 검색합니다(최대 255자). |
status | string | 아니요 | 선택 상태: queued, running, completed, failed, expired. 여러 상태는 쉼표로 구분합니다. |
curl --fail-with-body "https://YOUR_API_HOST/api/open/v1/tasks?page=1&page_size=20" \
-H "Authorization: Bearer $API_KEY"응답 필드 · 200 OK
| 필드 | 유형 | 설명 |
|---|---|---|
data.items | TaskSummary[] | TaskSummary 표에 있는 필드만 포함하는 작업 요약 목록입니다. |
data.has_more | boolean | 다음 페이지가 있는지 여부입니다. |
data.page | integer | 1부터 시작. 잘못된 값·1 미만은 1. |
data.page_size | integer | 페이지당 1–100개. 잘못된 값은 20. |
{
"code": 0,
"msg": "ok",
"data": {
"items": [
{
"task_id": "a90e6ab6-44f3-4554-b459-b62fe4c6b436",
"parse_type": 0,
"status": "completed",
"credits": 2,
"created_at": "2026-10-12T07:04:05Z",
"file": {
"name": "paper.pdf",
"size": 12345,
"mime_type": "application/pdf",
"source_type": "upload"
}
}
],
"has_more": false,
"page": 1,
"page_size": 20
}
}TaskSummary
| 필드 | 유형 | 설명 |
|---|---|---|
task_id | string (UUID) | 생성 시 data.task_id로 반환되는 작업 UUID. |
parse_type | integer (0 | 1) | 0: 일반 문서(기본값), 1: 화학 구조 인식. |
status | string | 전체 작업 상태. 상태 표 참조. |
credits | integer | 과금 수량: PDF 페이지, PPT 슬라이드, Excel 시트 수. Word, HTML, 이미지는 1입니다. URL 파일 검사 완료 전에는 0입니다. |
created_at | string (RFC3339) | 생성 시각, RFC3339. |
file.name | string | 입력 이름. URL 가져오기 전에는 호스트명일 수 있음. |
file.size | integer (int64) | 실제 저장 바이트. URL 가져오기 전에는 0. |
file.mime_type | string | 저장 MIME 유형. 가져오는 동안 비어 있을 수 있음. |
file.source_type | string | upload 또는 url. |
작업 결과 조회
/api/open/v1/tasks/{id}data.task.status를 확인하세요. results는 항상 사전이며 queued, running, failed, expired에서는 비어 있고 completed에서는 문서 결과 URL이 들어갑니다. ZIP URL은 results.full_zip_url입니다. 실패 시 HTTP 200, code task_failed, msg에 실패 이유를 반환합니다. 만료 시 code result_expired입니다.
경로 매개변수
| 필드 | 유형 | 필수 | 설명 |
|---|---|---|---|
id | string (UUID) | 예 | 생성 시 data.task_id로 반환되는 작업 UUID. |
curl --fail-with-body "https://YOUR_API_HOST/api/open/v1/tasks/$TASK_ID" \
-H "Authorization: Bearer $API_KEY"응답 필드 · 200 OK
| 필드 | 유형 | 설명 |
|---|---|---|
data.task | Task | Task 객체. 상세 조회 성공 시 반환. |
data.file | File | 입력 File. URL 메타데이터는 아직 없을 수 있음. |
data.results | object | 파일 및 이미지 URL을 포함하는 사전입니다. 미완료, 실패, 만료 시 빈 사전를 반환합니다. |
{
"code": 0,
"msg": "ok",
"data": {
"task": {
"task_id": "a90e6ab6-44f3-4554-b459-b62fe4c6b436",
"parse_type": 0,
"status": "running",
"credits": 2,
"force_ocr": true,
"expires_at": "2026-10-19T07:04:05Z",
"error": "",
"created_at": "2026-10-12T07:04:05Z"
},
"file": {
"name": "paper.pdf",
"size": 12345,
"mime_type": "application/pdf",
"suffix": "pdf",
"source_type": "upload",
"source_url": ""
},
"results": {}
}
}{
"code": 0,
"msg": "ok",
"data": {
"task": {
"task_id": "a90e6ab6-44f3-4554-b459-b62fe4c6b436",
"parse_type": 0,
"status": "completed",
"credits": 2,
"force_ocr": true,
"expires_at": "2026-10-19T07:04:05Z",
"error": "",
"created_at": "2026-10-12T07:04:05Z"
},
"file": {
"name": "paper.pdf",
"size": 12345,
"mime_type": "application/pdf",
"suffix": "pdf",
"source_type": "upload",
"source_url": ""
},
"results": {
"original_url": "https://downloads.example.com/uploads/4001a517-cd93-47a6-a56a-e53d2a0828df/aa0e6ab6-44f3-4554-b459-b62fe4c6b437.pdf?token=SIGNED_TOKEN",
"markdown_url": "https://downloads.example.com/results/a90e6ab6-44f3-4554-b459-b62fe4c6b436/preview/markdown.md?token=SIGNED_TOKEN",
"middle_json_url": "https://downloads.example.com/results/a90e6ab6-44f3-4554-b459-b62fe4c6b436/preview/middle_json.json?token=SIGNED_TOKEN",
"structured_json_url": "https://downloads.example.com/results/a90e6ab6-44f3-4554-b459-b62fe4c6b436/preview/structured_content.json?token=SIGNED_TOKEN",
"images": {
"images/001.jpg": "https://downloads.example.com/results/a90e6ab6-44f3-4554-b459-b62fe4c6b436/preview/images/001.jpg?token=SIGNED_TOKEN"
},
"full_zip_url": "https://downloads.example.com/results/a90e6ab6-44f3-4554-b459-b62fe4c6b436/exports/6b0e6ab6-44f3-4554-b459-b62fe4c6b439.zip?token=SIGNED_TOKEN"
}
}
}{
"code": "task_failed",
"msg": "MinerU job ended: failed",
"data": {
"task": {
"task_id": "a90e6ab6-44f3-4554-b459-b62fe4c6b436",
"parse_type": 0,
"status": "failed",
"credits": 2,
"force_ocr": true,
"expires_at": "2026-10-19T07:04:05Z",
"error": "MinerU job ended: failed",
"created_at": "2026-10-12T07:04:05Z"
},
"file": {
"name": "paper.pdf",
"size": 12345,
"mime_type": "application/pdf",
"suffix": "pdf",
"source_type": "upload",
"source_url": ""
},
"results": {}
}
}{
"code": 0,
"msg": "ok",
"data": {
"task": {
"task_id": "a90e6ab6-44f3-4554-b459-b62fe4c6b436",
"parse_type": 1,
"status": "completed",
"credits": 2,
"force_ocr": false,
"expires_at": "2026-10-19T07:04:05Z",
"error": "",
"created_at": "2026-10-12T07:04:05Z"
},
"file": {
"name": "paper.pdf",
"size": 12345,
"mime_type": "application/pdf",
"suffix": "pdf",
"source_type": "upload",
"source_url": ""
},
"results": {
"original_url": "https://downloads.example.com/uploads/4001a517-cd93-47a6-a56a-e53d2a0828df/aa0e6ab6-44f3-4554-b459-b62fe4c6b437.pdf?token=SIGNED_TOKEN",
"json_url": "https://downloads.example.com/results/a90e6ab6-44f3-4554-b459-b62fe4c6b436/molecular_structures.json?token=SIGNED_TOKEN"
}
}
}Task
| 필드 | 유형 | 설명 |
|---|---|---|
task_id | string (UUID) | 생성 시 data.task_id로 반환되는 작업 UUID. |
parse_type | integer (0 | 1) | 0: 일반 문서(기본값), 1: 화학 구조 인식. |
status | string | 전체 작업 상태. 상태 표 참조. |
credits | integer | 과금 수량: PDF 페이지, PPT 슬라이드, Excel 시트 수. Word, HTML, 이미지는 1입니다. URL 파일 검사 완료 전에는 0입니다. |
force_ocr | boolean | true / false; PDF에만 적용됩니다. 켜면 기존 텍스트 레이어를 무시하고 OCR을 사용하며, 끄면 자동으로 판단합니다. 다른 형식에는 영향을 주지 않습니다. |
expires_at | string | null (RFC3339) | 보관 기한. 결과·실패 기록 전에는 null일 수 있음. |
error | string | 처리 오류·복구 메시지. 없으면 빈 문자열. |
created_at | string (RFC3339) | 생성 시각, RFC3339. |
File
| 필드 | 유형 | 설명 |
|---|---|---|
name | string | 입력 이름. URL 가져오기 전에는 호스트명일 수 있음. |
size | integer (int64) | 실제 저장 바이트. URL 가져오기 전에는 0. |
mime_type | string | 저장 MIME 유형. 가져오는 동안 비어 있을 수 있음. |
suffix | string | 점 없는 소문자 확장자. 가져오는 동안 비어 있을 수 있음. |
source_type | string | upload 또는 url. |
source_url | string | 사용자가 제출한 URL. 업로드는 빈 값. |
results
| 필드 | 유형 | 설명 |
|---|---|---|
original_url | string | 입력 파일 서명 URL. |
json_url | string | 화학 인식 JSON 다운로드 URL. parse_type=1인 경우에만 반환됩니다. |
markdown_url | string | 미리보기용 markdown.md 서명 URL. |
middle_json_url | string | 페이지·구조·정규화 좌표가 있는 middle_json.json 서명 URL. |
structured_json_url | string | structured_content.json의 서명 URL. 해당 파일이 없으면 이 필드는 반환하지 않습니다. |
images | Record<string, string> | 상대 경로에서 서명 이미지 URL로의 맵. 이미지가 없으면 빈 객체. |
full_zip_url | string | results.full_zip_url은 API 최종 ZIP의 서명 URL이며 완료 후 만료 전에 반환됩니다. |
참고 사항
입력 형식 및 제한
Pro는 문서200 MiB, 이미지50 MiB, 500단위가 상한입니다. API와 웹은 일일5·월간1,000단위를 공유하며 일일분을 먼저 사용합니다. 검증 후 예약하고 기본 파싱 결과 저장 시 차감합니다. 파싱 실패나 종료 확인 후 예약을 해제합니다. 게시·내보내기 실패는 성공한 파싱을 환급하지 않으며 실행 실패나 시간 초과 시 미차감 예약을 자동으로 해제합니다. 내보내기는 재차감하지 않습니다.
| 형식 | 파일 확장자 | 과금 단위 |
|---|---|---|
.pdf | PDF 실제 페이지 수 | |
| Word | .doc, .docx | 파일당 1단위 |
| PowerPoint | .ppt, .pptx | 슬라이드 수 |
| Excel | .xls, .xlsx | 워크시트 수 |
| 이미지 | .png, .jpg, .jpeg, .webp, .gif, .bmp, .tif, .tiff | 파일당 1단위 |
| HTML | .html, .htm | 파일당 1단위 |
업로드 형식은 확장자로 판단하며 대소문자를 구분하지 않습니다. PDF·PowerPoint·Excel의 단위 메타데이터를 읽을 수 있어야 합니다. MIME으로 업로드 내용을 검증하지 않습니다. 빈 파일·미지원 확장자·암호화 PDF·초과 파일은 거부합니다. HTML은 정적 파싱이며 JavaScript를 실행하지 않습니다. 1 MiB = 1,048,576바이트.
작업 상태
queued·running은 계속 조회하고 completed이면 다운로드하세요. failed는 error를 확인하고 조회를 중지하며 expired는 보관 기한 만료입니다. status는 전체 작업 상태이며 API는 최종 ZIP이 준비되어야 completed입니다.
| task.status | 설명 |
|---|---|
queued | 접수됨. 처리를 기다리거나 URL 원본을 가져오는 중입니다. |
running | 파싱, 결과 저장, API ZIP 생성을 포함하여 처리 중입니다. |
completed | 최종 결과가 준비되어 조회하고 다운로드할 수 있습니다. |
failed | 처리 실패. error를 확인하고 자동으로 새 작업을 만들지 마세요. |
expired | expires_at의 보관 기한이 지나 다운로드 URL을 제공하지 않습니다. |
ZIP 결과 및 다운로드
API는 최종 ZIP 하나를 제공합니다. 기본적으로 Markdown·Middle JSON·구조화 JSON·저장 이미지를 포함합니다. extra_formats는 html·docx·latex만 지원하며 같은 ZIP에 추가됩니다. API 작업에 웹 내보내기 작업은 필요하지 않습니다. 추가 형식이 없으면 base.zip, 있으면 exports/의 ZIP을 반환합니다.
화학 작업은 results.original_url 및 results.json_url을 반환합니다. ZIP이나 추가 형식 내보내기는 제공하지 않습니다.
화학 결과는 JSON 배열입니다. 각 분자의 모든 MolParser 기본 필드를 보존하며 분자가 없으면 []를 반환합니다.
source, input_index, page_index, bbox, confidence, raw_caption, caption, smi, esmi, cxsmiles, markush, sru, groupsresult.zip
├── markdown.md
├── middle_json.json
├── structured_content.json
├── images/
│ └── …
├── model_output.json (optional)
├── result.html (extra_formats: html)
├── result.docx (extra_formats: docx)
└── result.tex (extra_formats: latex)결과는 7일간 보관됩니다. results.full_zip_url은 최대 15분이며 보관 기한을 넘지 않습니다. Authorization 없이 GET으로 다운로드하세요. 서명만 만료되었으면 상세를 다시 조회하여 새 URL을 받으세요. 미리보기 이미지는 최대 2시간, 다른 파일은 15분입니다.
ZIP은 원본 상대 이미지 경로와 저장 이미지를 유지하므로 CDN 서명에 의존하지 않습니다. 전체를 압축 해제하고 구조를 유지하세요. HTML 외부 이미지는 자동 저장되지 않아 원래 사이트를 참조할 수 있습니다.
오류 및 처리
code가 0이면 성공입니다. 0이 아닌 code는 오류 종류를, msg는 구체적인 이유를 나타냅니다. 실패하거나 만료된 작업을 조회하면 HTTP 200과 task_failed 또는 result_expired, 빈 results 객체를 반환합니다.
{
"code": "quota_exceeded",
"data": null,
"msg": "not enough available pages/units"
}| HTTP | code | 설명 |
|---|---|---|
| 200 | task_failed | 파싱에 실패했습니다. 이유는 msg를 확인하세요. |
| 200 | result_expired | 결과 보관 기간이 만료되었습니다. |
| 400 | invalid_request | 요청 매개변수 또는 파일이 유효하지 않습니다. 이유는 msg를 확인하세요. |
| 400 | too_many_pages | 문서가 페이지 또는 과금 단위 수 제한을 초과했습니다. |
| 401 | unauthorized | API 인증에 실패했습니다. |
| 402 | quota_exceeded | 사용 가능한 할당량이 부족합니다. |
| 403 | user_disabled | 계정이 비활성화되었습니다. |
| 403 | pro_required | 유효한 Pro 멤버십이 필요합니다. |
| 404 | not_found | 작업이 없거나 접근 권한이 없습니다. |
| 413 | file_too_large | 파일이 현재 요금제의 크기 제한을 초과했습니다. |
| 500 | internal_error | 서버 처리에 실패했습니다. 이유는 msg를 확인하세요. |