Convert Markdown
Convert Mathpix Markdown (MMD) text to other formats like DOCX, LaTeX, HTML, PDF, and PPTX.
Submit a conversion
- mpxpy
- cURL
- Python
- TypeScript
- Go
- Java
from mpxpy.mathpix_client import MathpixClient
client = MathpixClient(app_id="APP_ID", app_key="APP_KEY")
conversion = client.conversion_new(
mmd="_full mmd text_",
convert_to_docx=True,
convert_to_tex_zip=True,
)
print(conversion.conversion_id)
curl -X POST https://api.mathpix.com/v3/converter \
-H 'app_id: APP_ID' \
-H 'app_key: APP_KEY' \
-H 'Content-Type: application/json' \
--data '{"mmd": "_full mmd text_", "formats": {"docx": true, "tex.zip": true}}'
import requests, json
r = requests.post("https://api.mathpix.com/v3/converter",
json={
"mmd": "_full mmd text_",
"formats": {"docx": True, "tex.zip": True}
},
headers={
"app_id": "APP_ID",
"app_key": "APP_KEY",
"Content-type": "application/json"
}
)
print(r.json()) # {"conversion_id": "..."}
const response = await fetch("https://api.mathpix.com/v3/converter", {
method: "POST",
headers: {
app_id: "APP_ID",
app_key: "APP_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
mmd: "_full mmd text_",
formats: { docx: true, "tex.zip": true },
}),
});
const { conversion_id } = await response.json();
console.log(`Conversion ID: ${conversion_id}`);
body := bytes.NewBufferString(`{
"mmd": "_full mmd text_",
"formats": {"docx": true, "tex.zip": true}
}`)
req, _ := http.NewRequest("POST", "https://api.mathpix.com/v3/converter", body)
req.Header.Set("app_id", "APP_ID")
req.Header.Set("app_key", "APP_KEY")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
result, _ := io.ReadAll(resp.Body)
fmt.Println(string(result)) // {"conversion_id": "..."}
HttpClient client = HttpClient.newHttpClient();
String body = """
{
"mmd": "_full mmd text_",
"formats": { "docx": true, "tex.zip": true }
}
""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.mathpix.com/v3/converter"))
.header("app_id", "APP_ID")
.header("app_key", "APP_KEY")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
With conversion options
Customize output with format-specific options:
{
"mmd": "_full mmd text_",
"formats": {"docx": true, "pdf": true},
"conversion_options": {
"docx": {
"font": "Times New Roman",
"fontSize": "28",
"orientation": "portrait"
},
"pdf": {
"fontSize": "14",
"text_color": "black",
"margin": "40"
}
}
}
See Conversion Options for all format-specific settings.
Poll conversion status
- mpxpy
- cURL
- Python
- TypeScript
- Go
- Java
# wait_until_complete handles polling automatically
conversion.wait_until_complete(timeout=30)
print(conversion.conversion_status())
curl https://api.mathpix.com/v3/converter/CONVERSION_ID \
-H 'app_id: APP_ID' \
-H 'app_key: APP_KEY'
import requests, time
headers = {"app_id": "APP_ID", "app_key": "APP_KEY"}
conversion_id = "CONVERSION_ID"
while True:
r = requests.get(f"https://api.mathpix.com/v3/converter/{conversion_id}", headers=headers)
status = r.json()
print(status)
all_done = all(
v["status"] == "completed"
for v in status.get("conversion_status", {}).values()
)
if all_done:
break
time.sleep(3)
const headers = { app_id: "APP_ID", app_key: "APP_KEY" };
const conversionId = "CONVERSION_ID";
while (true) {
const response = await fetch(`https://api.mathpix.com/v3/converter/${conversionId}`, { headers });
const status = await response.json();
console.log(status);
const allDone = Object.values(status.conversion_status ?? {})
.every((v: any) => v.status === "completed");
if (allDone) break;
await new Promise((r) => setTimeout(r, 3000));
}
conversionId := "CONVERSION_ID"
delay := 3 * time.Second
for i := 0; i < 60; i++ { // timeout after ~5 minutes
req, _ := http.NewRequest("GET", "https://api.mathpix.com/v3/converter/"+conversionId, nil)
req.Header.Set("app_id", "APP_ID")
req.Header.Set("app_key", "APP_KEY")
resp, _ := http.DefaultClient.Do(req)
result, _ := io.ReadAll(resp.Body)
resp.Body.Close()
fmt.Println(string(result))
if bytes.Contains(result, []byte(`"completed"`)) {
break
}
time.Sleep(delay)
if delay < 15*time.Second {
delay = delay * 3 / 2 // backoff up to 15s
}
}
HttpClient client = HttpClient.newHttpClient();
String conversionId = "CONVERSION_ID";
while (true) {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.mathpix.com/v3/converter/" + conversionId))
.header("app_id", "APP_ID").header("app_key", "APP_KEY").GET().build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
if (response.body().contains("\"completed\"")) break;
Thread.sleep(3000);
}
Response while processing:
{
"status": "completed",
"conversion_status": {
"docx": { "status": "processing" },
"tex.zip": { "status": "processing" }
}
}
Response when all formats are ready:
{
"status": "completed",
"conversion_status": {
"docx": { "status": "completed" },
"tex.zip": { "status": "completed" }
}
}
Download results
Once a format's status is "completed", download by appending the extension to the conversion ID:
- mpxpy
- cURL
- Python
- TypeScript
- Go
- Java
# Save to files
conversion.to_docx_file(path="result.docx")
conversion.to_tex_zip_file(path="result.tex.zip")
conversion.to_html_file(path="result.html")
# Or get content in memory
docx_bytes = conversion.to_docx_bytes() # bytes
md_text = conversion.to_md_text() # str
# Download DOCX
curl https://api.mathpix.com/v3/converter/CONVERSION_ID.docx \
-H 'app_id: APP_ID' \
-H 'app_key: APP_KEY' > result.docx
# Download LaTeX zip
curl https://api.mathpix.com/v3/converter/CONVERSION_ID.tex.zip \
-H 'app_id: APP_ID' \
-H 'app_key: APP_KEY' > result.tex.zip
# Download HTML
curl https://api.mathpix.com/v3/converter/CONVERSION_ID.html \
-H 'app_id: APP_ID' \
-H 'app_key: APP_KEY' > result.html
import requests
headers = {"app_id": "APP_ID", "app_key": "APP_KEY"}
conversion_id = "CONVERSION_ID"
# Download DOCX
r = requests.get(f"https://api.mathpix.com/v3/converter/{conversion_id}.docx", headers=headers)
with open("result.docx", "wb") as f:
f.write(r.content)
# Download LaTeX zip
r = requests.get(f"https://api.mathpix.com/v3/converter/{conversion_id}.tex.zip", headers=headers)
with open("result.tex.zip", "wb") as f:
f.write(r.content)
# Download HTML
r = requests.get(f"https://api.mathpix.com/v3/converter/{conversion_id}.html", headers=headers)
with open("result.html", "wb") as f:
f.write(r.content)
import fs from "fs";
const headers = { app_id: "APP_ID", app_key: "APP_KEY" };
const conversionId = "CONVERSION_ID";
// Download DOCX
const docx = await fetch(`https://api.mathpix.com/v3/converter/${conversionId}.docx`, { headers });
fs.writeFileSync("result.docx", Buffer.from(await docx.arrayBuffer()));
// Download LaTeX zip
const tex = await fetch(`https://api.mathpix.com/v3/converter/${conversionId}.tex.zip`, { headers });
fs.writeFileSync("result.tex.zip", Buffer.from(await tex.arrayBuffer()));
// Download HTML
const html = await fetch(`https://api.mathpix.com/v3/converter/${conversionId}.html`, { headers });
fs.writeFileSync("result.html", Buffer.from(await html.arrayBuffer()));
conversionId := "CONVERSION_ID"
for _, ext := range []string{"docx", "tex.zip", "html"} {
req, _ := http.NewRequest("GET", "https://api.mathpix.com/v3/converter/"+conversionId+"."+ext, nil)
req.Header.Set("app_id", "APP_ID")
req.Header.Set("app_key", "APP_KEY")
resp, _ := http.DefaultClient.Do(req)
data, _ := io.ReadAll(resp.Body)
resp.Body.Close()
os.WriteFile("result."+ext, data, 0644)
}
HttpClient client = HttpClient.newHttpClient();
String conversionId = "CONVERSION_ID";
for (String ext : List.of("docx", "tex.zip", "html")) {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.mathpix.com/v3/converter/" + conversionId + "." + ext))
.header("app_id", "APP_ID").header("app_key", "APP_KEY").GET().build();
HttpResponse<byte[]> response = client.send(request, HttpResponse.BodyHandlers.ofByteArray());
Files.write(Path.of("result." + ext), response.body());
}
Available formats
md, docx, tex.zip, html, pdf, latex.pdf, pptx, mmd.zip, md.zip, html.zip
Workflow
- Submit MMD text with desired formats — returns a
conversion_id - Poll status with
GET /v3/converter/{conversion_id} - Download results by appending the format extension:
GET /v3/converter/{conversion_id}.docx,.tex.zip, etc.
Next steps
- POST v3/converter reference — Full request parameters, conversion options per format, and response schema
- Process a PDF — PDFs can also request conversion formats automatically