DEVELOPER API · V1

Documentación de la API de PaddleOCR — análisis a Markdown y JSON

Sube un documento, consulta la tarea y descarga Markdown, JSON e imágenes en un ZIP. Incluye autenticación, endpoints y límites. El acceso API requiere membresía Pro.

Empezando

Descripción general

Cree una tarea por archivo o URL, sondee su status y luego descargue el ZIP. Las solicitudes son asincrónicas. Pro Monthly y Pro Annual admiten API; Gratis no.

API URL base
>
https://YOUR_API_HOST/api/open/v1

Reemplace YOUR_API_HOST con su dominio API. Todas las rutas siguientes utilizan esta URL base. Los ejemplos utilizan ID de marcador de posición y URL firmadas.

Autenticación

Envíe Authorization: Bearer seguido de su clave Pro API en cada solicitud API. Obtenga o restablezca la clave usando el botón de clave API. Las claves distinguen entre mayúsculas y minúsculas: sk- más 24 letras y dígitos aleatorios. Los JWT de inicio de sesión de usuario no autentican estos puntos finales.

CampoTipoRequeridoDescripción
AuthorizationstringSíBearer seguido de la tecla Pro API; requerido en cada punto final.
Solicitar encabezados
>
Authorization: Bearer sk-YOUR_API_KEY

Mantenga la clave en su servidor. No lo exponga en la interfaz pública code, repositorios o solicitudes de descarga. Las descargas utilizan su propia URL firmada. Restablecer la clave invalida inmediatamente la clave anterior; El acceso API también requiere una membresía Pro activa.

Inicio rápido

Reemplace el host API, configure MINERU_API_KEY y proporcione paper.pdf. Estos ejemplos se cargan una vez, sondean cada 3 segundos durante hasta 30 minutos y luego transmiten el ZIP al disco. El tiempo de espera del sondeo es un límite del cliente y no cancela la tarea del servidor. Utilice el ID de la tarea para continuar con la consulta. Python requiere el paquete requests; Node.js necesita la versión 20+; cURL usa Bash y 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 puntos finales

Crear una tarea

POST/api/open/v1/tasks

Un punto final: POST /api/open/v1/tasks. Elija un método de entrada: cargue un archivo usando multipart/form-data o envíe source_url usando JSON. Ambos devuelven data.task_id para el mismo flujo de consulta de tareas. Cada envío aceptado crea una nueva tarea.

El modo químico solo acepta PDF e imágenes. No admite force_ocr ni extra_formats.

Opción 1: subir un archivo

Cargue exactamente un archivo directamente al servidor API. Deje que su cliente HTTP establezca el límite multiparte; no configure manualmente Content-Type. Enviar solo archivo y opcional force_ocr y extra_formats. El servidor verifica los bytes y las unidades recibidos antes de almacenarlos y ponerlos en cola. No se necesita ninguna solicitud de carga completa por separado.

Parámetros corporales · multipart/form-data
CampoTipoRequeridoDescripción
filebinarySíUn archivo; El nombre del archivo debe incluir una extensión compatible.
parse_typestring (0 | 1)No0: documentos generales (predeterminado); 1: estructuras químicas.Predeterminado: 0
force_ocrstring (true | false)Notrue / false; Solo para PDF. Activado: ignorar la capa de texto y usar OCR. Desactivado: detección automática. No afecta a otros formatos.Predeterminado: false
extra_formatsstring (JSON)NoCadena de matriz codificada con JSON, e.g. ["docx","html"]. Valores: html, docx, latex.Predeterminado: []
Ejemplo de solicitud · 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"]'
Campos de respuesta · 200 OK

HTTP 200 significa que se creó la tarea. code es 0, msg es ok y los datos contienen solo task_id. Consulta la tarea para obtener su status y results.

CampoTipoDescripción
codeinteger0 sobre la creación exitosa de la tarea.
data.task_idstring (UUID)La tarea UUID devolvió como data.task_id cuando se creó.
msgstringok sobre la creación exitosa de la tarea.
Ejemplo de respuesta
>
{
  "code": 0,
  "data": {
    "task_id": "a90e6ab6-44f3-4554-b459-b62fe4c6b436"
  },
  "msg": "ok"
}

Opción 2: enviar una URL

Envía JSON en lugar de multiparte. source_url debe ser un documento, una imagen o una URL HTML pública HTTP/HTTPS. La fuente debe exponer un Content-Length positivo y un formato compatible de encabezados o nombre de archivo; Los metadatos faltantes, conflictivos o modificados fallan la tarea. Se rechazan las direcciones privadas, las URL que contienen credenciales y las respuestas comprimidas o fragmentadas. Como máximo 5 redirecciones. La creación devuelve queued; Los errores de recuperación aparecen más adelante en task.error.

Parámetros corporales · application/json
CampoTipoRequeridoDescripción
source_urlstringSíURL de origen pública HTTP/HTTPS, sujeta a metadatos y validación de tamaño.
parse_typeinteger (0 | 1)No0: documentos generales (predeterminado); 1: estructuras químicas.Predeterminado: 0
force_ocrbooleanNotrue / false; Solo para PDF. Activado: ignorar la capa de texto y usar OCR. Desactivado: detección automática. No afecta a otros formatos.Predeterminado: false
extra_formatsstring[]NoMatriz de html, docx y /or latex, no una cadena JSON. Markdown y JSON ya están incluidos.Predeterminado: []
Ejemplo de solicitud · 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"]}'
Campos de respuesta · 200 OK

HTTP 200 significa que se creó la tarea. code es 0, msg es ok y los datos contienen solo task_id. Consulta la tarea para obtener su status y results.

CampoTipoDescripción
codeinteger0 sobre la creación exitosa de la tarea.
data.task_idstring (UUID)La tarea UUID devolvió como data.task_id cuando se creó.
msgstringok sobre la creación exitosa de la tarea.
Ejemplo de respuesta
>
{
  "code": 0,
  "data": {
    "task_id": "a90e6ab6-44f3-4554-b459-b62fe4c6b436"
  },
  "msg": "ok"
}
Tarea química · 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'

Listar tareas

GET/api/open/v1/tasks

Enumera sus tareas web y API juntas, las más nuevas primero. Los elementos contienen solo task_id, status, credits, created_at y nombre de archivo, tamaño, mime_type y source_type. Consulta los detalles de los metadatos del archivo, el motivo del error, la caducidad y las URL de resultados. page_size acepta 1–100; los valores no válidos son predeterminados en 20. página debajo de 1 predeterminados en 1.

Parámetros de consulta

CampoTipoRequeridoDescripción
pageintegerNoNúmero de página basado en 1; no válido o inferior a 1 utiliza 1.Predeterminado: 1
page_sizeintegerNoElementos por página, 1–100; valores no válidos utilizan 20.Predeterminado: 20
searchstringNoFiltre por nombre de archivo en todas sus tareas (hasta 255 caracteres).
statusstringNoFiltro status opcional: queued, running, completed, failed o expired. Separe varios estados con comas.
Ejemplo de solicitud · cURL
>
curl --fail-with-body "https://YOUR_API_HOST/api/open/v1/tasks?page=1&page_size=20" \
  -H "Authorization: Bearer $API_KEY"

Campos de respuesta · 200 OK

CampoTipoDescripción
data.itemsTaskSummary[]Resúmenes de tareas que contienen solo campos en la tabla TaskSummary.
data.has_morebooleanSi hay otra página disponible.
data.pageintegerNúmero de página basado en 1; no válido o inferior a 1 utiliza 1.
data.page_sizeintegerElementos por página, 1–100; valores no válidos utilizan 20.
Ejemplo de respuesta
>
{
  "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

CampoTipoDescripción
task_idstring (UUID)La tarea UUID devolvió como data.task_id cuando se creó.
parse_typeinteger (0 | 1)0: documentos generales (predeterminado); 1: estructuras químicas.
statusstringEstado general de la tarea; consulte Estados de tareas.
creditsintegerRecuento facturable: PDF páginas, PPT diapositivas u Excel hojas de trabajo; Word, HTML y las imágenes cuentan como 1.. Es 0 hasta que finaliza la inspección del archivo URL.
created_atstring (RFC3339)Hora de creación del registro en RFC3339.
file.namestringNombre del archivo de entrada almacenado; Las tareas de URL pueden mostrar inicialmente el host de origen.
file.sizeinteger (int64)Bytes almacenados reales; 0 antes de la descarga de la URL.
file.mime_typestringTipo MIME almacenado; puede estar vacío mientras se recupera.
file.source_typestringupload o url.

Obtener tarea results

GET/api/open/v1/tasks/{id}

Leer data.task.status. results es siempre un diccionario: vacío para queued, running, failed o expired, y contiene URL de documentos cuando completed. La URL ZIP es results.full_zip_url. Las tareas fallidas devuelven HTTP 200 con code task_failed y el motivo en msg; expired results use code result_expired.

Parámetros de ruta

CampoTipoRequeridoDescripción
idstring (UUID)SíLa tarea UUID devolvió como data.task_id cuando se creó.
Ejemplo de solicitud · cURL
>
curl --fail-with-body "https://YOUR_API_HOST/api/open/v1/tasks/$TASK_ID" \
  -H "Authorization: Bearer $API_KEY"

Campos de respuesta · 200 OK

CampoTipoDescripción
data.taskTaskObjeto de tarea, siempre devuelto tras una búsqueda de detalles exitosa.
data.fileFileObjeto de archivo de entrada; Es posible que los metadatos de la URL aún no estén listos.
data.resultsobjectUn diccionario de URL de archivos e imágenes. Las tareas inacabadas, failed o expired devuelven un diccionario vacío.
Procesando respuesta · 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": {}
  }
}
Ejemplo de respuesta · 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"
    }
  }
}
Respuesta de tarea fallida · 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": {}
  }
}
Tarea química · completada
>
{
  "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

CampoTipoDescripción
task_idstring (UUID)La tarea UUID devolvió como data.task_id cuando se creó.
parse_typeinteger (0 | 1)0: documentos generales (predeterminado); 1: estructuras químicas.
statusstringEstado general de la tarea; consulte Estados de tareas.
creditsintegerRecuento facturable: PDF páginas, PPT diapositivas u Excel hojas de trabajo; Word, HTML y las imágenes cuentan como 1.. Es 0 hasta que finaliza la inspección del archivo URL.
force_ocrbooleantrue / false; Solo para PDF. Activado: ignorar la capa de texto y usar OCR. Desactivado: detección automática. No afecta a otros formatos.
expires_atstring | null (RFC3339)Fecha límite de retención de tareas; puede ser null antes de que se registren los resultados/failure.
errorstringProcesando error o mensaje de recuperación; vacío cuando ninguno.
created_atstring (RFC3339)Hora de creación del registro en RFC3339.

File

CampoTipoDescripción
namestringNombre del archivo de entrada almacenado; Las tareas de URL pueden mostrar inicialmente el host de origen.
sizeinteger (int64)Bytes almacenados reales; 0 antes de la descarga de la URL.
mime_typestringTipo MIME almacenado; puede estar vacío mientras se recupera.
suffixstringExtensión en minúscula sin punto; puede estar vacío mientras se recupera.
source_typestringupload o url.
source_urlstringURL de origen enviada por el usuario; vacío para archivos cargados.

results

CampoTipoDescripción
original_urlstringURL del archivo original firmado.
json_urlstringURL del JSON químico; solo se devuelve con parse_type=1.
markdown_urlstringURL markdown.md nativa firmada para lectura previa.
middle_json_urlstringURL middle_json.json firmada con páginas, estructura de bloques y cuadros delimitadores normalizados.
structured_json_urlstringURL structured_content.json firmada; omitido si el recurso está ausente.
imagesRecord<string, string>Mapa de rutas relativas nativas a URL de imágenes firmadas; Objeto vacío cuando no hay imágenes.
full_zip_urlstringresults.full_zip_url es la URL final API ZIP firmada, devuelta solo cuando completed y retenida.

Notas de referencia

Formatos y límites

Límites profesionales: 200 MiB por documento, 50 MiB por imagen y 500 unidades facturables. API y web comparten 5 unidades diarias más 1,000 unidades mensuales, utilizando primero las unidades diarias. El uso se reserva después de la validación y se cobra cuando se guarda el resultado del análisis base. La falla de análisis confirmada o la terminación liberan reservas. El error en la publicación /export no reembolsa el análisis exitoso; failed o la ejecución agotada libera automáticamente las reservas no cargadas. Las exportaciones no vuelven a cobrar.

FormatoExtensiones de nombre de archivoUnidades facturables
PDF.pdfPáginas físicas PDF
Word.doc, .docx1 unidad por archivo
PowerPoint.ppt, .pptxNúmero de diapositivas
Excel.xls, .xlsxNúmero de hojas de trabajo
Imágenes.png, .jpg, .jpeg, .webp, .gif, .bmp, .tif, .tiff1 unidad por archivo
HTML.html, .htm1 unidad por archivo

El formato de carga está determinado por la extensión del nombre del archivo, sin distinguir entre mayúsculas y minúsculas. PDF, PowerPoint y Excel deben tener metadatos de página/unit legibles. MIME no se utiliza para validar los contenidos cargados. Se rechazan los archivos vacíos, las extensiones no compatibles, los archivos PDF cifrados o ilegibles y las entradas que exceden el límite. El análisis HTML es estático y no ejecuta JavaScript. 1 MiB = 1,048,576 bytes.

Estados de tarea

Sigue sondeando queued o running. Descargar en completed; lea error y deténgase en failed. expired significa que la retención ha finalizado. status describe toda la tarea; Las tareas API se completan solo cuando el ZIP final está listo.

task.statusDescripción
queuedAceptado; en espera de procesamiento o recuperando la entrada de URL.
runningProcesamiento, incluido análisis, guardado de paquetes results y API.
completedEl resultado final está listo para consultar y descargar.
failedProcesando failed; lea error. No cree automáticamente una tarea de reemplazo.
expiredLa fecha límite de retención de resultados en expires_at ha pasado; sin URL de descarga.

ZIP results y descargas

El API produce un ZIP final. Markdown, Medio JSON, estructurado JSON y las imágenes guardadas se incluyen de forma predeterminada. extra_formats admite html, docx y latex únicamente; los archivos solicitados se agregan a ese mismo ZIP. No cree un trabajo de exportación web independiente para una tarea API. Sin extras significa results.full_zip_url apunta a base.zip; los extras significan que apunta al archivo exports/a ZIP.

Las tareas químicas devuelven results.original_url y results.json_url, sin ZIP ni exportaciones adicionales.

El resultado químico es un array JSON con todos los campos nativos de MolParser por molécula. Sin moléculas devuelve [].

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)

Los resultados se conservan durante 7 días. results.full_zip_url está firmado por un máximo de 15 minutos y nunca más allá de la retención. Descargue con un GET simple, sin Authorization. Si la firma caduca mientras aún se conserva, consulte los detalles nuevamente para obtener una nueva URL. Los enlaces de imágenes de vista previa duran como máximo 2 horas; otros enlaces de archivos duran como máximo 15 minutos.

Los documentos ZIP mantienen referencias de imágenes relativas nativas e incluyen imágenes guardadas, por lo que esas referencias no dependen de las firmas CDN. Extraiga todo el archivo y mantenga su estructura de carpetas. Las imágenes remotas a las que hace referencia la entrada HTML no se archivan automáticamente y aún pueden apuntar al sitio web de origen.

Errores y recuperación

code 0 indica éxito. Un code distinto de cero identifica la categoría del error; msg explica el motivo. Las consultas de tareas fallidas o caducadas devuelven HTTP 200 con task_failed o result_expired y un objeto results vacío.

HTTP 402
>
{
  "code": "quota_exceeded",
  "data": null,
  "msg": "not enough available pages/units"
}
HTTPcodeDescripción
200task_failedFalló el análisis. Consulte el motivo en msg.
200result_expiredLos resultados han caducado.
400invalid_requestParámetros o archivo no válidos. Consulte el motivo en msg.
400too_many_pagesEl documento supera el límite de páginas o unidades facturables.
401unauthorizedFalló la autenticación de la API.
402quota_exceededCuota disponible insuficiente.
403user_disabledLa cuenta está desactivada.
403pro_requiredSe requiere una suscripción Pro activa.
404not_foundTarea no encontrada o acceso denegado.
413file_too_largeEl archivo supera el límite de tamaño de su plan.
500internal_errorFalló el procesamiento del servidor. Consulte el motivo en msg.