---
title: "Product telemetry"
description: "The six anonymous, content-free events a Chickpea deployment sends, what they never carry, and how to switch them off completely."
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.chickpea.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Product telemetry

**Product telemetry** is the small set of anonymous, content-free events a deployment sends to Chickpea's maintainers to measure adoption. Where usage records and audit events stay inside the state your deployment owns, these events are the one product signal that leaves it. This page lists the six events and their properties, what is never sent, how installation identity and delivery work, and how to switch telemetry off.

Telemetry is enabled by default. Chickpea runs outside any infrastructure its maintainers can observe, so the events answer four questions: whether installations reach a successful run, whether connections and schedules are adopted, whether installations return, and whether the project is growing. They are advisory only and are never used for billing, entitlements, security decisions, reliability alerts, or customer-facing state.

## What every event sends

| Property | Value |
|---|---|
| `distinct_id` | A random UUID standing for one installation. |
| `timestamp` | The UTC time when Chickpea attempted delivery. |
| `schema_version` | `1`. |
| `runtime_target` | `cloudflare` or `node`. |
| `app_version` | The package version compiled into the release. The current pre-release reports `0.0.0`. |
| `telemetry_environment` | `production`, `development`, or `test`. |
| `$process_person_profile` | `false`, so PostHog creates no person profile. |
| `$geoip_disable` | `true`, so PostHog derives no location from the request IP. |

Events that name a workspace or an Agent carry `workspace_key` and `agent_key` instead of real IDs. Each is the first 16 bytes of a domain-separated HMAC-SHA-256 value, encoded base64url and prefixed `ws_` or `agent_`. The key that produces them never leaves the deployment, so the same workspace looks unrelated across two installations.

## The six events

This list is exhaustive. Chickpea has no browser autocapture, session recording, exception capture, or catch-all event API, and no analytics SDK ships in the deployment. The field-level contract behind this table lives in [`TELEMETRY.md`](https://github.com/pejmanjohn/chickpea/blob/main/TELEMETRY.md) in the product repository.

| Event | When it fires | Event-specific properties |
|---|---|---|
| `workspace_connected` | A Slack workspace first reaches a healthy connected state. | `workspace_key`; `transport_mode` (`direct` or `gateway`) |
| `agent_created` | A user-created Agent is committed. Nothing is seeded, so every Agent on a fresh install emits it. | `workspace_key`; `agent_key`; `surface` (`admin`, `slack`, `mcp`, `other`) |
| `connection_ready` | A connected account first becomes ready for an Agent to use. | `workspace_key`; `agent_key`; `connection_kind` (`managed`, `mcp`, `api`); `owner_kind` (`team` or `member`); `surface` |
| `schedule_created` | A new schedule and its authority binding are committed. | `workspace_key`; `agent_key`; `cadence_kind` (`one_time` or `recurring`); `destination_kind` (`channel` or `direct_thread`) |
| `run_completed` | An interactive delivery or a scheduled run reaches a terminal state. | `workspace_key`; `agent_key`; `agent_origin` (`seeded` or `user_created`); `trigger_kind` (`interactive` or `scheduled`); `outcome` (`succeeded`, `no_op`, `failed`) |
| `installation_active` | Once per UTC day, appended to one other event. | `workspace_count`; `user_agent_count`; `ready_connection_count`; `enabled_schedule_count` |

`connection_ready` does not identify the provider, toolkit, account, or owner. `schedule_created` carries no task, expression, time zone, destination, or recipient. `run_completed` carries no output, duration, token count, model, failure class, or error text. Every count on `installation_active` is reduced to `0`, `1`, `2_4`, or `5_plus` before delivery, so a snapshot says "two to four Agents", never how many.

## What is never sent

- **No conversation content.** No Slack messages, prompts, instructions, memory, attachments, transcripts, or model input or output.
- **No work detail.** No tool names, tool arguments, tool results, code, repository contents, schedule tasks, connection data, or connector provider names.
- **No diagnostics.** No error messages, stack traces, HTTP response bodies, operational logs, performance timings, token counts, or model names.
- **No identifiers.** No Slack workspace, channel, user, user-group, message, or thread IDs, and no Chickpea Agent, connection, schedule, or run IDs.
- **No people or places.** No names, email addresses, usernames, organization names, hostnames, URLs, IP-derived location, headers, tokens, credentials, or secrets.
- **No web analytics.** No page views, clicks, session recordings, cookies, device fingerprints, or person profiles.

## Installation identity

On the first eligible event, Chickpea generates a random UUID and a random 32-byte HMAC key and stores them in its own settings store under `telemetry.identity.v1`. Neither value is derived from a machine, a Slack account, a network, a hostname, or customer data. The UUID becomes `distinct_id`; the key stays local and only produces the pseudonyms above.

The daily gate lives separately under `telemetry.active_day.v1` and holds one value: the last claimed UTC date. The day is claimed atomically before any inventory read, so concurrent activity cannot produce two snapshots, and a snapshot that fails is not retried.

Deleting `telemetry.identity.v1` while telemetry is disabled resets the anonymous identity, and the next eligible event creates an unrelated UUID and key. Delete `telemetry.active_day.v1` as well if the installation should be eligible for a fresh snapshot on the same UTC day. Events already stored by PostHog are not linked to the new identity and are not deleted by a local reset.

## Delivery

Each product outcome is sent immediately as an HTTPS `POST` to the fixed endpoint `https://us.i.posthog.com/batch`, PostHog US Cloud. The batch holds that event and, when the daily gate is won, one `installation_active` event. The compiled project token grants ingestion only; it is not a secret and cannot read project data.

A request is capped at 32 KiB and dropped rather than trimmed if it would exceed that, has a five-second deadline, follows no redirects, reads no response body, and is never retried. Failures are swallowed, and cannot change an HTTP response, a Slack acknowledgement, an Agent result, a state transition, a retry decision, or a scheduled-run outcome.

Like any HTTPS request, the network peer receives ordinary connection metadata: source IP, TLS and HTTP metadata, timing, and approximate request size. The Chickpea PostHog project discards source IP data, and GeoIP enrichment is disabled both on each event and in the project's transformation settings. Network intermediaries your host or platform selects may still process transport metadata under their own policies.

## Turning telemetry off

Set either variable to `1`, `true`, or `yes`, in any case. `DO_NOT_TRACK` is the common cross-tool opt-out; `CHICKPEA_DISABLE_TELEMETRY` covers Chickpea product telemetry only. Restart the deployment after changing its environment.

| Target | Where to set it |
|---|---|
| Cloudflare | A Worker variable in the dashboard, or `npx wrangler secret put DO_NOT_TRACK` |
| Node | The process or service environment that starts Chickpea |

Opting out is total. The telemetry composition returns a no-op before it reads or creates identity state, reads adoption inventory, generates randomness, starts a timer, makes a network request, or writes a telemetry log. Nothing is buffered for later delivery.

## Environment labels

`CHICKPEA_TELEMETRY_ENVIRONMENT` accepts `production`, `development`, or `test`. It labels events; it never disables them. With the variable unset, `NODE_ENV` supplies the label when it holds one of those three values, and otherwise Cloudflare labels events `production` and Node labels them `development`. A value outside the three resolves to `development`, so a mislabelled deployment cannot enter the production measurement set.

## Why it works this way

The privacy boundary is structural rather than editorial. A closed event union and a per-event serializer rebuild every payload from an explicit property allowlist, so an unknown event name or property is discarded at the boundary instead of forwarded. An unrecognised enum value falls back to a documented one: an unknown `surface` becomes `other`, an unknown `outcome` becomes `failed`. Raw workspace and Agent IDs exist only long enough to compute the installation-local pseudonyms.

Capture points sit after committed milestones and terminal settlements, never in logging or exception paths, which keeps operational text out of the input entirely. Adding or changing an event or a property requires an allowlist change, contract tests, and an update to the telemetry contract in the same reviewed change, so the published list cannot drift from the code.

## What is not covered

- **Telemetry says nothing about your other traffic.** Requests between your deployment and your model provider, Slack, or connected services are outside this page.
- **An opt-out is not a deletion request.** Events already stored by PostHog remain; the local identity reset only stops future events from joining them.
- **The integrity checks are not a security control.** Maintained queries flag unknown event names or person profiles, which detects public-token abuse but is not treated as protection.
- **`installation_active` is coarse by construction.** Bucketed counts cannot be reversed into an exact number of workspaces, Agents, connections, or schedules.

## Next steps

- [Security model](/security/security-model): the guarantees the rest of the deployment enforces, and the mechanism behind each.
- [Environment variables](/reference/environment-variables): the telemetry variables alongside every other variable an operator may set.
- [Configure your deployment](/operate/configuration): where to set variables on Cloudflare and on Node.
- [Security](/security): the rest of this section, including what is stored where.

Source: https://docs.chickpea.co/security/telemetry/index.mdx
