Protect PPTX API
Send a deck with EncryptPassword to POST /v2/convert/pptx/to/protect and it comes back encrypted, still named .pptx, asking for that password when it is opened. Our 47,390-byte sample returned as a 52,736-byte file locked with Tide-Table-2026.
- Endpoint
- POST /v2/
convert/ pptx/ to/ protect - Accepts
- pptx
- Sample timing
- 36 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/pptx/to/protect \
-H "Authorization: Bearer $PDFCONVERSIONAPI_KEY" \
-F File=@calloway-ferry-winter.pptx \
--form-string EncryptPassword=Tide-Table-2026 \
-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/pptx/to/protect",
headers={"Authorization": f"Bearer {key}"},
files=[("File", open("calloway-ferry-winter.pptx", "rb"))],
data={
"EncryptPassword": "Tide-Table-2026",
},
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 = "calloway-ferry-winter.pptx";
form.append("File", new Blob([await readFile(file)]), file);
form.append("EncryptPassword", "Tide-Table-2026");
const url = "https://api.pdfconversionapi.com/v2/convert/pptx/to/protect";
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.036,
"Files": [
{
"FileName": "calloway-ferry-winter.pptx",
"FileExt": "pptx",
"FileSize": 52736,
"FileData": "0M8R4KGxGuEAAAAAAAAAAAAA…"
}
]
}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
- calloway-ferry-winter.pptx (46 KB)
- Output
- calloway-ferry-winter.pptx (52 KB)
- Source
- A six-slide winter timetable deck for a fictional ferry operator, made by us for this site; slide 5 is hidden and slide 2 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 |
|---|---|
EncryptPasswordstring | Password the deck will ask for. Required; without it the answer is 400 "EncryptPassword is required". 255 characters were accepted and 256 refused. A password with ä and Chinese characters in it, Fähre-渡船-2026, worked and opened the deck again on our text route.Values: 1–255 characters |
Passwordstring | Current password, needed only when the uploaded deck is already encrypted. Sent with a new EncryptPassword, it changes the password in one call. |
FileNamestring | Name of the encrypted deck; FileName=ferry-locked returned ferry-locked.pptx. |
What carries over, and what doesn't
Kept
- The deck exactly as uploaded, inside the encryption. Opened with its password, the sample gave the same text and the same slide images as the original.
- Hidden slides and speaker notes, which stay in the file. Anyone with the password can see them.
- The file name and the
.pptxextension:calloway-ferry-winter.pptxcomes back under the same name - A new random 16-byte salt for every request: locking the same deck twice gives two different files
Lost or not yet supported
- Opening without the password. Previews, search indexers and tools that read .pptx without password support see an encrypted container, not a ZIP package.
- Recovery. Passwords are case-sensitive; with
tide-table-2026the sample stays closed, and there is no way back without the right one. - Edit restrictions. Only a password to open is set; the deck is not marked final or read-only.
- Size: the encrypted container is written in 512-byte blocks, so the sample grew from 47,390 to 52,736 bytes.
Limits
- PowerPoint 2007 and later packages (.pptx) only. There is no route for .ppt (404); convert it with
/v2/convert/ppt/to/pptxfirst. Sending a .ppt here returns 422 "this PPTX is already password-protected, or is an older binary Office file". - A deck that is already encrypted needs its
Password, or the answer is 422 "the input file is password-protected". - Requests up to 10 MB on the Free plan or 100 MB on paid plans; 120 seconds per conversion, then 504.
Where teams use it
Board and client decks sent by email
Encrypt the final deck right before it is attached, and share the password through another channel. A forwarded copy can't be opened without it.
Decks your service generates for each customer
If you build personalized .pptx files, such as quotes or account reviews, lock each one with a password the customer already knows before it is stored or sent.
Changing the password on stored decks
Send the encrypted file with the old Password and a new EncryptPassword. In our test the result opened with the new password and refused the old one.
Questions
Which encryption does the protected deck use?
ECMA-376 agile encryption, version 4.4 in the file's EncryptionInfo: AES with a 256-bit key in CBC mode, SHA-512 with 100,000 hashing rounds, and an HMAC check over the encrypted package. It is the scheme PowerPoint 2010 and later write for a password to open.
Can I still convert the protected deck with this API?
Yes, every PPTX route takes the password as Password. The locked sample gave the same 775-byte text from /v2/convert/pptx/to/txt and the same 93,308-byte first slide from /v2/convert/pptx/to/png as the original.
Does protecting a deck hide its hidden slides and notes?
No. They are encrypted along with everything else, but whoever has the password gets them back: the locked sample still has its hidden fare slide and the note on slide 2. Delete what the recipient should not see before you protect the file.
How do I take the password off again?
Send the file with its Password to /v2/convert/pptx/to/pptx. It returns a plain .pptx, 43,382 bytes for the sample.
Convert your first PPTX file in a minute.