markdown-to-html

Convert a Markdown file to a fully styled HTML document. The output is a complete, self-contained HTML page with embedded CSS, a responsive layout, and a built-in dark mode toggle -- ready to open in any browser.


Endpoint

POST /v1/convert/markdown-to-html

Content-Type: multipart/form-data

Accepted input: .md or .markdown files (UTF-8 encoded)

Output format: .html (text/html)


Authentication

Requires either a private API key or a JWT token from a public key.

X-API-Key: sk_live_your_private_key

Or:

Authorization: Bearer <jwt_token>

Request Parameters

Parameter Type Required Default Description
file file Yes -- The .md or .markdown file to convert. Must be UTF-8 encoded.
output_filename string No Input filename Custom output filename. The .html extension is added automatically.
direct_download boolean No true When true, returns the HTML document directly. When false, returns JSON metadata with a presigned download URL.

Conversion Rules

The converter uses Python-Markdown with the following extensions enabled:

Extension What It Does
tables Pipe-delimited Markdown tables rendered as HTML <table> elements
fenced_code Triple-backtick code blocks with language identifiers (```python)
codehilite Syntax highlighting CSS classes on code blocks (via Pygments)
toc Table of contents generation via a [TOC] marker in your document
attr_list Attach HTML attributes to elements using {.class #id} syntax

Example

Input:

# My Document

[TOC]

## Introduction

This is a **bold** and *italic* example.

## Data Table

| Name  | Age | City   |
|-------|-----|--------|
| Alice | 30  | London |
| Bob   | 25  | Paris  |

## Code Sample

```python
def hello():
    print("Hello, world!")
```

Output: A complete <!DOCTYPE html> document with:

  • The rendered Markdown inside a <body> with max-width 800px, centered layout
  • Styled tables, code blocks, links, and headings
  • A clickable table of contents generated from the headings
  • A dark mode toggle button (top-right corner) that persists the user's preference to localStorage

Output Styling

The generated HTML includes an embedded <style> block with:

  • Light and dark themes via CSS custom properties, toggled by a data-theme attribute
  • System font stack (-apple-system, BlinkMacSystemFont, Segoe UI, Arial, sans-serif)
  • Responsive layout with 800px max-width and centered content
  • Line height of 1.6 for readability
  • Styled elements: code blocks (with background), tables (with borders and striped rows), links, and block quotes
Note on syntax highlighting: The codehilite extension adds Pygments CSS class names to code blocks, but no Pygments stylesheet is bundled in the output. Code blocks will have correct structure and basic styling, but language-specific color highlighting requires adding a Pygments CSS theme to the page. The built-in styling provides background and font styling for all code blocks regardless.

Response

Direct Download (direct_download=true, default)

HTTP 200 OK
Content-Type: text/html
Content-Disposition: inline; filename="readme_20260405_123456789.html"

Returns the full HTML document. Since the Content-Disposition is inline, browsers will render the page directly.

Metadata Response (direct_download=false)

{
    "presigned_url": "https://spaces.example.com/...",
    "object_key": "env/files/{project_id}/markdown-to-html/readme_20260405_123456789.html",
    "filename": "readme_20260405_123456789.html",
    "file_size": 5678,
    "conversion_time_seconds": 0.04
}

Code Examples

Python

import requests

with open("README.md", "rb") as f:
    response = requests.post(
        "https://api.enconvert.com/v1/convert/markdown-to-html",
        headers={"X-API-Key": "sk_live_your_private_key"},
        files={"file": ("README.md", f, "text/markdown")}
    )

with open("README.html", "wb") as out:
    out.write(response.content)

Node.js

const form = new FormData();
form.append("file", fs.createReadStream("README.md"));

const response = await fetch("https://api.enconvert.com/v1/convert/markdown-to-html", {
    method: "POST",
    headers: { "X-API-Key": "sk_live_your_private_key" },
    body: form
});

const html = await response.text();
fs.writeFileSync("README.html", html);

PHP

$ch = curl_init("https://api.enconvert.com/v1/convert/markdown-to-html");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ["X-API-Key: sk_live_your_private_key"],
    CURLOPT_POSTFIELDS => ["file" => new CURLFile("README.md", "text/markdown")]
]);
$html = curl_exec($ch);
curl_close($ch);
file_put_contents("README.html", $html);

Go

body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
part, _ := writer.CreateFormFile("file", "README.md")
file, _ := os.Open("README.md")
io.Copy(part, file)
writer.Close()

req, _ := http.NewRequest("POST", "https://api.enconvert.com/v1/convert/markdown-to-html", body)
req.Header.Set("Content-Type", writer.FormDataContentType())
req.Header.Set("X-API-Key", "sk_live_your_private_key")
resp, _ := http.DefaultClient.Do(req)

JavaScript -- Browser (Public Key)

const tokenRes = await fetch("https://api.enconvert.com/v1/auth/token", {
    method: "POST",
    headers: { "X-API-Key": "pk_live_your_public_key" }
});
const { token } = await tokenRes.json();

const form = new FormData();
form.append("file", fileInput.files[0]);

const response = await fetch("https://api.enconvert.com/v1/convert/markdown-to-html", {
    method: "POST",
    headers: { "Authorization": `Bearer ${token}` },
    body: form
});

const data = await response.json();
window.open(data.presigned_url, "_blank");

Error Responses

Status Condition
400 Bad Request File is not a .md or .markdown file
400 Bad Request Invalid Markdown encoding (expected UTF-8)
400 Bad Request Markdown to HTML conversion failed
401 Unauthorized Missing or invalid API key / JWT token
402 Payment Required Monthly conversion limit reached
402 Payment Required Storage limit reached
413 Payload Too Large File exceeds plan's maximum file size

Limits

Limit Value
Max file size Plan-dependent (Free: 5 MB)
Input encoding UTF-8 only
Accepted extensions .md, .markdown
Monthly conversions Plan-dependent