PPT to PNG API
POST /v2/convert/ppt/to/png draws each visible slide of a .ppt deck and returns lossless PNGs. The sample asks for slides 1 to 3 at ImageWidth=1024 and gets three 1,024 × 768 images, 231,741 bytes together.
- Endpoint
- POST /v2/
convert/ ppt/ to/ png - Accepts
- ppt
- Sample timing
- 0.575 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/ppt/to/png \
-H "Authorization: Bearer $PDFCONVERSIONAPI_KEY" \
-F File=@eastgate-pantry-orientation.ppt \
--form-string PageRange=1-3 \
--form-string ImageWidth=1024 \
-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/ppt/to/png",
headers={"Authorization": f"Bearer {key}"},
files=[
("File", open("eastgate-pantry-orientation.ppt", "rb")),
],
data={
"PageRange": "1-3",
"ImageWidth": "1024",
},
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 = "eastgate-pantry-orientation.ppt";
form.append("File", new Blob([await readFile(file)]), file);
form.append("PageRange", "1-3");
form.append("ImageWidth", "1024");
const url = "https://api.pdfconversionapi.com/v2/convert/ppt/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.575,
"Files": [
{
"FileName": "eastgate-pantry-orientation-1.png",
"FileExt": "png",
"FileSize": 54167,
"FileData": "iVBORw0KGgoAAAANSUhEUgAA…"
},
{
"FileName": "eastgate-pantry-orientation-2.png",
"FileExt": "png",
"FileSize": 79401,
"FileData": "iVBORw0KGgoAAAANSUhEUgAA…"
},
{
"FileName": "eastgate-pantry-orientation-3.png",
"FileExt": "png",
"FileSize": 98173,
"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
- eastgate-pantry-orientation.ppt (80 KB)
- Output
- eastgate-pantry-orientation-1.png (53 KB)eastgate-pantry-orientation-2.png (78 KB)eastgate-pantry-orientation-3.png (96 KB)
- Source
- A six-slide volunteer orientation deck for a fictional food pantry, made by us and saved in the PowerPoint 97-2003 format; slide 5 is hidden and slide 3 has speaker notes. (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 | Visible slides to draw. 1-3 returns -1.png to -3.png; the hidden fifth slide of the sample is not counted.Values: e.g. 1-3, 4, 2-last |
ImageWidthinteger | Width in pixels. The sample's 1,024 gives 1,024 × 768, because these are 4:3 slides.Values: 1–20000 |
ImageHeightinteger | Height in pixels. With both sizes the slide fits inside the box: 1,024 × 576 returned 768 × 576. ScaleProportions=false stretches it to the full box instead.Values: 1–20000 |
ImageResolutioninteger, default 150 | Pixels per inch when no size is given: 1,500 × 1,125 per slide at 150, 720 × 540 at 72. A value you send is saved as the PNG's DPI.Values: 36–600 |
ConvertHiddenSlidesboolean, default false | Draw hidden slides too, numbered where they sit in the deck. |
TransparentColorstring | One exact color to make transparent; at 72 DPI, white cleared 94.9% of the bullet slide. |
ColorSpaceenum, default default | monochrome writes a black-and-white PNG: at the default 150 DPI the shift table slide took 21,007 bytes.Values: default, rgb, gray, monochrome |
Passwordstring | Encrypted decks can't be opened yet: a locked copy of the sample returned 422 "the input file is password-protected" even with its password. |
FileNamestring | Base name for the PNGs: FileName=pantry returned pantry-1.png and pantry-2.png. |
What carries over, and what doesn't
Kept
- The visible slides in order, each as an exact copy of the drawn slide with no compression loss
- The slide's own proportions, 4:3 in the sample, at any size you ask for, unless you send
ScaleProportions=false - The plum table header, the pie chart and its legend, and the orange title band
- Sharp lines at any resolution, since the deck is drawn from vector shapes; only the floor-plan picture has a fixed 480 × 300 pixels
Lost or not yet supported
- Speaker notes and hidden slides, unless
ConvertHiddenSlides=true. - Small files: the five slides are 541,903 bytes as PNG at 150 DPI, against 247,552 as WebP.
- Transparency of the slide itself. The PNGs are RGB with no alpha channel, so
ColorSpace=rgbreturns the same files; onlyTransparentColoradds an alpha channel. - Fonts the server lacks: Calibri text is drawn in Carlito, which keeps its letter widths.
Limits
- Up to 2,000 slides drawn per request.
- 16,000 pixels per side and 100 million pixels per image;
ImageResolutionfrom 36 to 600. - Requests up to 10 MB on the Free plan or 100 MB on paid plans. A conversion has 120 seconds before the API returns 504.
- A .ppt saved with a password returns 422 for now, with or without
Password.
Where teams use it
Moving an old slide library into a wiki or help center
Export the slides people still link to as PNG and place them in articles. Lossless images keep the 18-point table text readable when the page is zoomed.
Showing 4:3 slides in a 16:9 player
Send the player's frame as ImageWidth and ImageHeight. Each slide fits inside it at full height, ready to be centered on a background of your choice.
Feeding slides to a tool that reads only images
Image classifiers, OCR engines and visual diff tools get the slide exactly as drawn in PNG, with no JPEG noise around the letters.
Questions
How do I fit 4:3 slides into a 16:9 frame?
Send both sizes, for example ImageWidth=1024 and ImageHeight=576. The slide is fitted inside the box with its shape kept, so it comes back 768 × 576. The API doesn't add bars at the sides; pad the image in your player or page.
Are the PNG images lossless?
Yes. Each slide is drawn from its shapes and text, then stored without compression loss. The only lossy part is a photo that was already JPEG inside the deck.
Why does the response have three files when the deck has six slides?
The sample asks for PageRange=1-3. Without it you get five PNGs, one per visible slide; the fifth slide of the deck is hidden.
Can I convert .pps slide shows the same way?
Yes, /v2/convert/pps/to/png reads PowerPoint 97-2003 shows the same way. A .ppt renamed to .pps works there too, as the two share one file format.
Convert your first PPT file in a minute.