Documentation Index
Fetch the complete documentation index at: https://developer.trackpilots.com/llms.txt
Use this file to discover all available pages before exploring further.
π‘ Reseller WebhooksReseller webhooks deliver real-time tracking events from all your child organisations to a single endpoint β giving you a unified event stream across your entire reseller network.
π Overview
The Webhook page lets you configure webhook endpoints to receive tracking events from every organisation under your reseller account. It also includes a Live Desktop Event Feed β a real-time stream that lets you monitor incoming events directly in the dashboard without any external tooling.
π Direct link: https://app.trackpilots.com/resellers/webhook
β Create a Webhook
- Go to Resellers β Webhook
- Click Add Webhook
- Fill in the form:
| Field | Description | Required |
|---|
| Webhook Name | A friendly name to identify this webhook | β
Yes |
| Webhook URL | Your HTTPS endpoint (e.g. https://yourdomain.com/reseller/events) | β
Yes |
| Events | At least one event type to subscribe to | β
Yes |
- Click Create Webhook
π HTTPS RequiredOnly public HTTPS URLs are accepted. Localhost, private IPs (10.x, 192.168.x, 172.16β31.x), and HTTP URLs are rejected for security reasons.
βοΈ Edit a Webhook
Click the edit icon (βοΈ) on any webhook card to open the edit modal. You can update the webhook name, URL, and subscribed events. Click Update Webhook to save changes.
π‘ Supported Events
Subscribe to one or more of the following desktop tracking events:
| Event Name | Trigger |
|---|
desktop.app_tracking.captured | Fired when app/website usage is tracked on an employeeβs desktop |
desktop.screenshot_tracking.captured | Fired when a screenshot is captured from an employeeβs desktop |
desktop.activity_tracking.captured | Fired when an employeeβs work mode or privacy mode status changes |
Each event is delivered as a signed POST request to your webhook URL with the full event payload and security headers.
π Webhook Secret
Every webhook is assigned a unique secret key used to sign outgoing payloads. The secret is:
- Partially masked in the UI (
first8charsβ’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’)
- Copyable via the π copy button
- Used to verify the
x-webhook-signature header on incoming requests
See the Webhooks guide for the full HMAC SHA256 signature verification flow.
π Webhook Card Fields
| Field | Description |
|---|
| Webhook Name | Display name |
| Webhook URL | Endpoint that receives events |
| Subscribed Events | Badge list of event types |
| Secret | Masked API secret with copy button |
| Created | Date the webhook was created |
π§βπ» Sample Webhook Receiver (Node.js + Express)
Below is the exact receiver implementation for the reseller webhook endpoint.
β οΈ Different from Standard WebhooksThe reseller webhook uses express.json() (parsed JSON body) β not express.raw(). The signature is computed against JSON.stringify(req.body), not the raw buffer. Using the wrong body type will cause all signature checks to fail.
import express from "express";
import crypto from "crypto";
const app = express();
// π Reseller Webhook Endpoint
app.post(
"/webhooks/reseller",
express.json({ limit: "50mb" }),
(req, res) => {
try {
// π Reseller webhook secret (set in your environment variables)
const webhookSecret = process.env.RESELLER_WEBHOOK_SECRET;
if (!webhookSecret) {
console.error("β RESELLER_WEBHOOK_SECRET env var is not set");
return res.status(500).send("Webhook secret not configured");
}
// Read signature headers
const signature = req.headers["x-webhook-signature"];
const timestamp = req.headers["x-webhook-timestamp"];
if (!signature || !timestamp) {
return res.status(400).send("Missing signature");
}
// π Build the payload string for signing
// Note: sign against JSON.stringify(req.body), not the raw buffer
const payloadToSign = `${timestamp}.${JSON.stringify(req.body)}`;
const expectedSignature = crypto
.createHmac("sha256", webhookSecret)
.update(payloadToSign)
.digest("hex");
// π Verify using constant-time comparison (prevents timing attacks)
if (
!crypto.timingSafeEqual(
Buffer.from(signature, "hex"),
Buffer.from(expectedSignature, "hex"),
)
) {
return res.status(401).send("Invalid signature");
}
// β
Verified β process the event
const event = req.body;
console.log("π― Verified Reseller Event:", JSON.stringify(event, null, 2));
// Handle event types
switch (event.event) {
case "desktop.app_tracking.captured":
// process app tracking data
break;
case "desktop.screenshot_tracking.captured":
// process screenshot data
break;
case "desktop.activity_tracking.captured":
// process work mode / privacy mode change
break;
default:
console.log("Unknown event type:", event.event);
}
return res.status(200).json({ received: true });
} catch (error) {
console.error("β [Reseller Webhook] error:", error);
return res.status(500).send("Webhook processing failed");
}
},
);
app.listen(3000, () => {
console.log("π Reseller webhook server running on http://localhost:3000");
});
HMAC_SHA256(timestamp + "." + JSON.stringify(body), RESELLER_WEBHOOK_SECRET)
| Component | Value |
|---|
timestamp | Value of the x-webhook-timestamp header |
body | The parsed JSON request body |
RESELLER_WEBHOOK_SECRET | Your webhook secret (from the Reseller Webhook card) |
Store the secret in an environment variable β never hardcode it in your source code.
ποΈ Delete a Webhook
Click the delete icon (ποΈ) on a webhook card, then confirm in the modal. Deletion is immediate and permanent β no further events will be delivered to that endpoint.
πΊ Live Desktop Event Feed
The Live Desktop Event Feed is a real-time dashboard panel that streams incoming tracking events from all your reseller organisations as they happen.
β‘ Real-Time via Socket.IOEvents are pushed over a persistent WebSocket connection. No page refresh is needed β new events appear instantly as they arrive from employee desktops across your organisations.
The feed only appears when at least one event type is configured in a webhook.
π Connection Status
The top-right of the feed header shows:
| Badge | Meaning |
|---|
| π’ Connected | WebSocket is live and receiving events |
| β« Disconnected | Connection lost β events are not streaming |
| π΄ Live | Feed is actively listening |
ποΈ Event Tabs
Tabs are shown only for event types you have subscribed to in your webhooks:
| Tab | Color | Event Type |
|---|
| Tracking Event | π΅ Blue | desktop.app_tracking.captured |
| Screenshot Event | π Orange | desktop.screenshot_tracking.captured |
| Activity Event | π’ Green | desktop.activity_tracking.captured |
The badge on each tab shows the total number of events received in that session.
π Event Cards (Left Panel)
The left panel shows the latest 10 events for the selected tab. Each event card displays:
| Field | Description |
|---|
| Parent Organisation Name | Name of your reseller parent account |
| Reseller Organisation Name | Name of the child organisation that generated the event |
| UserId | ID of the employee whose desktop sent the event |
| TeamId | ID of the team the employee belongs to |
| Timestamp | Exact date/time the event was received |
| Relative time | Human-readable age (e.g. β3 sec agoβ, β2 min agoβ) |
| Payload | Full JSON event payload in a scrollable code block |
Every ID field has a π copy button for quick clipboard access.
New Event Highlight:
The most recently received card shows a βNew Eventβ badge (replacing the event type label) with a colored border highlight. Both disappear automatically after 3 seconds.
π Live Pool (Right Panel)
The Live Pool is a chronological log of all incoming events across all tabs (max 30 entries). Each entry shows:
- Event type with color-coded dot
- Organisation name
- Timestamp + relative time
- βNew Eventβ badge on the far right for the most recent entry (disappears after 3 seconds)
Pause / Resume:
Click the βΈοΈ pause button to stop new entries from appearing in the pool (events still arrive in the background). Click βΆοΈ resume to restart live updates.
π Toast Notifications
When a new event arrives, a toast notification appears in the top-right of the feed for 3 seconds showing:
- Event type icon and name
- Organisation name
- Exact timestamp + relative time
β
Summary
| Feature | Description |
|---|
| Create webhook | Configure a URL + events to receive |
| Edit webhook | Update name, URL, or subscribed events |
| Copy secret | One-click copy for HMAC signature verification |
| Live Event Feed | Real-time stream of events from all organisations |
| Event tabs | Filter feed by tracking / screenshot / activity |
| Event cards | Full event detail with copy buttons for all IDs |
| Live Pool | Cross-type chronological event log |
| Pause/Resume | Control live feed updates |
| New Event badge | Visual highlight for the latest event (auto-dismisses in 3s) |
π§ͺ Test Your Webhook Before Going LiveUse the built-in Simulations tool to send a signed test payload to your endpoint and verify itβs responding correctly before processing real events.
π Reseller Simulations