PDF optimization API
Use the PDF optimization API to reduce PDF file size and prepare documents for storage, sharing, or delivery. Nutrient DWS Processor API supports image optimization, mixed raster content (MRC) compression, grayscale conversion, image removal, and linearization options.
The /build endpoint handles PDF optimization. Add the source PDF as a parts item, set output.type to pdf, and configure output.optimize.
For signup, pricing, and task-level examples, refer to the PDF optimization API task page.
Optimize a PDF
The following example optimizes document.pdf with image optimization and MRC compression and writes the output to result.pdf:
curl -X POST https://api.nutrient.io/build \ -H "Authorization: Bearer your_api_key_here" \ -o result.pdf \ --fail \ -F document=@document.pdf \ -F instructions='{ "parts": [ { "file": "document" } ], "output": { "type": "pdf", "optimize": { "disableImages": false, "mrcCompression": true, "imageOptimizationQuality": 2 } } }'curl -X POST https://api.nutrient.io/build ^ -H "Authorization: Bearer your_api_key_here" ^ -o result.pdf ^ --fail ^ -F document=@document.pdf ^ -F instructions="{\"parts\": [{\"file\": \"document\"}], \"output\": {\"type\": \"pdf\", \"optimize\": {\"disableImages\": false, \"mrcCompression\": true, \"imageOptimizationQuality\": 2}}}"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 body = 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("output", new JSONObject() .put("type", "pdf") .put("optimize", new JSONObject() .put("disableImages", false) .put("mrcCompression", true) .put("imageOptimizationQuality", 2) ) ).toString() ) .build();
final Request request = new Request.Builder() .url("https://api.nutrient.io/build") .method("POST", body) .addHeader("Authorization", "Bearer your_api_key_here") .build();
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("result.pdf"), 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 request = 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" } }, ["output"] = new JsonObject { ["type"] = "pdf", ["optimize"] = new JsonObject { ["disableImages"] = false, ["mrcCompression"] = true, ["imageOptimizationQuality"] = 2 } } }.ToString());
request.AdvancedResponseWriter = (responseStream, response) => { if (response.StatusCode == HttpStatusCode.OK) { using (responseStream) { using var outputFileWriter = File.OpenWrite("result.pdf"); responseStream.CopyTo(outputFileWriter); } } else { var responseStreamReader = new StreamReader(responseStream); Console.Write(responseStreamReader.ReadToEnd()); } };
client.Execute(request); } }}// 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')
const formData = new FormData()formData.append('instructions', JSON.stringify({ parts: [ { file: "document" } ], output: { type: "pdf", optimize: { disableImages: false, mrcCompression: true, imageOptimizationQuality: 2 } }}))formData.append('document', fs.createReadStream('document.pdf'))
;(async () => { 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("result.pdf")) } 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
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' } ], 'output': { 'type': 'pdf', 'optimize': { 'disableImages': False, 'mrcCompression': True, 'imageOptimizationQuality': 2 } } }) }, stream = True)
if response.ok: with open('result.pdf', 'wb') as fd: for chunk in response.iter_content(chunk_size=8096): fd.write(chunk)else: print(response.text) exit()<?php
$FileHandle = fopen('result.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" } ], "output": { "type": "pdf", "optimize": { "disableImages": false, "mrcCompression": true, "imageOptimizationQuality": 2 } } }', '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);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" } ], "output": { "type": "pdf", "optimize": { "disableImages": false, "mrcCompression": true, "imageOptimizationQuality": 2 } }}--customboundaryContent-Disposition: form-data; name="document"; filename="document.pdf"Content-Type: application/pdf
(document data)--customboundary--Adjust image optimization quality
Use imageOptimizationQuality to control the tradeoff between file size and image quality. Supported values are 1, 2, 3, and 4.
1— Lowest file size and strongest compression.2— Balanced compression. Processor API examples use this value by default.3— Higher image quality.4— Highest image quality and lowest compression.
Use this instructions object to set image optimization quality:
{ "parts": [ { "file": "document" } ], "output": { "type": "pdf", "optimize": { "imageOptimizationQuality": 1 } }}Review optimized output visually when image fidelity matters.
Use MRC compression for scanned PDFs
MRC compression works well for scanned documents and mixed raster content. It can reduce file size while preserving readable text and important visual details.
Use this instructions object to enable MRC compression:
{ "parts": [ { "file": "scanned_document" } ], "output": { "type": "pdf", "optimize": { "mrcCompression": true, "imageOptimizationQuality": 2 } }}Convert content to grayscale
Use grayscale options when color isn’t required and you want to reduce output size or normalize document appearance.
Use this instructions object to convert content to grayscale:
{ "parts": [ { "file": "document" } ], "output": { "type": "pdf", "optimize": { "grayscaleText": true, "grayscaleGraphics": true, "grayscaleImages": true, "grayscaleFormFields": true, "grayscaleAnnotations": true } }}You can enable these options independently for text, graphics, images, form fields, and annotations.
Remove images
Set disableImages to true to remove images from the output PDF. Use this option only when images aren’t required in the final document.
Use this instructions object to remove images:
{ "parts": [ { "file": "document" } ], "output": { "type": "pdf", "optimize": { "disableImages": true } }}Removing images can reduce file size, but it changes the document’s visual appearance.
Optimize a PDF from a URL
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" } } ], "output": { "type": "pdf", "optimize": { "mrcCompression": true, "imageOptimizationQuality": 2 } }}Shell
Run this request to optimize a PDF from a URL:
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" } } ], "output": { "type": "pdf", "optimize": { "mrcCompression": true, "imageOptimizationQuality": 2 } } }' \ -o result.pdfOptimize selected PDF pages
Use parts[].pages to optimize only a page range from the source PDF. Page indexes are zero-based, and negative values count from the end of the document.
The following example optimizes only the first three pages:
{ "parts": [ { "file": "document", "pages": { "start": 0, "end": 2 } } ], "output": { "type": "pdf", "optimize": { "imageOptimizationQuality": 2 } }}The end value is inclusive, so { "start": 0, "end": 2 } includes pages zero, one, and two.
Optimize 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" } ], "output": { "type": "pdf", "optimize": { "imageOptimizationQuality": 2 } }}Nutrient DWS Processor API uses the password only to open the source document for processing. To set a password on the optimized output PDF, configure output.user_password, output.owner_password, and output.user_permissions.
Optimize and linearize for web delivery
You can combine optimization with linearization. Linearization restructures the PDF so viewers that support byte-range requests can load it incrementally over the network.
Use this instructions object to optimize and linearize a PDF:
{ "parts": [ { "file": "document" } ], "output": { "type": "pdf", "optimize": { "mrcCompression": true, "imageOptimizationQuality": 2, "linearize": true } }}For more details, refer to the PDF linearization API guide.
Use optimization before signing
Optimization changes the PDF file. If your workflow includes cryptographic signing, optimize the document before signing it. Treat signed PDFs as final artifacts.
A typical workflow includes these steps:
- Merge, split, rotate, fill forms, redact, or watermark the document.
- Optimize or linearize the final output.
- Apply a digital signature last, if required.
Reference
A PDF optimization request uses the Build API output.optimize object:
type OptimizePdf = { grayscaleText?: boolean; grayscaleGraphics?: boolean; grayscaleImages?: boolean; grayscaleFormFields?: boolean; grayscaleAnnotations?: boolean; disableImages?: boolean; mrcCompression?: boolean;
// Supported values are 1 through 4. imageOptimizationQuality?: 1 | 2 | 3 | 4;
// Linearize the output PDF for fast web viewing. linearize?: boolean;};
type PDFOutput = { type: "pdf"; optimize?: OptimizePdf;};
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 optimize. pages?: { start?: number; end?: number; };};
type BuildInstructions = { parts: FilePart[]; output: PDFOutput;};Related API reference operations
- Refer to the build document endpoint API reference to optimize PDFs and combine optimization with page selection, document assembly, security, or linearization.
Related guides
- Refer to the PDF linearization API guide.
- Refer to the PDF security API guide.
- Refer to the PDF digital signature API guide.
- Refer to the PDF merge API guide.
- Refer to the PDF split API guide.
- Refer to the tools and APIs guide.