PAGES to WebP API
Post a Pages document to /v2/convert/pages/to/webp and get one lossless WebP per page. The sample's A5 pages are 875 × 1,239 pixels: the full first page is 107,688 bytes and the two-line second page 6,660.
- Endpoint
- POST /v2/
convert/ pages/ to/ webp - Accepts
- pages
- Sample timing
- 0.56 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/pages/to/webp \
-H "Authorization: Bearer $PDFCONVERSIONAPI_KEY" \
-F File=@garden-rules.pages \
-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/pages/to/webp",
headers={"Authorization": f"Bearer {key}"},
files=[("File", open("garden-rules.pages", "rb"))],
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 = "garden-rules.pages";
form.append("File", new Blob([await readFile(file)]), file);
const url = "https://api.pdfconversionapi.com/v2/convert/pages/to/webp";
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.56,
"Files": [
{
"FileName": "garden-rules-1.webp",
"FileExt": "webp",
"FileSize": 107688,
"FileData": "UklGRqCkAQBXRUJQVlA4TJOk…"
},
{
"FileName": "garden-rules-2.webp",
"FileExt": "webp",
"FileSize": 6660,
"FileData": "UklGRvwZAABXRUJQVlA4TO8Z…"
}
]
}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
- garden-rules.pages (44 KB)
- Output
- garden-rules-1.webp (105 KB)garden-rules-2.webp (6.5 KB)
- Source
- A two-page A5 Apple Pages document with garden rules we wrote; we put our text into a Pages test file from an open-source office suite's test data (MPL-2.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 | Scale pages to this width for thumbnails: 300 gave the sample's pages as 27,486 and 1,670 bytes.Values: 1 to 20,000 |
ImageResolutioninteger, default 150 | Drawing resolution when no size is given; 150 DPI fits an A5 page into 875 × 1,239 pixels. WebP files carry no DPI.Values: 36 to 600 |
PageRangestring | Pick pages, for example 1 for a cover image.Values: Page numbers and ranges |
TransparentColorstring | Make one exact color transparent; the WebP keeps an alpha channel.Values: Color name, #RRGGBB or R,G,B |
FileNamestring | Stem of the files, garden-rules by default. |
StoreFileboolean, default false | Return 3-hour links instead of the images. |
What carries over, and what doesn't
Kept
- Lossless pixels (WebP's VP8L format):
ImageQuality=5returned the same bytes as the default - A5 proportions and the document's 2 cm margins
- The tab-aligned shed code and work hour lines, the bold sentence and the underlined phrase
- An alpha channel for
TransparentColor
Lost or not yet supported
- Lossy compression:
ImageQualityis not used for WebP, so there is no way to trade sharpness for size. - Bullets in the sample's list, and Apple's fonts (Helvetica is drawn as Liberation Sans).
- Any DPI value, which WebP has no field for.
Limits
- Page setup options return 400 "... is not supported yet for PAGES files".
- Up to 2,000 pages per request, each at most 16,000 pixels per side and 100 million pixels (413 otherwise).
- Requests up to 10 MB on the Free plan or 100 MB on paid plans, all files and fields together. A conversion can run for up to 120 seconds; after that the API returns 504.
Where teams use it
Lightweight previews of Pages uploads
Show each page of an uploaded Pages document in a browser without sending large PNGs; lossless WebP keeps the text crisp.
Archiving how a document looked
Keep an image of every page next to the original .pages file, so the look is preserved even when no Pages app is at hand.
Questions
Is the WebP lossy?
No. The files use WebP's lossless format, and ImageQuality is ignored: quality 5 and the default gave identical files. Use the JPG route for lossy images.
Why is page 2 so much smaller than page 1?
Lossless WebP compresses empty paper to almost nothing. The sample's second page has two lines of text, so it is 6,660 bytes, against 107,688 for the full first page at the same size.
How do I make small thumbnails?
Send ImageWidth, for example 300. The sample's pages then become 27,486 and 1,670 bytes.
Convert your first PAGES file in a minute.