# Images to PDF: many images into one PDF or one each (`examsens.ai/images-to-pdf`) Actor

Turns the images you link or store into one PDF in your order, or one PDF per image. Choose A4, Letter, Legal, A3, A5 or the image size, orientation, fit and margins. JPEG photos go in with no quality loss. Returns a download link for each PDF.

- **URL**: https://apify.com/examsens.ai/images-to-pdf.md
- **Developed by:** [Ed Rayyis](https://apify.com/examsens.ai) (community)
- **Categories:** Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.50 / 1,000 page createds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Images to PDF: many images into one PDF or one each

Give it images, by link or from one of your key value stores, and it puts them into one PDF in your order, or makes one PDF per image. Choose the page size, orientation, fit and margins. Every PDF goes into the run's key value store, and the dataset gives you its download link, page count and the details of every image in it.

### What it does

- One PDF or one per image: all images as pages of one PDF in the order you list them, or a separate PDF for each image
- Page size: A4, US Letter, US Legal, A3, A5, or the image size, where each page is exactly as big as its image plus the margins, at the DPI stored in the image, or 96 DPI when none or less than 30 is stored
- Orientation: auto makes each page horizontal for wide images and vertical for tall ones, or set every page vertical or horizontal
- Fit: fit inside the margins with the aspect ratio kept, shrink only images that are too big, fill the area and crop the overflow, or stretch to fill exactly
- Margins in millimeters, 0 for edge to edge
- No quality loss for photos: JPEG files that need no change go into the PDF as they are. Every other image goes in lossless
- Compress images: store every image as JPEG at the quality you set, for a smaller PDF
- Upright photos: images with an EXIF rotation, such as phone photos, are turned upright
- Transparency in PNG, WebP and GIF images is filled with the background color you choose, white by default
- PDF title stored in the document properties

Reads JPEG, PNG, WebP, GIF, BMP, TIFF and AVIF. An animated GIF uses its first frame, and the item says so.

### Example

Six images on A4 with 10 mm margins and auto orientation (a 550 by 368 JPEG, a WebP, a PNG with transparency, a portrait phone photo with an EXIF rotation, a TIFF and an animated GIF) gave one 6 page PDF of 1,350,681 bytes. The wide images got horizontal pages, the phone photo came out upright on a vertical page, and the JPEG went in unchanged. The same JPEG and PNG on US Letter with fill, no margins and compression at quality 60 gave a 2 page PDF of 53,790 bytes.

### Input

- Image URLs: direct links to images, in page order
- Files in a key value store: to use images from your computer, upload them to one of your key value stores and pick that store. Every record whose key ends in an image extension, such as `.jpg` or `.png`, is used, in key order
- Record keys: only use these records from that store, in this order
- Output: one PDF with all images (default) or one PDF per image
- Page size: A4 (default), US Letter, US Legal, A3, A5 or image size
- Orientation: auto (default), vertical or horizontal
- Fit: fit (default), shrink only, fill or stretch
- Margin in millimeters (default 10)
- Compress images (default off) and JPEG quality (default 80)
- Background for transparency (default white)
- PDF title (optional)
- File name for the single PDF (default `images`)
- Maximum images (default 500)
- Maximum image size in MB (default 50)

### Output

Dataset: one item per PDF with `pdfUrl` (download link), `pdfKey`, `pages`, `pdfBytes`, and `images`: for each page, its `position` in your list, `url`, `inputFormat`, `imageWidth`, `imageHeight` and how it was `embedded` (original JPEG, lossless PNG, or JPEG at the quality you set).

An image that cannot be used gets its own item with `ok: false` and an `error`, such as `HTTP 404`, "the link returns a web page, not an image", or "the file is not an image format this actor can read". The PDF is made from the images that work, so one bad image never stops the run.

### Pricing

Pay per event: one event per page in the PDFs made. Images that fail are not charged. When your maximum charge allows fewer pages than you sent, the PDF holds the first pages that fit and the rest get an error item.

### Scope and conduct

Only the files you supply are downloaded. The actor does not log in anywhere and uses no proxies. Use images you have the right to use.

### Support

Questions and problems: the Issues tab on this page. Replies are written by an AI assistant on behalf of the developer and reviewed by the developer.

# Actor input Schema

## `imageUrls` (type: `array`):

Direct links to images, in page order: JPEG, PNG, WebP, GIF, BMP, TIFF or AVIF.

## `inputStore` (type: `string`):

To use images from your computer, upload them to one of your key value stores, then pick that store here. Every record whose key ends in an image extension, such as .jpg or .png, is used in key order, or only the keys you list below in your order.

## `inputKeys` (type: `array`):

Only use these records from the store above, in this order, one key per line.

## `outputMode` (type: `string`):

One PDF with every image as a page in your order, or one PDF per image.

## `pageSize` (type: `string`):

A fixed paper size, or Image size: each page is exactly the size of its image plus the margins, at the DPI stored in the image, or 96 DPI when none or less than 30 is stored.

## `orientation` (type: `string`):

Auto makes each page horizontal for wide images and vertical for tall ones. Not used with Image size.

## `fit` (type: `string`):

Fit: scale the image to fit inside the margins with the aspect ratio kept. Shrink only: scale down images that are too big and leave smaller ones at their own size. Fill: cover the area inside the margins with the aspect ratio kept, cropping the overflow. Stretch: fill the area exactly and distort the image. Not used with Image size.

## `marginMm` (type: `number`):

Space around the image on every side, in millimeters. 0 for edge to edge.

## `compressImages` (type: `boolean`):

Store every image as JPEG at the quality below, for a smaller PDF. When off, JPEG photos go in unchanged and every other image goes in lossless.

## `jpegQuality` (type: `integer`):

1 to 100, used when Compress images is on.

## `backgroundColor` (type: `string`):

Fills transparent areas of PNG, WebP and GIF images. A CSS color such as #ffffff or white.

## `title` (type: `string`):

Title stored in the PDF properties. Optional.

## `outputName` (type: `string`):

Name of the single PDF. One PDF per image names each file after its image.

## `maxImages` (type: `integer`):

Upper limit of images used in one run.

## `maxFileSizeMb` (type: `integer`):

Larger images are skipped with an error item and are not charged.

## Actor input object example

```json
{
  "imageUrls": [
    {
      "url": "https://www.gstatic.com/webp/gallery/1.jpg"
    },
    {
      "url": "https://www.gstatic.com/webp/gallery/2.jpg"
    }
  ],
  "outputMode": "single",
  "pageSize": "a4",
  "orientation": "auto",
  "fit": "fit",
  "marginMm": 10,
  "compressImages": false,
  "jpegQuality": 80,
  "backgroundColor": "#ffffff",
  "outputName": "images",
  "maxImages": 500,
  "maxFileSizeMb": 50
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "imageUrls": [
        {
            "url": "https://www.gstatic.com/webp/gallery/1.jpg"
        },
        {
            "url": "https://www.gstatic.com/webp/gallery/2.jpg"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("examsens.ai/images-to-pdf").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "imageUrls": [
        { "url": "https://www.gstatic.com/webp/gallery/1.jpg" },
        { "url": "https://www.gstatic.com/webp/gallery/2.jpg" },
    ] }

# Run the Actor and wait for it to finish
run = client.actor("examsens.ai/images-to-pdf").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "imageUrls": [
    {
      "url": "https://www.gstatic.com/webp/gallery/1.jpg"
    },
    {
      "url": "https://www.gstatic.com/webp/gallery/2.jpg"
    }
  ]
}' |
apify call examsens.ai/images-to-pdf --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,examsens.ai/images-to-pdf"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/7oqTAezqCcOPt4LdI/builds/IpLiwZ0YAfFcwOCFq/openapi.json
