← All posts

How to track who downloaded a PDF you shared

A PDF is inert. Nothing inside it phones home when it opens, and nothing inside it knows whose laptop it opened on. So the only way to know who downloaded your file is to put something in front of the file that asks — a link that takes an email address, confirms the address is real, and writes a row the moment the download starts. Do that and every download carries a name, a time and a document. Skip it and the best you get is a number.

What cloud storage actually records

Two habits cover most of how files get shared, and neither one produces a record you can act on.

A share link. Set a Drive or Dropbox file to anyone-with-the-link and you have made it anonymous on purpose. Where viewer information exists at all, it is attributed to a signed-in account, which means it misses anyone reading in a private window, anyone signed into a personal account you have no relationship with, and everyone the link was forwarded to. You get opens by account, not opens by person, and the two diverge fast once the link leaves the room you sent it to.

An attachment. This one reports nothing. Once the mail leaves your outbox the file is a copy on someone else's disk, and copies don't report. Forward it to nine colleagues and you learn about none of the nine.

Both failures have the same shape. You handed out the file, and the file is not the thing that can count. What you're trying to measure is people.

What a download record has to contain to be worth reading

Three fields, and a row missing any of them is decoration.

Identity you can act on. Not an IP, not a browser fingerprint, not a session id. The test is whether you could send this person a follow-up and have it arrive. An address that only looks like an address fails that test, which is why the check matters more than the collection — rejecting disposable domains and confirming the inbox exists is what turns a string into a contact.

A timestamp. The question is almost never "who has ever taken this". It's "who took it after Tuesday's newsletter" or "who took it in the week the pricing changed". A log without times answers neither.

Which document. File names drift and revisions happen. If you correct the numbers in a report and swap the new file in underneath a link that already has a download history, every row in that history now lies about what was taken. Upload the revision as its own document with its own link. Then "downloaded the January figures" and "downloaded the corrected ones" stay distinguishable, which is the entire reason you kept the log.

How the file went outWhat you can know afterwards
Email attachment Nothing. Not even a count.
Anyone-with-the-link cloud share A count, sometimes an account name, never the forwards.
Landing page with a plain form Whatever was typed, real or not, plus a time.
Link behind a verified email wall A confirmed address, a time, and the document it belongs to.

A page view and a completed download are different facts

Between opening the link and having the file, a reader can stop at three places. They can see the email form and leave, which produces nothing at all. They can type an address, get a code and never enter it, which produces nothing either — an unconfirmed address is not a subscriber. Or they can verify, land on the page, and not click. That last one is a real subscriber with no download against their name.

Which is why the two events are worth keeping apart. subscriber.verified means someone proved they hold an inbox. document.downloaded means a file actually left the server. Collapse them into one "leads" number and it will be wrong in both directions at once.

Count addresses, not downloads. One person opening the link on a laptop and then again on a phone writes two download rows. Subscribers are deduplicated by normalised address; download events are not, because a second download is a real thing that happened. Deduplicate before you report a number to anyone, or you'll say you reached 140 people when you reached ninety.

Getting the record without building it

This is what Replilo is. You upload the file and get a link like https://replilo.com/s/q3-report. A visitor enters an email; the domain is checked against a mirrored blocklist of disposable providers and its DNS is checked for MX and SPF records before anything is sent. A six-digit code goes out. Entering it stores them as a verified subscriber and starts the download. Access is remembered per link, so the second visit is just a download.

Every fetch writes a download event: which link, which subscriber, when. The visitor's IP is stored as a hash rather than an address, because the hash is enough to spot a link being hammered and an address is more than you need to keep.

If you'd rather the record arrived than went looking for it, point a webhook at your own endpoint:

POST https://your-app.com/hooks/replilo
X-Replilo-Event: document.downloaded
X-Replilo-Signature: t=1756468442,v1=9f2c…

{
  "event": "document.downloaded",
  "createdAt": "2026-08-29T10:14:02Z",
  "data": {
    "subscriber": { "email": "[email protected]" },
    "link": { "slug": "q3-report", "title": "Q3 Revenue Report" },
    "document": { "name": "q3-report.pdf" }
  }
}

The signature is HMAC-SHA256 over the timestamp and the body, so you can verify the call came from us. A failed delivery is retried six times, backing off from thirty seconds to an hour, which is enough to survive a deploy. If you'd rather not run an endpoint, you can forward the same events into a spreadsheet, and the MCP server answers the same questions from an assistant — "who downloaded the pricing deck this week" comes back from your own rows.

The parts this can't tell you

A forwarded link reaches someone you didn't send it to, and they have to verify their own address before they get the file. That's mostly good: you end up with a row for a reader you'd never have known about. It also means the list can outgrow the audience you meant to reach, and the fix for that is a download cap or an expiry date on the link, not a better log.

You also only learn the address someone chose to hand you. A person with a work inbox and a personal one can be two rows, and there is no honest way to merge them. Verification proves they held that inbox at that moment — nothing more. And no tool of this kind can tell you the file was read. A download is a fetch, and treating it as attention is how a report ends up claiming things nobody said.

None of this decides whether the file belongs behind a wall in the first place. A gate buys you contact and costs you reach, and the cases where that trade is worth making are narrower than most content plans assume.

The short version

Files don't keep records; links do. Put the file behind a link that verifies an email address, and each download arrives as a row with a contactable person, a time and a document attached. Keep verifications and downloads as separate events, deduplicate by address before you quote a number, and don't ask the log for things it was never holding.

Find out who's actually taking your file

Free account, 100 MB of storage, no card. Upload it, share the link, read the rows.

Start sharing free