Apply Bates numbering
Bates numbering gives every page in a document set a stable, sequential identifier.
Run — free
This calculator produces the complete label plan before any PDF is stamped: enter the PDF page count, the prefix your matter or workflow requires, the number assigned to page one, and the desired digit width. The result pairs each physical page position with its numeric value and finished label. It also checks the end of the sequence in advance, preventing a too-narrow padding choice from creating inconsistent identifiers halfway through a file.
Define a numbering plan before altering the PDF
A reliable Bates workflow starts with a numbering plan, not with drawing text onto pages. First obtain the PDF page count from a trusted reader or document-processing step. Then choose a prefix that identifies the case, production, client, exhibit, or batch without relying on the filename. The starting number is the numeric value for the first physical page, while the padding width determines how many digit positions appear after the prefix. For example, a start of 17 with a width of five becomes 00017. This capability calculates the entire sequence and returns a record for every page, including its one-based page position, raw number, and finished label. Because it does not modify or upload PDF bytes, you can review the numbering plan, store it in an audit record, or feed it into a separate stamping process. This separation is useful when approval is required before permanent page marks are applied or when several tools must agree on the exact identifier assigned to each page.
Prevent padding changes inside a document
Padding is more than a visual preference. Fixed-width numbers sort correctly as text, align cleanly on a page, and remain easy to compare across document productions. The important check is not whether the starting number fits; it is whether the final number fits after every page has been counted. A 20-page PDF beginning at 990 ends at 1009, so a width of three would be invalid even though 990 initially appears to fit. This calculator determines that final value before producing any labels and returns an input error when its digit count exceeds the requested width. It never silently expands the later labels, because doing so would make the series internally inconsistent. Choose a width that can accommodate anticipated growth if subsequent files will continue the same sequence. The returned last number can become the reference point for the next batch: begin the following PDF at last number plus one, keep the same prefix and width, and preserve a continuous production range without overlaps or accidental gaps.
Use the labels safely in legal and records workflows
The result is deterministic: identical inputs always produce identical page mappings, with no network lookup, current time, or random component involved. That makes it suitable for repeatable evidence preparation, public-record releases, contract exhibits, internal investigations, and archival indexing. Keep the generated mapping beside the source document checksum and the final stamped-file checksum if chain-of-custody or reproducibility matters. Before stamping, confirm that the supplied page count includes every page the stamping tool will process, including covers, separator sheets, appendices, and intentionally blank pages. Also confirm whether an existing production requires a particular prefix spelling, punctuation pattern, starting value, and fixed width. This capability computes labels only; it does not edit a PDF, inspect page content, detect previously applied numbers, or decide where a mark belongs. Those boundaries are deliberate. They let a caller validate the sequence independently and then use a PDF stamping tool with explicit placement, font, color, and margin controls while retaining a clear record of exactly which label belongs to each page.
What you can do with it
Plan a legal document production
Create the exact page-to-label mapping for a disclosure batch before permanent Bates stamps are rendered.
Continue numbering across PDF files
Use the previous batch's final number to start the next document without duplicate identifiers or gaps.
Validate an automated stamping job
Compare the planned labels with extracted or visually inspected stamps after a separate tool modifies the PDF.
FAQ
Does this capability modify my PDF?
No. It receives a page count and numbering settings, then returns the label assigned to each page. A separate PDF tool can apply those labels.
What happens when the padding width is too small?
The request returns an invalid-input error if the final number has more digits than the requested width. Labels are never widened silently.
Can the prefix be empty?
Yes. An empty string produces labels containing only the zero-padded sequence number.
Can numbering start at zero?
Yes. The starting number may be zero or any non-negative safe integer, provided the complete range stays within the safe integer limit.
How much does an API request cost?
Each request costs $0.002. The browser version can use the same deterministic calculation without sending PDF content.
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/bates-numbering \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"page_count":4,"prefix":"CASE-","start_number":17,"padding_width":5}'const res = await fetch("https://api.kit.forhosting.com/pdf/bates-numbering", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"page_count": 4,
"prefix": "CASE-",
"start_number": 17,
"padding_width": 5
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/pdf/bates-numbering",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"page_count": 4,
"prefix": "CASE-",
"start_number": 17,
"padding_width": 5
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/pdf/bates-numbering", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"page_count":4,"prefix":"CASE-","start_number":17,"padding_width":5}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"page_count":4,"prefix":"CASE-","start_number":17,"padding_width":5}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/pdf/bates-numbering", 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_count": 4,
"prefix": "CASE-",
"start_number": 17,
"padding_width": 5
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "pdf.bates_numbering",
"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_pages | 100000 |
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. |