Split a PDF at a page
Split a PDF into two documents at a page boundary: everything before the split page, then the split page onward.
Split a PDF document into two documents at a page boundary: the pages before the
split page form the first part, and the split page and everything after it form
the second part. This action returns multiple documents (here, exactly two
parts) packaged into a single response according to the Accept header. The API
is stateless: your document is processed in-region and never stored.
Endpoint
/v1/split_at_pageAvailable in every region. See Regions & data residency for routing and data residency.
| Region | URL |
|---|---|
| Global | https://api.pdfblocks.com/v1/split_at_page |
| United States | https://us.api.pdfblocks.com/v1/split_at_page |
| US HIPAA | https://hipaa.api.pdfblocks.com/v1/split_at_page |
| European Union | https://eu.api.pdfblocks.com/v1/split_at_page |
| United Kingdom | https://uk.api.pdfblocks.com/v1/split_at_page |
| Canada | https://ca.api.pdfblocks.com/v1/split_at_page |
| Australia | https://au.api.pdfblocks.com/v1/split_at_page |
| Japan | https://jp.api.pdfblocks.com/v1/split_at_page |
| India | https://in.api.pdfblocks.com/v1/split_at_page |
| Brazil | https://br.api.pdfblocks.com/v1/split_at_page |
Authentication
Authenticate every request with your secret API key in the X-API-Key header,
over HTTPS. Create and manage keys from the
dashboard. See
Authentication for details.
Request
The endpoint accepts a multipart/form-data request body.
filefilerequiredThe input PDF document.
pageintegerrequiredThe page number that begins the second part. Must be between 2 and the number
of pages in the document, so that both parts contain pages.
Examples
Split a document into two parts at page 5:
curl https://api.pdfblocks.com/v1/split_at_page \
-H 'X-API-Key: your_api_key' \
-F file=@input.pdf \
-F page=5 \
-o parts.zip# pip install requests
import requests
with open('input.pdf', 'rb') as file:
response = requests.post(
'https://api.pdfblocks.com/v1/split_at_page',
headers={'X-API-Key': 'your_api_key'},
files={'file': file},
data={'page': 5},
)
response.raise_for_status()
with open('parts.zip', 'wb') as output:
output.write(response.content)// Node.js 18+
import { readFile, writeFile } from 'node:fs/promises';
const body = new FormData();
body.set('file', new Blob([await readFile('input.pdf')]), 'input.pdf');
body.set('page', '5');
const response = await fetch('https://api.pdfblocks.com/v1/split_at_page', {
method: 'POST',
headers: { 'X-API-Key': 'your_api_key' },
body,
});
if (!response.ok) throw new Error(`Request failed: ${response.status}`);
await writeFile('parts.zip', Buffer.from(await response.arrayBuffer()));<?php
$ch = curl_init('https://api.pdfblocks.com/v1/split_at_page');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['X-API-Key: your_api_key'],
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => [
'file' => new CURLFile('input.pdf', 'application/pdf'),
'page' => '5',
],
]);
$zip = curl_exec($ch);
if (curl_getinfo($ch, CURLINFO_HTTP_CODE) === 200) {
file_put_contents('parts.zip', $zip);
}# gem install http
require 'http'
response = HTTP
.headers('X-API-Key' => 'your_api_key')
.post('https://api.pdfblocks.com/v1/split_at_page', form: {
file: HTTP::FormData::File.new('input.pdf'),
page: '5',
})
File.write('parts.zip', response.body) if response.status.success?package main
import (
"bytes"
"io"
"mime/multipart"
"net/http"
"os"
)
func main() {
var buf bytes.Buffer
form := multipart.NewWriter(&buf)
file, _ := os.Open("input.pdf")
defer file.Close()
part, _ := form.CreateFormFile("file", "input.pdf")
io.Copy(part, file)
form.WriteField("page", "5")
form.Close()
req, _ := http.NewRequest("POST", "https://api.pdfblocks.com/v1/split_at_page", &buf)
req.Header.Set("Content-Type", form.FormDataContentType())
req.Header.Set("X-API-Key", "your_api_key")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
out, _ := os.Create("parts.zip")
defer out.Close()
io.Copy(out, res.Body)
}using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "your_api_key");
using var form = new MultipartFormDataContent
{
{ new ByteArrayContent(File.ReadAllBytes("input.pdf")), "file", "input.pdf" },
{ new StringContent("5"), "page" },
};
var response = await client.PostAsync(
"https://api.pdfblocks.com/v1/split_at_page", form);
response.EnsureSuccessStatusCode();
await File.WriteAllBytesAsync(
"parts.zip", await response.Content.ReadAsByteArrayAsync());The ZIP contains exactly two documents: 00001.pdf holds pages 1–4, and
00002.pdf holds page 5 through the end.
Response
This action returns multiple documents, packaged into a single response
according to the Accept request header. See
Response formats & content negotiation for the full
negotiation reference. With no Accept header, the default is a ZIP archive:
HTTP/1.1 200 OK
Content-Type: application/zipSelect the packaging with the Accept header:
Accept header |
Response |
|---|---|
| (none sent) | application/zip, the default |
application/zip |
A ZIP archive of the output PDFs |
application/json |
A JSON envelope of base64-encoded documents |
multipart/mixed |
One PDF per part |
| anything else | 406 Not Acceptable |
The output is always exactly two documents, named 00001.pdf (the pages before
the split page) and 00002.pdf (the split page and everything after it).
For end-to-end code that calls a split action and unpacks each format (extracting the ZIP, decoding the JSON envelope, or reading the multipart parts), see the Splitting a PDF guide.
Errors
Failed requests return an application/problem+json body. The most common one
for this endpoint is a 400, returned when page is missing or out of range, or
when file isn’t a readable PDF. The errors object names each field:
{
"type": "https://www.pdfblocks.com/docs/api/v1/error/400",
"title": "One or more validation errors occurred.",
"status": 400,
"errors": {
"page": ["The field page must be between 2 and the number of pages in the document."]
}
}If the Accept header matches none of application/zip, application/json, or
multipart/mixed (for example Accept: application/pdf), the API responds with
406 Not Acceptable. Omit Accept to take the ZIP default, or request one of the
supported media types. A missing or invalid X-API-Key returns a 401. See
Errors for every status code and the full response shape.
Recipes
A common variation. Expand it to see the code in every language.
Receive the parts as a JSON envelope
Send Accept: application/json to get every part inline in one response, then
base64-decode each entry’s content to a file named by its name:
curl https://api.pdfblocks.com/v1/split_at_page \
-H 'X-API-Key: your_api_key' \
-H 'Accept: application/json' \
-F file=@input.pdf \
-F page=5 \
| jq -r '.documents[] | .name + " " + .content' \
| while read -r name content; do
echo "$content" | base64 --decode > "$name"
done# pip install requests
import base64
import requests
with open('input.pdf', 'rb') as file:
response = requests.post(
'https://api.pdfblocks.com/v1/split_at_page',
headers={
'X-API-Key': 'your_api_key',
'Accept': 'application/json',
},
files={'file': file},
data={'page': 5},
)
response.raise_for_status()
for document in response.json()['documents']:
with open(document['name'], 'wb') as output:
output.write(base64.b64decode(document['content']))// Node.js 18+
import { readFile, writeFile } from 'node:fs/promises';
const body = new FormData();
body.set('file', new Blob([await readFile('input.pdf')]), 'input.pdf');
body.set('page', '5');
const response = await fetch('https://api.pdfblocks.com/v1/split_at_page', {
method: 'POST',
headers: { 'X-API-Key': 'your_api_key', Accept: 'application/json' },
body,
});
if (!response.ok) throw new Error(`Request failed: ${response.status}`);
const { documents } = await response.json();
for (const doc of documents) {
await writeFile(doc.name, Buffer.from(doc.content, 'base64'));
}<?php
$ch = curl_init('https://api.pdfblocks.com/v1/split_at_page');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'X-API-Key: your_api_key',
'Accept: application/json',
],
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => [
'file' => new CURLFile('input.pdf', 'application/pdf'),
'page' => '5',
],
]);
$body = curl_exec($ch);
if (curl_getinfo($ch, CURLINFO_HTTP_CODE) === 200) {
foreach (json_decode($body, true)['documents'] as $document) {
file_put_contents($document['name'], base64_decode($document['content']));
}
}# gem install http
require 'base64'
require 'http'
require 'json'
response = HTTP
.headers('X-API-Key' => 'your_api_key', 'Accept' => 'application/json')
.post('https://api.pdfblocks.com/v1/split_at_page', form: {
file: HTTP::FormData::File.new('input.pdf'),
page: '5',
})
if response.status.success?
JSON.parse(response.body)['documents'].each do |document|
File.write(document['name'], Base64.decode64(document['content']))
end
endpackage main
import (
"bytes"
"encoding/base64"
"encoding/json"
"io"
"mime/multipart"
"net/http"
"os"
)
func main() {
var buf bytes.Buffer
form := multipart.NewWriter(&buf)
file, _ := os.Open("input.pdf")
defer file.Close()
part, _ := form.CreateFormFile("file", "input.pdf")
io.Copy(part, file)
form.WriteField("page", "5")
form.Close()
req, _ := http.NewRequest("POST", "https://api.pdfblocks.com/v1/split_at_page", &buf)
req.Header.Set("Content-Type", form.FormDataContentType())
req.Header.Set("X-API-Key", "your_api_key")
req.Header.Set("Accept", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
var result struct {
Documents []struct {
Name string `json:"name"`
Content string `json:"content"`
} `json:"documents"`
}
json.NewDecoder(res.Body).Decode(&result)
for _, doc := range result.Documents {
data, _ := base64.StdEncoding.DecodeString(doc.Content)
os.WriteFile(doc.Name, data, 0644)
}
}using System.Text.Json;
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "your_api_key");
client.DefaultRequestHeaders.Add("Accept", "application/json");
using var form = new MultipartFormDataContent
{
{ new ByteArrayContent(File.ReadAllBytes("input.pdf")), "file", "input.pdf" },
{ new StringContent("5"), "page" },
};
var response = await client.PostAsync(
"https://api.pdfblocks.com/v1/split_at_page", form);
response.EnsureSuccessStatusCode();
using var json = JsonDocument.Parse(
await response.Content.ReadAsStringAsync());
foreach (var document in json.RootElement.GetProperty("documents").EnumerateArray())
{
var name = document.GetProperty("name").GetString()!;
var content = document.GetProperty("content").GetString()!;
await File.WriteAllBytesAsync(name, Convert.FromBase64String(content));
}