Turn Markdown into a clean, print-ready PDF or PNG. Tables, task lists and syntax highlighted code all render correctly — with thirteen typefaces, a full colour palette, and complete control over page size, orientation and margins.
Export AI answers, turn a README into a handout, build a resume or ship a status report — all from plain Markdown, with output that looks designed rather than generated.
CommonMark with the GitHub extensions: tables, task lists, strikethrough and autolinks.
Fenced code blocks are coloured on the server for more than thirty languages.
Thirteen typefaces, a light and dark theme, and every document colour under your control.
Code blocks and tables never split across pages, and table headers repeat on every page.
Devanagari, Chinese, Japanese, Korean, Arabic, Hebrew, Thai, Cyrillic and Greek render with no configuration.
Take a paginated PDF, or one tall image of the whole document at up to 300 DPI.
Start free and move up when you need more. Every plan renders with the same engine — higher tiers unlock larger documents, more output formats and full styling control.
Everything you need to integrate the Markdown to PDF API
Every request needs your API key in the x-api-key header. Keys are created in the dashboard and belong to your account rather than to a single API.
x-api-key: your_api_keyhttps://api.corenexis.com/markdown-to-pdf/v1One synchronous endpoint. Send the Markdown and the finished document comes back in the same response — there is no job to poll.
The Markdown can arrive in any of these forms. Use whichever suits your environment.
curl -X POST "https://api.corenexis.com/markdown-to-pdf/v1" \
-H "x-api-key: your_api_key" \
-H "Content-Type: application/json" \
-d '{"markdown": "# Invoice\n\nThank you for your business.", "page_size": "a4"}'curl -X POST "https://api.corenexis.com/markdown-to-pdf/v1" \
-H "x-api-key: your_api_key" \
-F "markdown=# Hello" \
-F "page_size=letter"curl -X POST "https://api.corenexis.com/markdown-to-pdf/v1" \
-H "x-api-key: your_api_key" \
-F "[email protected]"curl -X POST "https://api.corenexis.com/markdown-to-pdf/v1" \
-H "x-api-key: your_api_key" \
-H "Content-Type: text/markdown" \
--data-binary @report.md| Parameter | Type | Description |
|---|---|---|
| x-api-keyRequired | String | Your API key. Send in the request header. |
| markdownRequired | String | The Markdown to render. May also be sent as an uploaded file or as the raw request body. |
| formatOptional | String | pdf or png. PNG requires a paid plan.Default: pdf |
| outputOptional | String | Only url. Every result is delivered as a hosted link, on every plan, so this can be omitted. base64 and binary were withdrawn and now return a clear error.Default: url |
| page_sizeOptional | String | a3, a4, a5, letter, legal or tabloid.Default: a4 |
| orientationOptional | String | portrait or landscape.Default: portrait |
| margin_topOptional | Number | Top margin in millimetres, 0 to 100. Default: 20 |
| margin_rightOptional | Number | Right margin in millimetres, 0 to 100. Default: 15 |
| margin_bottomOptional | Number | Bottom margin in millimetres, 0 to 100. Default: 20 |
| margin_leftOptional | Number | Left margin in millimetres, 0 to 100. Default: 15 |
| fontOptional | String | Body typeface, from the list below. Paid plans only. Default: roboto |
| mono_fontOptional | String | Typeface for code. Paid plans only. Default: jetbrainsmono |
| font_sizeOptional | Number | Base size in points, 7 to 18. Paid plans only. Default: 11 |
| themeOptional | String | light or dark. Paid plans only.Default: light |
| colorsOptional | Object | Colour overrides as hex values. Paid plans only. |
| header_textOptional | String | Running header text. Paid plans only. |
| footer_textOptional | String | Running footer. Use {PAGENO} and {nb} for page numbers. Paid plans only. |
| png_modeOptional | String | stack returns the whole document as an ordered sequence of images, first takes page one, page takes a chosen page.Default: stack |
| png_pageOptional | Number | Which page to capture when png_mode is page. Any page the document has.Default: 1 |
| png_dpiOptional | Number | Resolution for PNG output, 72 to 300. Default: 144 |
| filenameOptional | String | Name for the produced file, without extension. Default: document |
Pass a key from this list as font for body text, or as mono_font for code. Font selection is a paid feature; the free plan renders in the defaults.
| Group | Available keys |
|---|---|
| Sans | roboto (default), opensans, lato, montserrat, nunito, ibmplexsans |
| Serif | ibmplexserif, liberationserif |
| Monospace | jetbrainsmono (default), ibmplexmono, firacode |
| Devanagari | lohitdevanagari |
Send a colors object to restyle the document. Every value must be a hex colour such as #2563eb; anything else is rejected. Available on paid plans.
{
"markdown": "# Report",
"theme": "light",
"colors": {
"text": "#1f2937",
"heading": "#111827",
"link": "#2563eb",
"accent": "#2563eb",
"code_text": "#111827",
"code_bg": "#f3f4f6",
"border": "#e5e7eb",
"quote": "#4b5563",
"background": "#ffffff",
"table_header_bg": "#f9fafb"
}
}Set theme to dark for a dark document, then override individual colours on top if you want.
CommonMark plus the GitHub extensions: tables, task lists, strikethrough and autolinks. Fenced code blocks are syntax highlighted on the server for more than thirty languages, so the colours survive into the PDF.
Every result is stored and handed back as a hosted link under data.url, on every plan including the free one. There is nothing to decode and nothing to stream.
| Plan | Link valid for | Why |
|---|---|---|
| Free | 2 hours | Long enough to fetch and use the file in the workflow that produced it. |
| Any paid plan | 7 days | Long enough to email, queue or hand on to another service. |
Inline delivery was withdrawn. A caller still sending the old value gets an error that says so rather than a silent change of behaviour.
| output | Status | Notes |
|---|---|---|
base64 | Withdrawn | The file inside the JSON response. It inflated every result by a third and had to be held in memory twice. |
binary | Withdrawn | The raw file as the response body. It could not carry a document that had become several images. |
url | The only mode | A hosted link under data.url. This is now the default, so the parameter can be omitted. |
Set format to png to receive page images instead of a PDF. PNG output is a paid feature.
A document is usually taller than one image can be: the compositor refuses any dimension above 32,000 pixels, which at the default resolution is seventeen A4 pages. So png_mode=stack returns an ordered sequence of images in data.images, each covering a page range, and data.image.truncated tells you whether the sequence covers the whole document.
| png_mode | What you get | When to use it |
|---|---|---|
stack | The whole document as an ordered sequence of images. | Default. Reading or displaying every page. |
first | One image of page one. | Thumbnails and previews. |
page | One image of the page named by png_page. | Pulling a single page out of a long document. |
image.pages_per_image.import requests
resp = requests.post(
"https://api.corenexis.com/markdown-to-pdf/v1",
headers={"x-api-key": "your_api_key"},
json={
"markdown": open("report.md").read(),
"page_size": "a4",
"font": "montserrat",
"colors": {"accent": "#2563eb"},
"footer_text": "Page {PAGENO} of {nb}",
},
timeout=120,
)
data = resp.json()
if not data["success"]:
raise SystemExit(data["message"])
# The result is a hosted link. Fetch it once and keep the file; the link expires.
pdf = requests.get(data["data"]["url"], timeout=120)
with open("report.pdf", "wb") as fh:
fh.write(pdf.content)const fs = require("fs");
const res = await fetch("https://api.corenexis.com/markdown-to-pdf/v1", {
method: "POST",
headers: { "x-api-key": "your_api_key", "Content-Type": "application/json" },
body: JSON.stringify({
markdown: fs.readFileSync("report.md", "utf8"),
format: "pdf",
output: "url",
}),
});
const data = await res.json();
if (!data.success) throw new Error(data.message);
console.log(data.data.url, "expires", data.data.expires_at);<?php
$ch = curl_init('https://api.corenexis.com/markdown-to-pdf/v1');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'x-api-key: your_api_key',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'markdown' => file_get_contents('report.md'),
'page_size' => 'a4',
]),
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
if (empty($response['success'])) {
exit($response['message'] ?? 'request failed');
}
// The result is a hosted link. Fetch it once and keep the file; the link expires.
file_put_contents('report.pdf', file_get_contents($response['data']['url']));urllib sends a default agent string our edge network refuses. The requests library, Node, Go, Java and cURL all work unchanged.{
"success": true,
"plan": "pro",
"data": {
"status": "completed",
"format": "pdf",
"mime": "application/pdf",
"pages": 1,
"page_size": "a4",
"orientation": "portrait",
"font": "roboto",
"mono_font": "jetbrainsmono",
"theme": "light",
"source_images": {
"embedded": 0, "skipped": 0, "bytes": 0, "budget_reached": false
},
"render_time_ms": 324,
"url": "https://cdn.corenexis.com/f/35at4d5YCjQ.pdf",
"filename": "document.pdf",
"size_bytes": 21168,
"expires_at": "2026-08-16T06:10:13+00:00"
},
"usage": { "remaining": 4998, "rate_limit": 30, "monthly_limit": 5000 }
}Always check the success field rather than the status code alone. On failure the body carries a code and a message naming what to change.
Every option below was sent to the live API and the response shown is what came back, including the request that produced it. Copy a command, put your own key in it, and you get the same shape of answer.
Only the document is required. Everything else has a default: A4 portrait, 11 pt Roboto, light theme.
curl -X POST "https://api.corenexis.com/markdown-to-pdf/v1" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"markdown": "# Quarterly Report\n\nRevenue held steady while costs fell.\n\n| Region | Revenue | Change |\n|---|---|---|\n| North | 48,200 | +4% |\n| South | 31,700 | -2% |\n\n- [x] Figures verified\n- [ ] Board review\n\n```python\ndef margin(revenue, cost):\n return (revenue - cost) / revenue\n```\n"
}'{
"success": true,
"plan": "basic",
"data": {
"status": "completed",
"format": "pdf",
"mime": "application/pdf",
"pages": 1,
"page_size": "a4",
"orientation": "portrait",
"font": "roboto",
"mono_font": "jetbrainsmono",
"theme": "light",
"source_images": {
"embedded": 0,
"skipped": 0,
"bytes": 0,
"budget_reached": false
},
"render_time_ms": 631,
"url": "https://cdn.corenexis.com/f/oxeBmDm6eJL.pdf",
"filename": "document.pdf",
"size_bytes": 50395,
"expires_at": "2026-08-09T06:57:05+00:00"
},
"usage": {
"remaining": 4977,
"rate_limit": 120,
"monthly_limit": 5000
}
}One of a3, a4, a5, letter, legal or tabloid. The response echoes it back, and the produced file really is that size.
curl -X POST "https://api.corenexis.com/markdown-to-pdf/v1" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"markdown": "# Quarterly Report\n\nRevenue held steady while costs fell.\n\n| Region | Revenue | Change |\n|---|---|---|\n| North | 48,200 | +4% |\n| South | 31,700 | -2% |\n\n- [x] Figures verified\n- [ ] Board review\n\n```python\ndef margin(revenue, cost):\n return (revenue - cost) / revenue\n```\n",
"page_size": "a5"
}'{
"success": true,
"plan": "basic",
"data": {
"status": "completed",
"format": "pdf",
"mime": "application/pdf",
"pages": 1,
"page_size": "a5",
"orientation": "portrait",
"font": "roboto",
"mono_font": "jetbrainsmono",
"theme": "light",
"source_images": {
"embedded": 0,
"skipped": 0,
"bytes": 0,
"budget_reached": false
},
"render_time_ms": 194,
"url": "https://cdn.corenexis.com/f/YjzZHeTWCQU.pdf",
"filename": "document.pdf",
"size_bytes": 50393,
"expires_at": "2026-08-09T06:57:06+00:00"
},
"usage": {
"remaining": 4976,
"rate_limit": 120,
"monthly_limit": 5000
}
}Swaps the page width and height. Combines with any page size.
curl -X POST "https://api.corenexis.com/markdown-to-pdf/v1" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"markdown": "# Quarterly Report\n\nRevenue held steady while costs fell.\n\n| Region | Revenue | Change |\n|---|---|---|\n| North | 48,200 | +4% |\n| South | 31,700 | -2% |\n\n- [x] Figures verified\n- [ ] Board review\n\n```python\ndef margin(revenue, cost):\n return (revenue - cost) / revenue\n```\n",
"orientation": "landscape"
}'{
"success": true,
"plan": "basic",
"data": {
"status": "completed",
"format": "pdf",
"mime": "application/pdf",
"pages": 1,
"page_size": "a4",
"orientation": "landscape",
"font": "roboto",
"mono_font": "jetbrainsmono",
"theme": "light",
"source_images": {
"embedded": 0,
"skipped": 0,
"bytes": 0,
"budget_reached": false
},
"render_time_ms": 164,
"url": "https://cdn.corenexis.com/f/sdCMl1hlrdl.pdf",
"filename": "document.pdf",
"size_bytes": 50394,
"expires_at": "2026-08-09T06:57:06+00:00"
},
"usage": {
"remaining": 4975,
"rate_limit": 120,
"monthly_limit": 5000
}
}Millimetres, 0 to 100 each. Set them independently; a value outside the range is refused before the document is rendered.
curl -X POST "https://api.corenexis.com/markdown-to-pdf/v1" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"markdown": "# Quarterly Report\n\nRevenue held steady while costs fell.\n\n| Region | Revenue | Change |\n|---|---|---|\n| North | 48,200 | +4% |\n| South | 31,700 | -2% |\n\n- [x] Figures verified\n- [ ] Board review\n\n```python\ndef margin(revenue, cost):\n return (revenue - cost) / revenue\n```\n",
"margin_top": 30,
"margin_right": 25,
"margin_bottom": 30,
"margin_left": 25
}'{
"success": true,
"plan": "basic",
"data": {
"status": "completed",
"format": "pdf",
"mime": "application/pdf",
"pages": 1,
"page_size": "a4",
"orientation": "portrait",
"font": "roboto",
"mono_font": "jetbrainsmono",
"theme": "light",
"source_images": {
"embedded": 0,
"skipped": 0,
"bytes": 0,
"budget_reached": false
},
"render_time_ms": 139,
"url": "https://cdn.corenexis.com/f/if0faXFgh7A.pdf",
"filename": "document.pdf",
"size_bytes": 50394,
"expires_at": "2026-08-09T06:57:06+00:00"
},
"usage": {
"remaining": 4974,
"rate_limit": 120,
"monthly_limit": 5000
}
}Points, 7 to 18. Headings scale with it, so the document stays proportioned rather than merely larger.
curl -X POST "https://api.corenexis.com/markdown-to-pdf/v1" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"markdown": "# Quarterly Report\n\nRevenue held steady while costs fell.\n\n| Region | Revenue | Change |\n|---|---|---|\n| North | 48,200 | +4% |\n| South | 31,700 | -2% |\n\n- [x] Figures verified\n- [ ] Board review\n\n```python\ndef margin(revenue, cost):\n return (revenue - cost) / revenue\n```\n",
"font_size": 13
}'{
"success": true,
"plan": "basic",
"data": {
"status": "completed",
"format": "pdf",
"mime": "application/pdf",
"pages": 1,
"page_size": "a4",
"orientation": "portrait",
"font": "roboto",
"mono_font": "jetbrainsmono",
"theme": "light",
"source_images": {
"embedded": 0,
"skipped": 0,
"bytes": 0,
"budget_reached": false
},
"render_time_ms": 128,
"url": "https://cdn.corenexis.com/f/dLV7w0Belpx.pdf",
"filename": "document.pdf",
"size_bytes": 50396,
"expires_at": "2026-08-09T06:57:06+00:00"
},
"usage": {
"remaining": 4973,
"rate_limit": 120,
"monthly_limit": 5000
}
}Any pair from the font tables above. Requesting a font is a paid feature.
curl -X POST "https://api.corenexis.com/markdown-to-pdf/v1" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"markdown": "# Quarterly Report\n\nRevenue held steady while costs fell.\n\n| Region | Revenue | Change |\n|---|---|---|\n| North | 48,200 | +4% |\n| South | 31,700 | -2% |\n\n- [x] Figures verified\n- [ ] Board review\n\n```python\ndef margin(revenue, cost):\n return (revenue - cost) / revenue\n```\n",
"font": "opensans",
"mono_font": "firacode"
}'{
"success": true,
"plan": "basic",
"data": {
"status": "completed",
"format": "pdf",
"mime": "application/pdf",
"pages": 1,
"page_size": "a4",
"orientation": "portrait",
"font": "opensans",
"mono_font": "firacode",
"theme": "light",
"source_images": {
"embedded": 0,
"skipped": 0,
"bytes": 0,
"budget_reached": false
},
"render_time_ms": 923,
"url": "https://cdn.corenexis.com/f/uEMhTrGlhmI.pdf",
"filename": "document.pdf",
"size_bytes": 63127,
"expires_at": "2026-08-09T06:57:07+00:00"
},
"usage": {
"remaining": 4972,
"rate_limit": 120,
"monthly_limit": 5000
}
}Repaints the page background as well as the text, so the margins are dark too rather than leaving a white border.
curl -X POST "https://api.corenexis.com/markdown-to-pdf/v1" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"markdown": "# Quarterly Report\n\nRevenue held steady while costs fell.\n\n| Region | Revenue | Change |\n|---|---|---|\n| North | 48,200 | +4% |\n| South | 31,700 | -2% |\n\n- [x] Figures verified\n- [ ] Board review\n\n```python\ndef margin(revenue, cost):\n return (revenue - cost) / revenue\n```\n",
"theme": "dark"
}'{
"success": true,
"plan": "basic",
"data": {
"status": "completed",
"format": "pdf",
"mime": "application/pdf",
"pages": 1,
"page_size": "a4",
"orientation": "portrait",
"font": "roboto",
"mono_font": "jetbrainsmono",
"theme": "dark",
"source_images": {
"embedded": 0,
"skipped": 0,
"bytes": 0,
"budget_reached": false
},
"render_time_ms": 136,
"url": "https://cdn.corenexis.com/f/qHKtneUhaVI.pdf",
"filename": "document.pdf",
"size_bytes": 50402,
"expires_at": "2026-08-09T06:57:07+00:00"
},
"usage": {
"remaining": 4971,
"rate_limit": 120,
"monthly_limit": 5000
}
}Any subset of the palette keys. Only #rgb and #rrggbb are accepted; an unknown key or a malformed colour is reported rather than ignored.
curl -X POST "https://api.corenexis.com/markdown-to-pdf/v1" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"markdown": "# Quarterly Report\n\nRevenue held steady while costs fell.\n\n| Region | Revenue | Change |\n|---|---|---|\n| North | 48,200 | +4% |\n| South | 31,700 | -2% |\n\n- [x] Figures verified\n- [ ] Board review\n\n```python\ndef margin(revenue, cost):\n return (revenue - cost) / revenue\n```\n",
"colors": {
"accent": "#7c3aed",
"link": "#7c3aed",
"heading": "#111827",
"code_bg": "#f5f3ff"
}
}'{
"success": true,
"plan": "basic",
"data": {
"status": "completed",
"format": "pdf",
"mime": "application/pdf",
"pages": 1,
"page_size": "a4",
"orientation": "portrait",
"font": "roboto",
"mono_font": "jetbrainsmono",
"theme": "light",
"source_images": {
"embedded": 0,
"skipped": 0,
"bytes": 0,
"budget_reached": false
},
"render_time_ms": 169,
"url": "https://cdn.corenexis.com/f/Zpdm4jN9OOU.pdf",
"filename": "document.pdf",
"size_bytes": 50389,
"expires_at": "2026-08-09T06:57:08+00:00"
},
"usage": {
"remaining": 4970,
"rate_limit": 120,
"monthly_limit": 5000
}
}{PAGENO} and {nb} are substituted per page. Verified across chunk boundaries on documents of several hundred pages.
curl -X POST "https://api.corenexis.com/markdown-to-pdf/v1" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"markdown": "...long document...",
"header_text": "Quarterly Report — Confidential",
"footer_text": "Page {PAGENO} of {nb}"
}'{
"success": true,
"plan": "basic",
"data": {
"status": "completed",
"format": "pdf",
"mime": "application/pdf",
"pages": 37,
"page_size": "a4",
"orientation": "portrait",
"font": "roboto",
"mono_font": "jetbrainsmono",
"theme": "light",
"source_images": {
"embedded": 0,
"skipped": 0,
"bytes": 0,
"budget_reached": false
},
"render_time_ms": 1055,
"url": "https://cdn.corenexis.com/f/RyZN0BtksWp.pdf",
"filename": "document.pdf",
"size_bytes": 86316,
"expires_at": "2026-08-09T06:57:09+00:00"
},
"usage": {
"remaining": 4969,
"rate_limit": 120,
"monthly_limit": 5000
}
}Sets the stored filename. Letters, digits, dot, dash and underscore, up to 80 characters; the extension is added.
curl -X POST "https://api.corenexis.com/markdown-to-pdf/v1" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"markdown": "# Quarterly Report\n\nRevenue held steady while costs fell.\n\n| Region | Revenue | Change |\n|---|---|---|\n| North | 48,200 | +4% |\n| South | 31,700 | -2% |\n\n- [x] Figures verified\n- [ ] Board review\n\n```python\ndef margin(revenue, cost):\n return (revenue - cost) / revenue\n```\n",
"filename": "invoice-2026-0184"
}'{
"success": true,
"plan": "basic",
"data": {
"status": "completed",
"format": "pdf",
"mime": "application/pdf",
"pages": 1,
"page_size": "a4",
"orientation": "portrait",
"font": "roboto",
"mono_font": "jetbrainsmono",
"theme": "light",
"source_images": {
"embedded": 0,
"skipped": 0,
"bytes": 0,
"budget_reached": false
},
"render_time_ms": 308,
"url": "https://cdn.corenexis.com/f/cJYU2qcqOAN.pdf",
"filename": "invoice-2026-0184.pdf",
"size_bytes": 50413,
"expires_at": "2026-08-09T06:57:09+00:00"
},
"usage": {
"remaining": 4968,
"rate_limit": 120,
"monthly_limit": 5000
}
}A document too tall for one image comes back as an ordered sequence. Each image holds as many pages as the compositor allows, and truncated tells you whether the set is complete.
curl -X POST "https://api.corenexis.com/markdown-to-pdf/v1" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"markdown": "...long document...",
"format": "png"
}'{
"success": true,
"plan": "basic",
"data": {
"status": "completed",
"format": "png",
"mime": "image/png",
"pages": 37,
"page_size": "a4",
"orientation": "portrait",
"font": "roboto",
"mono_font": "jetbrainsmono",
"theme": "light",
"source_images": {
"embedded": 0,
"skipped": 0,
"bytes": 0,
"budget_reached": false
},
"render_time_ms": 22574,
"url": "https://cdn.corenexis.com/f/ljTe16hzNpA.png",
"filename": "document-p1-17.png",
"size_bytes": 1368378,
"expires_at": "2026-08-09T06:57:32+00:00",
"image": {
"dpi": 144,
"pages_total": 37,
"pages_rendered": 37,
"pages_per_image": 17,
"truncated": false
},
"image_count": 3,
"total_bytes": 2945732,
"images": [
{
"url": "https://cdn.corenexis.com/f/ljTe16hzNpA.png",
"filename": "document-p1-17.png",
"size_bytes": 1368378,
"expires_at": "2026-08-09T06:57:32+00:00",
"page_from": 1,
"page_to": 17,
"width": 1191,
"height": 28628
},
{
"url": "https://cdn.corenexis.com/f/5FtJndj9BX7.png",
"filename": "document-p18-34.png",
"size_bytes": 1387052,
"expires_at": "2026-08-09T06:57:32+00:00",
"page_from": 18,
"page_to": 34,
"width": 1191,
"height": 28628
},
"... 1 more, one per page range, in order"
]
},
"usage": {
"remaining": 4967,
"rate_limit": 120,
"monthly_limit": 5000
}
}One image of page one. Useful for a thumbnail.
curl -X POST "https://api.corenexis.com/markdown-to-pdf/v1" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"markdown": "...long document...",
"format": "png",
"png_mode": "first"
}'{
"success": true,
"plan": "basic",
"data": {
"status": "completed",
"format": "png",
"mime": "image/png",
"pages": 37,
"page_size": "a4",
"orientation": "portrait",
"font": "roboto",
"mono_font": "jetbrainsmono",
"theme": "light",
"source_images": {
"embedded": 0,
"skipped": 0,
"bytes": 0,
"budget_reached": false
},
"render_time_ms": 2665,
"url": "https://cdn.corenexis.com/f/dBsZESv6l3a.png",
"filename": "document.png",
"size_bytes": 148265,
"expires_at": "2026-08-09T06:57:35+00:00",
"image": {
"dpi": 144,
"pages_total": 37,
"pages_rendered": 1,
"pages_per_image": 17,
"truncated": false
},
"image_count": 1,
"total_bytes": 148265,
"images": [
{
"url": "https://cdn.corenexis.com/f/dBsZESv6l3a.png",
"filename": "document.png",
"size_bytes": 148265,
"expires_at": "2026-08-09T06:57:35+00:00",
"page_from": 1,
"page_to": 1,
"width": 1191,
"height": 1684
}
]
},
"usage": {
"remaining": 4966,
"rate_limit": 120,
"monthly_limit": 5000
}
}Any page the document has. Asking beyond the end reports the real count.
curl -X POST "https://api.corenexis.com/markdown-to-pdf/v1" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"markdown": "...long document...",
"format": "png",
"png_mode": "page",
"png_page": 12
}'{
"success": true,
"plan": "basic",
"data": {
"status": "completed",
"format": "png",
"mime": "image/png",
"pages": 37,
"page_size": "a4",
"orientation": "portrait",
"font": "roboto",
"mono_font": "jetbrainsmono",
"theme": "light",
"source_images": {
"embedded": 0,
"skipped": 0,
"bytes": 0,
"budget_reached": false
},
"render_time_ms": 1109,
"url": "https://cdn.corenexis.com/f/7qc2gnVdmPw.png",
"filename": "document.png",
"size_bytes": 151355,
"expires_at": "2026-08-09T06:57:36+00:00",
"image": {
"dpi": 144,
"pages_total": 37,
"pages_rendered": 1,
"pages_per_image": 17,
"truncated": false
},
"image_count": 1,
"total_bytes": 151355,
"images": [
{
"url": "https://cdn.corenexis.com/f/7qc2gnVdmPw.png",
"filename": "document.png",
"size_bytes": 151355,
"expires_at": "2026-08-09T06:57:36+00:00",
"page_from": 12,
"page_to": 12,
"width": 1191,
"height": 1684
}
]
},
"usage": {
"remaining": 4965,
"rate_limit": 120,
"monthly_limit": 5000
}
}72 to 300 dpi. Higher resolution means fewer pages fit in one image, because the compositor's height limit is fixed.
curl -X POST "https://api.corenexis.com/markdown-to-pdf/v1" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"markdown": "# Quarterly Report\n\nRevenue held steady while costs fell.\n\n| Region | Revenue | Change |\n|---|---|---|\n| North | 48,200 | +4% |\n| South | 31,700 | -2% |\n\n- [x] Figures verified\n- [ ] Board review\n\n```python\ndef margin(revenue, cost):\n return (revenue - cost) / revenue\n```\n",
"format": "png",
"png_dpi": 300
}'{
"success": true,
"plan": "basic",
"data": {
"status": "completed",
"format": "png",
"mime": "image/png",
"pages": 1,
"page_size": "a4",
"orientation": "portrait",
"font": "roboto",
"mono_font": "jetbrainsmono",
"theme": "light",
"source_images": {
"embedded": 0,
"skipped": 0,
"bytes": 0,
"budget_reached": false
},
"render_time_ms": 744,
"url": "https://cdn.corenexis.com/f/tU78MX1UDiV.png",
"filename": "document.png",
"size_bytes": 84565,
"expires_at": "2026-08-09T06:57:37+00:00",
"image": {
"dpi": 300,
"pages_total": 1,
"pages_rendered": 1,
"pages_per_image": 8,
"truncated": false
},
"image_count": 1,
"total_bytes": 84565,
"images": [
{
"url": "https://cdn.corenexis.com/f/tU78MX1UDiV.png",
"filename": "document.png",
"size_bytes": 84565,
"expires_at": "2026-08-09T06:57:37+00:00",
"page_from": 1,
"page_to": 1,
"width": 2480,
"height": 3508
}
]
},
"usage": {
"remaining": 4964,
"rate_limit": 120,
"monthly_limit": 5000
}
}Laying out a single run of text costs time in proportion to its length squared, so this one shape is refused by name. The same words split into paragraphs render in under three seconds.
curl -X POST "https://api.corenexis.com/markdown-to-pdf/v1" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"markdown": "...40,000 words with no paragraph breaks..."
}'{
"success": false,
"code": "INVALID_INPUT",
"message": "This document contains a single unbroken block of text of 559,999 characters, which is too long to lay out. Break it into paragraphs separated by blank lines. Document length itself is not the problem.",
"longest_text_block": 559999
}Collapsed borders are resolved across the whole table before any of it is drawn, which is what makes a long table the most memory-hungry shape.
curl -X POST "https://api.corenexis.com/markdown-to-pdf/v1" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"markdown": "...a 7,000-row table..."
}'{
"success": false,
"code": "INVALID_INPUT",
"message": "This document contains 28,005 table cells, which is more than can be laid out in one request. Split the tables across several documents and combine the results.",
"table_cells": 28005
}Inline delivery was withdrawn. Every result is a hosted link.
curl -X POST "https://api.corenexis.com/markdown-to-pdf/v1" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"markdown": "# Quarterly Report\n\nRevenue held steady while costs fell.\n\n| Region | Revenue | Change |\n|---|---|---|\n| North | 48,200 | +4% |\n| South | 31,700 | -2% |\n\n- [x] Figures verified\n- [ ] Board review\n\n```python\ndef margin(revenue, cost):\n return (revenue - cost) / revenue\n```\n",
"output": "base64"
}'{
"success": false,
"code": "INVALID_INPUT",
"message": "'output' no longer accepts 'base64'. Every result is delivered as a hosted link, so omit the parameter or send output=url. The response carries the link in data.url."
}Errors arrive as JSON with a stable code.
| Code | HTTP | Meaning |
|---|---|---|
MISSING_KEY | 401 | The x-api-key header was not sent. |
INVALID_KEY | 401 | The key does not exist or has been revoked. |
KEY_DISABLED | 403 | The key exists but has been switched off. |
ACCOUNT_SUSPENDED | 403 | The account is suspended. |
NO_SUBSCRIPTION | 402 | The account has no subscription to this API. |
SUBSCRIPTION_EXPIRED | 402 | The subscription lapsed and the grace period has passed. |
RATE_LIMIT_EXCEEDED | 429 | Too many requests this minute. Retry shortly. |
QUOTA_EXCEEDED | 429 | The monthly allowance is used up. |
PARAM_LIMIT_EXCEEDED | 400 | A requested feature or value is above what the plan allows. The response names the parameter. |
INVALID_INPUT | 400 | Something in the request is malformed. The message names the field. |
RENDER_TIMEOUT | 408 | The document took too long. Simplify it and retry. |
PROCESSING_FAILED | 422 | The document could not be rendered. |
RENDERER_BUSY | 503 | Every worker is busy. Retry in a moment. |
| Limit | Value |
|---|---|
| Maximum input size | 1 MB free, up to 4 MB on Max |
| Pages that means in practice | About 300 pages free, about 1,300 on Max, for ordinary prose |
| Page limit | There is no page limit. Documents of a thousand pages and more render normally |
| What is actually refused | A single unbroken block of text, or more table cells than fit in memory. Both are named in the error |
| Maximum delivered file | 15 MB. Text contributes about 1.7 KB per page, so this is only reachable with embedded images |
| Embedded images | 6 MB per image, 40 per document, 12 MB in total |
| Hosted link lifetime | 2 hours on the free plan, 7 days on any paid plan |
The samples/ directory in the project repository holds real output across page sizes, orientations, fonts, themes, palettes and both formats, so you can see what each option produces before calling the API.
Create your free account and turn your first Markdown file into a PDF in seconds. No credit card required.