DEVELOPER API · V1

Documentation de l’API PaddleOCR — analyse vers Markdown et JSON

Importez un document, suivez la tâche et téléchargez Markdown, JSON et images dans un ZIP. Authentification, points d’entrée et limites inclus. L'accès API nécessite un abonnement Pro.

Pour commencer

Aperçu

Créez une tâche par fichier ou URL, interrogez son status, puis téléchargez le ZIP. Les demandes sont asynchrones. Pro Monthly et Pro Annual prennent en charge le API ; Ce n’est pas le cas de la gratuité.

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

Remplacez YOUR_API_HOST par votre domaine API. Tous les chemins ci-dessous utilisent cette URL de base. Les exemples utilisent des ID d'espace réservé et des URL signées.

Authentification

Envoyez Authorization : Bearer suivi de votre clé Pro API à chaque demande API. Obtenez ou réinitialisez la clé à l’aide du bouton clé API. Les clés sont sensibles à la casse : sk- plus 24 lettres et chiffres aléatoires. Les JWT de connexion utilisateur n'authentifient pas ces points de terminaison.

ChampTapezObligatoireDescriptif
AuthorizationstringOuiBearer suivi de la touche Pro API ; requis sur chaque point de terminaison.
En-têtes de requête
>
Authorization: Bearer sk-YOUR_API_KEY

Conservez la clé sur votre serveur. Ne l'exposez pas dans l'interface publique code, dans les référentiels ou dans les demandes de téléchargement. Les téléchargements utilisent leur propre URL signée. La réinitialisation de la clé invalide immédiatement l'ancienne clé ; L’accès API nécessite également un abonnement Pro actif.

Démarrage rapide

Remplacez l'hôte API, définissez MINERU_API_KEY et fournissez paper.pdf. Ces exemples sont téléchargés une fois, interrogés toutes les 3 secondes pendant 30 minutes maximum, puis diffusent les ZIP sur le disque. Le délai d'attente d'interrogation est une limite client et n'annule pas la tâche serveur. Utilisez l'ID de tâche pour continuer l'interrogation. Python nécessite le paquet requests ; Node.js nécessite la version 20+ ; cURL utilise Bash et 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 points de terminaison

Créer une tâche

POST/api/open/v1/tasks

Un point de terminaison : POST /api/open/v1/tasks. Choisissez une méthode de saisie : téléchargez un fichier en utilisant multipart/form-data ou envoyez source_url en utilisant JSON. Les deux renvoient data.task_id pour le même flux de requête de tâche. Chaque soumission acceptée crée une nouvelle tâche.

Le mode chimique accepte uniquement les PDF et images. force_ocr et extra_formats ne sont pas disponibles.

Option 1 : télécharger un fichier

Téléchargez exactement un fichier directement sur le serveur API. Laissez votre client HTTP définir la limite en plusieurs parties ; ne réglez pas manuellement Content-Type. Envoyez uniquement le fichier et force_ocr et extra_formats facultatif. Le serveur vérifie les octets et les unités reçus avant de les stocker et de les mettre en file d'attente. Aucune demande distincte de téléchargement complet n’est nécessaire.

Paramètres du corps · multipart/form-data
ChampTapezObligatoireDescriptif
filebinaryOuiUn fichier ; le nom de fichier doit inclure une extension prise en charge.
parse_typestring (0 | 1)Non0 : documents généraux (par défaut) ; 1 : structures chimiques.Par défaut: 0
force_ocrstring (true | false)Nontrue / false; PDF uniquement. Activé : ignorer la couche de texte et utiliser l’OCR. Désactivé : détection automatique. Les autres formats ne sont pas affectés.Par défaut: false
extra_formatsstring (JSON)NonChaîne de tableau codée JSON, e.g. ["docx","html"]. Valeurs : html, docx, latex.Par défaut: []
Exemple de demande · 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"]'
Champs de réponse · 200 OK

HTTP 200 signifie que la tâche a été créée. code est 0, msg est ok et les données ne contiennent que task_id. Interrogez la tâche pour obtenir ses status et results.

ChampTapezDescriptif
codeinteger0 en cas de création de tâche réussie.
data.task_idstring (UUID)La tâche UUID est renvoyée sous la forme data.task_id lors de sa création.
msgstringok en cas de création de tâche réussie.
Exemple de réponse
>
{
  "code": 0,
  "data": {
    "task_id": "a90e6ab6-44f3-4554-b459-b62fe4c6b436"
  },
  "msg": "ok"
}

Option 2 : soumettre une URL

Envoyez JSON au lieu de multipart. source_url doit être un document public HTTP/HTTPS, une image ou une URL HTML. La source doit exposer un Content-Length positif et un format pris en charge à partir des en-têtes ou du nom de fichier ; les métadonnées manquantes, conflictuelles ou modifiées font échouer la tâche. Les adresses privées, les URL contenant des informations d'identification, les réponses compressées ou fragmentées sont rejetées. Au maximum 5 redirections. La création renvoie queued ; les échecs de récupération apparaissent plus tard dans task.error.

Paramètres du corps · application/json
ChampTapezObligatoireDescriptif
source_urlstringOuiURL source publique HTTP/HTTPS, soumise à la validation des métadonnées et de la taille.
parse_typeinteger (0 | 1)Non0 : documents généraux (par défaut) ; 1 : structures chimiques.Par défaut: 0
force_ocrbooleanNontrue / false; PDF uniquement. Activé : ignorer la couche de texte et utiliser l’OCR. Désactivé : détection automatique. Les autres formats ne sont pas affectés.Par défaut: false
extra_formatsstring[]NonTableau de html, docx et /or latex, pas une chaîne JSON. Markdown et JSON sont déjà inclus.Par défaut: []
Exemple de demande · 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"]}'
Champs de réponse · 200 OK

HTTP 200 signifie que la tâche a été créée. code est 0, msg est ok et les données ne contiennent que task_id. Interrogez la tâche pour obtenir ses status et results.

ChampTapezDescriptif
codeinteger0 en cas de création de tâche réussie.
data.task_idstring (UUID)La tâche UUID est renvoyée sous la forme data.task_id lors de sa création.
msgstringok en cas de création de tâche réussie.
Exemple de réponse
>
{
  "code": 0,
  "data": {
    "task_id": "a90e6ab6-44f3-4554-b459-b62fe4c6b436"
  },
  "msg": "ok"
}
Tâche chimique · 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'

Liste des tâches

GET/api/open/v1/tasks

Répertorie vos tâches Web et API ensemble, la plus récente en premier. Les éléments contiennent uniquement task_id, status, credits, created_at et le nom du fichier, sa taille, mime_type et source_type. Détails de la requête pour les métadonnées du fichier, le motif de l'échec, l'expiration et les URL de résultat. page_size accepte 1–100 ; valeurs non valides par défaut à 20. page ci-dessous 1 par défaut à 1.

Paramètres de requête

ChampTapezObligatoireDescriptif
pageintegerNonNuméro de page basé sur 1 ; invalide ou inférieur à 1 utilise 1.Par défaut: 1
page_sizeintegerNonÉléments par page, 1–100 ; les valeurs non valides utilisent 20.Par défaut: 20
searchstringNonFiltrez par nom de fichier sur toutes vos tâches (jusqu'à 255 caractères).
statusstringNonFiltre status en option : queued, running, completed, failed ou expired. Séparez plusieurs statuts par des virgules.
Exemple de demande · cURL
>
curl --fail-with-body "https://YOUR_API_HOST/api/open/v1/tasks?page=1&page_size=20" \
  -H "Authorization: Bearer $API_KEY"

Champs de réponse · 200 OK

ChampTapezDescriptif
data.itemsTaskSummary[]Résumés de tâches contenant uniquement les champs de la table TaskSummary.
data.has_morebooleanSi une autre page est disponible.
data.pageintegerNuméro de page basé sur 1 ; invalide ou inférieur à 1 utilise 1.
data.page_sizeintegerÉléments par page, 1–100 ; les valeurs non valides utilisent 20.
Exemple de réponse
>
{
  "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

ChampTapezDescriptif
task_idstring (UUID)La tâche UUID est renvoyée sous la forme data.task_id lors de sa création.
parse_typeinteger (0 | 1)0 : documents généraux (par défaut) ; 1 : structures chimiques.
statusstringÉtat global de la tâche ; voir États des tâches.
creditsintegerNombre facturable : PDF pages, PPT diapositives ou Excel feuilles de calcul ; Word, HTML et les images comptent pour 1. Il reste 0 jusqu'à la fin de l'inspection du fichier URL.
created_atstring (RFC3339)Enregistrez l'heure de création dans RFC3339.
file.namestringNom du fichier d'entrée stocké ; Les tâches d'URL peuvent initialement afficher l'hôte source.
file.sizeinteger (int64)Octets stockés réels ; 0 avant le téléchargement de l'URL.
file.mime_typestringType MIME stocké ; peut être vide lors de la récupération.
file.source_typestringupload ou url.

Obtenir la tâche results

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

Lisez data.task.status. results est toujours un dictionnaire : vide pour queued, running, failed ou expired, et contient les URL des documents lorsque completed. L'URL ZIP est results.full_zip_url. Les tâches ayant échoué renvoient HTTP 200 avec code task_failed et la raison en msg ; expired results utilisez code result_expired.

Paramètres du chemin

ChampTapezObligatoireDescriptif
idstring (UUID)OuiLa tâche UUID est renvoyée sous la forme data.task_id lors de sa création.
Exemple de demande · cURL
>
curl --fail-with-body "https://YOUR_API_HOST/api/open/v1/tasks/$TASK_ID" \
  -H "Authorization: Bearer $API_KEY"

Champs de réponse · 200 OK

ChampTapezDescriptif
data.taskTaskObjet de tâche, toujours renvoyé en cas de recherche de détails réussie.
data.fileFileObjet Fichier d'entrée ; Les métadonnées de l'URL ne sont peut-être pas encore prêtes.
data.resultsobjectUn dictionnaire d'URL de fichiers et d'images. Les tâches inachevées, failed ou expired renvoient un dictionnaire vide.
Traitement de la réponse · 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": {}
  }
}
Exemple de réponse · 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"
    }
  }
}
Échec de la réponse à la tâche · 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": {}
  }
}
Tâche chimique · terminée
>
{
  "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

ChampTapezDescriptif
task_idstring (UUID)La tâche UUID est renvoyée sous la forme data.task_id lors de sa création.
parse_typeinteger (0 | 1)0 : documents généraux (par défaut) ; 1 : structures chimiques.
statusstringÉtat global de la tâche ; voir États des tâches.
creditsintegerNombre facturable : PDF pages, PPT diapositives ou Excel feuilles de calcul ; Word, HTML et les images comptent pour 1. Il reste 0 jusqu'à la fin de l'inspection du fichier URL.
force_ocrbooleantrue / false; PDF uniquement. Activé : ignorer la couche de texte et utiliser l’OCR. Désactivé : détection automatique. Les autres formats ne sont pas affectés.
expires_atstring | null (RFC3339)Date limite de rétention des tâches ; peut être null avant que les résultats/failure ne soient enregistrés.
errorstringTraitement de error ou message de récupération ; vide quand aucun.
created_atstring (RFC3339)Enregistrez l'heure de création dans RFC3339.

File

ChampTapezDescriptif
namestringNom du fichier d'entrée stocké ; Les tâches d'URL peuvent initialement afficher l'hôte source.
sizeinteger (int64)Octets stockés réels ; 0 avant le téléchargement de l'URL.
mime_typestringType MIME stocké ; peut être vide lors de la récupération.
suffixstringExtension minuscule sans point ; peut être vide lors de la récupération.
source_typestringupload ou url.
source_urlstringURL source soumise par l'utilisateur ; vide pour les fichiers téléchargés.

results

ChampTapezDescriptif
original_urlstringURL du fichier original signé.
json_urlstringURL du JSON chimique ; renvoyée uniquement pour parse_type=1.
markdown_urlstringURL native markdown.md signée pour la lecture d'un aperçu.
middle_json_urlstringURL middle_json.json signée avec pages, structure de bloc et cadres de délimitation normalisés.
structured_json_urlstringURL structured_content.json signée ; omis si la ressource est absente.
imagesRecord<string, string>Carte des chemins relatifs natifs vers les URL d'images signées ; objet vide lorsqu'il n'y a pas d'images.
full_zip_urlstringresults.full_zip_url est l'URL finale API ZIP signée, renvoyée uniquement lorsque completed et conservée.

Notes de référence

Formats et limites

Limites Pro : 200 MiB par document, 50 MiB par image et 500 unités facturables. API et partagez sur le Web 5 quotidiennement plus 1,000 unités mensuelles, en utilisant d'abord les unités quotidiennes. L'utilisation est réservée après validation et facturée lorsque le résultat de l'analyse de base est enregistré. L’échec ou la résiliation confirmé de l’analyse libère les réservations. L’échec de la publication/export ne rembourse pas l’analyse réussie ; failed ou une exécution expirée libère automatiquement les réservations non facturées. Les exportations ne sont plus facturées.

FormatExtensions de nom de fichierUnités facturables
PDF.pdfPages physiques PDF
Word.doc, .docx1 unité par fichier
PowerPoint.ppt, .pptxNombre de diapositives
Excel.xls, .xlsxNombre de feuilles de calcul
Images.png, .jpg, .jpeg, .webp, .gif, .bmp, .tif, .tiff1 unité par fichier
HTML.html, .htm1 unité par fichier

Le format de téléchargement est déterminé par l'extension du nom de fichier, sans tenir compte de la casse. PDF, PowerPoint et Excel doivent avoir des métadonnées de page/unit lisibles. MIME n'est pas utilisé pour valider le contenu téléchargé. Les fichiers vides, les extensions non prises en charge, les PDF cryptés ou illisibles et les entrées dépassant la limite sont rejetés. L'analyse HTML est statique et n'exécute pas JavaScript. 1 MiB = 1,048,576 octets.

États des tâches

Continuez à interroger queued ou running. Télécharger le completed ; lisez error et arrêtez-vous sur failed. expired signifie que la rétention est terminée. status décrit l'ensemble de la tâche ; Les tâches API ne sont terminées que lorsque le ZIP final est prêt.

task.statusDescriptif
queuedAccepté ; en attente de traitement ou de récupération de l'URL.
runningTraitement, y compris l'analyse, la sauvegarde des emballages results et API.
completedLe résultat final est prêt à être interrogé et téléchargé.
failedTraitement failed ; lire error. Ne créez pas automatiquement une tâche de remplacement.
expiredLa date limite de conservation des résultats en expires_at est dépassée ; aucune URL de téléchargement.

ZIP results et téléchargements

Le API produit un ZIP final. Markdown, Middle JSON, structuré JSON et les images enregistrées sont incluses par défaut. extra_formats prend en charge html, docx et latex uniquement ; les fichiers demandés sont ajoutés à ce même ZIP. Ne créez pas de tâche d'exportation Web distincte pour une tâche API. Aucun extra signifie results.full_zip_url points à base.zip ; les extras signifient qu'il pointe vers le fichier exports/a ZIP.

Les tâches chimiques renvoient results.original_url et results.json_url, sans ZIP ni autres formats d’export.

Le résultat chimique est un tableau JSON conservant tous les champs natifs MolParser pour chaque molécule. Sans molécule, il vaut [].

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)

Les résultats sont conservés pendant 7 jours. results.full_zip_url est signé pour une durée maximale de 15 minutes et jamais au-delà de la durée de conservation. Téléchargez avec un simple GET, sans Authorization. Si la signature expire alors qu'elle est encore conservée, interrogez à nouveau les détails pour obtenir une nouvelle URL. Les liens d’image d’aperçu durent au maximum 2 heures ; les autres liens de fichiers durent au maximum 15 minutes.

Les documents ZIP conservent les références d'images relatives natives et incluent les images enregistrées, de sorte que ces références ne dépendent pas des signatures CDN. Extrayez l’intégralité de l’archive et conservez sa structure de dossiers. Les images distantes référencées par l'entrée HTML ne sont pas automatiquement archivées et peuvent toujours pointer vers le site Web source.

Erreurs et récupération

code 0 indique un succès. Un code non nul identifie la catégorie d’erreur ; msg en explique la raison. Les tâches échouées ou expirées renvoient HTTP 200 avec task_failed ou result_expired et un objet results vide.

HTTP 402
>
{
  "code": "quota_exceeded",
  "data": null,
  "msg": "not enough available pages/units"
}
HTTPcodeDescriptif
200task_failedÉchec de l’analyse. Consultez msg pour connaître la raison.
200result_expiredLes résultats ont expiré.
400invalid_requestParamètres ou fichier invalides. Consultez msg pour connaître la raison.
400too_many_pagesLe document dépasse la limite de pages ou d’unités facturables.
401unauthorizedÉchec de l’authentification API.
402quota_exceededQuota disponible insuffisant.
403user_disabledLe compte est désactivé.
403pro_requiredUn abonnement Pro actif est requis.
404not_foundTâche introuvable ou accès refusé.
413file_too_largeLe fichier dépasse la taille maximale de votre formule.
500internal_errorÉchec du traitement sur le serveur. Consultez msg pour connaître la raison.