Webhook Events Reference

Complete reference for all webhook events sent by the SCORM API.

Table of Contents

Event Overview

All webhook events follow a consistent structure:

{
  "event": "event.type.name",
  "tenant_id": "550e8400-e29b-41d4-a716-446655440000",
  "data": {
    // Event-specific data
  },
  "timestamp": "2025-01-15T10:30:00.000Z",
  "delivery_id": "delivery_xyz789"
}

Common Fields

  • event (string): Event type identifier
  • tenant_id (UUID): Tenant that triggered the event
  • data (object): Event-specific payload
  • timestamp (ISO 8601): When the event occurred
  • delivery_id (string): Unique delivery identifier for tracking

Event Types

Package Events

package.processing.completed

Triggered when a SCORM package finishes processing successfully.

When: After package upload, validation, extraction, and database storage complete.

Payload:

{
  "event": "package.processing.completed",
  "tenant_id": "550e8400-e29b-41d4-a716-446655440000",
  "data": {
    "package_id": "pkg_abc123",
    "title": "Introduction to Safety Training",
    "version": "1.2",
    "scorm_version": "1.2",
    "revision": 1,
    "launch_url": "index.html",
    "manifest_url": "imsmanifest.xml",
    "file_size_bytes": 5242880,
    "storage_path": "tenant-550e8400/packages/pkg_abc123",
    "metadata": {
      "identifier": "com.example.course.001",
      "schema": "ADL SCORM",
      "schemaversion": "1.2",
      "sco_count": 5
    }
  },
  "timestamp": "2025-01-15T10:30:00.000Z",
  "delivery_id": "delivery_xyz789"
}

Use Cases:

  • Update package status in your system
  • Notify administrators of successful upload
  • Trigger course availability notifications
  • Update package catalog

package.processing.failed

Triggered when package processing fails.

When: During validation, extraction, or storage if an error occurs.

Payload:

{
  "event": "package.processing.failed",
  "tenant_id": "550e8400-e29b-41d4-a716-446655440000",
  "data": {
    "package_id": "pkg_abc123",
    "error": "Invalid SCORM manifest: missing imsmanifest.xml",
    "error_code": "INVALID_MANIFEST",
    "storage_path": "tenant-550e8400/uploads/tmp_123.zip",
    "original_filename": "course.zip"
  },
  "timestamp": "2025-01-15T10:30:00.000Z",
  "delivery_id": "delivery_xyz789"
}

Error Codes:

  • INVALID_MANIFEST - Manifest file missing or invalid
  • INVALID_SCORM_VERSION - Unsupported SCORM version
  • EXTRACTION_FAILED - Failed to extract package
  • STORAGE_ERROR - Storage backend error
  • QUOTA_EXCEEDED - Package or storage quota exceeded

Use Cases:

  • Notify user of upload failure
  • Log errors for debugging
  • Trigger retry mechanisms
  • Update package status to "failed"

Session Events

session.created

Triggered when a new learning session is created.

When: After calling /api/v1/packages/{id}/launch or /api/v1/sessions/external.

Payload:

{
  "event": "session.created",
  "tenant_id": "550e8400-e29b-41d4-a716-446655440000",
  "data": {
    "session_id": "session_abc123",
    "package_id": "pkg_abc123",
    "user_id": "user_xyz789",
    "launch_url": "https://app.allureconnect.com/player/session_abc123?token=eyJhbGciOi...",
    "expires_at": "2025-01-15T22:30:00.000Z"
  },
  "timestamp": "2025-01-15T10:30:00.000Z",
  "delivery_id": "delivery_xyz789"
}

Use Cases:

  • Track course starts
  • Update learner dashboard
  • Send welcome notifications
  • Log learning activity

session.completed

Triggered when a learner completes a course.

When: Session completion_status changes to completed.

Payload:

{
  "event": "session.completed",
  "tenant_id": "550e8400-e29b-41d4-a716-446655440000",
  "data": {
    "session_id": "session_abc123",
    "package_id": "pkg_abc123",
    "user_id": "user_xyz789",
    "completion_status": "completed",
    "success_status": "passed",
    "score": {
      "scaled": 0.85,
      "raw": 85,
      "min": 0,
      "max": 100
    },
    "time_spent_seconds": 3600,
    "attempts": 1
  },
  "timestamp": "2025-01-15T10:30:00.000Z",
  "delivery_id": "delivery_xyz789"
}

Use Cases:

  • Issue completion certificates
  • Update grade book
  • Trigger follow-up actions
  • Send completion notifications
  • Award badges or achievements

session.progress

Triggered when session CMI data is updated.

When: SCORM player updates progress, scores, or time spent.

Note: This event can be very frequent (multiple times per minute). Consider filtering or throttling on your end.

Payload:

{
  "event": "session.progress",
  "tenant_id": "550e8400-e29b-41d4-a716-446655440000",
  "data": {
    "session_id": "session_abc123",
    "package_id": "pkg_abc123",
    "user_id": "user_xyz789",
    "completion_status": "incomplete",
    "success_status": "unknown",
    "score": {
      "scaled": 0.65,
      "raw": 65,
      "min": 0,
      "max": 100
    },
    "time_spent_seconds": 1800,
    "version": 5
  },
  "timestamp": "2025-01-15T10:30:00.000Z",
  "delivery_id": "delivery_xyz789"
}

Use Cases:

  • Real-time progress tracking
  • Live dashboards
  • Progress notifications
  • Analytics aggregation

Performance Note: If you receive too many progress events, consider:

  • Filtering by completion status changes only
  • Throttling updates in your system
  • Using polling for progress instead

Delivery Guarantees

At-Least-Once Delivery

The SCORM API guarantees at-least-once delivery:

  • Events are delivered at least once
  • Events may be delivered multiple times (duplicates)
  • Failed deliveries are retried automatically

Retry Schedule

Failed deliveries are retried with exponential backoff:

Attempt Delay Total Time
1 Immediate 0s
2 60s 60s
3 2m 3m
4 4m 7m
5 8m 15m
6 16m 31m

After 5 retry attempts, the delivery is marked as "exhausted" and an email notification is sent.

Delivery Status

  • pending: Waiting for retry
  • delivered: Successfully delivered (2xx response)
  • failed: Delivery failed (non-2xx response)
  • exhausted: Max retries exceeded

Retry Logic

Automatic Retries

The SCORM API automatically retries failed deliveries:

  • Exponential backoff (60s → 2m → 4m → 8m → 16m)
  • Jitter to prevent thundering herd
  • Max 5 retry attempts
  • 30-second timeout per attempt

Manual Retry

You can manually retry a failed delivery:

curl -X POST https://app.allureconnect.com/api/admin/webhooks/deliveries/delivery_xyz789/retry \
  -H "X-API-Key: your-api-key"

Idempotency

Handling Duplicate Events

Since webhooks use at-least-once delivery, you may receive duplicate events. Implement idempotency:

const processedDeliveries = new Set<string>();

export async function POST(request: Request) {
  const event = await request.json();
  const deliveryId = event.delivery_id;

  // Check if already processed
  if (processedDeliveries.has(deliveryId)) {
    return new Response('Already processed', { status: 200 });
  }

  // Process event
  await handleEvent(event);

  // Mark as processed
  processedDeliveries.add(deliveryId);

  return new Response('OK', { status: 200 });
}

Database-Based Idempotency

For production, use database to track processed deliveries:

async function isDeliveryProcessed(deliveryId: string): Promise<boolean> {
  const result = await db.webhookDeliveries.findUnique({
    where: { delivery_id: deliveryId },
  });
  return !!result;
}

async function markDeliveryProcessed(deliveryId: string) {
  await db.webhookDeliveries.create({
    data: { delivery_id: deliveryId, processed_at: new Date() },
  });
}

Best Practices

  1. Process Asynchronously: Return 200 immediately, process in background
  2. Implement Idempotency: Handle duplicate deliveries gracefully
  3. Log All Events: Keep audit trail of all webhook events
  4. Handle Errors: Don't let webhook processing crash your application
  5. Monitor Delivery: Track delivery success rates
  6. Filter Progress Events: Consider filtering session.progress events if too frequent

Related Documentation


Last Updated: 2025-01-15