How to Split a PDF into Multiple Files
Split one PDF by page ranges, every N pages or page by page, or extract only the pages you need. In the dashboard or the API, including large scans.
Nobody splits a ten-page PDF. Splitting is what you do with the 300-page scan from the office copier, the monthly statement run that contains every customer, the deposition you need three exhibits out of. Big files, and usually more than one output.
PodPDF splits PDFs in the dashboard and through the API, into exactly the files you ask for.
Four Ways to Split
| Mode | Settings | You get |
|---|---|---|
extract | pages: "1,3,5-8" | One PDF with just those pages |
ranges | ranges: ["1-3", "4-9", "10-end"] | One PDF per range |
every_n | every_n: 10 | A new file every 10 pages |
each_page | — | One PDF per page |
Ranges use the same syntax as merge: 3, 1-3, 8-end, comma-separated, in the order you write them. Ranges may overlap — useful when the same cover page belongs in several files.
Split in the Dashboard
Open PDF Tools → Split and add your PDF. PodPDF checks it immediately: you see the page count, and a password-protected file is flagged before you spend any time on it.
Pick a mode and the page shows how many files you will get (→ 12 files) as you type, so a typo in a range shows up before you run anything. Click Split PDF, then download files one at a time or all of them as a ZIP.
Files larger than 4 MB upload when you add them and split in the background. You can leave the page; the result is waiting in Jobs.
Split with the API
For files up to 4 MB, POST /pdf/split does it in one call:
curl -X POST https://api.podpdf.com/pdf/split \
-H "X-API-Key: YOUR_API_KEY" \
-F "file=@statements.pdf" \
-F 'split={"mode": "every_n", "every_n": 2}' \
-F 'options={"filename_pattern": "statement-{index:03}"}'
When a split produces several files, the response is JSON with a download link for each file and one for a ZIP of all of them:
{
"job_id": "0f6c5a1e-...",
"operation": "pdf_split",
"status": "completed",
"input_pages": 48,
"output_count": 24,
"outputs": [
{
"index": 0,
"name": "statement-001.pdf",
"pages": 2,
"page_range": "1-2",
"size_bytes": 81234,
"download_url": "https://..."
}
],
"zip_url": "https://...",
"download_url_expires_at": "2026-09-13T11:00:00.000Z"
}
When the split produces a single file (extract, or one range), the response is the PDF itself, just like merge.
Naming the Files
filename_pattern controls output names. It understands {basename} (the input name without .pdf), {index} or {index:03} for a zero-padded number, and {pages} for the page range. The default is {basename}-{index:03}.pdf, so scan.pdf becomes scan-001.pdf, scan-002.pdf and so on. Unsafe characters are replaced, and duplicate names get a number added.
JavaScript
import fs from 'node:fs';
const form = new FormData();
form.append(
'file',
new Blob([fs.readFileSync('statements.pdf')], { type: 'application/pdf' }),
'statements.pdf'
);
form.append('split', JSON.stringify({ mode: 'ranges', ranges: ['1-4', '5-9', '10-end'] }));
const response = await fetch('https://api.podpdf.com/pdf/split', {
method: 'POST',
headers: { 'X-API-Key': process.env.PODPDF_API_KEY },
body: form,
});
const result = await response.json();
for (const output of result.outputs) {
const file = await fetch(output.download_url);
fs.writeFileSync(output.name, Buffer.from(await file.arrayBuffer()));
}
Python
import json
import requests
response = requests.post(
'https://api.podpdf.com/pdf/split',
headers={'X-API-Key': 'YOUR_API_KEY'},
files={'file': ('statements.pdf', open('statements.pdf', 'rb'), 'application/pdf')},
data={'split': json.dumps({'mode': 'each_page'})},
)
response.raise_for_status()
for output in response.json()['outputs']:
open(output['name'], 'wb').write(requests.get(output['download_url']).content)
Large PDFs
Instant splits cover files up to 4 MB and 500 pages, producing up to 100 files. Beyond that, upload the file and queue a job:
POST /pdf/upload-urlwithcontent_length_bytes— you get anupload_urland ans3_keyPUTthe file toupload_urlwithContent-Type: application/pdfPOST /pdf/jobswith{"operation": "split", "inputs": [{"s3_key": "..."}], "split": {"mode": "each_page"}}- Poll
GET /jobs/{job_id}, or wait for thejob.completedwebhook
Jobs handle files up to 150 MB and 5000 pages, producing up to 500 files. When the job is done, GET /jobs/{job_id}/files lists every output, GET /jobs/{job_id}/files/{index}/download gives a link to one of them, and GET /jobs/{job_id}/download gives the ZIP.
You can also check a file before splitting it: POST /pdf/inspect returns the page count and whether the file is encrypted, free of charge.
Why the Pieces Can Add Up to More Than the Whole
Split a 300-page statement run page by page and the 300 files together may be much larger than the original. That isn’t waste: each output is a complete PDF, so shared content — a letterhead image, an embedded font — has to be included in every file. Scanned documents, where each page has its own image, split into pieces that add up to roughly the original size.
PodPDF estimates the total size before it starts and refuses splits that would be unreasonably large (OUTPUT_TOO_LARGE), so you find out immediately instead of after a long wait.
What Isn’t Carried Over
Like merge, split copies pages. Fillable form fields and bookmarks don’t come along, and digital signatures are invalidated. You get a warning when the input had any of these.
Common Errors
| Code | What to do |
|---|---|
PDF_ENCRYPTED | Remove the password protection first |
PAGE_OUT_OF_RANGE | A range goes past the last page; details.total_pages has the count |
INVALID_PAGE_RANGE | Fix the range syntax — details.token shows the part that’s wrong |
OUTPUT_COUNT_EXCEEDED | Use every_n with a larger number, or split in two passes |
OUTPUT_TOO_LARGE | Split into fewer, larger files |
Pricing
A split is billed once per operation, based on the pages in the document — not per output file. Splitting a document page by page costs the same as splitting it in two. See pricing.
Get Started
- Split a PDF now: PDF Tools → Split
- Read the API reference
- See how merging works, or automate payslip and statement splitting