Event Notifications
Webhooks
Receive HTTP POST callbacks whenever key events happen in Thought Industries — enrollments, completions, certificates, user changes, and commerce. Configure your endpoint in admin to start receiving events.
Signed & Verified
Every webhook includes an HMAC-SHA256 signature header so you can verify authenticity.
Automatic Retries
Failed deliveries are retried up to 5 times with exponential backoff over 24 hours.
Near Real-Time
Events are dispatched within seconds of the triggering action on the platform.
Event Types
Click any event to view its full payload structure. All payloads follow a consistent envelope with event, timestamp, and data fields.
Enrollment
Course Progress
Certification
User
Commerce
Retry Behavior
If your endpoint returns a non-2xx status code or times out (30s), the platform will retry delivery using exponential backoff:
| Attempt | Delay | Note |
|---|---|---|
| 1st retry | 1 minute | Immediate retry after initial failure |
| 2nd retry | 5 minutes | Short backoff |
| 3rd retry | 30 minutes | Medium backoff |
| 4th retry | 2 hours | Extended backoff |
| 5th retry | 24 hours | Final attempt |
After 5 failed attempts, the event is marked as undeliverable. Consistently failing endpoints may be automatically disabled. Monitor your webhook logs in the admin panel.
Signature Verification
Every webhook request includes an X-TI-Signature header containing an HMAC-SHA256 hash of the request body. Always verify this signature before processing events.
const crypto = require('crypto');
function verifyWebhookSignature(payload, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
// In your webhook handler:
app.post('/webhooks/ti', (req, res) => {
const signature = req.headers['x-ti-signature'];
const isValid = verifyWebhookSignature(
JSON.stringify(req.body),
signature,
process.env.WEBHOOK_SECRET
);
if (!isValid) {
return res.status(401).json({ error: 'Invalid signature' });
}
// Process the event...
const { event, data } = req.body;
console.log(`Received: ${event}`, data);
res.status(200).json({ received: true });
});Best Practices
Respond quickly
Return a 200 status within 5 seconds. Process events asynchronously using a queue if your logic is complex.
Handle duplicates
Webhooks may be delivered more than once. Use the event ID or a combination of event type + entity ID + timestamp for idempotency.
Verify signatures
Always validate the X-TI-Signature header before processing. Reject unsigned or incorrectly signed requests.
Use HTTPS
Webhook endpoints must use HTTPS. The platform will not deliver events to insecure HTTP URLs.
Monitor your logs
Check the admin panel's webhook delivery logs regularly. Set up alerting for repeated failures.
Need help? Webhook configuration is managed in the Thought Industries admin panel under Settings → Webhooks. Contact your CSM or visit the support center for assistance setting up your endpoint.