Migrate importExternalCoursesStats
This guide details how to migrate from the v1 importExternalCoursesStats endpoint to the new v2 architecture.
Key changes
- From synchronous to asynchronous processing: API v2 processes statistics imports asynchronously, allowing bulk operations of up to 10,000 records per request.
- Simplified field structure: v2 consolidates activity tracking with clearer semantics and removes complex auto-calculation scenarios.
- Enhanced control: v2 introduces the
forceNewparameter to explicitly control whether statistics create new attempts or update existing ones.- Flexible user and course identification: v2 introduces identifier objects that allow you to reference courses and users by either external or internal IDs
Documentation links
- API v1 reference
- API v2 reference: Import integration statistics
Endpoint mapping
- v1:
/api/v1/externalContents/groups/:groupId/externalPlatforms/:externalPlatform/courses/stats - v2:
/api/v2/bulk/integrations/{integrationId}/stats
Prerequisites
Before migrating to v2, you must have an integration configuration created. If you haven't done this yet, see step 2 in Create an API-based integration for instructions on creating an integration using the POST /api/v2/integrations endpoint.
You'll need your integrationId (the _id returned when creating the integration).
Main input changes
Change type | API v1 | API v2 |
|---|---|---|
Modified | Path variables: | Path variable: |
| Modified |
|
|
| Modified |
|
|
| Modified |
|
|
| Modified |
|
|
| Modified |
|
|
| Modified |
|
|
| Modified |
|
|
| Added |
| |
| Added |
| |
| Added |
| |
| Added |
|
Behavioral changes
v1: Complex auto-calculation logic
v1 had four scenarios for calculating activity timestamps and globalTime.
v2 removes all auto-calculation logic. You must provide all required fields explicitly:
progress(0-100)timeSpent(in milliseconds)firstActivityAt(ISO 8601 datetime)lastActivityAt(ISO 8601 datetime)
Attempt creation/update logic
v2 uses the forceNew parameter to control behavior:
forceNew: true→ Always creates a new attemptforceNew: false(default) → Updates existing non-completed attempts OR creates new attempt if:- No attempt exists for this course/user combination
firstActivityAtis later than all existing attempts'lastActivityAtorcompletedAt
Main output changes
API v2 shifted from synchronous to asynchronous operations. Instead of an immediate result (200 OK), it returns a 202 Accepted status code indicating the bulk request has been queued. The full result must be tracked via the Location header.
Updated 22 days ago
