Skip to main content

Manager Notifications

Webhooks

When a learner enrolls, completes a course, buys something, or hits another trigger you pick, Thought Industries POSTs that event as JSON to a URL you own — your server, a Zapier Catch Hook, or another automation tool. You configure the URL in Admin, not through the REST API.

Real-time JSON POSTUsers → Manager NotificationsSame payload as the Events API

Choose a channel

Outbound learning data is configured once, in Users → Manager Notifications. Webhook is the real-time channel. The same screen can also email a person or drop a nightly file.

ChannelUse when
WebhookA CRM, marketing tool, or your own service should react immediately.
SFTPA warehouse or ETL job should pick up a file once a day.
EmailA person on your team should read the event.
REST pollYou cannot receive inbound HTTP, or you need to backfill.

Most webhooks fire as the learner acts. Two exceptions: subscription purchases (bundlePurchase) wait about an hour for financial systems; inactivity webhooks send daily at noon. Course-view reports are SFTP only.

Common jobs

Start with one trigger. You can add more notifications later — each one is a trigger + a channel + a destination.

Push a completion into a CRM or drip a follow-up email

Fires when a learner finishes a course. Typical first webhook.

courseCompletion

Create or update a contact when someone enrolls

Fires on enrollment. courseAction covers enroll plus status, certificate, and revoke in one feed.

courseEnrollment

Issue a badge or update a credential record

Fires when a course certificate should be issued.

courseCertificate

Sync a paid purchase to billing or fulfillment

Fires when a course is bought. Subscriptions use bundlePurchase and lag about an hour.

coursePurchase

Set it up

You need a public URL that accepts POST. That can be your own HTTPS endpoint, or a no-code catch URL such as a Zapier Catch Hook. Then, in Admin:

  1. Go to Users → Manager Notifications (/learn/manager/notification).
  2. Click Add Notification.
  3. Choose the trigger from the “When a …” list (for example, “course is completed by a learner”).
  4. Select Webhook. Almost every trigger offers it; course-view reports do not.
  5. Paste the destination URL. The form example is https://www.example.org/path.
  6. Optionally limit the notification to one course or learning path. The default is every item on the site.
  7. Click Test Event. When the sample arrives, click Save Notification.

Screenshots of this path are in Configuring Webhook Data Transfers and Setting Up Automated Data Notifications. Learner Notifications and System Notifications on the same Users menu are different features (campaigns and default learner emails).

Get a sample before you write mapping code

Field sets differ by trigger. Do not invent an envelope. On the same Add Notification form:

  • Download Sample JSON (or CSV) for the selected trigger. If the sample is empty, perform that action in the site once — it can take up to two hours to appear.
  • Test Event POSTs a representative sample to the URL you entered. Use that to confirm headers, body shape, and that your endpoint is reachable.

The posted body is the same event record as GET /incoming/v2/events/:kind. Realtime delivery wraps the object in a JSON array. Learner email is user; profile fields (name, externalCustomerId, custom refs) are on userDetail; the course or path UUID is notifiableId. IDs are UUIDs.

courseCompletion — mapper-owned fields
[
  {
    "event": "courseCompletion",
    "timestamp": "2026-03-13T16:45:00.000Z",
    "companyId": "11111111-1111-1111-1111-111111111111",
    "notifiableId": "22222222-2222-2222-2222-222222222222",
    "title": "API Fundamentals",
    "user": "[email protected]",
    "userDetail": {
      "id": "33333333-3333-3333-3333-333333333333",
      "firstName": "Jane",
      "lastName": "Doe",
      "externalCustomerId": "cust-100"
    }
  }
]

Extra keys from the underlying course-action row are present on a live event. Trust Test Event / Download Sample JSON over this sketch.

Receive the POST

Each firing is its own request. Return a status in 200–308 within 15 seconds or the attempt fails. Failed deliveries retry 10 times with backoff from 20 seconds up to 3600 seconds (about 3.5 hours). There is no delivery log in Admin — watch your own endpoint.

handler.js
// Acknowledge first — the worker times out at 15 seconds.
app.post('/webhooks/ti', (req, res) => {
  res.status(200).end();

  const items = Array.isArray(req.body) ? req.body : [req.body];
  for (const item of items) {
    // item.event is the trigger kind, e.g. "courseCompletion"
    // item.user is the learner email
    // item.notifiableId is the course (or path) UUID
    console.log(item.event, item.user, item.notifiableId);
  }
});

Acknowledge, then do the work

Return 200–308 immediately. Fan the payload into a queue if you call a CRM or send mail.

Treat retries as duplicates

The same event can arrive more than once. Deduplicate on a stable key (id when present, or event + user + notifiableId + timestamp).

Accept an array or a single object

Realtime delivery encodes the mapped event as a JSON array. A test payload should not break the handler if it arrives as one object.

Logins and visits

Both webhooks include userDetail.role, so you can segment managers from learners in an automation.

Whorole value
ManagerDefault Manager or Custom Manager
LearnerGuest, Registrant, Comp, or Student — depending on how they got access
Dual-role userWhichever role they are using for that session

User Logs In fires for managers and learners. User Visits Site fires only when a learner visits.

All webhook triggers

The label is what you pick in Admin. The kind is the event field on the JSON, and the path segment on GET /incoming/v2/events/:kind.

Course

courseEnrollment

Learner enrolls in a course

Events API
courseAction

Learner enrolls, changes status, earns a certificate, or has access revoked in a course

Events API
courseCompletion

Course is completed by a learner

Events API
courseCertificate

Course certificate should be issued

Events API
coursePurchase

Course is purchased

Events API
quizAttempt

Quiz is taken (includes tests, surveys, and reflections)

Events API
assignmentSubmission

Assignment is submitted by a learner

Events API
courseComment

Comment is created

Events API
courseInstructorMessage

Instructor is messaged

Events API
emailCapture

Email is entered on a course paywall or waitlist

Events API

Learning path

learningPathEnrollment

Learner enrolls in a learning path

Events API
learningPathAction

Learner enrolls, changes status, earns a certificate, or has access revoked in a learning path

Events API

Learner

login

Learner logs in

Also fires for manager logins. Use userDetail.role to tell them apart.

Events API
visit

Logged-in learner visits the school

Learners only — manager visits do not fire this webhook.

Events API
registration

Learner registers as part of free registration

Events API
onboardingSurveyResponse

Onboarding survey is submitted

Events API
award

Award or credit is granted

Events API
redemptionCodeRedeem

Redemption or registration code is redeemed

Events API
userLastActive7

Learner is inactive for 7 consecutive days

Batch. Webhooks send daily at 12:00 in the instance timezone.

Events API
userLastActive14

Learner is inactive for 14 consecutive days

Batch. Webhooks send daily at 12:00 in the instance timezone.

Events API
userLastActive31

Learner is inactive for 31 consecutive days

Batch. Webhooks send daily at 12:00 in the instance timezone.

Events API

Commerce

productPurchase

Product is purchased

Events API
bundlePurchase

Subscription is purchased or auto-renewed

About a one-hour delay while the purchase clears financial systems.

Events API
discountGroupPurchase

Course collection is purchased

Events API
pickableGroupPurchase

A la carte collection is purchased

Events API
subscriptionCancel

Subscription is canceled

Events API
subscriptionReactivation

Subscription is reactivated

Events API
newsletterSignup

Newsletter is signed up during checkout

Events API

SCORM, meetings, and discussions

scormAttempt

SCORM attempt record is updated

Events API
meetingAttendanceUpdate

Meeting attendance is updated

Events API
discussionsWidgetComment

Comment is created in a discussion widget

SFTP and polling

Nightly SFTP

Same Manager Notification screen, SFTP channel. File of the previous day’s events around 2am, CSV or JSON. 60s connect timeout, 5 minutes max transfer, same 10-retry backoff. Use this for a warehouse, not a live CRM write.

Poll the Events API

Call GET /incoming/v2/events/:kind with a startDate in epoch milliseconds and follow pageInfo.cursor. See Webhooks vs REST and Course Actions.

Real-time first

Webhook when another system should react as the learner acts.

Email a person

Same screen, Email channel — only on triggers that have a template.

We retry for you

10 attempts, 20s to 3600s. Still return 200–308 within 15 seconds.