PPS to PNG API
POST /v2/convert/pps/to/png reads a PowerPoint 97-2003 show and returns PNG images of its slides. The sample asks only for slides 1 and 2 with PageRange=1-2, and receives two 1,500 × 937 PNGs of 110,048 and 93,075 bytes.
- Endpoint
- POST /v2/
convert/ pps/ to/ png - Accepts
- pps
- Sample timing
- 0.608 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/pps/to/png \
-H "Authorization: Bearer $PDFCONVERSIONAPI_KEY" \
-F File=@riverside-lobby-loop.pps \
--form-string PageRange=1-2 \
-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/pps/to/png",
headers={"Authorization": f"Bearer {key}"},
files=[("File", open("riverside-lobby-loop.pps", "rb"))],
data={
"PageRange": "1-2",
},
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 = "riverside-lobby-loop.pps";
form.append("File", new Blob([await readFile(file)]), file);
form.append("PageRange", "1-2");
const url = "https://api.pdfconversionapi.com/v2/convert/pps/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.608,
"Files": [
{
"FileName": "riverside-lobby-loop-1.png",
"FileExt": "png",
"FileSize": 110048,
"FileData": "iVBORw0KGgoAAAANSUhEUgAA…"
},
{
"FileName": "riverside-lobby-loop-2.png",
"FileExt": "png",
"FileSize": 93075,
"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
- riverside-lobby-loop.pps (75 KB)
- Output
- riverside-lobby-loop-1.png (107 KB)riverside-lobby-loop-2.png (91 KB)
- Source
- A five-slide self-running lobby show for a fictional clock museum, made by us and saved as a PowerPoint 97-2003 show with fades and 8-second timings; slide 4 is hidden. (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, in show order. The sample's 1-2 returns the welcome and tours slides; 5 returns 400 because one of the five slides is hidden.Values: e.g. 1-2, 3, 2-last |
ImageResolutioninteger, default 150 | Pixels per inch; 150 makes the 10 × 6.25 in slides 1,500 × 937. When sent, it is stored as the PNG's DPI.Values: 36–600 |
ImageWidthinteger | Exact width in pixels, with the height from the slide's 16:10 shape. Use ImageHeight for the height, or both for a box.Values: 1–20000 |
TransparentColorstring | Make one exact color transparent. #F7F3EA, the sample's paper-colored background, cleared 81.4% of the welcome slide at 60 DPI. |
ColorSpaceenum, default default | gray turned the welcome slide into a one-channel PNG of 45,351 bytes, from 110,048. The default PNG is already RGB with no alpha channel, so rgb returns the same file.Values: default, rgb, gray, monochrome |
ConvertHiddenSlidesboolean, default false | Draw hidden slides as well, at their place in the show. |
Passwordstring | Encrypted shows can't be opened yet, with or without it: our locked test show returned 422 "the input file is password-protected". |
What carries over, and what doesn't
Kept
- Exact drawn pixels, with no compression artifacts around the small print
- The welcome slide's clock picture, background color and centered title lines
- The tour table's brass header row and its three tours
- Slide numbers in the file names:
riverside-lobby-loop-1.png,-2.png
Lost or not yet supported
- The show's motion: fades, the 8-second timing and the loop are not in still images.
- Hidden slides and the speaker note, unless asked for (notes are never drawn).
- Clean cut-outs: at 60 DPI the clock picture's corners came out one shade lighter than the background, (249, 245, 236), so a faint square stayed opaque with
TransparentColor; at the default 150 DPI they cleared. - Small size: at 150 DPI the four slides take 420,301 bytes as PNG, 183,582 as WebP.
Limits
- Requests up to 10 MB on the Free plan or 100 MB on paid plans. Each conversion must finish within 120 seconds or the API returns 504.
- 2,000 slides at most; each image at most 16,000 pixels per side and 100 million pixels.
- Password-protected .pps files are refused with 422 for now, even when the right
Passwordis sent.
Where teams use it
Keeping a record of what a public screen showed
Museums, shops and offices that run a looping .pps can file PNG copies of each slide with the date it went live. Lossless images keep the opening hours and prices legible.
Reusing show slides in print or on a website
Pull single slides out of a show with PageRange and place them in a newsletter or a page, at the resolution the layout needs.
Questions
Does `ImageQuality` change the PNG?
No. PNG is lossless, and the parameter is not part of this route, so ImageQuality=50 returned the same 110,048-byte welcome slide as no setting at all. Use ImageWidth or ImageResolution to make files smaller.
Why can't I ask for slide 5?
Slide numbers count only visible slides, and the sample's fourth slide is hidden, so the show has four. PageRange=4 is the gift shop slide, the last one in the show.
Can the slide background be made transparent?
For a flat color, yes: send it as TransparentColor. Pictures are resampled while the slide is drawn, so their backgrounds can come out a shade off and stay visible. On the sample that happened to the clock's corners at 60 DPI, but not at 150. The outer row and column of the slide cleared along with the rest of the background at both resolutions.
Convert your first PPS file in a minute.