Back to Blog
Technology6 min read

How Invoice View Tracking Actually Works

IN
Invoice Generator TeamAuthor
September 24, 2026Published
Also available in:NederlandsDeutsch

The "viewed" indicator next to an invoice looks like a single fact, but it's actually assembled from two different tracking mechanisms that were built together and record different things. One is a lightweight counter that lives on the share link itself. The other is a detailed, append-only event log that captures every open across every channel a client can use to see a document. Understanding how the two relate — and the one case where opening a link doesn't count as a view at all — explains most of the behavior people find confusing about view tracking.

Two Separate Tracking Paths: Share Links and the Client Portal

A client can see an invoice or estimate through two distinct channels, and each one is tracked with its own code path. The first is a share link — a token-based URL you generate and send directly, which anyone holding the link can open without logging in. The second is the client portal, where a client with a standing portal link browses a list of their documents and opens one from inside that list. Both paths ultimately call the same underlying recording function, but they tag the event with a different source_type — "share" or "portal" — and the portal path, because it already knows who the client is from their portal session, attaches a viewer name and email to the event. A share link, by contrast, is opened by whoever has the URL, so there's no reliable identity to attach; those events record only the technical details of the visit.

Why a Password-Protected Share Link Doesn't Count as Viewed Yet

If you've set a password on a share link, opening the link for the first time returns just enough information to render the password prompt — it does not increment the view counter or write a view event. The view is only recorded once the correct password has been submitted and verified against the stored hash. This is a deliberate ordering: counting a page load as a "view" before anyone has actually proven they're allowed to see the invoice would let someone finding the link accidentally (a forwarded email, a browser history entry) register as having viewed your invoice without ever seeing its contents. An unprotected share link, which has nothing to verify, records the view immediately on the first load instead.

What Gets Recorded on Each View

Every recorded view captures the invoice or estimate's group ID, which channel it came through, the requesting IP address, and the browser's user-agent string, timestamped to the moment it happened. Portal views additionally carry the client's name and email, pulled from the portal session rather than typed in by the viewer, so that data can't be spoofed by whoever's on the other end of the link. None of this is inferred or estimated after the fact — it's written synchronously as part of handling the request that serves the document, using the same IP-resolution logic (checking a forwarded-for header before falling back to the raw socket address) that the rest of the platform uses for anything IP-sensitive.

The Audit Trail Gets a "Viewed" Entry Too

Recording a view doesn't only write to the dedicated view-events table. It also appends a "viewed" entry to that invoice's audit trail, with the actor type set to "client" for portal views and "system" for share-link views — reflecting that a share link, unlike the portal, has no authenticated person to attribute the open to. This is why an invoice's audit history can show a "viewed" line even though nobody on your team did anything: it's the same event, mirrored into two places — one table optimized for "how many times has this been viewed and by whom," the other optimized for "here's the full chronological story of what happened to this invoice."

How the Views Panel Aggregates This Data

The views panel on an individual invoice queries the detailed event log directly, filtered to that invoice's group ID, and returns every recorded view — count, most recent view time, and the full list with channel, viewer details where available, and IP address — regardless of whether those views came from a share link or the portal. It's a single merged timeline rather than two separate share-views and portal-views lists, because from your side of the conversation, what you actually want to know is simply whether — and how often — the client has looked at the document, not which URL they used to do it.

Why the Share Link Also Keeps Its Own Counter

Separately from the detailed event log, the share link record itself keeps a running view_count and a last_viewed_at timestamp that get incremented in the same request that writes the detailed event. That's a deliberate bit of redundancy rather than an oversight: listing all of a workspace's share links with their view counts is a much cheaper query against that running counter than joining out to the event log and counting rows for every link, every time the list loads. The event log is there for when you need the detail; the counter is there for when you just need the number.

What View Tracking Can't Tell You

It's worth being precise about what this system actually measures: a page load of the invoice or estimate document, nothing more. It has no way to know whether the person who opened it actually read the line items, whether they forwarded the link to someone else who then opened it (that second open shows up as another anonymous share view, not attributed to anyone), or whether an email client's link-scanning security feature triggered the open before a human ever saw it. Treat a recorded view as "the document was loaded in a browser at this time," not as proof that your client has reviewed and understood what's on it — useful as a signal that a reminder probably reached its destination, but not a substitute for a reply.

Related Articles

Technology8 min read

How the Comment Notification Digest Batches Client Activity Into One Email

Why a burst of client comments produces exactly one email, not five — and how the rolling delay resets on every new comment.

IN
Invoice Generator TeamSeptember 11, 2026
Technology8 min read

How In-App Notifications Fan Out to Your Team

Why every workspace member gets their own independent notification row, and why you don't get notified about your own actions.

IN
Invoice Generator TeamSeptember 8, 2026
Technology9 min read

The Invoice Audit Trail: Every Event Logged Behind the Scenes

What actually gets recorded when an invoice is viewed, commented on, or changes status — and why the logging never blocks the action itself.

IN
Invoice Generator TeamSeptember 4, 2026
Technology6 min read

How Two-Factor Authentication Protects Your Account

2FA generates a six-digit code that changes every 30 seconds using the TOTP standard — no live connection between your phone and the server is ever required.

IN
Invoice Generator TeamAugust 27, 2026
Technology6 min read

How API Keys Are Stored (And What to Do If You Lose One)

The raw value of your API key is never stored anywhere after the moment you create it — only a one-way hash is kept, which is why a lost key can't be recovered.

IN
Invoice Generator TeamAugust 26, 2026
Technology11 min read

Is It Safe to Put a QR Code on Your Invoice?

If you've thought about adding a QR code to your invoices, you've probably also seen a headline or two about "quishing" — QR code phishing — and wondered whether you'd be handing your clients a security risk along with your bill. That's...

IN
Invoice Generator TeamAugust 13, 2026

Mastered Invoicing?

Put your knowledge into practice and create your first professional invoice today.

Create Your Invoice Now
How Invoice View Tracking Actually Works | Invoice Generator