Paste this to Monid and Ploid. It covers agent vs human, the three join paths, and what they have to capture. No buyer PII.
Subject: How we track if an agent or a human buys after an Agent Observatory hop
We cannot read the chat where an agent tells a human to buy. That conversation never hits our servers or yours. What we can join is a hop we issued to a paid event you send back.
What a hop is
A hop is a 302 we mint when an agent (or a human the agent sent) requests one of our /go/{your-host}/{dest} URLs. The 302 lands on your site with a common UTM scheme:
utm_source = agent-observatory
utm_medium = agent
utm_campaign = monid or ploid
utm_content = dest (home, cli, docs, …)
utm_term = channel (mcp, cursor, github, …)
utm_id = ao_ + 16 hex, minted only at that 302
Filter PostHog to utm_source = agent-observatory. That is the whole agent-observatory slice. Campaign splits the two of you.
Three paths after the hop
Path A — a human opens the hop
The agent pastes the hop URL. A browser follows the 302. Your HTML page loads PostHog JS. PostHog stores $utm_source and $initial_utm_source. Our first-touch snippet stores ao_hop for 90 days. Checkout copies ao_hop into Stripe (client_reference_id + metadata.utm_id) or into your paid event. You POST that sale to us with hop_id. We mark it hop-attributed. This is the only path that proves a human clicked a hop we issued.
Path B — the agent fetches, a human buys later on a clean session
Most hops are tool fetches of markdown, llms.txt, CLI docs, or APIs. PostHog JS does not run. No cookie is set on the human. If that human later buys from a normal visit, we cannot join the two. We still count the hop. We do not count a sale. Do not treat this as a failed conversion; it is unobservable.
Path C — the agent is the buyer
The agent keeps utm_id from the landing URL and writes it onto the API key, first paid run, invoice, or x402 metadata. The human never needs to click. You POST that paid object with hop_id. We mark it hop-attributed. This is how CLI / API / MCP purchases join.
How we tell agent-fetch from human click on our side
On every hop we classify request signals. We never store IP, raw User-Agent, query string, cookies, body, or prompts.
Sec-Fetch-Dest: document → likely a browser navigating (Path A)
Accept: text/markdown|json → likely an agent/tool fetch (Path B or C)
curl / python / node / go → agent fetch
Chrome / Safari / Firefox → browser navigation
Those classes sit next to dest and channel on the hop. When your sale carries the hop id, we can say whether that hop looked like a human click or an agent fetch. We still cannot see the chat in between.
What we need from you, once
1. PostHog JS on every HTML page we hop to.
2. identify() before checkout so $initial_utm_source survives to the buyer.
3. First-touch snippet (or the same cookies) on those HTML pages.
4. ao_hop copied into Stripe / paid-event metadata.
5. POST paid events to our sales API (invoice id + hop_id + amount + time). No email, name, card, or IP.
6. Server-capture of the query string on .md / .txt / API dests, or those hops will never appear in PostHog.
7. If signup 307s to WorkOS (Ploid login does today), persist utm_id in a cookie or WorkOS state before the redirect.
8. If the agent buys via CLI/API, write utm_id onto the key or first paid run.
Attribution we will report
hop = paid event carries a utm_id we minted
utm = paid event carries utm_source=agent-observatory for your campaign, but not the hop id
unknown = organic / other; excluded from hop → sale
Ratio = attributed sales / hops in the same window.
Live hop analytics
The client center Analytics tab shows every classified signal we keep on hopping agents for both sites: dest, channel, country, colo, continent, network family, UA family, language, Accept class, fetch dest, HTTP version, TLS, bot-score bucket, browser vs API kind, and a recent hop tape. Daily agent nicknames rotate and are not people.
Until sales are ingested, hop → sale stays 0.00%. Hops are already live.
Hop agents · classified signals only
What we capture on hopping agents
The live report of who is hopping to both sites now lives on its own page. Open it for the reading, dests, channels, geo, operators, and hop tape.
identity_tierHow we classified them (declared UA, machine endpoint, signed, …).
verified_bot / signed_agentCloudflare bot-management flags, 0 or 1.
agent_nickFirst 8 chars of the daily rotating hash. Not a person.
Discarded
IP addressNever stored. Mixed into a daily HMAC, then dropped.
Raw User-AgentClassified to a family (cursor, curl, chrome, …), then dropped.
Query string / cookies / body / promptsNot read on hops. Hop URLs are path-only.
Buyer email, name, cardSales ingest is an opaque invoice/key/run id plus hop_id.
Stable agent identityagent_id_hash rotates every UTC day. Not shared as a person.
One scheme · both PostHog projects
utm_source = agent-observatory
Every hop 302, MCP index, and catalog door now uses the same source and medium. Filter PostHog Web Analytics or an insight to utm_source = agent-observatory. Campaign is monid or ploid. Channel sits in utm_term, dest in utm_content.
utm_sourceagent-observatoryutm_mediumagentutm_campaignmonid or ploidutm_contentdest id (cli, docs, home…)utm_termchannel (mcp, cursor, github…)utm_idao_ + 16 hex, minted on the 302
How we know a human purchase came from an agent hop
We cannot read the agent telling a human to buy. The join is the hop token surviving into the paid event. Three paths:
Path A · human opens the link
Hop id on the buyer
Agent pastes the hop. Human browser follows the 302. PostHog records $utm_source and $initial_utm_source. The snippet stores ao_hop. Checkout copies it into Stripe. That sale is hop-attributed. This is the only path that proves the human clicked a hop we issued.
Path B · agent fetches, human arrives later
Unjoinable
Most hops are tool fetches of markdown or APIs. No PostHog JS, no cookie on the human. If the human later buys on a clean session, we cannot say that agent caused it. We still count the hop. We do not count a sale.
Path C · agent is the buyer
CLI / API / x402
The agent keeps utm_id from the landing URL and writes it onto the API key, first paid run, or invoice metadata. The human never needs to click. That sale is hop-attributed because the paid object carries the token.
Monid · monid.ai
monid.ai
Hops this window384
302s we issued
Sales ingested0
attributed paid events
Hop → sale0.00%
attributed sales / hops
PostHog test URL (their site, not a hop). Open it once and confirm utm_source = agent-observatory on the pageview.