ForHosting KIT · Documents & PDF

Generate a PDF table of contents from bookmarks

Turn an existing PDF bookmark outline into a consistent table-of-contents page without manually aligning titles and page numbers.

● BetaFree · in your browser
Use it from WebAPIEmailTelegramApp soon

Supply the bookmarks in document order, including each title, its one-based destination page, and an optional nesting level. The generator preserves that hierarchy with indentation, adds readable dot leaders, and returns both structured entries and ready-to-use page text. Empty outlines are rejected because a contents page without entries would conceal a missing extraction or preparation step.

Prepare the bookmark outline

Start with the outline already extracted from the PDF. Each entry needs a title and a one-based page number, and entries should appear in the same order in which readers encounter them. Add a level when the bookmark belongs beneath a chapter or another parent entry; level zero represents a top-level destination, level one is indented once, and deeper non-negative levels create further indentation. The generator does not inspect or modify PDF bytes, infer bookmarks from page text, or reorder the outline. That separation keeps the result predictable and makes data problems visible. Trim misleading whitespace before submission if possible, although repeated spaces and line breaks inside titles are normalized automatically. Titles must contain visible text, page numbers must be positive integers, and levels must stay within the documented range. An empty outline produces an input error rather than a blank page, which helps automation detect PDFs whose bookmarks were absent or lost during an earlier processing stage.

Understand the generated page

The result includes a heading, a normalized array of entries, an entry count, and a page field containing the rendered text. Every rendered line starts with indentation derived from the bookmark level, continues with the cleaned title, and ends with the page number. Dot leaders fill the space between title and number to make scanning easier. The formatter uses a stable target width, but it never truncates a long title merely to preserve alignment; when a title is long, it retains the full wording and inserts a minimum leader. This behavior protects meaningful chapter names and keeps output deterministic across the browser and API. The structured entries repeat the title, page, level, and final rendered line, so a caller can use the supplied page directly or apply its own typography later. The optional heading defaults to “Table of Contents” and can be replaced with another non-empty single-line label when a publication uses different editorial wording.

Place it into a PDF workflow

Use the returned page text as the content source for the stage that creates or inserts a physical PDF page. This capability deliberately focuses on rendering the outline, so it does not rewrite page destinations after insertion, choose fonts, paginate a long contents list, or add the page to the source file. If inserting a new page shifts destination numbers, adjust the supplied page values before generating the final contents text, or perform the update in the assembly step. Keeping those responsibilities explicit prevents the common off-by-one error caused by adding front matter after bookmark pages have already been recorded. For repeatable publishing, extract or maintain the bookmark outline, validate destination pages, generate the contents page, and then pass the result into the PDF composition stage. The same deterministic logic runs without network access or stored state, which makes it appropriate for browser checks, build pipelines, document portals, and regression fixtures where identical input must always produce identical page text.

Create contents from authored bookmarks

Convert a carefully maintained chapter outline into aligned page text before assembling the final PDF.

Automate document publishing

Generate the same predictable contents representation in a build pipeline whenever bookmark destinations change.

Validate extracted outlines

Reject an empty bookmark result early instead of silently publishing a blank table-of-contents page.

What does it cost?

The API costs $0.002 per request, and the browser version can run locally on this page.

Does this capability read the PDF file?

No. It accepts an already available bookmark outline and renders that data as table-of-contents text.

What happens when the outline is empty?

The request fails with an invalid input error so a missing bookmark outline cannot produce a misleading blank page.

How is bookmark hierarchy represented?

Use a zero-based level on each entry. Higher levels add two spaces of indentation per level.

Are long titles truncated?

No. Full normalized titles are retained, with at least three dots separating each title from its page number.

Will inserting the contents page update page numbers?

No. Supply the final destination numbers or adjust them in the later PDF assembly stage.

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.

POSThttps://api.kit.forhosting.com/pdf/table-of-contents

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.

curl -X POST https://api.kit.forhosting.com/pdf/table-of-contents \
  -H "Authorization: Bearer $KIT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"outline":[{"title":"Introduction","page":1,"level":0},{"title":"Installation","page":4,"level":1}]}'
{
  "outline": [
    {
      "title": "Introduction",
      "page": 1,
      "level": 0
    },
    {
      "title": "Installation",
      "page": 4,
      "level": 1
    }
  ]
}
{
  "task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
  "type": "pdf.table_of_contents",
  "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.

Per request$0.002

Published price — no tokens, no invented credits. A failed task is never charged.

max_items500
HTTPCodeMeaning
401unauthorizedMissing or invalid API key.
402insufficient_balanceYour balance doesn't cover the task price.
404unknown_typeThat task type doesn't exist.
429rate_limitedToo many requests. Use the webhook instead of polling.

Read the full KIT documentation →