> ## Documentation Index
> Fetch the complete documentation index at: https://developers.gonitro.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Optimize PDF Tutorial

> Optimize a PDF with the Nitro PDF Services API. Choose a profile, send a POST request, and download the result synchronously or async.

## 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](#1-choosing-an-optimization-profile)
2. [Sending the optimize request](#2-sending-the-optimize-request)
3. [Downloading the optimized file](#3-downloading-the-optimized-file)
4. [Running asynchronously for large files](#4-running-asynchronously-for-large-files)

## Prerequisites

### Authentication

You will need an access token to authenticate your requests. Check the [Getting Started](https://developers.gonitro.com/docs/getting-started/basic-setup) 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`.

<Warning>More aggressive file size minimization will result in lower image quality for some or all images in the PDF.</Warning>

## 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:**

<CodeGroup>
  ```bash Shell theme={null}
  curl --request POST https://api.gonitro.dev/transformations \
    --header 'Authorization: Bearer <access_token>' \
    --form 'method=optimize' \
    --form 'params={"profile":"minimal-file-size"}' \
    --form 'file=@/path/to/your-file.pdf'
  ```
</CodeGroup>

**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.

<CodeGroup>
  ```json JSON theme={null}
  {
    "result": {
      "file": {
        "URL": "https://your-optimized-file.pdf",
        "contentType": "application/pdf",
        "metadata": {
          "fileSizeBytes": 8543,
          "pageCount": 1
        }
      }
    }
  }
  ```
</CodeGroup>

## 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.

<CodeGroup>
  ```bash Shell theme={null}
  curl --output optimized.pdf "<result.file.URL>"
  ```
</CodeGroup>

<Tip>The pre-signed URL expires 15 minutes after the response is issued. Download the file (or copy it to your own storage) before then.</Tip>

### 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`:

<CodeGroup>
  ```bash Shell theme={null}
  curl --request POST https://api.gonitro.dev/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
  ```
</CodeGroup>

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:**

<CodeGroup>
  ```bash Shell theme={null}
  curl --request POST https://api.gonitro.dev/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'
  ```
</CodeGroup>

**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.

<CodeGroup>
  ```json JSON theme={null}
  {
    "jobID": "babe2aa7-9b5d-4eb2-a679-5fc12cf0a490",
    "location": "https://api.gonitro.dev/platform/jobs/babe2aa7-9b5d-4eb2-a679-5fc12cf0a490"
  }
  ```
</CodeGroup>

### 4.1 Poll job status

<CodeGroup>
  ```bash Shell theme={null}
  curl --request GET https://api.gonitro.dev/platform/jobs/<jobID>/status \
    --header 'Authorization: Bearer <access_token>'
  ```
</CodeGroup>

When the job's `status` becomes `completed`, fetch the result:

<CodeGroup>
  ```bash Shell theme={null}
  curl --request GET https://api.gonitro.dev/platform/jobs/<jobID>/result \
    --header 'Authorization: Bearer <access_token>'
  ```
</CodeGroup>

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](/api-reference/platform/transformations/optimize) reference.
