Call the free HTML to Markdown API endpoint
Post the HTML under a data key:
curl -X POST https://aisenseapi.com/services/v1/html_to_markdown \
-H "Content-Type: application/json" \
-d '{"data": "<title>Release notes</title><h1>Version 2</h1><p>Now with <b>tables</b> and <a href=\"https://aisense.no\">links</a>.</p><script>track()</script>"}'{"markdown":"# Version 2\n\nNow with **tables** and [links](https://aisense.no).","title":"Release notes"}title is the page title, or null when the HTML has none. The script is gone, and so would a style sheet, a form or an embedded video be. To go the other way, use the Markdown to HTML API endpoint.
A page fetched with curl can go straight in as the body:
curl -s https://aisense.no/free-public-apis | curl -X POST https://aisenseapi.com/services/v1/html_to_markdown \
-H "Content-Type: text/html" --data-binary @-What becomes what
| HTML | Markdown |
|---|---|
<h1> to <h6> | # to ###### |
<b>, <strong>, <i>, <em>, <s> | **bold**, *italic*, ~~struck~~ |
<a href>, <img> | [text](url) and , title kept |
<ul>, <ol start>, a checkbox first in an item | -, 3. and - [x], nested by indentation |
<table> | a GitHub table, or plain text when the table only lays out a page |
<pre>, <code> | a fenced code block with the language from a language- class, inline code in backticks |
<blockquote>, <br>, <hr> | >, a line break, --- |
<script>, <style>, the head, forms, <svg>, video, audio, comments | left out |
Text that would read as Markdown is escaped, so it reads back as the same text: 2 * 3 becomes 2 \* 3, and [a link] that is not one becomes \[a link\]. Links keep their URLs as written, relative ones included, and links with a javascript: or other unlisted scheme become their text. Images given as data URLs are left out, since their bytes are no use as text.
Sending the input
Send the text as {"data": "..."} with Content-Type: application/json, or as the raw request body with any other content type, such as text/html. It has to be UTF-8.
The HTML is read the way a browser forgives it: a <p> or <li> left open closes itself, a stray end tag is ignored, and nesting deeper than a hundred levels is flattened.
Errors
| Status | error | When |
|---|---|---|
| 400 | No HTML to convert. | No data string and no body |
| 400 | The HTML is not UTF-8 text. | A page in another encoding, sent as it is |
| 413 | Data over 1 MiB. | More than 1 MiB in one request |
| 413 | Too many HTML tags. | More than 40000 start and end tags outside scripts and styles |
Each refusal also carries fix, a sentence saying what to send instead.
Common uses
Agents reading pages
Fetch a page and hand an agent Markdown instead of HTML: the same text and links, without class names and scripts.
Context for a model
Headings, lists and tables survive as Markdown, which helps a language model find its way through a long page.
Archive and compare
Keep pages as Markdown and compare two versions as text, without the markup changing underneath.
Privacy and limits
Nothing is stored. The HTML to Markdown answer is worked out while the request is open and the data is gone with it. The access log records the path and the status, not the body.
The base URL is https://aisenseapi.com/services/v1. There is no key, no account and no sign-up step. One request carries at most 1 MiB of HTML and 40000 start and end tags. Scripts and styles are skipped whole, and tags inside them do not count. The service-wide limit is 5000 requests per IP address per day. Every endpoint in the collection is listed on the Free public REST APIs reference.