A webhook makes Learnster send an HTTPS request to your system when something happens to a learner, so your HR system, CRM or data warehouse stays up to date without exports.
Common uses:
Report course completions to an HR or competence system.
Tell another system when a learner is enrolled in or removed from a course.
Re-send a learner's course status when their account is reactivated.
A webhook has two parts. The webhook is where and what to send: URL, authentication, headers and the data fields. The trigger is when to send it: the event, and optionally which learners (by tag). Learnster support sets up both for you.
Before you start
You need an HTTPS endpoint that accepts JSON. It must:
Use HTTPS. Plain http:// URLs are rejected.
Have a valid SSL certificate. Learnster checks it on every request.
Accept POST (default), PATCH or GET, with a JSON body.
Answer with one fixed success status code. The default is 200. If your endpoint answers 201 or 204, tell support so they can change it (see Delivery, retries and status).
Be reachable from the internet. If you allow-list IP addresses, ask support for Learnster's outbound addresses.
Setting up a webhook
Learnster support creates the webhook and its trigger for you. Self-service setup in the admin view is in development.
Send support the following:
Target URL (must start with https://) and method: POST (most common), PATCH or GET.
Authentication your endpoint expects:
None – use only together with a secret custom header.
Static token – Learnster sends
Authorization: Bearer <your token>.OAuth2 client credentials – token URL, client ID, client secret and optional scopes, and whether the client credentials go in the request body (default) or headers. Learnster fetches a fresh access token before every request.
Custom headers, if any, for example an API gateway subscription key. A header value can use
<random_uuid>(a new ID per request) or<posix_now_date>(send time as a Unix timestamp).Events that should trigger the webhook, and any tags that limit which learners it covers.
Payload fields to send (codes from Payload format below), and any key names your system expects instead.
Success status code your endpoint returns (default 200), and how many retries you want.
Support sends a test request and confirms the result with you before the webhook goes live. Ask support how to share tokens and secrets securely.
ℹ️ Basic authentication is not available at the moment. Use a static token or OAuth2 instead.
Available events
Four events can trigger a webhook. Each request covers one learner in one course.
Event | When it is sent | Timing |
Course finished | A learner completes a course | Queued immediately, sent within about 15 minutes |
Learner added to course | A learner is enrolled in a course | Checked every 15 minutes |
Learner removed from course | A learner is unenrolled from a course | Checked every 15 minutes |
Learner activated | A deactivated learner is activated again. Sends one request per course: ongoing, finished and/or removed courses, as agreed with support | Queued immediately, sent within about 15 minutes |
A trigger can be limited to learners with specific tags, for example only employees of one company. Learners without any of the tags are skipped.
Deleted learners never trigger webhooks.
Payload format
The request body is a flat JSON object with one key per field you picked. The key is the field code, the value is the learner's data at the moment the event was recorded.
Example body for Course finished with eight fields:
{
"student_id": "bf03df9a-0883-4cc4-a00a-782822e95429",
"user_email": "[email protected]",
"user_first_name": "Anna",
"user_last_name": "Svensson",
"session_id": "b051069e-0705-4c61-9700-10ed8d51a306",
"course_child_name": "Fire safety 2026",
"course_status": "Completed",
"course_completion_date": "2026-08-31"
}Learner fields
Code | Value |
student_id | Learner's Learnster ID (stable, best for matching) |
user_personal_id | User ID from your HR system, if set |
user_unique_id | Unique ID, if set |
user_email, user_name | Email, username |
user_first_name, user_last_name | Name |
user_title, user_company, user_office, user_country, user_about | Profile fields |
user_custom_attributes | Custom attributes, as a list |
user_tags, user_teams | Assigned tags and teams, as lists |
user_direct_managers, user_team_managers | Managers, as lists |
Course fields
Code | Value |
session_id | Course (session) ID |
course_parent_name, course_child_name | Course template name, course (session) name |
course_description, course_notes, course_other_info | Text fields (may contain HTML) |
course_start_date, course_end_date | Dates, YYYY-MM-DD |
course_length, course_scheduled_time, course_self_study_time | Durations (length and scheduled time in minutes); empty when hidden on the course page |
course_tags, course_categories | Lists |
course_price, course_price_currency | Price |
course_recuring_enabled | Recertification on, true/false |
Learner-in-course fields
Code | Value |
participant_id | Enrolment ID (one learner in one course) |
course_status | One of Not started, In Progress, Completed, Failed, Events scheduled, Waiting for approval |
course_progress | Percentage, for example 100% |
session_is_completed | true/false |
user_enrolled_date, course_completion_date | Dates, YYYY-MM-DD |
last_activity, last_certification_date | Date and time, YYYY-MM-DD HH:MM (UTC) |
course_is_certified | true/false |
course_deadline_date, compliance_deadline_date, compliance_under_date | Deadline dates |
course_attendance, scheduled_events_to_attend, estimated_pages_length | Attendance and length |
participant_additional_info, promo_code | Enrolment extras |
Fields with no value are sent as null or an empty string. Learnster support can also rename keys to match what your system expects.
Delivery, retries and status
Learnster sends queued requests every 15 minutes and marks each one Done or Failed by comparing your endpoint's status code with the webhook's success code.
Your endpoint answers | Logged as |
Exactly the success code (default 200) | Done |
Any other code, including other 2xx such as 201 or 204 | Failed |
No answer, timeout, SSL or connection error | Failed |
OAuth2 token request fails | Failed |
Retries: by default a request is tried once. Support can set a number of retries per webhook; a failed request is then tried again on the next 15-minute run.
Failed requests are not resent automatically once retries run out. Ask support if you need them sent again.
Order is not guaranteed. Several requests for the same learner can arrive in the same second. Use course_status, session_is_completed or course_completion_date to decide what is newest, not arrival order.
Logs: Learnster logs every attempt: time sent, status code and the first 1,024 characters of your endpoint's response. Support can look up any request for you.
Success code: set by Learnster support. Tell them which code your endpoint returns on success.
Troubleshooting and FAQ
When something looks wrong, ask Learnster support to check the webhook log. The status code your endpoint returned shows whether the request arrived.
Problem | Likely cause | What to do |
The log shows Failed, but your system got the data | Your endpoint answers 201/202/204, the success code is 200 | Ask support to set the success code to what your endpoint returns |
No request at all for an event | No trigger connected, webhook not active, or the learner lacks the trigger's tags | Ask support to check the webhook is active and the trigger's tags |
Status 401 or 403 | Wrong or expired token, or missing gateway key header | Send support the new token or header value |
OAuth2 token error in the log | Wrong token URL, client ID, secret or scope | Check the values with your identity provider; try switching credentials between body and headers |
SSL or connection error | Expired or self-signed certificate, or firewall blocks Learnster | Renew the certificate or allow Learnster's addresses |
Old status arrived after the completion | Enrolment and completion requests were sent in the same run | Compare course_status or course_completion_date; ignore older data |
How quickly do webhooks arrive? Usually within 15 minutes of the event, and up to 30 minutes for enrolment and unenrolment.
Can I send to more than one system? Yes. Each receiving URL is set up as a separate webhook.
Which ID should I use to match learners? student_id never changes. user_personal_id works if your HR system sets it. Email can change, so avoid it as the only key.
Can webhooks be sent for past completions? No, only for events after the trigger is active. For history, use a report export or the Learnster API.
