DEVELOPER API · V1

PaddleOCR API 문서 - 문서 파싱 API(Markdown / JSON)

문서를 업로드하고 작업을 조회한 뒤 Markdown, JSON, 이미지를 ZIP으로 받으세요. 인증, 엔드포인트, 사용 한도를 다룹니다. API 이용에는 Pro 회원이 필요합니다.

시작하기

개요

파일 또는 URL마다 작업을 생성하고 상태를 조회한 후 ZIP을 다운로드합니다. 비동기 API이며 Pro 월간·연간만 지원합니다.

API 기본 주소
>
https://YOUR_API_HOST/api/open/v1

YOUR_API_HOST를 API 도메인으로 바꾸세요. 아래 경로는 이 주소를 기준으로 합니다. ID와 서명 URL은 예시입니다.

인증 및 헤더

각 요청에 Authorization: Bearer와 Pro API 키를 넣으세요. API key 버튼에서 확인·재설정할 수 있습니다. 키는 sk- 뒤에 무작위 영숫자 24자이며 대소문자를 구분합니다. 로그인 JWT는 사용할 수 없습니다.

필드유형필수설명
Authorizationstring예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가 필요합니다.

Python
>
# 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 인터페이스

작업 생성

POST/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
필드유형필수설명
filebinary예지원 확장자를 가진 파일 하나.
parse_typestring (0 | 1)아니요0: 일반 문서(기본값), 1: 화학 구조 인식.기본값: 0
force_ocrstring (true | false)아니요true / false; PDF에만 적용됩니다. 켜면 기존 텍스트 레이어를 무시하고 OCR을 사용하며, 끄면 자동으로 판단합니다. 다른 형식에는 영향을 주지 않습니다.기본값: false
extra_formatsstring (JSON)아니요JSON 배열 문자열. html·docx·latex만 허용됩니다.기본값: []
요청 예제 · cURL
>
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에서 상태와 결과를 확인하세요.

필드유형설명
codeinteger작업 생성 성공 시 0.
data.task_idstring (UUID)생성 시 data.task_id로 반환되는 작업 UUID.
msgstring작업 생성 성공 시 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_urlstring예공개 HTTP/HTTPS URL. 메타데이터·크기 검증 대상.
parse_typeinteger (0 | 1)아니요0: 일반 문서(기본값), 1: 화학 구조 인식.기본값: 0
force_ocrboolean아니요true / false; PDF에만 적용됩니다. 켜면 기존 텍스트 레이어를 무시하고 OCR을 사용하며, 끄면 자동으로 판단합니다. 다른 형식에는 영향을 주지 않습니다.기본값: false
extra_formatsstring[]아니요문자열이 아닌 배열. html·docx·latex를 지정하며 Markdown·JSON은 기본 포함입니다.기본값: []
요청 예제 · cURL
>
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에서 상태와 결과를 확인하세요.

필드유형설명
codeinteger작업 생성 성공 시 0.
data.task_idstring (UUID)생성 시 data.task_id로 반환되는 작업 UUID.
msgstring작업 생성 성공 시 ok.
응답 예제
>
{
  "code": 0,
  "data": {
    "task_id": "a90e6ab6-44f3-4554-b459-b62fe4c6b436"
  },
  "msg": "ok"
}
화학 구조 인식 · cURL
>
curl --fail-with-body "https://YOUR_API_HOST/api/open/v1/tasks" \
  -H "Authorization: Bearer $API_KEY" \
  -F '[email protected]' \
  -F 'parse_type=1'

작업 목록 조회

GET/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입니다.

쿼리 매개변수

필드유형필수설명
pageinteger아니요1부터 시작. 잘못된 값·1 미만은 1.기본값: 1
page_sizeinteger아니요페이지당 1–100개. 잘못된 값은 20.기본값: 20
searchstring아니요내 모든 작업에서 파일 이름을 검색합니다(최대 255자).
statusstring아니요선택 상태: queued, running, completed, failed, expired. 여러 상태는 쉼표로 구분합니다.
요청 예제 · cURL
>
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.itemsTaskSummary[]TaskSummary 표에 있는 필드만 포함하는 작업 요약 목록입니다.
data.has_moreboolean다음 페이지가 있는지 여부입니다.
data.pageinteger1부터 시작. 잘못된 값·1 미만은 1.
data.page_sizeinteger페이지당 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_idstring (UUID)생성 시 data.task_id로 반환되는 작업 UUID.
parse_typeinteger (0 | 1)0: 일반 문서(기본값), 1: 화학 구조 인식.
statusstring전체 작업 상태. 상태 표 참조.
creditsinteger과금 수량: PDF 페이지, PPT 슬라이드, Excel 시트 수. Word, HTML, 이미지는 1입니다. URL 파일 검사 완료 전에는 0입니다.
created_atstring (RFC3339)생성 시각, RFC3339.
file.namestring입력 이름. URL 가져오기 전에는 호스트명일 수 있음.
file.sizeinteger (int64)실제 저장 바이트. URL 가져오기 전에는 0.
file.mime_typestring저장 MIME 유형. 가져오는 동안 비어 있을 수 있음.
file.source_typestringupload 또는 url.

작업 결과 조회

GET/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입니다.

경로 매개변수

필드유형필수설명
idstring (UUID)예생성 시 data.task_id로 반환되는 작업 UUID.
요청 예제 · cURL
>
curl --fail-with-body "https://YOUR_API_HOST/api/open/v1/tasks/$TASK_ID" \
  -H "Authorization: Bearer $API_KEY"

응답 필드 · 200 OK

필드유형설명
data.taskTaskTask 객체. 상세 조회 성공 시 반환.
data.fileFile입력 File. URL 메타데이터는 아직 없을 수 있음.
data.resultsobject파일 및 이미지 URL을 포함하는 사전입니다. 미완료, 실패, 만료 시 빈 사전를 반환합니다.
처리 중 응답 · running
>
{
  "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": {}
  }
}
응답 예제 · completed
>
{
  "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"
    }
  }
}
실패한 작업 응답 · HTTP 200
>
{
  "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_idstring (UUID)생성 시 data.task_id로 반환되는 작업 UUID.
parse_typeinteger (0 | 1)0: 일반 문서(기본값), 1: 화학 구조 인식.
statusstring전체 작업 상태. 상태 표 참조.
creditsinteger과금 수량: PDF 페이지, PPT 슬라이드, Excel 시트 수. Word, HTML, 이미지는 1입니다. URL 파일 검사 완료 전에는 0입니다.
force_ocrbooleantrue / false; PDF에만 적용됩니다. 켜면 기존 텍스트 레이어를 무시하고 OCR을 사용하며, 끄면 자동으로 판단합니다. 다른 형식에는 영향을 주지 않습니다.
expires_atstring | null (RFC3339)보관 기한. 결과·실패 기록 전에는 null일 수 있음.
errorstring처리 오류·복구 메시지. 없으면 빈 문자열.
created_atstring (RFC3339)생성 시각, RFC3339.

File

필드유형설명
namestring입력 이름. URL 가져오기 전에는 호스트명일 수 있음.
sizeinteger (int64)실제 저장 바이트. URL 가져오기 전에는 0.
mime_typestring저장 MIME 유형. 가져오는 동안 비어 있을 수 있음.
suffixstring점 없는 소문자 확장자. 가져오는 동안 비어 있을 수 있음.
source_typestringupload 또는 url.
source_urlstring사용자가 제출한 URL. 업로드는 빈 값.

results

필드유형설명
original_urlstring입력 파일 서명 URL.
json_urlstring화학 인식 JSON 다운로드 URL. parse_type=1인 경우에만 반환됩니다.
markdown_urlstring미리보기용 markdown.md 서명 URL.
middle_json_urlstring페이지·구조·정규화 좌표가 있는 middle_json.json 서명 URL.
structured_json_urlstringstructured_content.json의 서명 URL. 해당 파일이 없으면 이 필드는 반환하지 않습니다.
imagesRecord<string, string>상대 경로에서 서명 이미지 URL로의 맵. 이미지가 없으면 빈 객체.
full_zip_urlstringresults.full_zip_url은 API 최종 ZIP의 서명 URL이며 완료 후 만료 전에 반환됩니다.

참고 사항

입력 형식 및 제한

Pro는 문서200 MiB, 이미지50 MiB, 500단위가 상한입니다. API와 웹은 일일5·월간1,000단위를 공유하며 일일분을 먼저 사용합니다. 검증 후 예약하고 기본 파싱 결과 저장 시 차감합니다. 파싱 실패나 종료 확인 후 예약을 해제합니다. 게시·내보내기 실패는 성공한 파싱을 환급하지 않으며 실행 실패나 시간 초과 시 미차감 예약을 자동으로 해제합니다. 내보내기는 재차감하지 않습니다.

형식파일 확장자과금 단위
PDF.pdfPDF 실제 페이지 수
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를 확인하고 자동으로 새 작업을 만들지 마세요.
expiredexpires_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 기본 필드를 보존하며 분자가 없으면 []를 반환합니다.

molecular_structures.json
>
source, input_index, page_index, bbox, confidence, raw_caption, caption, smi, esmi, cxsmiles, markush, sru, groups
ZIP
>
result.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 객체를 반환합니다.

HTTP 402
>
{
  "code": "quota_exceeded",
  "data": null,
  "msg": "not enough available pages/units"
}
HTTPcode설명
200task_failed파싱에 실패했습니다. 이유는 msg를 확인하세요.
200result_expired결과 보관 기간이 만료되었습니다.
400invalid_request요청 매개변수 또는 파일이 유효하지 않습니다. 이유는 msg를 확인하세요.
400too_many_pages문서가 페이지 또는 과금 단위 수 제한을 초과했습니다.
401unauthorizedAPI 인증에 실패했습니다.
402quota_exceeded사용 가능한 할당량이 부족합니다.
403user_disabled계정이 비활성화되었습니다.
403pro_required유효한 Pro 멤버십이 필요합니다.
404not_found작업이 없거나 접근 권한이 없습니다.
413file_too_large파일이 현재 요금제의 크기 제한을 초과했습니다.
500internal_error서버 처리에 실패했습니다. 이유는 msg를 확인하세요.