Skip to content

Documentation

Product usage from PostHog

If you already run PostHog, you already know who is using your product and how much. Kicklace reads two things out of it: a summary on each person — first seen, last seen, and how many events in the last 30 days and the last 7 — and the few events you name as the ones that mean somebody is really using it. Everything else is counted, not kept: a product firing a million events a day is not a million rows on a timeline.

If you already run PostHog, you already know who is using your product and how much. Kicklace reads two things out of that and refuses the third.

The summary. For everybody PostHog has seen with an email address: when they were first seen, when they were last seen, and how many events they fired in the last 30 days and the last 7. Three figures on their record, kept up to date every hour. That is what makes "quiet for a month" and "using it more than they were" answerable about a person rather than about a chart.

The events that count. The few you name — "project created", "design exported" — land on that person's timeline as events, so an automation can answer one and a report can count it.

Not everything else. A product firing a million events a day is not a million rows on a timeline, and a CRM that copied them would be a slower PostHog with a worse chart. Everything you have not named is counted into the two figures above and thrown away. PostHog keeps your analytics; Kicklace keeps your customers.

Four things it will never do.

  • It never writes to PostHog. Every call is a read: a SQL query against their query API, and a list of the event names your project has seen. Nothing is created, changed or deleted over there.
  • It never puts anybody on a list. Somebody appearing in your analytics is an account, not permission to email them. What they agreed to is not in PostHog, so there is nothing to keep as the proof — people who arrive this way are on no list until they join one.
  • It never shows your key back. It is encrypted the moment it arrives, the same way every other secret here is, and it only ever travels in an Authorization header. The screen says the day it was set and offers Replace.
  • It never stores an event you did not name. Not as a row, not as a copy, not "just in case".

The screen is Settings → Integrations → Product usage from PostHog, and only an owner or an admin can connect or disconnect it.


Setting it up

1. Name your project. Pick where your PostHog is — US cloud, EU cloud, or your own address — and give the project id. It is the number after /project/ in PostHog's own address, and it is on your project's settings page.

2. Paste a personal API key. In PostHog, open Settings → Personal API keys and create one. Scope it to this project, and give it read access to three things:

Scope What it is for
query:read the two queries that read the summary and the named events
person:read the email address on a person, which is how somebody is matched here
event_definition:read the list of event names you tick in step 3

It starts with phx_. The key that starts with phc_ is your project's public key, which belongs in a browser and cannot read anything; Kicklace refuses it by name rather than letting you find out an hour later.

3. Choose the events that count. Kicklace asks PostHog which event names your project has seen and shows them, newest first, with PostHog's own $pageview-style names last and unticked. Tick up to twelve. Those are the ones that become rows; everything else is counted, not kept.

A PostHog name can be anything, and a Kicklace event name is lowercase words joined by underscores, so the name is folded on the way in: Project Created becomes project_created. Where the folded name is one Kicklace already knows — signup, activated, purchase, churned — it is that event and moves the lifecycle the way that event always has. Anything else is an event of your own and moves nobody, which is the same rule your own servers post under.

4. Read the history. The hourly read starts thirty days back, because a query that has to answer in ten seconds cannot honestly go further. Press Read the history and Kicklace reads all of it: everybody PostHog has ever seen with an address, with the day they were first seen, and every one of your named events on the day it happened. It runs in the background, page by page, and pressing it again carries on from where it stopped rather than starting over.

No automation runs and nobody is put on a list. A year of activations arriving at once is a past being read, not a year of people activating.

5. Hear them the moment they happen (optional). The read above is hourly. A webhook destination in PostHog posts your named events the second they happen, so an automation answers an activation while somebody is still in your product.

The card gives you three things to paste into PostHog under Data pipeline → Destinations → Webhook: the address, one header, and the body. The header is a secret Kicklace mints and shows once — PostHog's webhook destination signs nothing, so that header is the whole of the proof that a post is yours. If you lose it, make a new one.

The body asks for exactly what Kicklace reads and nothing more:

{
  "uuid": "{event.uuid}",
  "event": "{event.event}",
  "timestamp": "{event.timestamp}",
  "distinct_id": "{event.distinct_id}",
  "email": "{person.properties.email}",
  "properties": {event.properties}
}

Set the destination's own filter to the events you ticked. A post about anything else is answered 200 and dropped, so PostHog does not retry it for ever, but filtering it over there is cheaper for both of us.


What lands here

On a person. Three fields, made once on your People object and filled every hour:

Field What it is
Last seen in the product the day of their most recent event in PostHog
Events, 30 days how many events they fired in the last 30 days
Events, 7 days and in the last 7

They are ordinary fields. You can put them in a view, sort a list by them, filter on them, or count them in a report, like any field you made yourself.

The person themself is found by email address, the way everything else here is: somebody PostHog knows who is already a record here is that record, and somebody new becomes one, with the day PostHog first saw them as their first touch. Somebody PostHog knows only by a distinct id is nobody — Kicklace will not invent a person out of an id with no address beside it.

On a timeline. One row per named event, with the day it happened, the ten smallest of its own properties, and the name PostHog gave it kept beside the folded one. A report counting that event reads it like any other.

Nowhere at all. Every other event, every session recording, every feature flag, every property bag longer than a sentence. Kicklace does not hold them and does not want to.


The two reads and the one post

There are three ways an event can reach here — the hourly read, the history, and the destination — and an event lands once whichever way it arrives. Every one of the three writes it under PostHog's own uuid, so a post that arrives a second after the read wrote the same event finds it already there and writes nothing. Read the history twice and nothing is written twice; turn the destination on a month after connecting and nothing doubles up.

The one difference between them is what fires:

Dated by Fires an automation
The hourly read PostHog's clock yes — something happening now is a signal
The history PostHog's clock no
The destination PostHog's clock yes

The summary fires nothing on any path. A measurement being taken is not the person doing something, and it does not touch their last-activity date either — so "quiet for thirty days" stays true of somebody who really is quiet.


When it goes wrong

Whatever PostHog refuses with is what the card says, in PostHog's own words: "Project not found.", "Incorrect authentication credentials.", and so on. Nothing is invented and your key is in none of it. The read tries again on the next hour; the history stops and waits for you, because a key that is being refused should not be asked four hundred times.

Disconnecting stops the reads and the address stops answering. Everybody who came in through it stays exactly where they are: they are people your workspace knows, and where Kicklace first heard of them is not a reason to forget them.

From Claude

read_history with source: "posthog" starts or carries on the same read from the connector or from Ask Kicklace, and takes no key — the key is pasted into the form, never into a message. describe_workspace says how many people PostHog has seen in the last 30 days and the last 7, which events are counted, and what the three fields on a person are called.