Skip to content

Progress Reporting

Supported Endpoints

Endpoint Permission Purpose
GET /api/v1/progress/events read_progress Poll durable progress events in cursor order
GET /api/v1/progress read_progress Get one learner's aggregate progress in one course
GET /api/v1/progress/summary read_progress Get one learner's progress across courses with activity
GET /api/v1/courses/{course_id}/progress read_progress Get roster-level progress for learners with activity in a course
GET /api/v1/progress/courses/{course_id} read_progress Get one learner's per-topic progress in one course

Poll Progress Events

GET /api/v1/progress/events returns McCoy Surface session lifecycle events in feed order.

curl "https://api.mccoy.org/api/v1/progress/events?course_id=550e8400-e29b-41d4-a716-446655440000&page_size=100" \
  -H "X-Api-Key: YOUR_API_KEY"

Filters:

Parameter Description
learner_id Optional McCoy learner ID
course_id Optional course UUID
event_type Optional comma-separated event types
start_date Optional inclusive activity date, YYYY-MM-DD
end_date Optional inclusive activity date, YYYY-MM-DD
page_size Results per page, default 100, max 500
cursor Opaque cursor from the previous response

Process events in response order and dedupe by event_id. Store pagination.next_cursor after every successful page, including empty pages.

Event source is surface. Event types can include session_started, session_completed, and session_abandoned.

{
  "data": {
    "events": [
      {
        "event_id": "event-uuid",
        "event_type": "session_completed",
        "event_timestamp": "2026-06-02T14:22:00Z",
        "emitted_at": "2026-06-02T14:22:01Z",
        "source": "surface",
        "learner_id": "lrn_01HX7N8V2K9Q4R6M3B5C7D9E0F",
        "course_id": "550e8400-e29b-41d4-a716-446655440000",
        "course_name": "Biology 101",
        "session_id": "session-uuid",
        "level_id": "level-uuid",
        "level_name": "Level 1",
        "session_type": "learn",
        "score_correct": 8,
        "score_total": 10,
        "score_percentage": 80.0
      }
    ]
  },
  "pagination": {
    "page_size": 100,
    "next_cursor": "opaque-cursor",
    "has_more": false
  }
}

Read Learner Progress

GET /api/v1/progress returns one learner's aggregate progress in one course.

curl "https://api.mccoy.org/api/v1/progress?course_id=550e8400-e29b-41d4-a716-446655440000&learner_id=lrn_01HX7N8V2K9Q4R6M3B5C7D9E0F" \
  -H "X-Api-Key: YOUR_API_KEY"

Single-course progress can return not_started, in_progress, or completed.

{
  "data": {
    "learner_id": "lrn_01HX7N8V2K9Q4R6M3B5C7D9E0F",
    "course_id": "550e8400-e29b-41d4-a716-446655440000",
    "course_name": "Biology 101",
    "completion_percentage": 45.0,
    "status": "in_progress",
    "levels_completed": 9,
    "total_levels": 20,
    "first_activity_at": "2026-06-01T08:30:00Z",
    "last_activity_at": "2026-06-02T14:22:00Z"
  }
}

GET /api/v1/progress/summary lists courses where the learner has activity.

Parameters:

Parameter Description
learner_id Required McCoy learner ID
status Optional comma-separated filter: completed, in_progress
sort_by Optional: completion_percentage, last_activity_at, first_activity_at, course_name, levels_completed
sort_order Optional: asc or desc; default desc
curl "https://api.mccoy.org/api/v1/progress/summary?learner_id=lrn_01HX7N8V2K9Q4R6M3B5C7D9E0F" \
  -H "X-Api-Key: YOUR_API_KEY"
{
  "data": {
    "learner_id": "lrn_01HX7N8V2K9Q4R6M3B5C7D9E0F",
    "summary": {
      "total_courses": 2,
      "completed": 1,
      "in_progress": 1,
      "total_levels_completed": 14
    },
    "courses": [
      {
        "course_id": "550e8400-e29b-41d4-a716-446655440000",
        "course_name": "Biology 101",
        "completion_percentage": 100.0,
        "status": "completed",
        "levels_completed": 10,
        "total_levels": 10,
        "first_activity_at": "2026-06-01T08:30:00Z",
        "last_activity_at": "2026-06-10T16:45:00Z"
      },
      {
        "course_id": "660e8400-e29b-41d4-a716-446655440001",
        "course_name": "Chemistry 101",
        "completion_percentage": 40.0,
        "status": "in_progress",
        "levels_completed": 4,
        "total_levels": 10,
        "first_activity_at": "2026-06-12T09:15:00Z",
        "last_activity_at": "2026-06-18T11:20:00Z"
      }
    ]
  }
}

Read Course Progress

GET /api/v1/courses/{course_id}/progress returns progress for learners with activity in a course. Use it for instructor, admin, or reporting dashboards.

Parameters:

Parameter Description
page Optional page number, default 1
page_size Optional results per page, default 50, max 100
status Optional comma-separated filter: completed, in_progress
sort_by Optional: completion_percentage, last_activity_at, first_activity_at, levels_completed
sort_order Optional: asc or desc; default desc
inactive_days Optional filter to learners with no activity for at least this many days

GET /api/v1/progress/courses/{course_id}?learner_id=... returns the same learner scoped to per-topic completion counts for one course.

{
  "data": {
    "course_id": "550e8400-e29b-41d4-a716-446655440000",
    "last_active_topic_id": "770e8400-e29b-41d4-a716-446655440002",
    "last_activity_at": "2026-06-02T14:22:00Z",
    "topics": [
      {
        "topic_id": "770e8400-e29b-41d4-a716-446655440002",
        "completed_count": 8,
        "total_count": 10,
        "attempted_count": 9,
        "accuracy": 0.89
      }
    ],
    "total_completed": 8,
    "total_attempted": 9,
    "accuracy": 0.89,
    "percentage": 80.0
  }
}

Error Codes

HTTP Status Code Description
400 MISSING_FIELDS Required field missing
400 INVALID_REQUEST Malformed request or invalid field value
400 INVALID_PARAMETERS Invalid feed filter, pagination value, or cursor
401 UNAUTHORIZED Missing or invalid API key
403 COURSE_ACCESS_DENIED No access to the specified course
404 LEARNER_NOT_FOUND The learner_id was not found for this API key
404 RESOURCE_NOT_FOUND Course not found or unavailable for this API key

Next Steps