Extract pages into a new PDF, remove pages, or split a PDF into one file per page. Here is the whole call in Python, with the output it produced when we ran it.
Before you start
An API key. Create a free account; it comes with free tokens every month. Put the key in an environment variable so it stays out of your code: export BLOODWEB_KEY=your_key
Python 3 with the requests library: pip install requests
The input file in the same folder: report.pdf. Use your own; that is the name the code expects.
The code
Save it as pdf-split.py and run python3 pdf-split.py.
import os
import requests
resp = requests.post(
"https://bloodweb.net/api/v1/pdf-split",
headers={"Authorization": f"Bearer {os.environ['BLOODWEB_KEY']}"},
files={"file": open("report.pdf", "rb")},
data={"mode": "extract", "pages": "2-4"},
timeout=120,
)
if not resp.ok:
raise SystemExit(f"{resp.status_code}: {resp.json()['error']['message']}")
with open("pages.pdf", "wb") as f:
f.write(resp.content)
What you get
Tested 19 October 2026: this exact code ran against our test copy of the API, which runs the same service code as bloodweb.net, and produced this.
It writes pages.pdf: a PDF, 3 pages, 2 KB.
Page 1 of the result.
Change the call
Every option the PDF splitter takes. Add or change them the same way as the ones in the code.
mode: extract: a PDF of the chosen pages, in the order given. remove: the PDF without the chosen pages. each: a zip with one PDF per chosen page. One of: extract, remove, each.
pages: Pages such as 1-3,5 or 8- (to the end). Required for extract and remove; each defaults to all pages.
If it fails
A failed call is not charged. The answer is JSON with an error object; the code above prints its message. The usual ones:
401missing_key or invalid_key: BLOODWEB_KEY is not set in the shell that runs the code, or the key was revoked.
415unsupported_type: the file is not a type this service reads. The type is read from the file itself, so renaming a file does not change it.
413file_too_large: the file is over the limit on the service page.
402insufficient_tokens: the balance does not cover the call. Top up in the dashboard.
429rate_limited: too many calls at once. Wait the seconds in the Retry-After header and send it again.