CLItrail Docs

First-run events

The hook reports one of three event types. Two of them are conversions, counted once per installation.

EventReport itCounted
install_completedAfter every installation step succeeded.Once per installation ID. The default.
first_runFrom your CLI's entry point, on launch.Once per installation ID.
install_startedBefore installing, to measure attempts.Once per installation ID. Not a conversion: only webhooks receive it.

#Installation IDs

On its first run, the hook creates a random 128-bit installation ID and keeps it in <state dir>/<service>/<website>/<scope>.id, where the state dir defaults to ~/.local/state/clitrail. Later reports from the same user, website and scope reuse it, so launching your CLI a hundred times still produces one first_run. Updating the hook you bundle keeps existing IDs: in the default folder, a hook with no ID yet reuses the one an older copy kept under ~/.local/state/opfs-attribution-shell.

  • A repeated report of the same event type for the same installation, install_started included, returns the original result with "duplicate": true. A pre-install hook that runs several times counts one attempt.
  • Reusing an event_id with the same installation and type is idempotent. Reusing it for anything else is refused with event_id_conflict.
  • Destinations receive one conversion per installation and event type, identified by a stable event ID the platforms deduplicate on.

#Installation scopes

Use --installation-scope (or CLITRAIL_INSTALLATION_SCOPE) when one website ships several products, or one product can be installed several independent times on a machine. Each scope gets its own installation ID.

#Choosing the event

  • Use install_completed where your code runs at the end of a real install: a shell installer or an npm postinstall.
  • Use first_run where there is no install step you control: npx, Homebrew launchers, Python entry points and single binaries. It counts people who actually launch the CLI, not downloads.

Google Ads, Meta, TikTok and X Ads destinations send install_completed only until you tick first_run in their events; GA4 and webhooks send both by default. X Ads sends first runs to a second event of your pixel, so they never count as installs.

#Late receipts

An install is resolved when it is first reported. If it was unmatched, reporting it again does not attach a receipt that became readable later.