Operational changes are useful outside an analytics dashboard. A goal conversion may need to notify billing, a completed import may unblock a migration, and a team membership change may need to update an internal system. Polling the REST API adds delay and repeated work.
HitKeep 2.11.0 adds signed outbound webhooks for those workflows. Site and instance administrators can subscribe an HTTPS endpoint to the events they need, send a test delivery, rotate its signing secret, and inspect delivery attempts without adding a separate integration service to HitKeep.
What Shipped
- Site and instance webhooks: subscribe one endpoint to a site’s events or use instance scope for cross-site and administrative events.
- HMAC-SHA256 signatures: every request signs its timestamp and exact JSON body with a secret shown only after creation or rotation.
- Bounded retries: unsuccessful deliveries use exponential backoff, with six attempts by default and a six-hour maximum delay.
- Test delivery: queue a
webhook.testevent before connecting a production workflow. - Delivery history: inspect event type, status, attempts, response code, and creation time in a paginated, sortable table.
- Focused administration: search and sort configured endpoints, scan subscribed events, and open delivery, test, edit, rotate, or delete actions from the row menu.
- Destination protection: production endpoints require HTTPS and cannot resolve to loopback, private, link-local, multicast, documentation, or other reserved addresses.
- Single-binary operation: the dispatcher, retry worker, recovery sweep, and retention cleanup run inside the existing HitKeep process.

Verify The Exact Request Body
Each delivery includes a Unix timestamp and a v1 HMAC-SHA256 signature. Verify the original bytes before decoding JSON; parsing and re-serializing the body can change whitespace or key ordering and invalidate the signature.
body, err := io.ReadAll(io.LimitReader(r.Body, 1<<20))if err != nil { http.Error(w, "invalid body", http.StatusBadRequest) return}
timestamp := r.Header.Get("X-HitKeep-Timestamp")signature := strings.TrimPrefix( r.Header.Get("X-HitKeep-Signature"), "v1=",)provided, err := hex.DecodeString(signature)if err != nil { http.Error(w, "invalid signature", http.StatusUnauthorized) return}
mac := hmac.New(sha256.New, []byte(signingSecret))mac.Write([]byte(timestamp + "."))mac.Write(body)if !hmac.Equal(mac.Sum(nil), provided) { http.Error(w, "invalid signature", http.StatusUnauthorized) return}Receivers should also reject stale timestamps and persist X-HitKeep-Event-ID or X-HitKeep-Delivery-ID before returning success. Delivery is at least once, and events may arrive out of order, so downstream processing must be idempotent.
The signed webhook guide includes a complete Go receiver with timestamp validation and the full request-header contract.
Events At The Right Scope
Site webhooks cover lifecycle, goal, import, and test events for one site:
site.updatedandsite.deletedgoal.created,goal.updated,goal.deleted, andgoal.convertedimport.completedandimport.failedwebhook.test
Instance webhooks can subscribe to every site event plus site.created, user lifecycle events, team lifecycle events, and team membership changes. The dashboard loads the valid event catalog for the selected scope, and the API rejects invalid combinations.
This is deliberately an operational event surface, not a raw analytics stream. Webhook payloads do not export pageview histories, visitor records, form contents, or Ask AI conversations. Use open exports and takeout when another system needs analytics data rather than a notification that an operational change happened.
One-Time Secrets And Rotation
Creating a webhook returns its signing secret once. The dashboard presents it through the same one-time credential pattern used for API client tokens: copy it into the receiver’s secret store before leaving the page.
Rotation replaces the configured secret and re-signs pending, retrying, and processing delivery records with the new value. A request already in flight may still carry the previous signature, so receivers that rotate during active delivery should allow a short overlap window.
Webhook administration remains a human dashboard workflow. Instance owners and administrators can manage instance webhooks. Site owners and administrators can manage a site’s webhooks. Editors, viewers, instance users, and delegated API clients cannot create endpoints or rotate secrets. The roles and permissions guide documents the complete boundary.
Retries Without An Unbounded Queue
Any 2xx response marks a delivery successful. Timeouts, connection failures, and non-2xx responses retry with exponential backoff. The defaults keep failure bounded:
| Behavior | Default |
|---|---|
| Request timeout | 10 seconds |
| Maximum attempts | 6 total attempts |
| Initial retry delay | 30 seconds |
| Maximum retry delay | 6 hours |
| Global delivery concurrency | 8 |
| Per-endpoint concurrency | 1 |
| Delivery-history retention | 30 days |
| Recovery sweep | Every 30 seconds |
Operators can tune these limits through the outbound webhook configuration. The default per-endpoint concurrency of one prevents one slow receiver from being flooded, while the global limit keeps outbound work predictable inside the single process.
Delivery history stores outcomes and attempt metadata, not saved response bodies or secrets. The dashboard exposes that history in a paginated and sortable table, so a failed endpoint can be diagnosed without turning the UI into a raw payload archive.

Safer Outbound Destinations
An outbound webhook feature creates a server-side request boundary, so endpoint validation happens both when an administrator saves the URL and immediately before delivery. Production destinations must use HTTPS. HitKeep does not follow redirects, does not inherit proxy settings for webhook delivery, and blocks hostnames that resolve to non-public address space.
Self-hosted developers can explicitly enable HTTP and private targets with HITKEEP_WEBHOOK_ALLOW_DEVELOPMENT_TARGETS=true. That flag removes the destination protections intended to prevent server-side request forgery and should never be enabled in production. The security reference covers webhook delivery alongside HitKeep’s other optional outbound connections.
What Is Not Changing
HitKeep 2.11.0 keeps the same operating model:
- one Go binary
- embedded DuckDB data stores
- embedded NSQ queueing
- no required PostgreSQL, Redis, Kafka, ClickHouse, or separate integration service
- cookie-free browser tracking by default
- open export paths
- self-hosted and managed cloud built from the same product foundation
Webhooks add outbound operational delivery; they do not change browser tracking or broaden the stored analytics data model.
Upgrade Guidance
Upgrade to 2.11.0 when another system needs to react to HitKeep goal, import, site, team, or user changes without polling.
After upgrading:
- Open Integration → Webhooks and choose site or instance scope.
- Create an HTTPS endpoint and subscribe only to the events the receiver needs.
- Store the one-time signing secret outside HitKeep.
- Send a test event and verify the timestamp, signature, and delivery ID.
- Confirm the delivery appears as successful in delivery history.
- Review retry, concurrency, and retention defaults before enabling a high-volume workflow.
Read More
- Configure and verify signed outbound webhooks
- Webhook roles and permissions
- Outbound webhook configuration
- HitKeep security model
- Runtime facts and product limits
- Public roadmap
Self-hosted HitKeep includes webhook delivery in the same binary as the dashboard, queue, and database. If you want signed operational delivery without managing upgrades, backups, and worker operations, start a managed HitKeep Cloud deployment.
