Skip to content

Split PDF

Splits a PDF into one single-page PDF per page and returns a link to each, in page order. The source can be a public http(s):// URL or an s3:// object.

Slugsplit-pdf
SyncPOST /v1/utilities/split-pdfrunSplitPdf
AsyncPOST /v1/utilities/split-pdf/jobscreateSplitPdfJob
Max duration900 s (15 min)
OutputN application/pdf files, one per page, plus pageCount

Quick example

bash
curl -X POST https://api.servicelabs.dev/v1/utilities/split-pdf \
  -H "Authorization: Bearer $DU_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "input": { "url": "https://example.com/statement.pdf" } }'
js
const base = 'https://api.servicelabs.dev'
const headers = {
  Authorization: `Bearer ${process.env.DU_API_KEY}`,
  'Content-Type': 'application/json',
}

// 1. start the job
const started = await fetch(`${base}/v1/utilities/split-pdf/jobs`, {
  method: 'POST',
  headers,
  body: JSON.stringify({ input: { url: 's3://finnoto-data/uploads/statement.pdf' } }),
}).then((r) => r.json())

// 2. long-poll until it finishes (each call waits up to 30 s)
let job = started
while (!['succeeded', 'failed', 'cancelled'].includes(job.status)) {
  job = await fetch(`${base}/v1/jobs/${started.id}?wait=30`, { headers }).then((r) => r.json())
}

if (job.status === 'succeeded') {
  for (const page of job.result.files) console.log(page.pageNumber, page.url)
} else {
  console.error(job.error)
}
python
import os, requests

job = requests.post(
    "https://api.servicelabs.dev/v1/utilities/split-pdf",
    headers={"Authorization": f"Bearer {os.environ['DU_API_KEY']}"},
    json={"input": {"url": "https://example.com/statement.pdf"}},
    timeout=100,
).json()

for f in job["result"]["files"]:
    print(f["pageNumber"], f["url"])
json
// → 200 OK (abridged)
{
  "id": "job_01K7Z3Q4N5P6R7S8T9V0W1X2Y3",
  "utility": "split-pdf",
  "status": "succeeded",
  "timings": { "queueMs": 0, "upstreamMs": 1320, "storageMs": 95, "totalMs": 1438 },
  "result": {
    "pageCount": 3,
    "files": [
      {
        "url": "https://files.servicelabs.dev/split-pdf/2026-09-10/job_01K7Z3Q4N5P6R7S8T9V0W1X2Y3/page-1.pdf",
        "key": "split-pdf/2026-09-10/job_01K7Z3Q4N5P6R7S8T9V0W1X2Y3/page-1.pdf",
        "name": "page-1.pdf",
        "size": 48211,
        "contentType": "application/pdf",
        "pageNumber": 1
      },
      { "name": "page-2.pdf", "pageNumber": 2, "…": "…" },
      { "name": "page-3.pdf", "pageNumber": 3, "…": "…" }
    ]
  },
  "error": null
}

Input

FieldTypeRequiredDescription
urlstringyesThe PDF to split. http://, https:// or s3://, ≤ 4096 chars.

No other input fields are accepted.

Result

FieldDescription
result.pageCountNumber of pages produced (= files.length).
result.files[]One entry per page, in page order.
files[].pageNumber1-indexed page number.
files[].namepage-<N>.pdf (no zero padding — use pageNumber to order).
files[].contentTypeapplication/pdf.

Limits & behaviour

LimitValue
Maximum source size150 MB (streamed with a running size check — oversized downloads abort early)
Maximum pages500
Source download timeout60 s
Encrypted / password-protected PDFsrejected — decrypt first
Empty (0-page) PDFsrejected
  • Splitting is fast and memory-light (pages are copied, not re-rendered), so even 500-page documents finish well inside the time limit. Most of the wall-clock time is the download and the copy of N files to storage.
  • Pages are written sequentially. For documents with hundreds of pages prefer the async route: the sync route answers 202 with the job id if it runs past 90 s anyway.

Errors specific to this utility

SituationOutcome
url missing or not http(s):// / s3://400 invalid_request — no job
Download failed, or source > 150 MBfailed job, 422 upstream_rejected
Not a valid PDF / unsupported PDFfailed job, 422 upstream_rejected (Invalid or unsupported PDF: …)
Password-protected PDFfailed job, 422 upstream_rejected (Password-protected PDFs are not supported)
More than 500 pages, or 0 pagesfailed job, 422 upstream_rejected
Unexpected failure mid-splitfailed job, 502 upstream_error

See Conventions & errors for the full table.

ServiceLabs · a Finnoto company