Versions 6.4.0 and 6.4.1 add the first product-usage telemetry the extension has ever shipped — and the design brief was simple: tell us which views are being opened and which features are getting used, without ever touching work-item content or user identities. The result is a tightly-bounded allow-list on both sides of the wire. The extension can only emit ten named events, each with a small set of allow-listed property values; the server rejects anything else with a 400. If a future bug in the client tried to leak a work-item title, the request would never make it past the API.
Ten event names — and that's the whole list
The extension can emit exactly these ten events. There is no "miscellaneous" bucket and no free-text field. If a future feature wants to record something new, the event name has to be added to both the client and the server allow-list as a code change.
- view_opened — which dashboard or analytics view was opened (e.g. cycle-time, sprint-summary, ai-metrics).
- session_started — a hub session began for an Azure DevOps org.
- feature_used — a specific named feature was triggered (e.g. powerpoint-export, theme-toggle, whats-new-dismissed).
- config_event — a configuration tab was saved (e.g. workflow-mapping, item-types, sle).
- workflow_mapping_completed — first-install auto-detection was accepted.
- team_count_reported — coarse team count for the org (used for capacity planning on our side).
- trial_day_milestone — the in-app trial banner crossed a day boundary (Day 7 / 14 / 23 / 28).
- license_activated — a license key was activated against an org.
- purchase_flow_opened — the in-app purchase CTA was clicked.
- error_observed — a categorised error occurred (e.g. api-403, render-fail) — category only, no message text or stack.
What is never sent
The boundary is enforced by the shape of the payload, not by trust. Each event carries the Azure DevOps organisation ID, the extension version, an event name, a license-status string (trial / active / expired), and a tiny `properties` object whose keys and values are themselves allow-listed. That is the entire schema.
- No work-item titles, descriptions, comments, or field values.
- No user identities — no email, no display name, no Azure DevOps user ID.
- No team names, project names, area paths, or iteration paths.
- No free-text properties — `view_opened.view`, `feature_used.feature`, `config_event.configType`, and `error_observed.category` are constrained to closed lists in the client and re-checked on the server.
- No stack traces or error messages — only the category bucket.
Why we built it this way
We wanted the answer to two questions: which features are people actually using, and where are they getting stuck. Either question can be answered without ever seeing what's inside a work item — but only if the design refuses to allow it from the start. A telemetry pipeline that accepts arbitrary properties "just in case" is one bad code path away from leaking sensitive content. So the extension never has the option. Every property name and every property value is reviewed when it's added to the allow-list, and the server enforces the same list independently.
This pairs with what was already on our privacy page — read-only Azure DevOps scopes, customer-tenant storage of analytics data, and no work-item content collection. The new usage events sit in a separate `UsageEvent` table on our side, foreign-keyed to the org's installation record, so they can be queried for product analysis without touching any analytics data.
Trial milestone emails (Day 7 and Day 14)
Alongside the telemetry work, 6.4.x extends the trial-warnings cron with two earlier touchpoints. New trials now get a Day 7 welcome / orientation email and a Day 14 check-in email, in addition to the existing Day 23 and Day 28 conversion warnings. The Day 7 email points new admins at the views most teams find valuable in the first week (Sprint Summary, Cycle Time, Next Sprint Planning); the Day 14 check-in is a real human-style email asking whether the team has hit any rough edges. Both can be opted out at any time from the trial-contact preferences in the extension.
Updating
The extension auto-updates from the Marketplace, so existing customers don't need to do anything. If you'd like to see the full client-side allow-list, it's published in the `usageEvents` module of the extension and mirrored by the server's allow-list — both are open for inspection. New installs can grab v6.4.1 from the Marketplace listing at https://marketplace.visualstudio.com/items?itemName=Baytek.agile-analytics.