PPS to TIFF API
POST /v2/convert/pps/to/tiff turns the visible slides of a PowerPoint 97-2003 show into frames of one TIFF file. The sample sets ImageWidth=800 and gets riverside-lobby-loop.tiff, four 800 × 500 frames in 147,405 bytes.
- Endpoint
- POST /v2/
convert/ pps/ to/ tiff - Accepts
- pps
- Sample timing
- 0.577 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/tiff \
-H "Authorization: Bearer $PDFCONVERSIONAPI_KEY" \
-F File=@riverside-lobby-loop.pps \
--form-string ImageWidth=800 \
-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/tiff",
headers={"Authorization": f"Bearer {key}"},
files=[("File", open("riverside-lobby-loop.pps", "rb"))],
data={
"ImageWidth": "800",
},
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("ImageWidth", "800");
const url = "https://api.pdfconversionapi.com/v2/convert/pps/to/tiff";
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.577,
"Files": [
{
"FileName": "riverside-lobby-loop.tiff",
"FileExt": "tiff",
"FileSize": 147405,
"FileData": "SUkqABXDAAABAAAAAQAAAAEA…"
}
]
}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.tiff (144 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 |
|---|---|
ImageWidthinteger | Frame width in pixels; the 16:10 slides become 800 × 500 at the sample's 800. With a width alone the frames record no DPI: their resolution tags say 1, with no unit.Values: 1–20000 |
ImageResolutioninteger, default 150 | Pixels per inch when no size is given, and the DPI written into the frames when you send it. Combined with ImageWidth=800, a value of 96 gave the same 800 × 500 frames and file size, with 96 DPI in the tags.Values: 36–600 |
MultiPageboolean, default true | false returns one TIFF per slide instead. Those are stored without compression: 1,200,226 bytes each at 800 × 500. |
PageRangestring | Visible slides to include. A range of two or more stays one compressed file.Values: e.g. 1-2, 3 |
ConvertHiddenSlidesboolean, default false | Adds the hidden staff slide in its place as frame 4, which moves the gift shop to frame 5 (172,005 bytes for the file at 800 wide). |
Passwordstring | Doesn't open encrypted shows yet: a locked copy got 422 "the input file is password-protected" with the correct password as well. |
What carries over, and what doesn't
Kept
- The show's visible slides as frames 1 to 4, in show order
- Lossless pixels, LZW-compressed when two or more slides are in the file
- The 16:10 slide shape at whatever width you choose
- Text, the table and the banner drawn as vectors, so wider frames get real detail
Lost or not yet supported
- The show itself: no transitions, timings or loop setting are stored in a TIFF.
- Compression for single frames, which are written raw: 1,200,226 bytes for one 800 × 500 slide.
- A DPI value unless
ImageResolutionis sent; the tags then say 1 with no unit. - Speaker notes, and hidden slides by default.
Limits
- Up to 2,000 slides per request; frames at most 16,000 pixels per side and 100 million pixels.
- Requests up to 10 MB on the Free plan or 100 MB on paid plans; after 120 seconds a conversion ends with 504.
- Settings this route can't apply yet, such as
ConvertSpeakerNotes=Separate, return 400 "… is not supported yet for PPS files". - A .pps saved with a password returns 422 for now, even with the right
Password.
Where teams use it
Proof of what ran on a public display
If you keep copies of the notices a screen showed, such as opening hours or prices, a dated multi-page TIFF holds every slide of the loop in one file.
Feeding a show into a document imaging system
Where an archive or case system takes multi-page TIFF, one request per show gives a single file with a frame for each visible slide.
Questions
Should I size the frames by width or by resolution?
By width when the frames need an exact size: ImageWidth=800 gave 800 × 500 frames and a 147,405-byte file. Adding ImageResolution=96 changed only the tags, which then say 96 DPI; the pixels and the file size stayed the same. Without a width or height, ImageResolution sets the pixel count.
How big is the TIFF at the default settings?
273,959 bytes for the sample: four 1,500 × 937 frames at 150 pixels per inch, LZW-compressed, with no DPI recorded.
Can I get each slide as a separate TIFF?
Yes, with MultiPage=false, which returns riverside-lobby-loop-1.tiff to -4.tiff. Expect large files, because single frames are not compressed.
Convert your first PPS file in a minute.