Webhooks

English only

Event Notifications

Pluvo supports webhooks that send you notifications for important events, such as changes in users, trainings, groups, progress, enrollments, or portfolio items. These are sent as POST requests to an endpoint you have configured.

Configuration

Webhooks are configured through the admin interface of your organization's Pluvo environment. For each webhook subscription, you specify:

  • Target URL — The endpoint that receives the POST request
  • Events — Which events trigger the webhook

Security (Signature Verification)

Each webhook contains two headers for verification:

  • X-Signature — HMAC signature of the request body
  • X-Signature-Salt — Random salt used for the signature

Verification steps:

  1. Combine the X-Signature-Salt header with your Pluvo Webhook Key
  2. Generate a SHA1-HMAC hash of the request body using the combined key
  3. Base64-encode the hash
  4. Compare it with the X-Signature header
Always verify webhook signatures in production to prevent spoofed requests.

Retry Policy

  • Webhooks have a 30-second timeout per request
  • Failed requests (4xx except 410, and 5xx) are retried with exponential backoff
  • Maximum 72 retry attempts
  • A 410 Gone response permanently disables the subscription

Webhook Events

User Events

Events: USER_CREATED, USER_UPDATED, USER_DELETED

{
  "id": "uuid",
  "ref": "user-ref",
  "event": "USER_CREATED",
  "name": "User X",
  "email": "test@example.com",
  "isActive": true,
  "extraFields": {
    "Department": "Marketing"
  },
  "sentDate": "2020-01-01T10:15:00.000Z"
}

Training Events

Events: TRAINING_CREATED, TRAINING_UPDATED, TRAINING_DELETED

{
  "id": "uuid",
  "ref": "training-ref",
  "event": "TRAINING_CREATED",
  "title": "Training X",
  "subtitle": "Subtitle",
  "introduction": "Introduction text",
  "startDate": "2020-02-01",
  "endDate": "2021-02-01",
  "isActive": true,
  "sentDate": "2020-01-01T10:15:00.000Z"
}

Group Events

Events: GROUP_CREATED, GROUP_UPDATED, GROUP_DELETED

{
  "id": "uuid",
  "ref": "group-ref",
  "event": "GROUP_CREATED",
  "name": "Group X",
  "enableChat": true,
  "sentDate": "2020-01-01T10:15:00.000Z"
}

Enrollment Events

Events: OFFER_EVENT_ENROLLED, OFFER_EVENT_ENROLLMENT_STATUS_UPDATED, OFFER_EVENT_UNENROLLED

{
  "id": "uuid",
  "user": {
    "id": "uuid",
    "name": "Jane Doe",
    "email": "jane@example.com",
    "isActive": true,
    "ref": "EMP-12345",
    "extraFields": { "Department": "Marketing" }
  },
  "status": "ENROLLED",
  "offer_event": {
    "id": "uuid",
    "ref": "event-sept-2024",
    "title": "Starting Moment September",
    "price": "0.00",
    "max_subscriptions": 25,
    "cancelled": false,
    "kind": "TRAINING"
  },
  "sentDate": "2024-09-01T10:15:00.000Z",
  "event": "OFFER_EVENT_ENROLLED"
}

The status field can be: ENROLLED, REQUESTED, DENIED, COMPLETED, ABSENT

Attendance Update

Event: OFFER_EVENT_ATTENDANCE_UPDATE

{
  "id": "uuid",
  "new_status": "PRESENT",
  "offer_event": {
    "id": "uuid",
    "ref": "event-sept-2024",
    "title": "Starting Moment September"
  },
  "offer_event_date": {
    "id": "uuid",
    "ref": "session-1",
    "start_date": "2024-09-12T09:00:00Z",
    "end_date": "2024-09-12T12:00:00Z",
    "location": "Room 101"
  },
  "user": {
    "id": "uuid",
    "name": "Jane Doe",
    "email": "jane@example.com",
    "ref": "EMP-12345"
  },
  "sentDate": "2024-09-12T12:30:00.000Z",
  "event": "OFFER_EVENT_ATTENDANCE_UPDATE"
}

The new_status field can be: PRESENT, ABSENT, NO_STATUS

Training Finished

Event: TRAINING_FINISHED

{
  "id": "uuid",
  "score": null,
  "start_date": "2023-08-07T14:38:08+02:00",
  "user": { "id": "uuid", "name": "User X", "email": "..." },
  "training": { "id": "uuid", "title": "Training X" },
  "sentDate": "2023-08-07T12:43:00.976Z",
  "event": "TRAINING_FINISHED"
}

Course Finished

Event: COURSE_FINISHED

{
  "id": "uuid",
  "score": 0,
  "time_spent": { "days": 0, "seconds": 0, "microseconds": 0 },
  "user": { "id": "uuid", "name": "User X", "email": "..." },
  "course": { "id": "uuid", "title": "Course X" },
  "type": "COURSE",
  "sentDate": "2023-08-07T12:06:02.178Z",
  "event": "COURSE_FINISHED"
}

Module Group Events

Events: EVENT_CONDITIONS_FULFILLED, EVENT_FILE_UPLOADED, EVENT_CERTIFICATE_ACHIEVED, EVENT_CERTIFICATE_STATUS_CHANGED

Example payload (EVENT_CERTIFICATE_ACHIEVED)

{
  "id": "uuid",
  "user": {
    "id": "uuid",
    "name": "Jane Doe",
    "email": "jane@example.com",
    "ref": "EMP-12345"
  },
  "title": "Safety Certificate",
  "subtitle": "",
  "text": "",
  "creationDate": "2024-03-15",
  "expiryDate": "2025-03-15",
  "certificate_ref": "cert-safety",
  "file": "https://files.pluvo.co/certificates/abc123.pdf",
  "training": {
    "id": "uuid",
    "title": "Safe Working Training",
    "ref": "safety-2024"
  },
  "sentDate": "2024-03-15T12:06:02.178Z",
  "event": "EVENT_CERTIFICATE_ACHIEVED"
}

Portfolio Item Events

Events: PORTFOLIO_ITEM_CREATED, PORTFOLIO_ITEM_UPDATED, PORTFOLIO_ITEM_DELETED, PORTFOLIO_ITEM_SYNC

PORTFOLIO_ITEM_SYNC is a debounced event (3-second delay) that fires when portfolio data is synchronized.
{
  "id": "uuid",
  "user": { "id": "uuid", "name": "...", "email": "..." },
  "title": "Portfolio item title",
  "description": "Description",
  "start_date": "2023-08-05T00:00:00+02:00",
  "end_date": "2023-08-17T00:00:00+02:00",
  "files": ["https://files.pluvo.co/..."],
  "sentDate": "2023-08-07T10:52:28.819Z",
  "event": "PORTFOLIO_ITEM_CREATED"
}

Assignment Grade Update

Event: ASSIGNMENT_GRADE_UPDATE

{
  "id": "uuid",
  "score": 0.1,
  "fulfilled": null,
  "state": "open",
  "user": { "id": "uuid", "name": "..." },
  "assignment": {
    "id": "uuid",
    "assignment_type": "participant",
    "score_type": "numeral",
    "weight": 0
  },
  "sentDate": "2023-08-07T12:49:07.442Z",
  "event": "ASSIGNMENT_GRADE_UPDATE"
}

Complete Event Reference

EventCategoryDescription
USER_CREATEDUsersNew user created
USER_UPDATEDUsersUser data changed
USER_DELETEDUsersUser archived/deleted
GROUP_CREATEDGroupsNew group created
GROUP_UPDATEDGroupsGroup data changed
GROUP_DELETEDGroupsGroup deleted
TRAINING_CREATEDTrainingsNew training created
TRAINING_UPDATEDTrainingsTraining data changed
TRAINING_DELETEDTrainingsTraining archived/deleted
TRAINING_FINISHEDProgressUser completed entire learning journey
COURSE_FINISHEDProgressUser completed a course/module
OFFER_EVENT_ENROLLEDEnrollmentsUser enrolled in offer event
OFFER_EVENT_ENROLLMENT_STATUS_UPDATEDEnrollmentsEnrollment status changed
OFFER_EVENT_UNENROLLEDEnrollmentsUser unenrolled from event
OFFER_EVENT_ATTENDANCE_UPDATEEnrollmentsAttendance status changed
EVENT_CONDITIONS_FULFILLEDModule GroupsModule group conditions met
EVENT_FILE_UPLOADEDModule GroupsFile uploaded in module group
EVENT_CERTIFICATE_ACHIEVEDCertificatesCertificate automatically issued
EVENT_CERTIFICATE_STATUS_CHANGEDCertificatesCertificate status changed
PORTFOLIO_ITEM_CREATEDPortfolioNew portfolio item
PORTFOLIO_ITEM_UPDATEDPortfolioPortfolio item changed
PORTFOLIO_ITEM_DELETEDPortfolioPortfolio item removed
PORTFOLIO_ITEM_SYNCPortfolioPortfolio item synced
ASSIGNMENT_GRADE_UPDATEAssignmentsAssignment grade changed
Schließ die Richtung