Ask a developer what the opposite of Extract Pages is, and most will say Delete Pages without thinking twice. Keep some pages, or remove some pages, same mental model, two ends of one dial.
Then you read PDF4me's own live parameter table for Delete Pages and find a pageNumbers field described almost word for word the same way as its counterpart on Extract Pages: individual pages, page ranges, mixed formats, indices starting from 1. Same field name. Same syntax. Send "2-4" to one endpoint and get a three-page PDF containing pages 2, 3, and 4. Send the identical string to the other and get the opposite document: everything except pages 2, 3, and 4. Swap which endpoint you call without re-reading which one you meant, and you ship the wrong document to a client with no error thrown anywhere in the pipeline.
Two endpoints, one shared field, opposite intent
Extract Pages - POST /api/v2/ExtractPages
Request:
{
"docContent": "<base64-encoded PDF>",
"docName": "contract.pdf",
"pageNumbers": "2-4"
}
Response: docContent (base64 PDF containing only pages 2 through 4), docName.
Delete Pages - POST /api/v2/DeletePages
Request:
{
"docContent": "<base64-encoded PDF>",
"docName": "contract.pdf",
"pageNumbers": "2-4"
}
Response: docContent (base64 PDF with pages 2 through 4 removed, everything else intact), docName.
Identical request shape. Identical field name. Inverted output. pageNumbers on Extract Pages answers "what do I keep." The same field on Delete Pages answers "what do I remove." Nothing in the field name, type, or accepted syntax tells you which question you're answering, only the endpoint you call does.
One honest gap worth flagging: neither live parameter table makes a specific, named promise about bookmarks, annotations, or form fields surviving either operation, both pages only describe general "quality preservation." If your workflow depends on those surviving an Extract Pages or Delete Pages call, verify it against a real document before you build a dependency on it.
Here's a minimal Python example for both, using requests:
import base64
import requests
API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.pdf4me.com"
def read_pdf_base64(path):
with open(path, "rb") as f:
return base64.b64encode(f.read()).decode("utf-8")
headers = {
"Content-Type": "application/json",
"Authorization": API_KEY,
}
# Keep only pages 2 through 4
extract_payload = {
"docContent": read_pdf_base64("contract.pdf"),
"docName": "contract.pdf",
"pageNumbers": "2-4",
}
extract_resp = requests.post(f"{BASE_URL}/api/v2/ExtractPages", json=extract_payload, headers=headers)
# Remove pages 2 through 4, keep everything else
delete_payload = {
"docContent": read_pdf_base64("contract.pdf"),
"docName": "contract.pdf",
"pageNumbers": "2-4",
}
delete_resp = requests.post(f"{BASE_URL}/api/v2/DeletePages", json=delete_payload, headers=headers)
Same pageNumbers value, same source document, two structurally opposite results depending only on which URL the request hits.
The feature people actually confuse Delete Pages with
Delete Blank Pages from PDF sits right next to Delete Pages in PDF4me's own docs and solves an adjacent but distinct problem. Delete Pages requires you to already know which page numbers you want gone, you supply pageNumbers yourself. Delete Blank Pages does the opposite kind of work: it scans the document, detects pages with no meaningful text or image content, and removes them automatically, no page numbers required. If your actual problem is "this scanned batch has empty separator pages mixed in and I don't know which page numbers they land on," Delete Blank Pages is the correct tool, not Delete Pages with a manually-computed range.
Extract Pages has full platform parity. Delete Pages does not, at least not under one name
Extract Pages is documented identically across every surface PDF4me ships: the Make module, the Zapier action, the Power Automate action, the n8n node, and its own interactive API Tester. Six touchpoints, one consistent name, no gaps.
Delete Pages does not have that same clean parity, at least not under one consistent name. The Make module matches the REST name. Zapier documents the same capability as "Delete PDF Pages". n8n documents it as "Delete Unwanted Pages From PDF", and its own API Tester page uses that same "Delete Unwanted Pages" name rather than "Delete Pages." What doesn't currently show up anywhere in PDF4me's documentation index is a Power Automate action for deleting specific PDF pages by number or range, Power Automate's docs cover a same-named action for Word documents, a different file format and endpoint entirely, but nothing indexed for the PDF version. That's worth stating carefully: a documentation index gap isn't proof the live connector picker lacks it, only proof it isn't indexed the way the other three platforms' equivalents are. If Power Automate is your automation layer and this matters, check the connector picker directly before assuming the gap is real.
Put together: the same feature, remove these specific pages from a PDF, answers to three different names across PDF4me's own docs. "Delete Pages" on the REST API and in Make. "Delete PDF Pages" on Zapier. "Delete Unwanted Pages" on n8n and in the API Tester. All three describe the same pageNumbers-driven removal. But if you're searching PDF4me's docs site for "delete pages" while building an n8n workflow, you won't find the node under that literal phrase, you'll find it under "unwanted."
For anyone new to PDF4me's REST API generally, the Connect to the PDF4me V2 API guide covers authentication and request structure once, instead of re-explaining it per endpoint. The Extract Pages API Tester and Delete Unwanted Pages API Tester both let you send a real pageNumbers value against a real PDF and see the actual output before writing a single line of integration code.
Website: pdf4me.com
Documentation: docs.pdf4me.com
Developer portal: dev.pdf4me.com
Top comments (0)