# EasyLink EMR-Mask Medical Record Desensitization

## Overview

EMR-Mask is a specialized intelligent desensitization model for medical documents. After uploading a medical document (PDF/image), the model automatically identifies and masks sensitive information such as patient names, ID numbers, and contact phone numbers, returning a download link for the desensitized file. This ensures the safety and compliance of medical data in sharing, archiving, and training scenarios.

This interface uses async mode: submit a task to obtain a task ID, then poll to query the result.

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

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

## Supported Models

- `easydoc-emr-mask`

## Request Parameters

### Submit Task

| Field | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| model | string | Yes | Model name, fixed as `easydoc-emr-mask` |
| input.img_url | string | Yes | URL of the file to desensitize; supports PDF / JPG / PNG / TIFF |
| input.prompt | string | Yes | Desensitization rules as a JSON Schema format string, specifying fields to desensitize |

`input.prompt` example (specifying fields to desensitize):

```json
{
  "type": "object",
  "properties": {
    "Patient Name": {"type": "string"},
    "Patient Gender": {"type": "string"},
    "Admission Date": {"type": "string"},
    "Discharge Date": {"type": "string"},
    "Age": {"type": "string"},
    "Length of Stay": {"type": "string"}
  }
}
```

### 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 desensitized files (valid for 1 hour) |
| output.error_message | string | Error message (returned on failure) |
| usage.page_count | integer | Number of pages in the file, used for billing |

## 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-emr-mask",
    "input": {
      "img_url": "https://example.com/medical_record.pdf",
      "prompt": "{\"type\":\"object\",\"properties\":{\"Patient Name\":{\"type\":\"string\"},\"Patient Gender\":{\"type\":\"string\"},\"Age\":{\"type\":\"string\"}}}"
    }
  }'
```

**Query Task Status:**

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

### Python Example

```python
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-emr-mask",
    "input": {
        "img_url": "https://example.com/medical_record.pdf",
        "prompt": '{"type":"object","properties":{"Patient Name":{"type":"string"},"Patient Gender":{"type":"string"},"Age":{"type":"string"}}}',
    },
}

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":
        print("Desensitized file links:")
        for url in result["output"]["urls"]:
            print(url)
        print(f"Pages: {result['usage']['page_count']}")
        break
    elif status == "Failure":
        print(f"Failed: {result['output'].get('error_message')}")
        break

    time.sleep(5)
```

## Response Examples

**Submission successful:**

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

**Task completed:**

```json
{
  "output": {
    "task_id": "b_mask_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "task_status": "Success",
    "urls": [
      "https://oss.easylink-ai.com/easylink-easydoc-task/mask_merge/xxxxxxxx.pdf?..."
    ],
    "submit_time": 1700000000,
    "finish_time": 1700000060
  },
  "usage": {
    "duration": 60,
    "page_count": 3
  },
  "request_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
```

## Usage Notes

1. **File formats**: Supports PDF, JPG, PNG, TIFF. Pass the publicly accessible URL via `input.img_url`.
2. **Desensitization rules**: Pass a JSON Schema string via `input.prompt` specifying the field names to desensitize. Omitting or leaving it empty will cause the task to fail.
3. **Result link expiry**: The returned desensitized file URL is valid for 1 hour. Download and save it promptly.
4. **Billing**: Billed by number of pages; page count is returned via `usage.page_count`.
