N-up PDF pages
The N-up PDF page layout calculator turns an original PDF page size and a supported pages-per-sheet value into a complete placement plan.
Run — free
It reports the grid dimensions, required output sheet width and height, and the exact position of every source-page cell. Use the same unit for width and height—PDF points, millimetres, inches, or another consistent unit—and the result remains in that unit. The calculation is deterministic and does not alter, upload, or render the document itself.
Start with the original PDF page dimensions
An N-up layout begins with the media size of one original PDF page. Supply that size as page_width and page_height, using the same unit for both values. PDF software commonly reports dimensions in points, where seventy-two points equal one inch, but the calculator does not force a particular unit. Millimetres, inches, or another consistent measurement work equally well because every result is produced by multiplication rather than conversion. The tool assumes that all source pages use the supplied dimensions. If a document mixes portrait, landscape, or custom page sizes, calculate a separate plan for each size group or normalize the pages first. Both dimensions must be finite numbers greater than zero; zero, negative, missing, infinite, and nonnumeric values are rejected. This strict validation prevents a plausible-looking sheet specification from being built on unusable geometry. The capability reads page geometry, not PDF bytes, so extract the media-box width and height from the PDF before calling it in an automated workflow.
Choose a supported pages-per-sheet grid
Set n to 2, 4, 6, or 9. Each supported value maps to one predictable grid: two pages use two columns and one row, four pages use two columns and two rows, six pages use three columns and two rows, and nine pages use three columns and three rows. This explicit mapping avoids ambiguous arrangements and keeps repeated jobs stable across systems. The output sheet width equals the original page width multiplied by the number of columns, while the sheet height equals the original page height multiplied by the number of rows. The layout preserves every source page at full size, with no scaling, rotation, margins, gutters, bleed, or crop marks. Those production choices can be applied later by a PDF imposition or rendering tool. Values outside the supported set are rejected instead of being rounded or forced into a partly filled grid. That behavior makes configuration mistakes visible early, particularly when n comes from a user preference, stored job template, or command-line option.
Use the placement plan to build each sheet
The placements array describes cells in row-major order with zero-based page_index, row, and column values. The first source page goes in the top-left cell, later pages move across the row, and a new row begins after the final column. Each placement includes x and y coordinates plus the unchanged cell width and height. Coordinates use a top-left grid convention: x increases to the right and y increases downward. If your PDF library uses a bottom-left origin, convert y during rendering by subtracting y plus the cell height from sheet_height. For each output sheet, take the next n source pages and apply the same placement entries in sequence. The last sheet may contain fewer source pages; simply ignore unused placement entries rather than manufacturing blank pages unless your print workflow requires padding. Because the result contains both overall sheet geometry and individual rectangles, it can drive PDF page creation, print previews, imposition checks, or job-ticket generation without repeating the grid arithmetic in every integration.
What you can do with it
Prepare an imposition job
Create the target sheet and place each source page using deterministic grid coordinates before writing the output PDF.
Estimate required sheet dimensions
Calculate the full-size canvas needed for a supported N-up arrangement without opening or modifying the source document.
Validate print workflow settings
Reject unsupported pages-per-sheet options early and compare the planned grid with printer or finishing constraints.
FAQ
What does it cost?
Each API request costs $0.002. The calculation can also run in the browser.
Which N-up values are supported?
The supported values are 2, 4, 6, and 9. Any other value returns an invalid-input error.
Which measurement unit should I use?
Use any unit as long as page_width and page_height use the same one. All returned dimensions and coordinates preserve that unit.
Does the calculator resize or rotate pages?
No. It preserves the supplied page width and height and computes a full-size grid without rotation, scaling, margins, or gutters.
Does it upload or rewrite my PDF?
No. It only calculates geometry from page dimensions and n; it does not read, store, render, or modify PDF bytes.
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/pdf/n-up-layout \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"page_width":612,"page_height":792,"n":4}'const res = await fetch("https://api.kit.forhosting.com/pdf/n-up-layout", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"page_width": 612,
"page_height": 792,
"n": 4
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/pdf/n-up-layout",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"page_width": 612,
"page_height": 792,
"n": 4
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/pdf/n-up-layout", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"page_width":612,"page_height":792,"n":4}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"page_width":612,"page_height":792,"n":4}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/pdf/n-up-layout", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"page_width": 612,
"page_height": 792,
"n": 4
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "pdf.n_up_layout",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Limits
max_mb | 25 |
max_pages | 200 |
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |