You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Replace the current inconsistent webhook data maps with documented, event-specific payloads for all 17 existing webhook events. In particular, make goal.converted actionable by including the triggering custom-event properties or a privacy-bounded pageview snapshot.
This is a versioned contract cleanup: the envelope remains stable, while deliveries created under the release containing this change use the new nested data shape without legacy flat aliases.
Problem
Webhook payloads currently expose uneven, producer-specific fields. For example, goal.converted identifies the matched goal but deliberately omits the metadata from the custom event or pageview that triggered the conversion. Receivers therefore need extra API calls—or cannot implement the workflow at all—to route conversions, synchronize lifecycle state, or act on changes.
The payload fields are also represented in OpenAPI as an unrestricted object, so integrations cannot discover or validate the event-specific contract.
Who Benefits
Self-hosted operators
Managed Cloud operators
Developers integrating HitKeep with CRMs, automation systems, alerting, and data pipelines
API consumers that need a stable, machine-readable webhook contract
Proposed Solution
Keep the existing envelope fields:
api_version
id
delivery_id
type
created_at
data
Make data.actor required but nullable. Human actions use { "id": "<uuid>" }; system and background events use null.
Explicitly exclude user-agent, device/screen dimensions, language, geo/network fields, QR identifiers, and internal tracker fields. Set the conversion envelope's created_at from the triggering source timestamp.
User Workflow
An operator subscribes an instance or site webhook to the relevant event types.
HitKeep delivers a typed payload whose data schema is selected by api_version and type.
The receiver validates the documented schema and acts without additional lookups for the included product data.
Conversion receivers can route on custom-event properties or approved pageview attribution without receiving the complete raw hit.
Implementation Notes
Introduce typed payload structs/builders in the webhook package and replace producer-owned map[string]any construction.
Validate each event type against its expected payload before persistence.
Add occurrence time to the internal webhook event interface and propagate it through batch enqueueing.
Capture snapshots before destructive operations and before/after values for updates.
Preserve transactional final delivery for site deletion.
Pass the approved source fields directly from in-memory ingest records while preserving subscriber short-circuiting, batch emission, stable conversion IDs, retry safety, and exact stored delivery bytes.
Model WebhookEventPayload in runtime OpenAPI as a oneOf over all event-specific schemas using constant event types.
Synchronize the adjacent docs OpenAPI and webhook/goal guides.
Success Criteria
All 17 existing event types have typed, documented payload schemas.
data.actor is always present and is either an ID-only object or null.
Update events include the latest snapshot and typed from/to changes.
Delete events include the final pre-delete snapshot.
goal.converted includes custom properties or the approved pageview context.
Disallowed tracking, identity, secret, destination, and internal-error fields remain absent.
Conversion created_at uses the source occurrence time.
Existing queued deliveries retry with their original api_version and exact stored body; no migration rewrites payload JSON.
Runtime and docs OpenAPI describe every catalog event with an event-specific schema.
The webhook and goal-conversion guides document examples, privacy boundaries, and receiver migration.
Test Plan
Table-driven serialization coverage for all 17 schemas, including required/null behavior.
Producer tests for actor propagation, snapshot/diff behavior, membership causes, import errors, and ID-only people.
Ingest tests proving approved conversion metadata is present and excluded fields are absent.
Delivery tests for signing, identifiers, deduplication, retry immutability, batching, and site-deletion outbox behavior.
OpenAPI coverage ensuring every catalog event has a corresponding schema.
Run change-aware QA while iterating, PR-parity before review, and the exhaustive profile before release because this changes a public integration contract.
Constraints
No new event types, dashboard UI, MCP surface, takeout payload exposure, or subscription behavior.
No email, display name, raw user profile, membership-role snapshot, secret, destination URL, raw internal error, or unrestricted hit export.
Self-hosted and managed-cloud behavior must remain identical.
Do not add compatibility aliases inside the new data objects; receivers distinguish the contract through the release-line api_version.
No database migration or rewrite of historical/queued payloads.
Alternatives Considered
Enrich only goal.converted: rejected because all current event types share the same undocumented-contract problem.
Add more flat fields: rejected because it perpetuates inconsistent producer-owned payloads.
Add nested fields alongside legacy aliases: rejected in favor of a clean release-versioned contract.
Release Notes
Webhook deliveries now contain typed resource snapshots and change details. Goal conversion events include privacy-bounded metadata from the triggering custom event or pageview. Receivers should select the appropriate payload schema using api_version and type.
Docs Impact
Needed: runtime OpenAPI, adjacent docs OpenAPI, webhook integration guide, goal-conversion guide, and release notes. No screenshot or localization update is required.
Summary
Replace the current inconsistent webhook
datamaps with documented, event-specific payloads for all 17 existing webhook events. In particular, makegoal.convertedactionable by including the triggering custom-event properties or a privacy-bounded pageview snapshot.This is a versioned contract cleanup: the envelope remains stable, while deliveries created under the release containing this change use the new nested
datashape without legacy flat aliases.Problem
Webhook payloads currently expose uneven, producer-specific fields. For example,
goal.convertedidentifies the matched goal but deliberately omits the metadata from the custom event or pageview that triggered the conversion. Receivers therefore need extra API calls—or cannot implement the workflow at all—to route conversions, synchronize lifecycle state, or act on changes.The payload fields are also represented in OpenAPI as an unrestricted object, so integrations cannot discover or validate the event-specific contract.
Who Benefits
Proposed Solution
Keep the existing envelope fields:
api_versioniddelivery_idtypecreated_atdataMake
data.actorrequired but nullable. Human actions use{ "id": "<uuid>" }; system and background events usenull.Define reusable snapshots:
id,team_id,domain,data_retention_days,created_atid,name,type,value,created_atid,name,logo_url,created_atid,provider,status,rows_imported,created_at, optionalstarted_at,finished_at, and the existing user-visibleerror{ "from": ..., "to": ... }entries; no arbitrary change keysEvent payloads
datasite.createdsite,actorsite.updatedsite,changesfordomainordata_retention_days,actorsite.deletedsite,actorgoal.createdgoal,actorgoal.updatedgoal,changesforname,type, orvalue,actorgoal.deletedgoal,actorgoal.convertedgoal, triggeringsource,actor: nullimport.completedimport,actor: nullimport.failedimportincluding its user-visible error,actor: nullwebhook.testid,name,scope; nullable site reference;actorsystem.user.updatedchanges.instance_role,actorsystem.user.deletedactorteam.createdteam,actorteam.updatedteam,changesfornameorlogo_url,actorteam.archivedteam,actorteam.member.addedinvite_acceptedorsso_provisioned,actorteam.member.removedremovedorleft,actorGoal conversion source
Model
goal.converted.data.sourceas a discriminated union:type: "event",id,session_id,occurred_at,name, andproperties(always an object)type: "pageview",id,session_id,occurred_at,path, optionalhostname,referrer, and optional UTM fieldsExplicitly exclude user-agent, device/screen dimensions, language, geo/network fields, QR identifiers, and internal tracker fields. Set the conversion envelope's
created_atfrom the triggering source timestamp.User Workflow
dataschema is selected byapi_versionandtype.Implementation Notes
map[string]anyconstruction.WebhookEventPayloadin runtime OpenAPI as aoneOfover all event-specific schemas using constant event types.Success Criteria
data.actoris always present and is either an ID-only object ornull.goal.convertedincludes custom properties or the approved pageview context.created_atuses the source occurrence time.api_versionand exact stored body; no migration rewrites payload JSON.Test Plan
Constraints
dataobjects; receivers distinguish the contract through the release-lineapi_version.Alternatives Considered
goal.converted: rejected because all current event types share the same undocumented-contract problem.Release Notes
Webhook deliveries now contain typed resource snapshots and change details. Goal conversion events include privacy-bounded metadata from the triggering custom event or pageview. Receivers should select the appropriate payload schema using
api_versionandtype.Docs Impact
Needed: runtime OpenAPI, adjacent docs OpenAPI, webhook integration guide, goal-conversion guide, and release notes. No screenshot or localization update is required.