PDF linearization API
Use the PDF linearization API to optimize PDFs for web viewing. A linearized PDF is structured so viewers can start displaying the first pages before the entire file downloads, provided the file is served from a server that supports HTTP byte-range requests.
The /build endpoint handles PDF linearization. Add the source PDF as a parts item, set output.type to pdf, and set output.optimize.linearize to true.
For signup, pricing, and task-level examples, refer to the PDF linearization API task page.
Linearize a PDF
The following example linearizes document.pdf 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": { "linearize": true } } }'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\": {\"linearize\": true}}}"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("linearize", true) ) ).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 { ["linearize"] = true } } }.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: { linearize: true } }}))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': { 'linearize': True } } }) }, 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": { "linearize": true } } }', '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": { "linearize": true } }}--customboundaryContent-Disposition: form-data; name="document"; filename="document.pdf"Content-Type: application/pdf
(document data)--customboundary--Linearize 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": { "linearize": true } }}Shell
Run this request to linearize 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": { "linearize": true } } }' \ -o result.pdfLinearize after assembling a PDF
Apply linearization to the final PDF that you plan to publish or deliver. You can assemble a document and linearize the assembled output in the same /build request.
The following example merges a cover page, body, and appendix, and then linearizes the final PDF:
{ "parts": [ { "file": "cover" }, { "file": "body" }, { "file": "appendix" } ], "output": { "type": "pdf", "optimize": { "linearize": true } }}Combine linearization with compression
You can combine linearization with other optimization options, such as mixed raster content (MRC) compression and image optimization.
Use this instructions object to combine linearization with compression:
{ "parts": [ { "file": "document" } ], "output": { "type": "pdf", "optimize": { "mrcCompression": true, "imageOptimizationQuality": 2, "linearize": true } }}For more compression options, refer to the PDF optimization API guide.
Linearize selected pages
Use parts[].pages to create a linearized output from only a selected page range. Page indexes are zero-based, and negative values count from the end of the document.
The following example extracts the first three pages and linearizes the resulting PDF:
{ "parts": [ { "file": "document", "pages": { "start": 0, "end": 2 } } ], "output": { "type": "pdf", "optimize": { "linearize": true } }}The end value is inclusive, so { "start": 0, "end": 2 } includes pages zero, one, and two.
Linearize 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": { "linearize": true } }}Nutrient DWS Processor API uses the password only to open the source document for processing. To set a password on the linearized output PDF, configure output.user_password, output.owner_password, and output.user_permissions.
Publish linearized PDFs correctly
Linearization prepares the PDF for incremental loading, but delivery still depends on how you host the file. Follow these requirements when you publish the output:
- Publish the linearized PDF from a server or object storage service that supports HTTP byte-range requests.
- Use a PDF viewer that supports incremental loading.
- Apply linearization to the final PDF after all content-changing operations are complete.
Use linearization before signing
Linearization changes the PDF file structure. If your workflow includes cryptographic signing, linearize the PDF before signing it. Treat signed PDFs as final artifacts.
A typical web delivery 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.
- Publish the signed output without further modification.
Reference
A PDF linearization request uses the Build API output.optimize.linearize option:
type OptimizePdf = { // Linearize the output PDF for fast web viewing. linearize?: boolean,
// Optional additional optimization settings. mrcCompression?: boolean, imageOptimizationQuality?: 1 | 2 | 3 | 4, disableImages?: boolean, grayscaleText?: boolean, grayscaleGraphics?: boolean, grayscaleImages?: boolean, grayscaleFormFields?: boolean, grayscaleAnnotations?: 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 include before linearization. pages?: { start?: number, end?: number, },};
type BuildInstructions = { parts: FilePart[], output: PDFOutput,};Related API reference operations
- Refer to the build document endpoint API reference to linearize PDFs and combine linearization with document assembly, page selection, compression, or security options.
Related guides
- Refer to the PDF optimization 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.