HTML to Markdown Converter - URL or HTML to GFM avatar

HTML to Markdown Converter - URL or HTML to GFM

Pricing

$1.50 / 1,000 converted pages

Go to Apify Store
HTML to Markdown Converter - URL or HTML to GFM

HTML to Markdown Converter - URL or HTML to GFM

Convert a page (by URL) or raw HTML to clean GitHub-Flavored Markdown - headings, links, fenced code, tables, strikethrough. Single, bulk, or inline HTML. $0.0015 per page no start fee, cheaper than paid converters; failed fetches free.

Pricing

$1.50 / 1,000 converted pages

Rating

0.0

(0)

Developer

Anthony Snider

Anthony Snider

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 hours ago

Last modified

Share

HTML to Markdown Converter - URL or Raw HTML to Clean GitHub-Flavored Markdown

Give it a URL or an HTML string, get clean GitHub-Flavored Markdown back - real code fences with language hints, real GFM tables, strikethrough, and links, with the scripts, styles and hidden elements stripped out. Single page, bulk list, or inline HTML. $0.0015 per page, no start fee. Failed fetches are recorded free.

Feeding pages to an LLM is the common case: Markdown carries the same structure as HTML at a fraction of the tokens. Docs migration, turning a knowledge base into a RAG corpus, and archiving articles as text all want the same thing.

What you get

Per page or HTML string, one record with these exact fields:

  • ok - true when the conversion produced Markdown
  • url - the final URL after redirects (null when you passed raw HTML with no baseUrl)
  • title - the page's <title>, when it has one
  • markdown - the converted document
  • length - character length of the Markdown
  • error - present instead of markdown when the fetch failed. Never charged.

Conversion specifics that matter in practice:

  • ATX headings (#), - bullets, inlined links, **bold**, *italic*, ~~strikethrough~~
  • Fenced code blocks, with the language taken from class="language-js", lang-js or highlight-js
  • <table> rebuilt as a GFM pipe table, with | inside cells escaped
  • <script>, <style>, <noscript>, <iframe>, <svg>, <link>, <meta> and elements hidden via display:none or hidden are removed before conversion
  • Only <body> is converted, so head metadata never leaks into the text
  • Relative links and images are rewritten to absolute URLs using the page URL (or baseUrl for raw HTML)

Example 1: raw HTML, showing what survives conversion

Input:

{
"html": "<html><head><title>Release notes</title></head><body><h1>v2.1</h1><p>Ships <del>beta</del> <strong>stable</strong> support.</p><pre><code class=\"language-js\">const x = 1;</code></pre><table><tr><th>Flag</th><th>Default</th></tr><tr><td>retry</td><td>3</td></tr></table><script>alert(1)</script></body></html>"
}

Output (real run, 2026-08-15):

{
"ok": true,
"url": null,
"title": "Release notes",
"markdown": "# v2.1\n\nShips ~~beta~~ **stable** support.\n\n```js\nconst x = 1;\n```\n\n| Flag | Default |\n| --- | --- |\n| retry | 3 |",
"length": 114
}

The <script> is gone, the <del> became ~~beta~~, the code block kept its js language hint, the table is valid GFM, and the <title> was captured separately instead of being dumped into the text.

Example 2: one live page

Input:

{ "url": "https://example.com" }

Output (real run, 2026-08-15):

{
"ok": true,
"url": "https://example.com/",
"title": "Example Domain",
"markdown": "# Example Domain\n\nThis domain is for use in documentation examples without needing permission. Avoid use in operations.\n\n[Learn more](https://iana.org/domains/example)",
"length": 167
}

Note url is the URL after redirects. Any relative link on a page (/docs/install) is rewritten against that final URL, so the Markdown still resolves when you store it somewhere else.

Example 3: bulk, for a docs migration

Input:

{
"urls": [
"https://example.com/docs/intro",
"https://example.com/docs/install",
"https://example.com/docs/api"
],
"maxUrls": 200
}

One record per URL, each charged once. A URL that 404s becomes {"ok": false, "error": "HTTP 404"} and is not charged. When urls is filled, the single url field is ignored - you are charged for the pages you listed and nothing else.

Pricing

$0.0015 per page converted. No start fee. One event covers one page fetched and converted, or one raw HTML string converted, including the title extraction. A failed fetch (DNS failure, timeout, 4xx, 5xx) is recorded and never charged.

Honest comparison, prices read from the Apify Store API on 2026-08-07:

ActorPricingCost of one page
This actor$0.0015 per page, no start fee$0.0015
shoebill-dev27/html-to-markdown$0.005 start + $0.002 per item$0.007
scrapeworks/pandoc-document-converter$0.00005 start + $0.005 per result$0.005

Those are single-page costs. On a 500-page docs migration the start fee amortizes, so the honest comparison there is per-item: $0.0015 against $0.002 and $0.005.

When NOT to use this

  • JavaScript-rendered pages. This fetches server HTML. If the content only exists after the page runs its scripts (most single-page apps, infinite-scroll feeds), you will get the shell, not the article. Render it yourself with a browser actor and pass the result in as html.
  • Pages behind a login or a bot wall. Requests are plain unauthenticated GETs with a normal User-Agent. There is no proxy rotation, no cookie jar, no CAPTCHA handling.
  • PDFs, Word documents, or images. This is an HTML converter. Use a PDF text extractor for those.
  • Pixel-faithful layout. Deeply nested tables and CSS grid layouts are flattened into valid Markdown, which is a lossy target by design.
  • A single page, once, by hand. Browser extensions do that for free. This is worth paying for in a pipeline, across many pages, or as a tool an agent can call.

Honest limits

  • Server-side HTML only, as above. 20 second fetch timeout per page.
  • Up to 200 pages per run (maxUrls, default 50).
  • Nested tables are simplified; a table inside a table cell will not round-trip.
  • Raw HTML mode takes priority: if you pass html, no URL is fetched in that run. Pass baseUrl when you want relative links inside that HTML resolved to absolute ones.

FAQ

How do I convert a web page to Markdown for an LLM or RAG pipeline? Send {"url": "https://..."} and use the markdown field. It typically costs a fraction of the tokens the raw HTML would, and it keeps the headings, lists and tables that chunking relies on.

Can I pass HTML I already fetched or rendered myself? Yes, that is the html field, and it is the recommended path for JavaScript-heavy sites: render the page with your own browser or a browser actor, then send the DOM here. Add baseUrl so relative links resolve.

Does it keep code blocks and their language? Yes. <pre><code class="language-js"> becomes a fenced block tagged js. Common class conventions (language-, lang-, highlight-) are all recognized.

Are HTML tables converted to Markdown tables? Yes, as GFM pipe tables, with a header separator row and | characters inside cells escaped so the table does not break. Ragged rows are padded to the widest row.

How many pages can I convert in one run? Up to 200. Put them in urls; each is one record and one charge, and one bad URL does not stop the rest.

Do relative links break when I move the Markdown elsewhere? No. Links and image sources are resolved against the page's final URL (after redirects), so they come out absolute.

Why did a page come back with almost no Markdown? Almost always JavaScript rendering: the server HTML really was near-empty. Check length - if it is tiny for a page you know is long, render it first and pass html.

Use from code or AI agents

curl -s "https://api.apify.com/v2/acts/EliAI~html-to-markdown/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
-X POST -H 'Content-Type: application/json' \
-d '{"url":"https://github.com/apify/apify-sdk-js"}'

Agents: connect Apify MCP and call the EliAI/html-to-markdown tool.

  • Capability: convert a page URL, a bulk list of URLs, or a raw HTML string into GitHub-Flavored Markdown
  • Required input: url, urls, or html
  • Returns: one record per page; markdown and title are the payload
  • Bounded: 200 pages per run; failures isolate per page
  • Side effects: none beyond fetching the pages you named
  • Markdown to HTML (EliAI/markdown-to-html) - the inverse trip, with a table of contents and sanitized output.