Skip to main content
When an AI agent needs to respond to a 500-page PDF, the natural thing to do would be to convert the entire thing to Markdown and put it in the prompt. This is expensive: 250,000 tokens per LLM, seconds to mine, and most of the content is unused. The correct pattern is index first, then extract only what is necessary.

Advantages

  • Tokens at LLM: 20-30x less. AI client pays less.
  • Latency: spine in 300-700ms even for 500MB PDFs.
  • Backend cost: extract only the requested pages, not the 5000. Your bill is reduced proportionally.
  • No server cache: the spine travels to the client, it is not saved. Respect privacy.
  • Stateless: the agent decides. No session or job required.

When NOT to use

  • Small PDFs (<10 pages): the fixed cost of the spine is not worth it. Use direct /convert/from-url.
  • You need the complete Markdown: skip the index and ask for /convert/from-url without pages=.
  • Agent that cannot make routing decisions: needs logic to map question -> sections.

How it works internally

  1. The backend downloads the PDF (1 time, no cache).
  2. Makes sample of 32 distributed pages (start, middle, end) to build the font model.
  3. Go through all the pages reading only the head (first 8 spans) to detect headings.
  4. Detects repeated headers/footers in the top/bottom 12% of each page.
  5. Returns JSON ~5-15KB with the entire map.
  6. Delete the temporary and finish.
Constant cost with respect to the size of the PDF: a PDF with 50 pages and one with 5000 pages take almost the same time to be indexed.

Usage pattern for AI agents

Pattern 1 - search by section

Pattern 2 - search by density

Pattern 3 - user guided navigation

Actual comparison

PDF of 500 pages (academic paper, 10MB decompressed in Markdown): AI Client pays 18x less. Your backend bills 8x less compute. Both win.

Honest limitations

  • Heuristic detection. Sections are detected by font size + numbering + bold. It’s not real semantics. It works very well with structured documents, but worse with free-form PDFs.
  • Tables not detected v1. Only headings + body chars + repeated headers/footers. For tables use mode=balanced.
  • pages[] truncated to 200. PDFs >200 pages expose pages_truncated: true; the agent must navigate to sections[].
  • No server cache: each call re-downloads the PDF. If you are going to make many, keep content_hash on the client to reuse it via cache_key= in /convert/from-url.

Compatibility with other endpoints

  • The spine tells you what to ask for. The actual extraction always goes through /convert/from-url (or any other conversion endpoint) with pages=.
  • mode=ultra_fast + pages= = faster combination.
See also: POST /pdf/index, POST /convert/from-url, Modes, and Formats.