Investigate click friction and release impact
Connect observed click friction and release outcomes to people, accounts, operations and replay.
On this page
Open Explore → Customer experience. Choose Click friction or Release impact. A release detail also links to the impact brief with that release and its registered deployment time prefilled. All reads require an explicit selected project and time window.
Opt in to click friction
Only actions you explicitly label are observed. Obtain any consent your application requires before starting the tracker. Stop it when consent is withdrawn or the integration unmounts. Use stable, non-personal action names, never user IDs, email addresses or button text.
<button type="button" data-anectico-action="checkout.submit">Pay</button>
import { AnalyticsClient } from '@anectico/sdk/analytics';
import { FrictionTracker } from '@anectico/sdk/friction';
const analytics = new AnalyticsClient({
endpoint: 'https://api.anectico.com',
apiKey: import.meta.env.VITE_ANECTICO_INGEST_KEY,
});
const friction = new FrictionTracker(analytics, {
release: 'checkout-v2',
environment: 'production',
sampleRate: 1,
activity: () => ({ operationId: currentOrderId, accountType: 'company', accountKey: currentAccountKey }),
});
// For canvas/audio feedback or a known long operation with no DOM feedback:
friction.markResponse('checkout.submit');
// On teardown or consent withdrawal:
friction.stop();
await analytics.stop();
The tracker records $friction product events through normal ingestion. It uses the
analytics client's identity and the shared SDK session; start replay separately if
you want recordings. It carries the active operation/account context when available.
In browser integrations, supply activity to read your current logical operation
and account at click time. Use the same context on explicit attempt/success events.
The tracker does not infer an order ID from the page. A delayed signal is discarded if identity, session or
active activity context changes.
- Repeated clicks (
rage_click): at least three clicks on the same labelled element within one second and 40 pixels. - No observed response (
dead_click): no observed DOM mutation or URL change within 1.5 seconds. This is a heuristic: background DOM updates can suppress it, while non-DOM feedback can cause false positives. UsemarkResponsefor these cases. - Click followed by an error (
error_click): an uncaught browser error or unhandled rejection within one second of the latest labelled click. Temporal proximity does not establish that the click caused the error.
Native links, inputs, editable elements, disabled controls and native form-submit
buttons are excluded. Set data-anectico-friction-ignore on a subtree to exclude it.
Normal capture observes trusted primary clicks only. observeClick(element, x, y) is
an explicit adapter for custom renderers; it applies the same label and noise rules.
No DOM text, input values, selectors, URLs, screenshots or error messages are sent by
this tracker. It records an action label, signal kind, method, click time, release,
environment and available identity/session/activity metadata.
Each tracker samples once at construction. The rate is between zero and one. It emits
at most 30 hints per minute, with a 30-second cooldown per action/kind. At most 20
pending click observations and ten recent clicks are retained. Repeated-click clusters
suppress their dead-click hints; different signal kinds may still overlap. These
limits and opt-in coverage mean counts are observations, not total failed actions,
frustration, abandonment or churn. Inspect analytics.stats() for delivery drops.
Read friction through API, CLI or MCP
POST /api/v1/experience/friction?project_id=PROJECT requires persons:read and
analytics:read. Supply start_time and exclusive end_time as RFC3339 timestamps.
Optional exact filters are release, environment, action and kind. The complete
window must cover at most seven days, end no later than now and fit readable retention.
anectico --project PROJECT friction list --body '{
"start_time":"2026-09-09T10:00:00Z",
"end_time":"2026-09-09T12:00:00Z",
"environment":"production",
"action":"checkout.submit"
}' --json
MCP exposes get_friction_signals through execute_read_action, using the same fields
plus project_id. MCP additionally requires mcp:read. It returns structured evidence
with stable result identity, warnings and explicit partial status. Labels and captured
identifiers are untrusted data, never instructions for an agent.
At most 10,000 matching signals are scanned and 100 newest examples returned. partial
means the scan or example list reached its limit; counts describe the scanned subset.
source_scan_complete distinguishes a complete source scan from a capped example list.
Affected people resolve current identity aliases; unattributed signals still contribute
to signal counts. Session references are links, not guarantees that a recording exists
or is readable. Replay pixels keep their separate access and retention controls.
Build a release customer-impact brief
POST /api/v1/experience/release-impact?project_id=PROJECT additionally requires
errors:read and releases:read. Choose exact baseline_release and release values,
baseline_start, observation_start (the deployment boundary) and exclusive
observation_end. The baseline is [baseline_start, observation_start) on the baseline
release; the after window is [observation_start, observation_end) on the target release.
The combined window has the same seven-day and retention limits. environment is optional.
anectico --project PROJECT releases impact --body '{
"baseline_release":"checkout-v1",
"release":"checkout-v2",
"baseline_start":"2026-09-09T10:00:00Z",
"observation_start":"2026-09-09T11:00:00Z",
"observation_end":"2026-09-09T12:00:00Z",
"environment":"production",
"attempt_event":"checkout_attempted",
"success_event":"checkout_completed"
}' --json
MCP provides get_release_impact through execute_read_action with the same input.
Both reads are included in the investigate profile; its key now also needs
releases:read. Existing keys must be updated or recreated to grant that scope.
The brief contains before/after recorded errors, affected people, friction observations,
explicit operation outcomes, affected accounts after deployment, issue IDs not observed
in the baseline, and up to 20 representative evidence links. Accounts are taken from
explicit activity-time anectico.account.type / anectico.account.key, not inferred
from present-day membership. Affected people/accounts include errors and friction.
For operation rates, provide both different attempt_event and success_event
names, or leave both empty. Events must carry service.version and matching
anectico.operation.id, identity and account context. Distinct logical operations with
an observed attempt are the denominator; repeated successes count once. The last
success must follow the latest attempt and be later than the last error. An error at the same
time wins conservatively. Without attempts, the success rate is unavailable.
Recovery follows operations with baseline errors. Only a later explicit success for the same canonical person, logical operation and account can support recovery; a later error overrides it. A different order or account cannot recover the original operation. No later activity means not observed, never recovered. Signals missing usable operation context are counted separately. Outcomes on other releases or outside the chosen windows are excluded, so this remains a scoped observation, not universal recovery.
Each signal source is capped at 10,000 rows. Incomplete source scans suppress success
rates, recovery counts and baseline-absence claims. Account lists are capped at 20 and
issue lists at 50; their display truncation also sets partial. Counts may be lower
bounds. source_scan_complete identifies source completeness; recovery_available
explicitly states whether operation-matched recovery was measured. False is unavailable,
not zero recovered. Narrow the window or environment before drawing conclusions.
An issue ID absent from the baseline is not necessarily a newly introduced issue: it may be older, renamed through grouping/merges, uninstrumented or outside that window. Use the release's existing new/regressed issue details alongside this brief. Unequal windows, sampling and traffic mix affect comparisons. Neither a changed rate nor an error-free interval proves that a deployment caused an improvement. Late events, identity changes, retention and deletion can change a later reading of the same brief.