资讯 文档
技术能力
语音技术
文字识别
人脸与人体
图像技术
语言与知识
视频技术

Asynchronous API Usage Guide

Asynchronous API Usage Guide

  • Supports up to 1000 PDF pages per request.
  • Supports file URLs. File size must not exceed 200 MB.
  • Supports local file uploads. File size must not exceed 50 MB.

Complete Asynchronous API Call Example

Depending on the model, the fields in the returned result may differ slightly. Below are call examples for PaddleOCR-VL Series / PP-StructureV3 and PP-OCRv5 respectively.

1. PaddleOCR-VL-1.5, PaddleOCR-VL, PP-StructureV3 Call Examples

Applicable to PaddleOCR-VL-1.5, PaddleOCR-VL, and PP-StructureV3 models.

# Please make sure the requests library is installed
# pip install requests
import json
import os
import requests
import sys
import time

JOB_URL = "https://paddleocr.aistudio-app.com/api/v2/ocr/jobs"
TOKEN = ""
# Optional models: "PaddleOCR-VL-1.5", "PaddleOCR-VL", "PP-StructureV3"
MODEL = "PaddleOCR-VL-1.5"

file_path = "<local file path or file url>"

headers = {
    "Authorization": f"bearer {TOKEN}",
}

optional_payload = {
    "useDocOrientationClassify": False,
    "useDocUnwarping": False,
    "useChartRecognition": False,
}

print(f"Processing file: {file_path}")

if file_path.startswith("http"):
    # URL Mode
    headers["Content-Type"] = "application/json"
    payload = {
        "fileUrl": file_path,
        "model": MODEL,
        "optionalPayload": optional_payload
    }
    job_response = requests.post(JOB_URL, json=payload, headers=headers)
else:
    # Local File Mode
    if not os.path.exists(file_path):
        print(f"Error: File not found at {file_path}")
        sys.exit(1)
        
    data = {
        "model": MODEL,
        "optionalPayload": json.dumps(optional_payload)
    }
    
    with open(file_path, "rb") as f:
        files = {"file": f}
        job_response = requests.post(JOB_URL, headers=headers, data=data, files=files)

print(f"Response status: {job_response.status_code}")
if job_response.status_code != 200:
    print(f"Response content: {job_response.text}")

assert job_response.status_code == 200
jobId = job_response.json()["data"]["jobId"]
print(f"Job submitted successfully. job id: {jobId}")
print("Start polling for results")

jsonl_url = ""
while True:
    job_result_response = requests.get(f"{JOB_URL}/{jobId}", headers=headers)
    assert job_result_response.status_code == 200
    state = job_result_response.json()["data"]["state"]
    if state == 'pending':
        print("The current status of the job is pending")
    elif state == 'running':
        try:
            total_pages = job_result_response.json()['data']['extractProgress']['totalPages']
            extracted_pages = job_result_response.json()['data']['extractProgress']['extractedPages']
            print(f"The current status of the job is running, total pages: {total_pages}, extracted pages: {extracted_pages}")
        except KeyError:
             print("The current status of the job is running...")
    elif state == 'done':
        extracted_pages = job_result_response.json()['data']['extractProgress']['extractedPages']
        start_time = job_result_response.json()['data']['extractProgress']['startTime']
        end_time = job_result_response.json()['data']['extractProgress']['endTime']
        print(f"Job completed, successfully extracted pages: {extracted_pages}, start time: {start_time}, end time: {end_time}")
        jsonl_url = job_result_response.json()['data']['resultUrl']['jsonUrl']
        break
    elif state == "failed":
        error_msg = job_result_response.json()['data']['errorMsg']
        print(f"Job failed, failure reason:{error_msg}")
        sys.exit()

    time.sleep(5)

if jsonl_url:
    jsonl_response = requests.get(jsonl_url)
    jsonl_response.raise_for_status()
    lines = jsonl_response.text.strip().split('\n')
    output_dir = "output"
    os.makedirs(output_dir, exist_ok=True)
    page_num = 0
    for line_num, line in enumerate(lines, start=1):
        line = line.strip()
        if not line:
            continue
        result = json.loads(line)["result"]
        # Note: layoutParsingResults field is used here
        for i, res in enumerate(result["layoutParsingResults"]):
            md_filename = os.path.join(output_dir, f"doc_{page_num}.md")
            with open(md_filename, "w", encoding="utf-8") as md_file:
                md_file.write(res["markdown"]["text"])
            print(f"Markdown document saved at {md_filename}")
            for img_path, img in res["markdown"]["images"].items():
                full_img_path = os.path.join(output_dir, img_path)
                os.makedirs(os.path.dirname(full_img_path), exist_ok=True)
                img_bytes = requests.get(img).content
                with open(full_img_path, "wb") as img_file:
                    img_file.write(img_bytes)
                print(f"Image saved to: {full_img_path}")
            for img_name, img in res["outputImages"].items():
                img_response = requests.get(img)
                if img_response.status_code == 200:
                    # Save image to local
                    filename = os.path.join(output_dir, f"{img_name}_{page_num}.jpg")
                    with open(filename, "wb") as f:
                        f.write(img_response.content)
                    print(f"Image saved to: {filename}")
                else:
                    print(f"Failed to download image, status code: {img_response.status_code}")
            page_num += 1

2. PP-OCRv5 Call Example

Applicable to PP-OCRv5 model.

# Please make sure the requests library is installed
# pip install requests
import json
import os
import requests
import sys
import time

JOB_URL = "https://paddleocr.aistudio-app.com/api/v2/ocr/jobs"
TOKEN = ""
MODEL = "PP-OCRv5"

file_path = "<local file path or file url>"

headers = {
    "Authorization": f"bearer {TOKEN}",
}

optional_payload = {
    "useDocOrientationClassify": False,
    "useDocUnwarping": False,
    "useTextlineOrientation": False,
}

print(f"Processing file: {file_path}")

if file_path.startswith("http"):
    # URL Mode
    headers["Content-Type"] = "application/json"
    payload = {
        "fileUrl": file_path,
        "model": MODEL,
        "optionalPayload": optional_payload
    }
    job_response = requests.post(JOB_URL, json=payload, headers=headers)
else:
    # Local File Mode
    if not os.path.exists(file_path):
        print(f"Error: File not found at {file_path}")
        sys.exit(1)
        
    data = {
        "model": MODEL,
        "optionalPayload": json.dumps(optional_payload)
    }
    
    with open(file_path, "rb") as f:
        files = {"file": f}
        job_response = requests.post(JOB_URL, headers=headers, data=data, files=files)

print(f"Response status: {job_response.status_code}")

if job_response.status_code != 200:
    print(f"Response content: {job_response.text}")

assert job_response.status_code == 200
jobId = job_response.json()["data"]["jobId"]
print(f"Job submitted successfully. job id: {jobId}")
print("Start polling for results")

jsonl_url = ""
while True:
    job_result_response = requests.get(f"{JOB_URL}/{jobId}", headers=headers)
    assert job_result_response.status_code == 200
    state = job_result_response.json()["data"]["state"]
    if state == 'pending':
        print("The current status of the job is pending")
    elif state == 'running':
        try:
            total_pages = job_result_response.json()['data']['extractProgress']['totalPages']
            extracted_pages = job_result_response.json()['data']['extractProgress']['extractedPages']
            print(f"The current status of the job is running, total pages: {total_pages}, extracted pages: {extracted_pages}")
        except KeyError:
             print("The current status of the job is running...")
    elif state == 'done':
        extracted_pages = job_result_response.json()['data']['extractProgress']['extractedPages']
        start_time = job_result_response.json()['data']['extractProgress']['startTime']
        end_time = job_result_response.json()['data']['extractProgress']['endTime']
        print(f"Job completed, successfully extracted pages: {extracted_pages}, start time: {start_time}, end time: {end_time}")
        jsonl_url = job_result_response.json()['data']['resultUrl']['jsonUrl']
        break
    elif state == "failed":
        error_msg = job_result_response.json()['data']['errorMsg']
        print(f"Job failed, failure reason:{error_msg}")
        sys.exit()

    time.sleep(5)

if jsonl_url:
    jsonl_response = requests.get(jsonl_url)
    jsonl_response.raise_for_status()
    lines = jsonl_response.text.strip().split('\n')
    output_dir = "output"
    os.makedirs(output_dir, exist_ok=True)
    page_num = 0
    for line_num, line in enumerate(lines, start=1):
        line = line.strip()
        if not line:
            continue
        result = json.loads(line)["result"]
        # Note: PP-OCRv5 uses ocrResults field
        for i, res in enumerate(result["ocrResults"]):
            image_url = res["ocrImage"]
            img_response = requests.get(image_url)
            if img_response.status_code == 200:
                # Save image to local
                filename = f"output/img_output_{page_num}.jpg"
                with open(filename, "wb") as f:
                    f.write(img_response.content)
                print(f"Image saved to: {filename}")
            else:
                print(f"Failed to download image, status code: {img_response.status_code}")
            page_num += 1

API Documentation

Base URL: https://paddleocr.aistudio-app.com/

Submit Parsing Job

Path: /api/v2/ocr/jobs

Method: POST

Header:

  • Authorization: Bearer {access_token}
  • Content-Type: application/json (Set when passing file URL, automatically adapted in sample code)
  • Content-Type: multipart/form-data (Set when uploading files, automatically adapted in sample code)
  • Accept-Encoding: gzip, deflate, br

Request Parameter Description

Parameter Type Required Example Description
file bytes 是(与 fileUrl 二选一) 二进制文件数据
fileUrl string 是(与 file 二选一) 文件链接
model string Yes PP-OCRv5
PP-StructureV3
PaddleOCR-VL
PaddleOCR-VL-1.5
OCR Model Name
optionalPayload object No {"useDocOrientationClassify": false} Parsing parameters, varying by model type, see:
PP-OCRV5: Doc
PP-StructureV3: Doc
PaddleOCR-VL: Doc
PaddleOCR-VL-1.5: Doc
pageRanges string No "2,4-6": Page 2, Pages 4 to 6
"2--2": Page 2 to the second to last page
Specify the range of pages to parse
batchId string No Unique identifiable string Batch ID, used for querying batch tasks

Response Parameter Description

Parameter Type Example Description
traceId string 0b1eb3150f5bec03dab9e74b4264c615 Request ID
code int 10002 Interface status code, 0 for success, see "Error Code Description" for failure details
msg string File URL unrecognized Interface response message, see "Error Code Description" for failure details
data object
data.jobId string ocrjob-f4377241b695 Job ID

Get Parsing Result

Path: /api/v2/ocr/jobs/{jobId}

Method: GET

Header:

  • Authorization: Bearer {access_token}
  • Content-Type: application/json

Response Parameter Description

Parameter Type Example Description
traceId string 0b1eb3150f5bec03dab9e74b4264c615 Request ID
code int 0 Interface status code, Success: 0
msg string Success Interface processing information, Success: "Success"
data object
data.jobId string ocrjob-f4377241b695 Job ID
data.state string done Job processing status
* done: Completed
* pending: Queued
* running: Parsing in progress
* failed: Parsing failed (no partial success)
data.errorMsg string File format not supported, please upload a file type that meets the requirements Parsing failure reason, valid when state=failed
data.resultUrl object Provides BOS short link
{ "jsonUrl": "https://***.com", "markdownUrl": "https://***.com"}
Document parsing result, valid when state=done
data.extractProgress object Document parsing progress, valid when state=running
data.extractProgress.startTime string 2026-01-01T12:00:00+08:00 Document parsing start time
data.extractProgress.endTime string 2026-01-01T12:00:00+08:00 Document parsing end time
data.extractProgress.totalPages string 10 Total number of pages in the document
data.extractProgress.extractedPages string 1 Number of pages already parsed

Batch Get Task Results

Path: /api/v2/ocr/jobs/batch/{batchId}

Method: GET

Header:

  • Authorization: Bearer {access_token}
  • Content-Type: application/json
  • Accept-Encoding: gzip, deflate, br

Response Parameter Description

Parameter Type Example Description
traceId string 0b1eb3150f5bec03dab9e74b4264c615 Request ID
code int 0 Interface status code, Success: 0
msg string Success Interface processing information, Success: "Success"
data object
data.batchId string batchid-202601210000 Batch Task ID, custom format as passed by user.
data.extractResult array List of inference results
data.extractResult.jobId string ocrjob-f4377241b695 Job ID
data.extractResult.state string done Job processing status
* done: Completed
* pending: Queued
* running: Parsing in progress
* failed: Parsing failed (no partial success)
data.extractResult.errorMsg string File format not supported, please upload a file type that meets the requirements Parsing failure reason, valid when state=failed
data.extractResult.resultUrl object Provides BOS short link
{ "jsonUrl": "https://***.com", "markdownUrl": "https://***.com"}
Document parsing result, valid when state=done
data.extractResult.extractProgress object Document parsing progress, valid when state=running
data.extractResult.extractProgress.startTime string 2026-01-01T12:00:00+08:00 Document parsing start time
data.extractResult.extractProgress.endTime string 2026-01-01T12:00:00+08:00 Document parsing end time
data.extractResult.extractProgress.totalPages int 10 Total number of pages in the document
data.extractResult.extractProgress.extractedPages int 1 Number of pages already parsed

Error Codes

Error Code Error Code Description Suggestion
401 Token Invalid Check token, get token from link: Link
500 System Error Please contact official support or try again later
10001 Empty file (http status corresponds to 400) Please check the file
10002 File URL unrecognized (http status corresponds to 400) Please check the URL
10003 File size exceeds limit (http status corresponds to 400) Please check the file
10004 File format not supported (http status corresponds to 400) Please check the file
10005 File content cannot be parsed (http status corresponds to 400) Please check the file
10006 Number of file pages exceeds limit (http status corresponds to 400) Please check the file
10007 Model parameter error (http status corresponds to 400) Model does not exist, please check the model name
10008 Request parameter error (http status corresponds to 400) optionalPayload or extraFormats parameter error, please correct according to data.errorMsg prompt
10009 Only 100 tasks are allowed for the same batchId (http status corresponds to 400) Please change batchId
10010 Job submission queue is full Please try again later
11001 jobId does not exist (http status corresponds to 404) Please check jobId
11002 job expired (http status corresponds to 400) Please change JobId
11003 job parsing failed (http status corresponds to 200) Parsing failed, specific reason see: data.errorMsg
12001 Daily page limit reached (http status corresponds to 403) Exceeded daily quota, if you need to increase, please see Quota Description
12002 Request frequency too high (http status corresponds to 429) Please try again later
上一篇
API Quota Rules and Error Code Description