WebP to WebP API
POST a WebP to /v2/convert/webp/to/webp to resize, crop or recolor it and get a lossless WebP back. The result keeps any alpha channel but no metadata, and an animated input comes back as a still of its first frame.
- Endpoint
- POST /v2/
convert/ webp/ to/ webp - Accepts
- webp
- Sample timing
- 5 ms 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/webp/to/webp \
-H "Authorization: Bearer $PDFCONVERSIONAPI_KEY" \
-F File=@guest-badge.webp \
--form-string ImageWidth=200 \
-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/webp/to/webp",
headers={"Authorization": f"Bearer {key}"},
files=[("File", open("guest-badge.webp", "rb"))],
data={
"ImageWidth": "200",
},
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 = "guest-badge.webp";
form.append("File", new Blob([await readFile(file)]), file);
form.append("ImageWidth", "200");
const url = "https://api.pdfconversionapi.com/v2/convert/webp/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.005,
"Files": [
{
"FileName": "guest-badge.webp",
"FileExt": "webp",
"FileSize": 22342,
"FileData": "UklGRj5XAABXRUJQVlA4TDJX…"
}
]
}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
- guest-badge.webp (9.4 KB)
- Output
- guest-badge.webp (22 KB)
- Source
- A guest pass for a made-up trade show that we drew for this page, saved as a lossy WebP with a transparent background and a soft shadow. (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 | New width. The sample sends 200 and gets a 200 × 130 WebP of 22,342 bytes.Values: 1–20000 |
ImageHeightinteger | New height; with ImageWidth, the image fits inside the box, so 200 × 200 also gave 200 × 130.Values: 1–20000 |
ScaleProportionsboolean, default true | false with a 200 × 200 box squashed the badge into a 200 × 200 square (29,988 bytes). |
ScaleIfLargerboolean, default false | true with ImageWidth=800 left the 400-pixel badge at its own size. |
ScaleImageboolean, default true | false with 200 × 100 kept the badge's top-left 200 × 100 pixels unscaled (17,496 bytes). |
ColorSpaceenum, default default | At full size, gray gave a 20,450-byte gray WebP with its alpha and monochrome 3,970 bytes; at the sample's 200 px width they gave 10,718 and 1,912 bytes. cmyk returns 400.Values: default, rgb, gray, monochrome |
TransparentColorstring | Clears one exact color in addition to the existing alpha. On this lossy badge at full size, #FFFFFF cleared 42,768 pixels of the white card (10,032 clear pixels in all at the sample's 200 × 130), but near-white specks around the text and edges stayed.Values: Color name, #RRGGBB or R,G,B |
ImageResolutioninteger | Range-checked and otherwise unused; the output has no resolution field.Values: 10–800 |
ImageInterpolationboolean, default false | Accepted either way; resizing uses Lanczos. |
FileNamestring | Output name; the sample would come back as guest-badge.webp unless you rename it. |
StoreFileboolean, default false | true keeps the result for 3 hours and returns a URL. |
Not supported yet
Setting one of these to anything but its default returns 400.
| Option | What to do instead |
|---|---|
ImageQuality | Output is lossless only. 75, ConvertAPI's default, is accepted; 40, 100 and every other value return 400 'ImageQuality is not supported yet for WebP → WebP'. |
What carries over, and what doesn't
Kept
- Alpha, including the soft shadow, now stored losslessly.
- The pixels exactly when you don't resize: a default conversion equals the reference decode of the original.
- A readable QR code at 200 × 130; the pass number still decoded.
- The aspect ratio when only one side is given: 400 × 260 to 200 × 130.
- EXIF orientation, turned into the pixels: a 300 × 200 WebP tagged 6 came back 200 × 300 and upright, with no EXIF chunk left.
Lost or not yet supported
- File size. The output is lossless, so the 9,596-byte lossy badge became 45,956 bytes at full size, and even the half-size sample is 22,342 bytes.
- Animation: frames after the first are dropped and the result is a still.
- EXIF, XMP and ICC chunks.
- Lossy output. There is no quality setting, so you can't recompress a WebP to make it smaller.
Limits
- One WebP per request.
- Requests up to 10 MB on the Free plan or 100 MB on paid plans, all files and fields together.
- Input and resized output are limited to 100,000,000 pixels each; above that the API returns 413.
ImageWidthandImageHeighttake 1 to 20,000, but a WebP side can't exceed 16,384 px: a 16,385 × 100 request returned 413 'WebP images can be at most 16,384 pixels on a side, and this one is 16,385×100; lower ImageWidth or ImageHeight'.- A conversion is stopped after 120 seconds (504).
Where teams use it
Thumbnails that stay WebP
Make smaller copies of uploaded WebPs for a gallery or a list view without switching format. The alpha channel comes along, so cut-out images stay cut out.
A still from an animated WebP
Send an animated WebP and get its first frame as a single-image WebP, for a preview that doesn't move.
Removing metadata
The re-saved WebP carries no EXIF, XMP or ICC chunks, which removes camera details and location tags before images are shared.
Questions
Can this make my WebP smaller?
Only by resizing, and not always then. The output is lossless, so a lossy WebP can grow: the sample went from 9,596 bytes at 400 × 260 to 22,342 bytes at 200 × 130. ImageQuality returns 400 for any value but 75.
Is the result lossy or lossless?
Lossless (VP8L) every time. A WebP with transparency keeps its alpha channel; an opaque one comes back as RGB without one, as a 400 × 260 lossy WebP with no alpha did (42,156 bytes). Without resizing, the output decodes to exactly the pixels of the original's decode.
What happens to an animated WebP?
You get a still WebP of the first frame. A three-frame test file came back as one VP8L image with no animation chunk.
Is metadata kept?
No. EXIF, XMP and ICC profiles are not copied. An EXIF orientation is applied to the pixels before the tag is dropped, so a sideways-stored image comes back upright. A Display P3 WebP lost its profile, so its colors will be read as sRGB.
Convert your first WebP file in a minute.