# EasyLink EasyDoc-Parse Intelligent Document Parsing

## Overview

EasyDoc-Parse is an intelligent document parsing model. After uploading a document (PDF/image), the model automatically identifies the document structure and returns structured JSON containing nodes such as titles, text, tables, and figures, along with Markdown-formatted content. It is suitable for document digitization, content extraction, RAG knowledge base construction, and similar scenarios.

This interface uses async mode: submit a task to obtain a task ID, then poll to query the result. The parsed result is stored as a file and returned via `output.urls[0]` as a download link valid for 7 days.

For more details, see the [EasyLink official documentation](https://docs.easylink-ai.com/docs/capabilities/parsing/api-v2).

**Request URL**: `https://api-us-ca.umodelverse.ai/v1/tasks/submit`

## Supported Models

- `easydoc-parse-premium`

## Request Parameters

### Submit Task

| Field | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| model | string | Yes | Model name, fixed as `easydoc-parse-premium` |
| input.img_url | string | Yes | URL of the file to parse; supports PDF / JPG / PNG / BMP / TIFF |

### Query Task Status

| Field | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| task_id | string | Yes | Task ID returned when the task was submitted |

## Response Fields

### Submit Response

| Field | Type | Description |
| :--- | :--- | :--- |
| output.task_id | string | Task ID for subsequent queries |
| request_id | string | Request ID |

### Status Query Response

| Field | Type | Description |
| :--- | :--- | :--- |
| output.task_status | string | Task status: `Pending` / `Running` / `Success` / `Failure` |
| output.urls | array | List of download links for parsed result files (returned on success, valid for 7 days) |
| output.error_message | string | Error message (returned on failure) |
| usage.page_count | integer | Number of pages in the file, used for billing |

Structure of the JSON downloaded from `output.urls[0]`:

| Field | Type | Description |
| :--- | :--- | :--- |
| file_name | string | File name |
| nodes | array | Document node array, see below |
| markdown | string | Document content in Markdown format |

Structure of each element in `nodes`:

| Field | Type | Description |
| :--- | :--- | :--- |
| id | integer | Node ID |
| type | string | Node type: `Title` / `Text` / `Table` / `Figure` |
| text | string | Node text content |
| parent_id | integer | Parent node ID; `-1` indicates root node |
| composing_blocks | array | Coordinate position info, including `page_number`, `coordinates [x1,y1,x2,y2]`, `layout_width`, `layout_height` |
| path_info | object | Node path information |

## Examples

### Curl Examples

**Submit Task:**

```bash
curl -X POST https://api-us-ca.umodelverse.ai/v1/tasks/submit \
  -H "Authorization: Bearer {api_key}" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "easydoc-parse-premium",
    "input": {
      "img_url": "https://example.com/document.pdf"
    }
  }'
```

**Query Task Status:**

```bash
curl "https://api-us-ca.umodelverse.ai/v1/tasks/status?task_id={task_id}" \
  -H "Authorization: Bearer {api_key}"
```

**Download Parsed Result:**

```bash
curl "{output.urls[0]}" -o result.json
```

### Python Example

```python
import json
import time
import requests

api_key = "YOUR_API_KEY"
base_url = "https://api-us-ca.umodelverse.ai/v1"

headers = {
    "Authorization": f"Bearer {api_key}",
    "Content-Type": "application/json",
}

# Submit task
submit_data = {
    "model": "easydoc-parse-premium",
    "input": {
        "img_url": "https://example.com/document.pdf",
    },
}

resp = requests.post(f"{base_url}/tasks/submit", headers=headers, json=submit_data)
task_id = resp.json()["output"]["task_id"]
print(f"task_id: {task_id}")

# Poll for results
while True:
    result = requests.get(
        f"{base_url}/tasks/status",
        headers=headers,
        params={"task_id": task_id},
    ).json()

    status = result["output"]["task_status"]
    print(f"status: {status}")

    if status == "Success":
        download_url = result["output"]["urls"][0]
        print(f"Result download link: {download_url}")
        parsed = requests.get(download_url).json()
        print(f"File name: {parsed['file_name']}")
        print(f"Number of nodes: {len(parsed['nodes'])}")
        print(f"Total pages: {result['usage']['page_count']}")
        break
    elif status == "Failure":
        print(f"Failed: {result['output'].get('error_message')}")
        break

    time.sleep(10)
```

## Response Examples

**Submission successful:**

```json
{
  "output": {
    "task_id": "parse_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
  },
  "request_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
```

**Task completed:**

```json
{
  "output": {
    "task_id": "parse_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "task_status": "Success",
    "urls": [
      "https://text-store.cn-wlcb.ufileos.com/easylink/parse/parse_xxxxxxxx.json?Expires=xxxxxxxxxx&Signature=xxx&UCloudPublicKey=xxx"
    ],
    "submit_time": 1700000000,
    "finish_time": 1700000060
  },
  "usage": {
    "duration": 60,
    "page_count": 5
  },
  "request_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
```

**Example of the JSON structure returned by the download link:**

```json
{
  "file_name": "document.pdf",
  "nodes": [
    {
      "id": 1,
      "type": "Title",
      "text": "Document Title",
      "parent_id": -1,
      "composing_blocks": [
        {
          "page_number": 1,
          "coordinates": [582, 271, 1121, 328],
          "system": "PixelSpace",
          "layout_width": 1708,
          "layout_height": 2212
        }
      ],
      "path_info": {
        "path_context": "",
        "path": []
      }
    }
  ],
  "markdown": "# Document Title\n\nBody content..."
}
```

## Usage Notes

1. **File formats**: Supports PDF, JPG, PNG, BMP, TIFF. Pass the publicly accessible URL via `input.img_url`.
2. **Retrieving results**: After the task succeeds, `output.urls[0]` is the download link for the parsed result JSON file. You need to make an additional request to download and obtain the structured content.
3. **Link expiry**: Download links are valid for 7 days. Download and save them promptly.
4. **Billing**: Billed by number of pages; page count is returned via `usage.page_count`.
