Blog/PDF tools

Split or extract PDF pages with a split pdf api

PDF tools··6 min read

To split or extract PDF pages with a split pdf api, POST one existing PDF to /v1/pdf/extract and name the pages you want to keep. The tools hub describes extract as “Split page ranges from one source PDF.” The product page is more precise: keep selected pages from one PDF. The result is a single extracted PDF, not a zip of parts and not an interval-split job. Select pages with a 1-indexed range string such as 1-2,5 or with an integer array. Product: https://relaypdf.com/pdf-tools/extract. Hub: https://relaypdf.com/pdf-tools. REST list: https://relaypdf.com/docs.

This is a PDF tool, not a renderer. You send a finished file (url or file), not HTML. Typical order is generate or convert first, then extract. Print with POST /v1/pdf, convert Office with POST /v1/convert, merge a packet with POST /v1/pdf/merge if several files must be one, then extract the pages you will ship. Each successful tools call is $0.005 on the live rate card. Failed jobs are not billed. This article uses only documented fields.

Keep pages vs drop pages

OpenAPI names the body ExtractPdfRequest. Properties: url (URI), file (string), pages (string or array of integers), filename (string), response (ResponseMode), callbackUrl (URI). There is no interval field, no splitMode, and no output-parts array. The docs hub row is “Extract or split page ranges.” The extract product page tells you the inverse: to drop pages instead, use POST /v1/pdf/delete-pages.

Use extract when the keep-set is the smaller description (cover plus two exhibits). Use delete-pages when the drop-set is the smaller description (strip a blank last page). DeletePagesPdfRequest also takes pages as a string or integer array; that schema additionally lists password. ExtractPdfRequest does not list password. Do not send password on extract.

The source PDF is url or file on the same object. Mixing both is an exclusive-source problem (invalid_request). Mixing html, markdown, or templateId into this body is not documented. file is a JSON string (base64 in REST; Python SDK file may be bytes). There is no multipart upload on this API.

You haveSend
A finished PDF; keep a subsetPOST /v1/pdf/extract
A finished PDF; drop a subsetPOST /v1/pdf/delete-pages
A public HTTPS PDFurl
PDF bytes you already holdfile (base64 in JSON; SDKs accept bytes)
Pages to keeppages: "1-2,5" or [1, 2, 5]
A Word or HTML sourceConvert or render first, then extract
Several PDFs that must be one file firstPOST /v1/pdf/merge, then extract
Need many separate filesCall extract once per keep-set (no multi-part output)

1-indexed ranges

pages is a string or an array of integers. The extract product page: “Select pages using string ranges like 1-3,5 or explicit integer arrays.” The live JSON sample is pages "1-2,5" with filename excerpt.pdf. The CLI sample is relaypdf extract report.pdf --pages 1-3 --out slice.pdf. Those examples treat page 1 as the first page of the source (1-indexed). OpenAPI does not add a second description and does not mark pages required on ExtractPdfRequest (it is required on DeletePagesPdfRequest). Product and CLI samples always send pages. Send pages.

String form is a comma-separated list of singles and hyphen ranges: 1-3,5. Array form is integers: [1, 2, 5]. Do not invent zero-based indexes, open-ended ranges, last-page tokens, or negative indexes. Those tokens are not on the schema. Order, deduplication, and out-of-range behavior are not published; if a body is rejected, treat it as invalid_request and read the message.

One request produces one PDF that contains the kept pages. There is no documented interval splitter (every N pages into N files). If you need three separate deliverables, make three extract calls with three pages values and three filenames. Zip those outputs later with POST /v1/zip if you need one download.

Limits and price (live, 23 Aug 2026 ET)

Extract is billed as a PDF tool. Pricing lists “PDF tools /v1/pdf/* · /v1/barcodes · /v1/zip” at $0.005 per successful operation. The Python SDK README names tools (merge, stamp, raster, barcode, zip, …) at the same rate. Extract is that class. Failed jobs, validation errors, 429s, and 402s do not debit.

A megabyte cap is not published on pricing, the docs hub, the extract product page, or OpenAPI. Oversized HTML or files return HTTP 413 payload_too_large. New accounts get the $5 trial. Trial rate limit is 20/min; funded or auto-reload is 60/min; burst is 5 / 10s (SDK READMEs). callbackUrl must be https. Private, loopback, and metadata hosts on url are url_not_allowed.

ConstraintPublished valueSource
EndpointPOST /v1/pdf/extractdocs hub; OpenAPI
SchemaExtractPdfRequestopenapi.json
Sourceurl or fileExtractPdfRequest
pagesstring or integer arrayExtractPdfRequest; product page
Range examples1-3,5 and 1-2,5 (1-indexed)product page; CLI
passwordNot on ExtractPdfRequestOpenAPI
OutputOne extracted PDFproduct page
InversePOST /v1/pdf/delete-pagesproduct page
Price$0.005 per successful job/pricing
Output modesbinary | url | asyncdocs hub; ResponseMode
url-mode downloadGET /v1/files/:id, 24 hours, no keydocs hub
Byte capNot published; 413 payload_too_large/docs/errors

Extract a range

Send one source plus pages. filename names the output. Default response is binary: PDF bytes plus x-relaypdf-id, x-relaypdf-size, and content-disposition. Set response to url for a 24-hour GET /v1/files/:id with no key. Set response to async for HTTP 202 and poll GET /v1/jobs/:id, or supply callbackUrl (https).

curl -X POST https://api.relaypdf.com/v1/pdf/extract
  -H "Authorization: Bearer $RELAYPDF_API_KEY"
  -H "Content-Type: application/json"
  -d '{
    "url": "https://example.com/report.pdf",
    "pages": "1-2,5",
    "filename": "excerpt.pdf"
  }'
  --output excerpt.pdf

That JSON matches the extract product page. The same keep-set as an integer array:

curl -X POST https://api.relaypdf.com/v1/pdf/extract
  -H "Authorization: Bearer $RELAYPDF_API_KEY"
  -H "Content-Type: application/json"
  -d '{
    "url": "https://example.com/report.pdf",
    "pages": [1, 2, 5],
    "filename": "excerpt.pdf",
    "response": "url"
  }'

url mode returns JSON with id, status, url, filename, sizeBytes, and expiresAt. The url is public for 24 hours. Do not put a secret document on that mode unless the leak window is acceptable. If the source must stay closed after extract, protect the excerpt with POST /v1/pdf/protect (userPassword).

Node, Python, and CLI

Python (relaypdf 0.1.x) exposes pdf.extract(pages, **input). REST field names stay camelCase. file may be bytes. Node maps the same REST body on the pdf tools surface. CLI on /docs/cli: relaypdf extract report.pdf --pages 1-3 --out slice.pdf. MCP lists extract. Do not ask anyone to paste a key; run npx @relaypdf/cli setup.

import os
from relaypdf import RelayPDF
client = RelayPDF(api_key=os.environ["RELAYPDF_API_KEY"])
pack = client.pdf.merge(
    files=[
        {"url": "https://example.com/cover.pdf"},
        {"url": "https://example.com/body.pdf"},
    ]
)
excerpt = client.pdf.extract(
    pages="1-2,5",
    file=pack.bytes,
    filename="excerpt.pdf",
)
excerpt.save("excerpt.pdf")
import { RelayPDF } from "@relaypdf/sdk";
const client = new RelayPDF({
  apiKey: process.env.RELAYPDF_API_KEY!,
});
const report = await client.pdf.fromUrl("https://example.com/report.html", {
  filename: "report.pdf",
});
const excerpt = await client.pdf.extract({
  file: report.kind === "binary" ? report.bytes : undefined,
  pages: "1-3",
  filename: "front-matter.pdf",
});
await excerpt.save("front-matter.pdf");

Errors and what is not billed

Failures are { error: { code, message } }. SDKs throw RelayPDFError. Branch on code. invalid_request covers exclusive sources, a missing or unusable pages value, or other field errors. url_not_allowed covers a private, loopback, or metadata host, or a non-https callbackUrl. payload_too_large is 413. processing_failed is a 502 on a tool job. payment_required is an empty wallet. rate_limited includes Retry-After. None of those debit.

Only a successful extract (HTTP 200, or a completed async job) takes $0.005. Rendering first is $0.015. A LibreOffice convert first is $0.04. Merge, stamp, protect, compress, info, and zip are separate tools jobs if you call them.

What this is not

Extract does not render HTML, convert Office, merge, stamp, protect, or zip. It does not split one PDF into a numbered series of files in one call. It does not OCR. It does not e-sign. Chain documented tools on the bytes or on the 24-hour url. Inverse sibling: POST /v1/pdf/delete-pages (listed on the extract product page and the tools hub). Watermark how-to: https://relaypdf.com/pdf-tools/stamp.

The public extract schema has no password, no interval, no part-count, and no published page-count cap. Do not invent them. If you need the page count before you write pages, POST /v1/pdf/info returns page count and metadata JSON as a separate tools job.

Ship it

Use the split pdf api when the source is already a PDF and you need a 1-indexed keep-set in one file. $0.005 on success. Start at https://relaypdf.com/pdf-tools/extract. Copy ExtractPdfRequest from https://relaypdf.com/openapi.json. Auth is a bearer key on https://api.relaypdf.com.

Ready to generate?

One API for HTML, Markdown, URLs, and Office. REST, SDK, CLI, or MCP.