Extract first and last PDF pages
The first and last PDF page extractor turns a known document page count into an exact, deterministic extraction instruction.
Run — free
Supply the total number of pages and it identifies page one and the final page, returning a two-page PDF manifest with a stable filename and media type. The input must describe a document with at least two pages, because a one-page file cannot provide two distinct boundary pages. This focused result is useful when another step already knows the PDF page count and needs an unambiguous selection for a downstream PDF operation.
Keep the two pages that frame a document
Long PDFs often place their most useful framing information at opposite ends. The first page may contain a cover, title, account identity, reporting period, or submission reference, while the final page may contain signatures, approval language, totals, appendices, or filing marks. This capability expresses the common operation of retaining those two boundary pages without requiring a caller to calculate the final page number separately. Provide the PDF's total page count and the result identifies source page 1 and the source page whose number equals that count. The returned manifest always describes a two-page PDF in the same order as the original: first page first, last page second. It also supplies the PDF media type and a predictable download filename, making the result straightforward to pass into a file-producing workflow. The original document is not modified. Because the selection is based only on page positions, it does not inspect, classify, summarize, or reinterpret the contents of either selected page.
Understand the validation and page numbering
Page numbering is one-based, matching the numbers people see in ordinary PDF tools: the opening page is page 1, not page 0. The `page_count` value must be a finite integer and must be at least 2. Fractions, numeric strings, missing values, arrays, and objects are rejected instead of being silently converted. That strictness prevents an extraction request from appearing valid when its source metadata is malformed. A one-page PDF is also rejected because its first and last page are the same physical page, while this capability promises two distinct boundary pages. For a 2-page document the selected pages are 1 and 2; for a 300-page document they are 1 and 300. The output reports both the original source count and the new count of 2, so downstream code does not have to infer which number describes which document. It also returns the selected source page numbers explicitly, allowing logs, user interfaces, and later processing steps to explain exactly what was requested.
Use the manifest safely in an automated PDF workflow
This capability is intentionally deterministic and bounded. It performs no network requests, reads no secrets, stores no document, and uses no current time or random value. The same valid page count therefore produces exactly the same extraction manifest every time. A typical workflow obtains a trusted page count during PDF inspection, calls this capability to determine the boundary selection, and hands `extracted_pages` to the component that copies those pages from the source bytes into a new PDF. Keeping selection separate from byte transfer is useful in browser tools, queued pipelines, and audit systems where file access and business rules live in different stages. Validate that the page count belongs to the same source PDF that the copying stage receives; a stale count could otherwise identify a page beyond the newer file's end. API automation costs $0.002 per request, while the pure selection logic can also run in the browser. The response never changes the source, and callers should choose a separate retention policy for the resulting file.
What you can do with it
Prepare cover and signature pages
Select the opening cover and final signature page from a contract package for a compact review file.
Archive report boundaries
Record the title page and closing certification page of a long report without calculating the final position in application code.
Build a PDF processing pipeline
Turn page-count metadata into an explicit two-page selection that a downstream PDF copier can execute.
FAQ
What does the API request cost?
Each API request costs $0.002. The deterministic selection logic can also run in the browser.
Why are PDFs with one page rejected?
A one-page PDF has the same first and last page. This capability requires two distinct source pages and therefore needs a page count of at least two.
Are page numbers zero-based or one-based?
They are one-based. The first source page is 1, and the last source page is equal to `page_count`.
Does this change the original PDF?
No. It returns a deterministic extraction manifest describing a new two-page PDF and leaves the source unchanged.
Can I provide the page count as a string?
No. Provide `page_count` as an integer. Numeric strings and fractional values are rejected to avoid ambiguous input.
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/first-last-page-extract \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"page_count":12}'const res = await fetch("https://api.kit.forhosting.com/pdf/first-last-page-extract", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"page_count": 12
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/pdf/first-last-page-extract",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"page_count": 12
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/pdf/first-last-page-extract", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"page_count":12}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"page_count":12}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/pdf/first-last-page-extract", 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": 12
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "pdf.first_last_page_extract",
"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. |