Skip to main content

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.

HMAC-SHA256Auto retries — 24hNear real-time

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:

AttemptDelay
1st retry1 minute
2nd retry5 minutes
3rd retry30 minutes
4th retry2 hours
5th retry24 hours

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.

webhook-handler.js
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.