Skip to main content

Overview

This tutorial walks you through optimizing a PDF end-to-end with the Nitro PDF Services API. Optimization is a good first integration because it exercises the full request shape (auth, file upload, parameters, and result download) in a single call. The Optimize method of the Transformations endpoint restructures a PDF and applies image downsampling according to a chosen profile, producing an output tailored to a specific use case such as web viewing, printing, or archiving. This tutorial covers:
  1. Choosing an optimization profile
  2. Sending the optimize request
  3. Downloading the optimized file
  4. Running asynchronously for large files

Prerequisites

Authentication

You will need an access token to authenticate your requests. Check the Getting Started guide first to obtain a client_id and client_secret and generate an access token.

A PDF to optimize

You can use any PDF file you have available. The endpoint accepts files up to 100 MB and 500 pages.

1. Choosing an optimization profile

The params.profile field controls how the PDF is restructured and how aggressively images are downsampled. Pick the profile that matches your end use:
  • web — Linearizes the PDF for fast web delivery and downsamples images to screen resolution. Best for online viewing and email attachments.
  • print — Preserves print-resolution images and optimizes for fidelity over size. Best for high-quality printing.
  • archive — Converts to PDF/A, embedding all fonts and color profiles. Best for long-term storage and compliance.
  • minimal-file-size — Aggressively downsamples images and removes redundant data to produce the smallest possible file. Best when size reduction is the priority.
  • mixed-raster-content — Applies MRC compression, separating text and background layers. Best for scanned documents and pages mixing text and images.
If your goal is to shrink the file as much as possible, start with minimal-file-size.
More aggressive file size minimization will result in lower image quality for some or all images in the PDF.

2. Sending the optimize request

You send a multipart POST request and pass method=optimize together with the parameters and the input file. The request body fields are:
  • method: Always optimize for this operation.
  • params: JSON object with the optimization profile ({"profile": "minimal-file-size"}).
  • file: The PDF binary to optimize.
Request:
curl --request POST https://api.gonitro.dev/platform/transformations \
  --header 'Authorization: Bearer <access_token>' \
  --form 'method=optimize' \
  --form 'params={"profile":"minimal-file-size"}' \
  --form 'file=@/path/to/your-file.pdf'
Response example: By default, the endpoint runs synchronously and responds with JSON containing a pre-signed URL to the optimized file.
  • result.file.URL: A pre-signed download URL for the optimized PDF. Valid for 15 minutes.
  • result.file.contentType: Always application/pdf for optimize output.
  • result.file.metadata.fileSizeBytes: Size of the optimized output.
  • result.file.metadata.pageCount: Page count of the output PDF.
{
  "result": {
    "file": {
      "URL": "https://your-optimized-file.pdf",
      "contentType": "application/pdf",
      "metadata": {
        "fileSizeBytes": 8543,
        "pageCount": 1
      }
    }
  }
}

3. Downloading the optimized file

Fetch the optimized PDF from the pre-signed URL returned in result.file.URL. No authentication header is needed — the URL is already signed.
curl --output optimized.pdf "<result.file.URL>"
The pre-signed URL expires 15 minutes after the response is issued. Download the file (or copy it to your own storage) before then.

Get the binary directly

If you would rather skip the download step and have the response stream the optimized file back, set the Accept header to application/octet-stream:
curl --request POST https://api.gonitro.dev/platform/transformations \
  --header 'Authorization: Bearer <access_token>' \
  --header 'Accept: application/octet-stream' \
  --form 'method=optimize' \
  --form 'params={"profile":"minimal-file-size"}' \
  --form 'file=@/path/to/your-file.pdf' \
  --output optimized.pdf
Binary output is only supported in synchronous mode.

4. Running asynchronously for large files

For files that take a long time to process — or to avoid keeping a long-lived HTTP connection open — switch the request to async by setting Prefer: respond-async. Request:
curl --request POST https://api.gonitro.dev/platform/transformations \
  --header 'Authorization: Bearer <access_token>' \
  --header 'Prefer: respond-async' \
  --form 'method=optimize' \
  --form 'params={"profile":"minimal-file-size"}' \
  --form 'file=@/path/to/your-file.pdf'
Response example: The response now contains a Job ID instead of a result. Poll the job status endpoint to check when the file is ready.
{
  "jobID": "babe2aa7-9b5d-4eb2-a679-5fc12cf0a490",
  "location": "https://api.gonitro.dev/platform/jobs/babe2aa7-9b5d-4eb2-a679-5fc12cf0a490"
}

4.1 Poll job status

curl --request GET https://api.gonitro.dev/platform/jobs/<jobID>/status \
  --header 'Authorization: Bearer <access_token>'
When the job’s status becomes completed, fetch the result:
curl --request GET https://api.gonitro.dev/platform/jobs/<jobID>/result \
  --header 'Authorization: Bearer <access_token>'
The result payload has the same result.file.URL shape as the synchronous response.

Success!

You’ve now optimized your first PDF with the Nitro PDF Services API and covered both the synchronous and asynchronous flows. For the full list of available transformations, extractions, and conversions, explore the PDF Services API reference.