Skip to main content
Every analytics integration and the outcome_event webhook topic send the same catalog, puntego.v1: one event per thing that happened in the guide. Each event carries only properties Puntego defines and types: outcomes, counts, ratings and scores, your guide, revision, experiment and declared target IDs, a page route with IDs collapsed and no query string, language and device class. Puntego never sends what anyone typed or read: no questions, answers, notes, survey text, form values, selectors, page text, accessible names or URLs with query strings. Every value is re-read through the catalog’s strict shapes just before it is sent; a value outside its shape is dropped, never copied.

The envelope

Each event has the same envelope: * marks a value that is always present. Route keys collapse segments that look like IDs (/invoices/8812/edit becomes /invoices/*/edit) and keep a hash route (/#/billing).

Catalog

Choose the groups each integration sends in its panel under Dashboard → Settings → Integrations. tour_step_viewed is high-volume and stays off until you turn on Tour steps.

Conversations (conversations)

Answers (answers)

Actions (actions)

Guides and tours (guides)

Struggle and help offers (struggle)

Struggle signals are back_and_forth, dead_click, failed_submit, form_error_idle, host_error and rage_click, each counted 1–20 per page view. top_target_id names the control you declared in the manifest that collected most signals, and only once that control has at least five page views on the page in the last 30 days.

Versioning

Adding an event or an optional property keeps schema: 1. Renaming, removing or retyping anything becomes schema: 2, and both versions are sent side by side for 90 days under different event IDs.

How each tool receives it

Tools take flat properties, so the envelope arrives prefixed: puntego_schema, puntego_event, puntego_event_id, then every context and event property as puntego_<key> (for example puntego_route_key, puntego_resolution). Struggle counts become one number per signal (puntego_signal_rage_click). Mixpanel always receives ip: 0, so the Worker’s address is never geolocated onto your visitor. Deliveries are sent in batches of up to 100 events, every minute. The deduplication ID is stable across retries, so a retried batch never double-counts. Data you send to your own tools is governed by your agreement with that provider. Deleting a customer in Puntego stops future deliveries but does not delete what your tool already received.

Webhooks

The outcome_event topic sends the same catalog to your webhook endpoint, one request per event:
Every request carries these headers: To verify a request, compute the HMAC-SHA256 of the timestamp, a period and the raw request body (before any JSON parsing) with your signing secret, compare it with v1 in constant time, and reject timestamps more than five minutes old. Use data.event_id to discard a repeated delivery: each delivery is attempted up to six times. No webhook topic carries what anyone typed or read: runtime_event sends the event’s name, IDs and time without its properties, guide_action_log leaves out the model’s reason, and experience_engagement sends survey scores and chosen options but never written answers. Every webhook about a person is sent only under that person’s current consent. Puntego’s own telemetry never leaves: these internal events are recorded for you in Puntego and in the export API, and are not sent to webhooks or analytics tools: ai_disclosure_seen, conversation.turn_completed, install_verified, llm_usage, llm_usage_group_completed, magic_moment.latency, pii/token-miss, voice.failover, and every customer.* and workspace.* event.