Label sheet grid calculator
This label sheet grid calculator turns physical sheet measurements into a practical row-and-column layout.
Run — free
Enter the page width and height, the dimensions of one label, four edge margins, and the horizontal and vertical gaps between labels. The result shows how many complete labels fit, how much usable space the grid consumes, and what remains. Every measurement may use millimetres, inches, points, or another unit, provided all fields use that same unit. The calculation is deterministic, runs without network access, and rejects dimensions that cannot contain even one label.
Define the printable rectangle before counting labels
A label sheet is not normally available from edge to edge. Printers have non-printable boundaries, pre-cut stock may begin several millimetres from an edge, and production templates often reserve extra space for registration marks. Start by entering the full sheet width and height, then describe that reserved area with the left, right, top, and bottom margins. The calculator subtracts opposite margins to obtain the usable rectangle. All values must share one unit: a sheet entered in millimetres requires labels, margins, and gutters in millimetres too. You can instead use inches or points without selecting a unit because the arithmetic depends on ratios and subtraction, not a conversion table. Width always controls columns, while height controls rows. Label width and height describe the finished rectangular label, not its pitch or the distance to the next label. If a label is physically wider or taller than the complete sheet, the request fails with a clear error. It also fails when the label fits the bare sheet but cannot fit after the specified margins, preventing a misleading zero-label layout from appearing valid.
Understand how gutters change the grid
Gutters are the clear gaps between neighbouring labels, and they occur only between labels, never outside the first or last item. For columns, the calculator effectively asks how many repetitions of label width plus horizontal gutter can fit after crediting back the final gutter that is not needed. In formula form, columns are the floor of usable width plus horizontal gutter divided by label width plus horizontal gutter. Rows use the matching formula with heights and the vertical gutter. This treatment avoids the common mistake of charging a gutter after the final label, which can undercount a layout exactly at its boundary. A zero gutter is valid for butt-cut labels that touch. Negative gutters and margins are rejected because overlap requires a different imposition model and would make the meaning of remaining space ambiguous. The returned used width and used height include every complete label and only the internal gutters. Remaining width and height are measured inside the margin-defined usable rectangle, so they are suitable for checking slack, centring a grid in a later design step, or comparing two stock options without confusing edge margins with unused grid space.
Apply the result to templates, purchasing, and automation
The primary result is labels_per_sheet, calculated as complete columns multiplied by complete rows. Use that integer to estimate how many sheets a print run requires, while remembering that this capability lays out one fixed orientation and does not rotate individual labels or mix sizes. The columns and rows fields are equally important when building a document template: they tell a PDF generator, design application, or spreadsheet how many repeated cells to create along each axis. Used and remaining dimensions provide a compact audit trail for the layout decision. If remaining width or height seems unexpectedly large, check whether a gutter was entered as the full pitch, which already includes label size, rather than as the empty gap alone. The same deterministic function powers browser and API execution, so exploratory measurements and automated production calculations agree. Running it on this page is free; a successful API request costs $0.002. No dimensions are stored, and no external catalogue of commercial label products is consulted. Confirm the result against printer tolerances, bleed requirements, cutting registration, and the actual manufacturer template before committing a large print job, since those production constraints are deliberately outside this geometric grid count.
What you can do with it
Plan a custom sticker sheet
Convert page size, safe margins, sticker dimensions, and cutting gaps into a complete row-and-column count before designing artwork.
Estimate sheets for a print run
Use the labels-per-sheet result as the capacity input for purchasing stock and scheduling batches.
Generate repeatable document grids
Feed the returned columns, rows, and used extents into a PDF or layout pipeline without reimplementing boundary arithmetic.
FAQ
What units should I use?
Use any length unit, including millimetres or inches, but use the same unit for the sheet, label, margins, and gutters.
Does the calculator rotate labels to fit more?
No. It preserves the entered label width and height. Swap those two inputs yourself to evaluate the rotated orientation.
Are gutters added at the sheet edges?
No. Horizontal and vertical gutters occur only between adjacent labels; edge clearance belongs in the four margin fields.
What happens when one label is larger than the sheet?
The calculation returns an invalid-input error instead of reporting a zero-label grid. Margins that leave too little usable room are also rejected.
How much does the API calculation cost?
Each successful API request costs $0.002. You can also run the same deterministic calculation free in your browser.
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/doc/label-sheet-layout-calc \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"sheet_width":210,"sheet_height":297,"label_width":63.5,"label_height":38.1}'const res = await fetch("https://api.kit.forhosting.com/doc/label-sheet-layout-calc", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"sheet_width": 210,
"sheet_height": 297,
"label_width": 63.5,
"label_height": 38.1
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/doc/label-sheet-layout-calc",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"sheet_width": 210,
"sheet_height": 297,
"label_width": 63.5,
"label_height": 38.1
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/doc/label-sheet-layout-calc", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"sheet_width":210,"sheet_height":297,"label_width":63.5,"label_height":38.1}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"sheet_width":210,"sheet_height":297,"label_width":63.5,"label_height":38.1}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/doc/label-sheet-layout-calc", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"sheet_width": 210,
"sheet_height": 297,
"label_width": 63.5,
"label_height": 38.1
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "doc.label_sheet_layout_calc",
"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. |