← All documentation

Audience analytics

How far people got in a shared demo, and which beat was on screen when they stopped — counted in aggregate, with no viewer recorded at all.

A shared demo reports how far the people who opened it got — and, because Demofy knows what every second of the file is about, which beat was on screen when they stopped. The panel says "most viewers stop around Clicks Upgrade plan" rather than "drop-off at 0:34".

It appears as an Audience tab on the job page once at least one person has pressed play.

The privacy floor is structural, not a policy

The stored record is a count per video per mark. That is the whole row:

  • No viewer identifier.
  • No IP address.
  • No session, no cookie, no device, no user agent.
  • No timestamp.

An individual's viewing is not merely unqueryable — it was never written, so there is nothing to correlate, leak, subpoena or retain. Any column that could distinguish one viewer from another would repeal that claim, which is why the database's own column list is what a test asserts.

The trade is honest and worth stating: unique viewers, rewatch rate, watched-seconds and views-over-time all need per-view state, so none of them exists and none of them is coming without this floor changing.

What the marks mean

There are 6 of them: pressed play, 10% in, a quarter in, halfway, three quarters and watched to the end.

A mark means REACHED, never WATCHED. A viewer who drags the scrubber to the end reaches every rung. Telling a seek from a watch needs exactly the per-view state the floor forbids, and a metric whose meaning is unstated is a metric that gets over-read — so the panel says so where you read it.

The first mark is the odd one out and deliberately so: it is taken from the moment the video actually starts playing, not from a position. A scrub of a paused video reports positions too, and counting one as a play would inflate the denominator every other row is a percentage of.

"Nine of twelve people who opened the link pressed play" is the first honest thing this can say, and neither the page-open count nor the play count answers it alone.

How the beat is worked out

The wire carries the mark's name — never a position and never a beat index. The beat is derived when you read the report, from the seekable positions already stored in the demo's own plan.

Two consequences:

  • Nothing a hostile client sends can write a fact about your plan.
  • If those positions do not describe the video that is playing, no beat is named anywhere and the funnel still reads. A drop-off attributed to the wrong beat is the confident lie the whole design refuses.

Where it does and does not count

  • It counts on public share links, including every embed of them.
  • It does not count on the job page. You watching your own demo is not audience data.
  • An import gets the funnel but not the beat names, because it has no plan.

The beacon that reports a mark cannot cost a viewing: it is fire-and-forget, its failure is swallowed, and the endpoint answers with no body so there is nothing for a player to branch on.

What happens when you delete or revoke

  • Revoking the link stops new marks immediately, because the beacon re-takes the same check the page does.
  • Deleting the video deletes its marks with it, in the same statement. This is a fact about a video with no cost control to protect, and dying with the demo is the only reading of "delete everything" a privacy floor like this can honestly offer.