POTX to PNG API
POST /v2/convert/potx/to/png draws a template's slides as PNG. With PageRange=1 and ImageWidth=480, our project review template returned one 480 × 360 cover of 19,778 bytes for a template picker.
- Endpoint
- POST /v2/
convert/ potx/ to/ png - Accepts
- potx
- Sample timing
- 0.682 s median of 5 runsHow we measure
- Request size
- Up to 10 MB on the Free plan or 100 MB on paid plans, all files together
Request and response
Every sample below ran against the API before this page was published. Set PDFCONVERSIONAPI_KEY to your key and run it as is.
curl -sS -X POST \
https://api.pdfconversionapi.com/v2/convert/potx/to/png \
-H "Authorization: Bearer $PDFCONVERSIONAPI_KEY" \
-F File=@project-review.potx \
--form-string PageRange=1 \
--form-string ImageWidth=480 \
-o response.json
# FileData is base64. Save the first file in converted/,
# or print the JSON error.
if jq -e '.Files' response.json > /dev/null; then
mkdir -p converted
name=$(jq -r '.Files[0].FileName' response.json)
jq -r '.Files[0].FileData' response.json \
| base64 --decode > "converted/$name"
else
cat response.json
fiimport base64
import os
import requests
key = os.environ["PDFCONVERSIONAPI_KEY"]
response = requests.post(
"https://api.pdfconversionapi.com/v2/convert/potx/to/png",
headers={"Authorization": f"Bearer {key}"},
files=[("File", open("project-review.potx", "rb"))],
data={
"PageRange": "1",
"ImageWidth": "480",
},
timeout=180,
)
result = response.json()
if not response.ok:
raise SystemExit(f"{result['Code']}: {result['Message']}")
os.makedirs("converted", exist_ok=True)
for file in result["Files"]:
path = os.path.join("converted", file["FileName"])
with open(path, "wb") as out:
out.write(base64.b64decode(file["FileData"]))
print(path, file["FileSize"], "bytes")
import { mkdir, readFile, writeFile } from "node:fs/promises";
import { join } from "node:path";
const form = new FormData();
const file = "project-review.potx";
form.append("File", new Blob([await readFile(file)]), file);
form.append("PageRange", "1");
form.append("ImageWidth", "480");
const url = "https://api.pdfconversionapi.com/v2/convert/potx/to/png";
const key = process.env.PDFCONVERSIONAPI_KEY;
const response = await fetch(url, {
method: "POST",
headers: { Authorization: `Bearer ${key}` },
body: form,
});
const result = await response.json();
if (!response.ok) {
throw new Error(`${result.Code}: ${result.Message}`);
}
await mkdir("converted", { recursive: true });
for (const file of result.Files) {
const path = join("converted", file.FileName);
await writeFile(path, Buffer.from(file.FileData, "base64"));
console.log(path, file.FileSize, "bytes");
}
{
"ConversionCost": 1,
"ConversionTime": 0.682,
"Files": [
{
"FileName": "project-review-1.png",
"FileExt": "png",
"FileSize": 19778,
"FileData": "iVBORw0KGgoAAAANSUhEUgAA…"
}
]
}Response from our test run on 2026-11-03. ConversionTime shows the median of 5 runs. FileData is shortened here; the real response carries the whole file as base64.
The sample, converted
The same file the code sends. Download the input and the output and compare them yourself.

- Input
- project-review.potx (43 KB)
- Output
- project-review-1.png (19 KB)
- Source
- A six-slide project review template for a fictional design studio, with bracketed text to replace and one hidden instructions slide. We made it for this page. (CC0-1.0). How it was made
- Made by
- 2026-11-04, API build
9eeeb0640aba
Parameters
Send these as form fields next to the file. Names are case-insensitive. If you set one of the documented options below that we don't support yet, the request fails with a 400 that names it instead of returning a file made without it.
| Parameter | What it does |
|---|---|
PageRangestring | 1 draws only the title slide, as project-review-1.png. Without it you get all 5 visible slides.Values: e.g. 1, 1-3 |
ImageWidthinteger | Exact width; the 4:3 slide sets the height, so 480 gives 480 × 360.Values: 1–20,000 |
ImageHeightinteger | With ImageWidth, a box the slide is fitted into: 480 by 480 still returns 480 × 360.Values: 1–20,000 |
ScaleProportionsboolean, default true | false stretches the slide to fill ImageWidth × ImageHeight exactly: 480 × 480, 23,155 bytes. |
ScaleImageboolean, default true | false draws at ImageResolution and cuts to the size instead: ImageWidth=480 then keeps the left 480 pixels of a 1,500 × 1,125 render. |
ImageResolutioninteger, default 150 | Used when no size is set: 150 gives 1,500 × 1,125, 10 by 7.5 inches of slide.Values: 36–600 |
TransparentColorstring | white made 91.7% of the cover transparent, leaving the band, title, subtitle and footer. The logo stays too, apart from its white chevron, which turns see-through. |
ConvertHiddenSlidesboolean, default false | Also draw the hidden how-to slide, as page 5. |
Passwordstring | For an encrypted template: our locked copy drew its cover with the password and returned 422 without it. |
FileNamestring | FileName=kestrel-cover returns kestrel-cover-1.png. |
Not supported yet
Setting one of these to anything but its default returns 400.
| Option | What to do instead |
|---|---|
ConvertSpeakerNotes | Not drawn on the images; values other than Disabled return 400. |
PageSize | Returns 400 "PageSize is not supported yet for POTX files"; use ImageWidth and ImageHeight. |
What carries over, and what doesn't
Kept
- The master's teal band, footer line and round logo on each slide
- Bracketed placeholders as typed: "[Project name] review", "Prepared by [name] on [date]"
- The 4:3 proportions of the template
- Lossless pixels, so the small footer text stays as sharp as the scale allows
Lost or not yet supported
- Prompts in empty placeholders, such as the layout's "Add up to five points, one line each".
- Cambria and Calibri letter shapes: the slides are drawn with Caladea and Carlito.
- The speaker note, and the hidden how-to slide unless you ask for it.
Limits
- At most 2,000 slides per request.
- 16,000 pixels per side, 100 million pixels per image; 413 above that.
- 10 MB on the Free plan or 100 MB on paid plans per request; 120 seconds for the conversion.
Where teams use it
Cover tiles in a template picker
Show a small picture of each .potx in a new-presentation dialog or an intranet library. One request per template returns one PNG; our template's cover is 19,778 bytes at 480 pixels wide.
Checking branding across a template set
Render every slide of every template after a brand change and look for the band, logo and footer in the wrong place or the wrong color.
Questions
How do I get just a cover image?
Send PageRange=1 with the width you need. The API draws only the first visible slide and returns a single file named after the template, ending in -1.png.
Will thumbnails of different templates match in size?
Only if the templates share a slide shape: ImageWidth=480 gives 480 × 360 for this 4:3 template and 480 × 270 for a 16:9 one. Add ImageHeight to fit every slide in the same box, or ScaleProportions=false to force the exact size.
Does the thumbnail show the layout's prompts?
No. Prompt text exists for editing only. A thumbnail shows what is typed on the slide and what the master and layout draw.
Convert your first POTX file in a minute.