Use the PDF split API to create a new PDF from selected pages of an existing PDF. The /build endpoint handles the split operation. Add the source PDF as a parts item, and set a pages range for the pages you want in the output.
For signup, pricing, and task-level examples, refer to the split PDF API task page.
Extract a page range
The following example extracts the first three pages from document.pdf and writes them to result.pdf.
Page indexes are zero-based, so page 0 is the first page. The end value is inclusive, so { "start": 0, "end": 2 } includes pages zero, one, and two.
curl -X POST https://api.nutrient.io/build \ -H "Authorization: Bearer your_api_key_here" \ -o first_half.pdf \ --fail \ -F document=@document.pdf \ -F instructions='{ "parts": [ { "file": "document", "pages": { "end": -6 } } ] }'
curl -X POST https://api.nutrient.io/build \ -H "Authorization: Bearer your_api_key_here" \ -o second_half.pdf \ --fail \ -F document=@document.pdf \ -F instructions='{ "parts": [ { "file": "document", "pages": { "start": -5 } } ] }'curl -X POST https://api.nutrient.io/build ^ -H "Authorization: Bearer your_api_key_here" ^ -o first_half.pdf ^ --fail ^ -F document=@document.pdf ^ -F instructions="{\"parts\": [{\"file\": \"document\", \"pages\": {\"end\": -6}}]}"
curl -X POST https://api.nutrient.io/build ^ -H "Authorization: Bearer your_api_key_here" ^ -o second_half.pdf ^ --fail ^ -F document=@document.pdf ^ -F instructions="{\"parts\": [{\"file\": \"document\", \"pages\": {\"start\": -5}}]}"package com.example.pspdfkit;
import java.io.File;import java.io.IOException;import java.nio.file.FileSystems;import java.nio.file.Files;import java.nio.file.StandardCopyOption;
import org.json.JSONArray;import org.json.JSONObject;
import okhttp3.MediaType;import okhttp3.MultipartBody;import okhttp3.OkHttpClient;import okhttp3.Request;import okhttp3.RequestBody;import okhttp3.Response;
public final class PspdfkitApiExample { public static void main(final String[] args) throws IOException { final RequestBody firstHalfBody = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart( "document", "document.pdf", RequestBody.create( MediaType.parse("application/pdf"), new File("document.pdf") ) ) .addFormDataPart( "instructions", new JSONObject() .put("parts", new JSONArray() .put(new JSONObject() .put("file", "document") .put("pages", new JSONObject() .put("end", -6) ) ) ).toString() ) .build();
final Request firstHalfRequest = new Request.Builder() .url("https://api.nutrient.io/build") .method("POST", firstHalfBody) .addHeader("Authorization", "Bearer your_api_key_here") .build();
final RequestBody secondHalfBody = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart( "document", "document.pdf", RequestBody.create( MediaType.parse("application/pdf"), new File("document.pdf") ) ) .addFormDataPart( "instructions", new JSONObject() .put("parts", new JSONArray() .put(new JSONObject() .put("file", "document") .put("pages", new JSONObject() .put("start", -5) ) ) ).toString() ) .build();
final Request secondHalfRequest = new Request.Builder() .url("https://api.nutrient.io/build") .method("POST", secondHalfBody) .addHeader("Authorization", "Bearer your_api_key_here") .build();
executeRequest(firstHalfRequest, "first_half.pdf"); executeRequest(secondHalfRequest, "second_half.pdf"); }
private static void executeRequest(final Request request, final String outputFileName) throws IOException { final OkHttpClient client = new OkHttpClient() .newBuilder() .build();
final Response response = client.newCall(request).execute();
if (response.isSuccessful()) { Files.copy( response.body().byteStream(), FileSystems.getDefault().getPath(outputFileName), StandardCopyOption.REPLACE_EXISTING ); } else { // Handle the error throw new IOException(response.body().string()); } }}using System;using System.IO;using System.Net;using RestSharp;
namespace PspdfkitApiDemo{ class Program { static void Main(string[] args) { var client = new RestClient("https://api.nutrient.io/build");
var firstHalfRequest = new RestRequest(Method.POST) .AddHeader("Authorization", "Bearer your_api_key_here") .AddFile("document", "document.pdf") .AddParameter("instructions", new JsonObject { ["parts"] = new JsonArray { new JsonObject { ["file"] = "document", ["pages"] = new JsonObject { ["end"] = -6 } } } }.ToString());
firstHalfRequest.AdvancedResponseWriter = OutputFileResponseWriter("first_half.pdf");
var secondHalfRequest = new RestRequest(Method.POST) .AddHeader("Authorization", "Bearer your_api_key_here") .AddFile("document", "document.pdf") .AddParameter("instructions", new JsonObject { ["parts"] = new JsonArray { new JsonObject { ["file"] = "document", ["pages"] = new JsonObject { ["start"] = -5 } } } }.ToString());
secondHalfRequest.AdvancedResponseWriter = OutputFileResponseWriter("second_half.pdf");
client.Execute(firstHalfRequest); client.Execute(secondHalfRequest); }
static Action<Stream, IHttpResponse> OutputFileResponseWriter(string outputFileName) { return (responseStream, response) => { if (response.StatusCode == HttpStatusCode.OK) { using (responseStream) { using var outputFileWriter = File.OpenWrite(outputFileName); responseStream.CopyTo(outputFileWriter); } } else { var responseStreamReader = new StreamReader(responseStream); Console.Write(responseStreamReader.ReadToEnd()); } }; } }}// This code requires Node.js. Do not run this code directly in a web browser.
const axios = require('axios')const FormData = require('form-data')const fs = require('fs')
;(async () => { const firstHalf = new FormData() firstHalf.append('instructions', JSON.stringify({ parts: [ { file: "document", pages: { end: -6 } } ] })) firstHalf.append('document', fs.createReadStream('document.pdf'))
const secondHalf = new FormData() secondHalf.append('instructions', JSON.stringify({ parts: [ { file: "document", pages: { start: -5 } } ] })) secondHalf.append('document', fs.createReadStream('document.pdf'))
await executeRequest(firstHalf, "first_half.pdf") await executeRequest(secondHalf, "second_half.pdf")})()
async function executeRequest(formData, outputFile) { try { const response = await axios.post('https://api.nutrient.io/build', formData, { headers: formData.getHeaders({ 'Authorization': 'Bearer your_api_key_here' }), responseType: "stream" })
response.data.pipe(fs.createWriteStream(outputFile)) } catch (e) { const errorString = await streamToString(e.response.data) console.log(errorString) }}
function streamToString(stream) { const chunks = [] return new Promise((resolve, reject) => { stream.on("data", (chunk) => chunks.push(Buffer.from(chunk))) stream.on("error", (err) => reject(err)) stream.on("end", () => resolve(Buffer.concat(chunks).toString("utf8"))) })}import requestsimport json
def process_first_half(): response = requests.request( 'POST', 'https://api.nutrient.io/build', headers = { 'Authorization': 'Bearer your_api_key_here' }, files = { 'document': open('document.pdf', 'rb') }, data = { 'instructions': json.dumps({ 'parts': [ { 'file': 'document', 'pages': { 'end': -6 } } ] }) }, stream = True )
if response.ok: with open('first_half.pdf', 'wb') as fd: for chunk in response.iter_content(chunk_size=8096): fd.write(chunk) else: print(response.text) exit()
def process_second_half(): response = requests.request( 'POST', 'https://api.nutrient.io/build', headers = { 'Authorization': 'Bearer your_api_key_here' }, files = { 'document': open('document.pdf', 'rb') }, data = { 'instructions': json.dumps({ 'parts': [ { 'file': 'document', 'pages': { 'start': -5 } } ] }) }, stream = True )
if response.ok: with open('second_half.pdf', 'wb') as fd: for chunk in response.iter_content(chunk_size=8096): fd.write(chunk) else: print(response.text) exit()
process_first_half()process_second_half()<?php
function process_first_half() { $FileHandle = fopen('first_half.pdf', 'w+');
$curl = curl_init();
curl_setopt_array($curl, array( CURLOPT_URL => 'https://api.nutrient.io/build', CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_POSTFIELDS => array( 'instructions' => '{ "parts": [ { "file": "document", "pages": { "end": -6 } } ] }', 'document' => new CURLFILE('document.pdf') ), CURLOPT_HTTPHEADER => array( 'Authorization: Bearer your_api_key_here' ), CURLOPT_FILE => $FileHandle, ));
$response = curl_exec($curl);
curl_close($curl);
fclose($FileHandle);}
function process_second_half() { $FileHandle = fopen('second_half.pdf', 'w+');
$curl = curl_init();
curl_setopt_array($curl, array( CURLOPT_URL => 'https://api.nutrient.io/build', CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_POSTFIELDS => array( 'instructions' => '{ "parts": [ { "file": "document", "pages": { "start": -5 } } ] }', 'document' => new CURLFILE('document.pdf') ), CURLOPT_HTTPHEADER => array( 'Authorization: Bearer your_api_key_here' ), CURLOPT_FILE => $FileHandle, ));
$response = curl_exec($curl);
curl_close($curl);
fclose($FileHandle);}
process_first_half();process_second_half();POST https://api.nutrient.io/build HTTP/1.1Content-Type: multipart/form-data; boundary=--customboundaryAuthorization: Bearer your_api_key_here
--customboundaryContent-Disposition: form-data; name="instructions"Content-Type: application/json
{ "parts": [ { "file": "document", "pages": { "end": -6 } } ]}--customboundaryContent-Disposition: form-data; name="document"; filename="document.pdf"Content-Type: application/pdf
(document data)--customboundary--
POST https://api.nutrient.io/build HTTP/1.1Content-Type: multipart/form-data; boundary=--customboundaryAuthorization: Bearer your_api_key_here
--customboundaryContent-Disposition: form-data; name="instructions"Content-Type: application/json
{ "parts": [ { "file": "document", "pages": { "start": -5 } } ]}--customboundaryContent-Disposition: form-data; name="document"; filename="document.pdf"Content-Type: application/pdf
(document data)--customboundary--Split a PDF into two files
The /build endpoint returns one output file per request. To split one PDF into two separate PDFs, send two requests with complementary page ranges.
The following example creates these files:
first_half.pdf— All pages except the last five.second_half.pdf— The last five pages.
Negative page indexes count from the end of the document. For example, -1 is the last page, -2 is the second-to-last page, and so on.
Shell
Run these requests to create two output PDFs:
curl -X POST https://api.nutrient.io/build \ -H "Authorization: Bearer $NUTRIENT_API_KEY" \ -F document=@document.pdf \ -F 'instructions={ "parts": [ { "file": "document", "pages": { "end": -6 } } ] }' \ -o first_half.pdf
curl -X POST https://api.nutrient.io/build \ -H "Authorization: Bearer $NUTRIENT_API_KEY" \ -F document=@document.pdf \ -F 'instructions={ "parts": [ { "file": "document", "pages": { "start": -5 } } ] }' \ -o second_half.pdfExtract pages from a remote PDF
For remotely hosted source files, send a JSON request and pass the source URL in parts[].file.url. Use this instructions object:
{ "parts": [ { "file": { "url": "https://example.com/document.pdf" }, "pages": { "start": 3, "end": 7 } } ]}Shell
Run this request to extract pages from a remote PDF:
curl -X POST https://api.nutrient.io/build \ -H "Authorization: Bearer $NUTRIENT_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "parts": [ { "file": { "url": "https://example.com/document.pdf" }, "pages": { "start": 3, "end": 7 } } ] }' \ -o result.pdfExtract the last page
Use -1 for both start and end to extract only the last page of a document. Use this instructions object:
{ "parts": [ { "file": "document", "pages": { "start": -1, "end": -1 } } ]}Create a packet from multiple page ranges
Include more than one parts item to assemble selected ranges into a single output PDF. Use this approach when you want to split out specific sections and combine them into a new packet.
The following example creates one PDF from pages zero through two and pages 10 through the end of the same source document:
{ "parts": [ { "file": "document", "pages": { "start": 0, "end": 2 } }, { "file": "document", "pages": { "start": 10, "end": -1 } } ]}The order of the parts array controls the page order in the output PDF.
Split password-protected PDFs
If the source PDF is password-protected, include the password on the part. Use this instructions object:
{ "parts": [ { "file": "protected_document", "password": "document-password", "pages": { "start": 0, "end": 2 } } ]}Nutrient DWS Processor API uses the password only to open the source document for processing. To set a password on the output PDF, configure output.user_password, output.owner_password, and output.user_permissions.
Combine splitting with other actions
The /build endpoint can extract pages and then apply actions to the resulting PDF. Actions run after Nutrient DWS Processor API assembles the selected parts.
The following example extracts pages zero through two and then rotates the output by 90 degrees:
{ "parts": [ { "file": "document", "pages": { "start": 0, "end": 2 } } ], "actions": [ { "type": "rotate", "rotateBy": 90 } ]}For workflows that include signing, extract or split the required pages before signing the final PDF.
Reference
A PDF split request uses the Build API parts array. Each part can include an optional pages range:
type PageRange = { // First page to include. Defaults to 0. // Page indexes are zero-based. Negative values count from the end. start?: number,
// Last page to include. Defaults to -1, which means the last page. // The end value is inclusive. end?: number,};
type FilePart = { // Multipart field name, or a remote URL object. file: string | { url: string },
// Optional password for encrypted input PDFs. password?: string,
// Optional page range to extract from this part. pages?: PageRange,};
type BuildInstructions = { parts: FilePart[], actions?: BuildAction[], output?: { type?: "pdf", },};Related API reference operations
- Refer to the build document endpoint API reference for extracting page ranges, assembling selected pages, and applying follow-up actions in a single request.
Related guides
- Refer to the PDF merge API guide.
- Refer to the PDF rotate API guide.
- Refer to the PDF flatten API guide.
- Refer to the PDF watermark API guide.
- Refer to the PDF security API guide.
- Refer to the tools and APIs guide.