# HTML to Markdown Converter — Clean conversion with batch (`perryay/html-to-markdown`) Actor

Clean, AI-ready Markdown from any HTML source. Converts web pages or raw HTML to well-structured Markdown — preserving headings, lists, tables, code blocks, links, and images. Clean mode strips ads and navigation. Batch convert up to 50 items via URL fetch or direct HTML input.

- **URL**: https://apify.com/perryay/html-to-markdown.md
- **Developed by:** [Perry AY](https://apify.com/perryay) (community)
- **Categories:** Developer tools, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.01 / actor start

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## HTML to Markdown Converter 📝

**Clean, AI-ready Markdown from any HTML source — with noise-stripping clean mode**

Converting HTML to clean, readable Markdown is a common but surprisingly tricky task. Inline styles, complex nested layouts, navigation elements, ads, and sidebar content all get in the way of producing clean output. **HTML to Markdown Converter** handles the entire conversion pipeline — fetch from a URL or paste raw HTML, strip unwanted noise, preserve document structure, and produce clean Markdown ready for LLM ingestion, documentation migration, content archiving, or web scraping pipelines.

Supports batch processing of up to 50 items per request, two conversion modes, and multiple output formats. Every result includes metadata — title, word count, image count — alongside the full Markdown content.

---

### ✨ Features

- **URL or raw HTML input** — Fetch content from any public URL with automatic redirect following, or paste raw HTML directly for offline conversion without network requests

- **Structure preservation** — Headings (H1–H6), ordered and unordered lists, tables, code blocks, inline code, links, blockquotes, and images are all accurately preserved in the Markdown output using the markdownify library

- **Clean mode** — Premium mode that strips ads, navigation bars, sidebars, footers, cookie notices, popups, social share buttons, comment sections, and other non-content elements before conversion; uses 20+ CSS selectors to identify noise elements

- **Metadata extraction** — Automatically extracts the page title from `<title>` tags, counts the number of words in the output, and reports the number of images found in the original HTML

- **Batch processing** — Convert up to 50 items in a single run, mixing URL and raw HTML inputs with independent mode settings per item

- **Flexible output** — JSON for programmatic consumption (contains full Markdown + metadata), plain text for quick review with truncated Markdown preview, or CSV for spreadsheet-friendly metadata export

- **Clean Mode Selectors** — 20+ CSS/jQuery-style selectors used to remove noise: structural elements (nav, footer, aside), advertising containers (.ad, .advertisement, .banner, .promo), social widgets (.social-share, .share-buttons), technical markup (script, style, iframe), and notification overlays (.cookie, .popup)

- **Comprehensive summaries** — Every run appends a summary row with total items converted, total word count across all documents, clean mode usage count, and error count

### 🚀 Quick Start

#### Convert from URL — Standard Mode

```json
{
  "source": "https://example.com/article",
  "sourceType": "url",
  "mode": "standard"
}
````

**Response example (standard mode):**

```json
{
  "original_url": "https://example.com/article",
  "markdown": "# Article Title\n\nThis is the article content converted to clean Markdown.\n\n## Section One\n\n- Bullet point one\n- Bullet point two\n\n> A blockquote from the article.\n\n| Header 1 | Header 2 |\n|----------|----------|\n| Cell A   | Cell B   |\n",
  "title": "Article Title | Example Site",
  "word_count": 845,
  "images_count": 3,
  "error": ""
}
```

#### Convert Raw HTML

```json
{
  "source": "<h1>Hello World</h1><p>Welcome to <strong>Markdown</strong> conversion.</p><ul><li>Item A</li><li>Item B</li></ul>",
  "sourceType": "raw",
  "mode": "standard"
}
```

**Response example (raw HTML):**

```json
{
  "original_url": "",
  "markdown": "# Hello World\n\nWelcome to **Markdown** conversion.\n\n- Item A\n- Item B\n",
  "title": "",
  "word_count": 14,
  "images_count": 0,
  "error": ""
}
```

#### Convert URL with Clean Mode

```json
{
  "source": "https://example.com/article",
  "sourceType": "url",
  "mode": "clean"
}
```

**Response example (clean mode — notice ad/content noise removed):**

```json
{
  "original_url": "https://example.com/article",
  "markdown": "# Article Title\n\nClean article body without navigation, ads, or sidebars.\n\n## Main Content\n\nThe article text converted directly.\n",
  "title": "Article Title | Example Site",
  "word_count": 620,
  "images_count": 2,
  "error": ""
}
```

#### Batch Mode — Mixed Inputs

```json
{
  "batchMode": true,
  "batchData": [
    {
      "source": "https://site1.com/article",
      "sourceType": "url",
      "mode": "clean"
    },
    {
      "source": "<h2>Offline Content</h2><p>Raw HTML snippet</p>",
      "sourceType": "raw",
      "mode": "standard"
    }
  ]
}
```

### 📋 Input Parameters

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `source` | string | `""` | HTML content or URL to convert. For `url` sourceType, must be a valid HTTP(S) URL. For `raw` sourceType, must be valid HTML markup. |
| `sourceType` | string | `"url"` | Input type: `url` (fetch from the web) or `raw` (treat source as raw HTML string) |
| `mode` | string | `"standard"` | Conversion mode: `standard` (full HTML → Markdown) or `clean` (strips noise before conversion, premium feature) |
| `outputFormat` | string | `"json"` | Output format: `json` (full results with Markdown content), `plain` (truncated Markdown for quick review), or `csv` (metadata only) |
| `batchMode` | boolean | `false` | Enable batch processing for multiple independent conversion jobs in a single run |
| `batchData` | array | `[]` | Array of per-item input objects, each with its own `source`, `sourceType`, and `mode`. Maximum 50 entries. |

### 📤 Output Format

Each conversion produces one result row:

| Field | Type | Description |
|-------|------|-------------|
| `original_url` | string | Source URL (only populated when `sourceType` is `url`). Empty for raw HTML input. |
| `markdown` | string | The converted Markdown content. Full document in `json` format, truncated to 2000 characters in `plain` format. Not included in `csv` format. |
| `title` | string | Page title extracted from the HTML `<title>` tag. Empty string if no title found. |
| `word_count` | integer | Number of words in the output Markdown |
| `images_count` | integer | Number of `<img>` tags found in the original HTML |
| `error` | string | Error description if fetching or conversion failed. Empty string on success. |

#### CSV Format Fields

When `outputFormat` is `csv`, the output includes: `original_url`, `title`, `word_count`, `images_count`, and `error`. The full Markdown content is excluded from CSV format for spreadsheet compatibility.

#### Summary Row

A `_summary` row is appended at the end with aggregate statistics:

| Field | Type | Description |
|-------|------|-------------|
| `_summary` | boolean | Always `true` for the summary row |
| `total_items` | integer | Number of items processed |
| `total_words` | integer | Total word count across all converted documents |
| `clean_mode_used` | integer | Number of items converted with clean mode enabled |
| `error_count` | integer | Number of items that failed conversion |

### ⚙️ Technical Details

#### Conversion Pipeline

The conversion process follows five steps:

1. **Input acquisition:** If `sourceType` is `url`, the actor fetches the page with async HTTP (urllib) using a 30-second timeout and automatic redirect following. If `sourceType` is `raw`, the `source` string is used directly as HTML without any network request.

2. **Title extraction:** The `<title>` tag content is extracted from the HTML using BeautifulSoup's `find("title")` method. If no title tag exists, an empty string is returned.

3. **Image counting:** All `<img>` tags are counted using a regex pattern (`<img[^>]+>`) applied to the raw HTML. This counts all images regardless of whether they would render in the Markdown output.

4. **Clean mode (optional):** When `mode` is `clean`, the HTML is parsed with BeautifulSoup and elements matching 20+ CSS selectors are removed via `tag.decompose()`. This includes structural elements (nav, footer, aside), advertising containers, social widgets, comment sections, cookie notices, popups, and technical markup (script, style, iframe).

5. **Markdown conversion:** The HTML (cleaned or original) is converted to Markdown using the `markdownify` library with ATX heading style (`#` through `######`), dash (`-`) bullet markers, and automatic code block detection.

#### Clean Mode Selectors

Clean mode removes all elements matching these CSS selectors:

| Category | Selectors | Purpose |
|----------|-----------|---------|
| Structural | `nav`, `footer`, `aside`, `.header`, `.footer` | Remove page chrome |
| Navigation | `.nav`, `.navigation`, `.menu`, `[role=navigation]` | Remove menus/breadcrumbs |
| Advertising | `.advertisement`, `.ads`, `.ad`, `.banner`, `.promo` | Remove ad content |
| Social | `.social-share`, `.share-buttons` | Remove sharing widgets |
| Content noise | `.sidebar`, `.related-posts`, `.comments`, `#comments`, `[role=complementary]` | Remove side content |
| Technical | `script`, `style`, `noscript`, `iframe` | Remove non-content markup |
| Notifications | `.cookie`, `.popup` | Remove overlays |

#### Markdown Element Mapping

| HTML Element | Markdown Output | Example |
|-------------|-----------------|---------|
| `<h1>`–`<h6>` | ATX headings | `# Title`, `## Section` |
| `<p>` | Paragraph text | blank-line-separated |
| `<ul>`, `<ol>` | List items | `- item` / `1. item` |
| `<table>` | Pipe table | pipe-separated columns |
| `<pre><code>` | Fenced code block | triple backtick wrap |
| `<code>` | Inline code | backtick-wrapped text |
| `<a>` | Inline link | `[text](url)` |
| `<img>` | Inline image | `![alt](url)` |
| `<blockquote>` | Blockquote | `> quoted text` |
| `<strong>`, `<b>` | Bold | `**bold text**` |
| `<em>`, `<i>` | Italic | `*italic text*` |
| `<br>` | Line break | two trailing spaces |

#### Error Handling

- **URL fetch failures:** If a URL cannot be fetched (timeout, DNS error, 4xx/5xx), the result contains an `error` description and all other fields are empty or zero
- **Conversion errors:** If markdownify encounters malformed HTML, the actor catches the exception and returns it in the `error` field
- **Batch isolation:** Individual item failures do not block processing of remaining items in the batch
- **Empty input:** If `source` is empty, the item is silently skipped

### 🎯 Use Cases

- **LLM data preparation** — Convert web content to clean Markdown for RAG pipelines, AI training datasets, and fine-tuning corpora; clean mode strips navigation noise so only the article content is processed

- **Documentation migration** — Bulk-convert HTML documentation to Markdown for static site generators (Jekyll, Hugo, Docusaurus, MkDocs) — preserves headings, code blocks, tables, and link structure

- **Content archiving** — Save stripped, readable versions of web articles and blog posts as clean Markdown files for long-term archival, offline reading, and cross-referencing

- **Web scraping pipelines** — Integrate with crawlers and web scrapers to produce clean, structured Markdown output ready for further processing, NLP analysis, or content extraction

- **Email to Markdown conversion** — Convert HTML-formatted emails to clean Markdown for note-taking systems, CRM logging, or knowledge base ingestion

- **Newsletter preparation** — Clean and reformat web content for inclusion in email newsletters, stripping promotional elements while preserving the core article body

- **Static site generation** — Convert legacy HTML content for use with Hugo, Jekyll, or Gatsby static sites that require Markdown source files

#### Choosing Between Standard and Clean Mode

The choice between `standard` and `clean` mode depends on your use case:

| Scenario | Recommended Mode | Rationale |
|----------|-----------------|-----------|
| LLM data preparation | `clean` | Remove navigation noise for clean training data |
| Documentation migration | `standard` | Preserve all page structure including navigation |
| Content archiving | `clean` | Store only the article body for compact archives |
| Web scraping pipeline | `clean` | Produce focused Markdown for downstream processing |
| Full page capture | `standard` | Keep a complete record of the page as rendered |

Clean mode is particularly valuable when the output Markdown will be fed into LLM pipelines, as navigation text and advertisements can confuse model training and RAG retrieval.

### ❓ FAQ & Troubleshooting

**Q: What is the difference between `standard` and `clean` mode?**
A: `standard` mode converts the entire HTML document to Markdown, including navigation, sidebars, and ads. `clean` mode (premium) pre-processes the HTML to remove these non-content elements before conversion, producing a cleaner, more focused document.

**Q: Does clean mode work on all websites?**
A: Clean mode uses a comprehensive set of CSS selectors targeting common class names and element types used by most websites. It works well on news sites, blogs, documentation sites, and articles. Highly customized or JavaScript-rendered sites may retain some navigation elements.

**Q: How are tables converted?**
A: HTML tables are converted to GitHub-flavored Markdown pipe tables with header row, separator row, and data rows. Complex tables (colspan/rowspan, nested tables) may have simplified representation.

**Q: Can I process JavaScript-rendered pages?**
A: The actor fetches raw HTML from the URL and does not execute JavaScript. Pages that require JavaScript to render their content may produce incomplete Markdown. For JS-rendered content, consider a headless browser scraper first.

**Q: Why is the word count different between standard and clean mode?**
A: Clean mode removes navigation, ads, sidebars, and other non-content elements, so the word count is typically lower than standard mode which includes all visible text on the page.

**Q: What is the maximum input size for raw HTML?**
A: Raw HTML input is limited only by the Apify platform's input size constraints. Very large HTML documents (>1 MB) may be subject to platform-level limits. For large documents, consider converting via URL instead.

**Q: How is the title extracted?**
A: The actor extracts text from the first `<title>` tag in the HTML using BeautifulSoup. If the page uses JavaScript to set the title, the static HTML `<title>` value is used.

**Q: Can I convert multiple URLs with different modes in one run?**
A: Yes. Use batch mode (`batchMode: true`) with `batchData` array. Each entry in the array can have its own `source`, `sourceType`, and `mode` settings.

**Q: What image formats are counted?**
A: The actor counts all `<img>` tags regardless of src format (jpg, png, gif, svg, webp, etc.). Image counting happens on the raw HTML before conversion, so even images that would not render in Markdown are counted.

**Q: Does clean mode remove inline styles?**
A: No. Clean mode removes structural elements (nav, aside, footer, etc.) and containers identified by class/id/role selectors. Inline styles and formatting within the remaining content are preserved and converted to Markdown formatting.

**Q: How are nested lists converted?**
A: The markdownify library preserves nested list structures with appropriate indentation. Unordered sub-lists use dashes, and ordered sub-lists use numbers with correct nesting.

**Q: Can I convert an HTML file from my local machine?**
A: The actor runs on the Apify cloud platform and cannot access local files. To convert a local HTML file, either upload it to a publicly accessible URL and use `sourceType: "url"`, or paste the HTML content directly as `sourceType: "raw"`.

**Q: What happens if the URL returns a non-HTML content type?**
A: If the URL returns a non-HTML response (e.g., PDF, image, JSON), the actor still attempts conversion. Results may be unpredictable or empty. The `error` field will describe the issue if conversion fails.

**Q: Does the actor preserve HTML comments?**
A: No. HTML comments (`<!-- -->`) are stripped during conversion and do not appear in the Markdown output.

**Q: How are `<pre>` blocks with code converted?**
A: `<pre><code>` blocks are converted to fenced code blocks using triple backticks. If the `<code>` tag has a `class` attribute with a language hint (e.g., `class="language-python"`), the language identifier is included after the opening backticks.

**Q: Can I control the heading style in the output?**
A: The conversion uses ATX heading style (`#` through `######`) by default. Setext style (underlined with `=` and `-`) is not currently supported.

**Q: How are `<hr>` horizontal rules converted?**
A: Horizontal rules (`<hr>`) are converted to three dashes (`---`) on a separate line.

**Q: Are `<br>` line breaks preserved?**
A: Yes. `<br>` tags are converted to two trailing spaces followed by a newline, which is the Markdown convention for a hard line break.

**Q: How does the actor handle `<table>` elements with colspan/rowspan?**
A: Complex table attributes like `colspan` and `rowspan` may not be fully preserved in the pipe-table Markdown output. Simple tables with aligned columns convert cleanly; highly complex layouts may produce simplified representations.

**Q: Can I use the actor to clean up email HTML for archiving?**
A: Yes. Copy the HTML source of an email (most email clients have a "show original" or "view source" option) and paste it as `sourceType: "raw"` input for conversion to clean Markdown suitable for archiving and search.

**Q: What is the difference between `sourceType: "url"` and `sourceType: "raw"`?**
A: `url` fetches the HTML from a live web URL using an async HTTP client. `raw` treats the `source` string directly as HTML content without making any network request. Use `raw` for offline HTML files, email sources, or pre-fetched content.

# Actor input Schema

## `source` (type: `string`):

The HTML content or URL to convert to Markdown

## `sourceType` (type: `string`):

Specify whether 'source' is a URL to fetch or raw HTML content

## `mode` (type: `string`):

Conversion mode — 'standard' for full conversion, 'clean' for conversion with ads/nav/sidebar stripping

## `outputFormat` (type: `string`):

Output format: json, plain, or csv

## `batchMode` (type: `boolean`):

Enable batch processing for multiple conversions in one run

## `batchData` (type: `array`):

Array of input objects for batch processing. Each object can have source, sourceType, mode, and outputFormat.

## Actor input object example

```json
{
  "source": "https://example.com/article",
  "sourceType": "url",
  "mode": "standard",
  "outputFormat": "json",
  "batchMode": false
}
```

# Actor output Schema

## `results` (type: `string`):

Per-source Markdown conversion results in the default dataset

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "source": "https://example.com/article"
};

// Run the Actor and wait for it to finish
const run = await client.actor("perryay/html-to-markdown").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "source": "https://example.com/article" }

# Run the Actor and wait for it to finish
run = client.actor("perryay/html-to-markdown").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "source": "https://example.com/article"
}' |
apify call perryay/html-to-markdown --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=perryay/html-to-markdown",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "HTML to Markdown Converter — Clean conversion with batch",
        "description": "Clean, AI-ready Markdown from any HTML source. Converts web pages or raw HTML to well-structured Markdown — preserving headings, lists, tables, code blocks, links, and images. Clean mode strips ads and navigation. Batch convert up to 50 items via URL fetch or direct HTML input.",
        "version": "1.0",
        "x-build-id": "s6IJCb9Kw53QdD6IT"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/perryay~html-to-markdown/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-perryay-html-to-markdown",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/perryay~html-to-markdown/runs": {
            "post": {
                "operationId": "runs-sync-perryay-html-to-markdown",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/perryay~html-to-markdown/run-sync": {
            "post": {
                "operationId": "run-sync-perryay-html-to-markdown",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "source": {
                        "title": "Source",
                        "type": "string",
                        "description": "The HTML content or URL to convert to Markdown"
                    },
                    "sourceType": {
                        "title": "Source Type",
                        "enum": [
                            "url",
                            "raw"
                        ],
                        "type": "string",
                        "description": "Specify whether 'source' is a URL to fetch or raw HTML content",
                        "default": "url"
                    },
                    "mode": {
                        "title": "Conversion Mode",
                        "enum": [
                            "standard",
                            "clean"
                        ],
                        "type": "string",
                        "description": "Conversion mode — 'standard' for full conversion, 'clean' for conversion with ads/nav/sidebar stripping",
                        "default": "standard"
                    },
                    "outputFormat": {
                        "title": "Output Format",
                        "enum": [
                            "json",
                            "plain",
                            "csv"
                        ],
                        "type": "string",
                        "description": "Output format: json, plain, or csv",
                        "default": "json"
                    },
                    "batchMode": {
                        "title": "Batch Mode",
                        "type": "boolean",
                        "description": "Enable batch processing for multiple conversions in one run",
                        "default": false
                    },
                    "batchData": {
                        "title": "Batch Data",
                        "type": "array",
                        "description": "Array of input objects for batch processing. Each object can have source, sourceType, mode, and outputFormat."
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
