Call the free Markdown to HTML API endpoint
Post the Markdown under a data key:
curl -X POST https://aisenseapi.com/services/v1/markdown_to_html \
-H "Content-Type: application/json" \
-d '{"data": "# Report\n\n- **3** jobs done\n- [ ] one left\n\n| Job | Time |\n|---|--:|\n| sync | 2.1 s |"}'{"html":"<h1>Report</h1>\n<ul>\n<li><strong>3</strong> jobs done</li>\n<li><input type=\"checkbox\" disabled=\"\" /> one left</li>\n</ul>\n<table>\n<thead>\n<tr>\n<th>Job</th>\n<th style=\"text-align: right\">Time</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>sync</td>\n<td style=\"text-align: right\">2.1 s</td>\n</tr>\n</tbody>\n</table>"}The html value is a fragment, with no <html> or <body> around it:
<h1>Report</h1>
<ul>
<li><strong>3</strong> jobs done</li>
<li><input type="checkbox" disabled="" /> one left</li>
</ul>
<table>
<thead>
<tr>
<th>Job</th>
<th style="text-align: right">Time</th>
</tr>
</thead>
<tbody>
<tr>
<td>sync</td>
<td style="text-align: right">2.1 s</td>
</tr>
</tbody>
</table>To go the other way, use the HTML to Markdown API endpoint.
Safe to show
The HTML can go into a page as it is, even when the Markdown came from someone else. Raw HTML in the Markdown is shown as text, never passed through, and a link or image whose scheme is not on a short list is shown as its text:
curl -X POST https://aisenseapi.com/services/v1/markdown_to_html \
-H "Content-Type: application/json" \
-d '{"data": "<script>alert(1)</script> and [click](javascript:alert(1))"}'{"html":"<p><script>alert(1)</script> and click</p>"}| Allowed | Where |
|---|---|
http:, https: and relative URLs | links and images |
mailto:, tel:, ftp: | links |
| PNG, GIF, JPEG and WebP data URLs | images |
Anything else, javascript:, vbscript:, data:text/html and SVG data included, however it is spelled or escaped, becomes text. Attribute values are escaped, so a title or URL cannot add an attribute of its own.
What it reads
| Markdown | HTML |
|---|---|
# to ######, or a line underlined with === or --- | <h1> to <h6> |
*em*, **strong**, ~~struck~~, `code` | <em>, <strong>, <del>, <code>, by the CommonMark rules |
[text](url "title"), [text][ref], <https://...>, a bare www. or https:// link | <a href> |
 | <img> with its alt text |
-, *, +, 1., 1), - [ ] and - [x] | lists, tight or loose, with start numbers and checkboxes |
| a | b | over |:--|--:| | a table with its column alignment |
| fenced code with a language, indented code | <pre><code class="language-..."> |
>, ---, two spaces or a backslash at a line end | <blockquote>, <hr />, <br /> |
Markdown to PDF in one pipe
The HTML to PDF API endpoint takes the html as its data and stores the PDF for 24 hours:
curl -s -X POST https://aisenseapi.com/services/v1/markdown_to_html \
-H "Content-Type: text/markdown" --data-binary @report.md \
| jq '{data: .html}' \
| curl -s -X POST https://aisenseapi.com/services/v1/html2pdf \
-H "Content-Type: application/json" --data-binary @-The answer carries the storage_url of the PDF.
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/markdown. It has to be UTF-8.
Windows and old Mac line ends are read as line ends.
Errors
| Status | error | When |
|---|---|---|
| 400 | No Markdown to convert. | No data string and no body |
| 400 | The Markdown is not UTF-8 text. | Text in another encoding, sent as it is |
| 413 | Data over 256 KiB. | More than 256 KiB in one request |
| 413 | Too many Markdown lines. | More than 20000 lines in one request |
Each refusal also carries fix, a sentence saying what to send instead.
Common uses
Reports from agents
An agent writes Markdown, people read HTML: put its report in a page or an email as it comes back.
Text people wrote
Show comments and notes with their formatting, and without any HTML or script they slipped in.
Documents to PDF
Render a Markdown file here and hand the HTML to the HTML to PDF endpoint for a printable copy.
Privacy and limits
Nothing is stored. The Markdown to HTML 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 256 KiB of Markdown and 20000 lines. 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.