Skip to main content

Overview

The User Progress API tracks completion status for learning resources. Progress is global per user per resource - when a resource is marked complete, it appears complete across all instances.

Key Concepts

Global Progress

Progress is tracked globally, not per-instance:
  • Completing a resource in one study plan instance marks it complete everywhere
  • User can have multiple instances of the same plan, but resource completion is shared
  • Progress records store userId and resourceId (no instanceId)

Progress Fields

  • completed - Boolean completion status
  • progress - Numeric progress (0-100)
  • timeSpent - Time spent in minutes
  • notes - User notes on the resource
  • completedAt - Timestamp when marked complete
  • lastAccessedAt - Last interaction timestamp

Get User Progress

curl -X GET "https://your-domain.com/api/user-progress?resourceId=507f1f77bcf86cd799439011" \
  -H "Authorization: Bearer YOUR_TOKEN"
GET /api/user-progress Get user’s progress records. Requires authentication.

Query Parameters

resourceId
string
Filter by specific resource ID

Response

progress
array
Array of progress objects

Update Progress

curl -X POST "https://your-domain.com/api/user-progress" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "instanceId": "507f1f77bcf86cd799439011",
    "resourceId": "507f191e810c19729de860ea",
    "completed": true,
    "timeSpent": 45,
    "notes": "Great explanation of quicksort!"
  }'
POST /api/user-progress Create or update progress for a resource. Requires authentication.

Request Body

instanceId
string
required
Instance ID (used for verification and updating instance’s completedResources)
resourceId
string
required
Resource ID
completed
boolean
Mark as completed/incomplete
progress
number
Progress percentage (0-100)
timeSpent
number
Time spent in minutes
notes
string
User notes about the resource

Response

message
string
“Progress created successfully” or “Progress updated successfully”
progress
object
The created/updated progress object

Behavior

  • If progress record exists: Updates the existing record
  • If progress record doesn’t exist: Creates new record
  • When completed changes from false to true: Sets completedAt timestamp
  • When completed changes from true to false: Clears completedAt
  • Updates instance’s completedResources array accordingly
  • Always updates lastAccessedAt to current time

Check Completion Status

curl -X GET "https://your-domain.com/api/user-progress/check?resourceIds=507f1f77bcf86cd799439011,507f191e810c19729de860ea" \
  -H "Authorization: Bearer YOUR_TOKEN"
GET /api/user-progress/check Check completion status for multiple resources. Requires authentication.

Query Parameters

resourceIds
string
required
Comma-separated list of resource IDs

Response

Returns an object mapping resource IDs to completion status:
{
  "507f1f77bcf86cd799439011": {
    "completed": true,
    "completedAt": "2026-03-15T14:30:00Z"
  },
  "507f191e810c19729de860ea": {
    "completed": false,
    "completedAt": null
  }
}
[resourceId]
object
Completion status for each resource

Bulk Update

curl -X POST "https://your-domain.com/api/user-progress/bulk" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "resourceIds": [
      "507f1f77bcf86cd799439011",
      "507f191e810c19729de860ea",
      "507f191e810c19729de860eb"
    ],
    "completed": true
  }'
POST /api/user-progress/bulk Mark multiple resources as complete or incomplete. Requires authentication.

Request Body

resourceIds
array
required
Array of resource IDs to update
completed
boolean
required
Completion status to set for all resources

Response

message
string
“Bulk update completed”
results
array
Array of result objects for each resource
Example response:
{
  "message": "Bulk update completed",
  "results": [
    {
      "resourceId": "507f1f77bcf86cd799439011",
      "success": true
    },
    {
      "resourceId": "invalid-id",
      "success": false,
      "error": "Invalid resource ID"
    }
  ]
}

Behavior

  • Creates progress records if they don’t exist
  • Updates existing records
  • Sets completedAt timestamp when marking complete
  • Clears completedAt when marking incomplete
  • Processes all resources, returns individual success/failure for each

Progress and Instances

While progress is global, it affects instances:
  1. Instance Creation: New instance starts with no completed resources
  2. Marking Complete: Updates global progress AND adds to instance’s completedResources array
  3. Instance Queries: Instance endpoints automatically populate completion status from global progress
  4. Multiple Instances: Same resource can appear in multiple instances, completion shared

Example Flow

// User has two instances of the same study plan
const instance1 = '507f1f77bcf86cd799439011';
const instance2 = '507f1f77bcf86cd799439012';
const resource = '507f191e810c19729de860ea';

// Mark resource complete in instance1
await fetch('/api/user-progress', {
  method: 'POST',
  body: JSON.stringify({
    instanceId: instance1,
    resourceId: resource,
    completed: true
  })
});

// Resource now appears complete in BOTH instances
// because progress is global

Error Responses

400 Bad Request

{
  "error": "Invalid instanceId or resourceId"
}
{
  "error": "resourceIds (array) and completed status are required"
}

403 Forbidden

{
  "error": "You do not have permission to update this progress"
}

404 Not Found

{
  "error": "Instance not found"
}

Build docs developers (and LLMs) love