PDF extraction

How to track views on a PDF link

Share a PDF as a link and get honest view counts. What counts as a view, why bots and Range requests inflate numbers, and how to read the daily chart.

August 28, 2026 5 min read okraPDF

You send someone a PDF. Then nothing. Did they open it? Did anyone?

An email attachment gives you zero signal. A file in a shared drive tells you it was “opened” without saying by what — a person, a preview thumbnailer, or a sync client. And the PDF itself can’t help you: a PDF file can’t carry an analytics tag. There is no script that runs when someone reads page three of a document in their browser’s PDF viewer.

So if you want view counts, they have to come from the delivery layer — the server that hands the bytes to the reader. That turns “track my PDF” into a hosting question: put the file behind a URL you control, and count at the URL.

This post covers what a view should mean at that layer, the three ways naive counters overcount, and how okraPDF’s link analytics counts views on hosted PDF links.

The obvious counter is wrong

The naive implementation is one line: increment a counter on every request for the file. It’s also wrong by a large margin, for three separate reasons.

1. Browser PDF viewers make many requests per open

Modern PDF viewers don’t download the whole file and then render it. They fetch a byte range, read the cross-reference table, then issue follow-up Range requests for the pages and objects they actually need. One human opening one document can produce a burst of partial-content requests — sometimes dozens for a large file.

Count every request and one reader looks like a crowd.

2. Clients probe before they fetch

Browsers, download managers, and link checkers send HEAD requests to ask about the file — its size, its type, whether it supports ranges — before (or instead of) fetching it. A HEAD is not a view. Nobody saw anything.

The moment a link is public, bots find it. Search crawlers, security scanners, uptime checkers, and — the big one for shared links — unfurlers. Paste a link into a chat app or a social feed and the platform’s bot fetches it immediately to build the preview card. That fetch happens even if no human ever clicks.

On public web traffic we’ve measured, automated requests outnumber human ones several times over. A counter that treats every GET as a reader isn’t measuring interest; it’s measuring how much software touched your URL. And yes — curl is a bot. If your “view count” goes up when a script pings the link, the number means nothing.

What should count as a view

Here is the definition okraPDF settled on after building it: a view is a full, inline GET of the PDF by a non-bot client. Concretely, per request:

RequestCounted?Why
GET of the PDF, inline, browser user agent✅ YesSomeone opened the document
Range follow-up requests❌ NoSame open, more bytes — already counted
HEAD request❌ NoA probe, not a read
Bot user agent (crawler, unfurler, curl)❌ NoSoftware, not a reader
Download of an attachment variant❌ NoSeparate intent from an inline view

Two properties fall out of this definition:

  • One open ≈ one view. The Range-request burst from a single reader collapses to a single increment.
  • Sharing the link doesn’t move the number. The unfurl fetch is filtered; the count moves when a person clicks through.

The counting itself happens server-side, off the hot path — the reader’s request is served first, the counter updates asynchronously. No pixel, no JavaScript, nothing injected into the document.

Counts over time, not just a total

A lifetime total answers “did anyone ever open this?” The more useful question is “is anyone opening it now?” — after you sent the proposal, after you posted the link, after the meeting.

So each okraPDF link keeps three things:

  • Total views — lifetime, filtered as above.
  • Last viewed — the timestamp of the most recent real view. This is the “did they open it yet?” field.
  • Daily buckets — a per-day time series, so a spike after you share the link somewhere is visible as a spike, not just a bigger total.

In the dashboard the daily series renders as a small trend chart per link, with the totals beside it. The same numbers are available over the API, so you can pull them into your own reporting if a dashboard isn’t where you live.

What deliberately isn’t tracked

Some document-tracking products answer a different question: who viewed the file, by name, with per-page dwell time — usually by putting an email form in front of the document.

okraPDF’s link analytics doesn’t do that, on purpose:

  • Counts, not identities. There is no viewer identification and no email gate. Your reader clicks the link and sees the PDF. That’s the whole experience.
  • No tracking script in the viewer. The count comes from the delivery request itself.
  • Access control is separate from analytics. If a document shouldn’t be public, you can password-protect the link — protection is a lock, not a data-collection funnel.

If your workflow genuinely needs per-person engagement data, a sales-engagement tool is the right category. If you need to know whether the thing you shared is being read, honest counts are enough — and your readers don’t pay for them with a form.

The flow, end to end:

  1. Go to okrapdf.com/tools/pdf-to-link and drop a PDF.
  2. Publish. You get a short, clean URL on its own subdomain that opens the PDF directly in the browser — no viewer chrome, no interstitial.
  3. Share the URL anywhere a link works: email, chat, a QR code, a footnote.
  4. Open Links & analytics in the okraPDF app to see total views, last-viewed, and the daily trend for every link you’ve published.

The link serves the document inline with proper headers, so it behaves like a first-class web page: it loads in the browser, previews correctly when pasted into chat apps, and stays at the same URL when you need to point people at it again.

And when the count says 0, it means zero people — not zero bots, probes, or byte-range echoes. A small number you can trust beats a big number you can’t.