---
title: "Api Learn Activity Log"
method: GET
path: "/api/learn/activity-log"
tags: ["Education"]
---

# Api Learn Activity Log

`GET /api/learn/activity-log`

## Request

- Base URL: `https://www.oxfordledge.com` (the document declares no server; this is the origin it was published from)
- URL: `https://www.oxfordledge.com/api/learn/activity-log`
- Auth: none declared

Return the authenticated user's most recent activity events.

Used by progress.ts:fetchActivityLog() to render the Reading-Room
Ledger's reading-log section. Falls through to the synthesis
fallback (progress.ts:deriveReadingLog) on:
  - 401 anon caller (require_auth rejects)
  - 200 with rows=[] (brownfield pre-v112, no events yet, or
    PG read failure swallowed by pg_get_user_activity_log)

The reading-log render in progress.ts:buildReadingLog handles
both branches uniformly -- rows=[] paints the "No entries yet"
empty state.

## Query parameters

- `limit` integer

## Response `200`

Successful Response

- ActivityLogResponse: `GET /api/learn/activity-log` response shape. Required: rows (always present, possibly empty). FE list-iteration (progress.ts:buildReadingLog) MUST NOT NPE on a missing key -- mirrors the 2026-04-27 /api/institutional-holders/ changes incident pattern (contract-test substrate). On any error the route returns rows=[] with 500 status; FE falls through to its synthesis fallback (deriveReadingLog).
  - `rows` ActivityRowOut[], required: Chronological newest-first list of activity events for the authenticated user. Capped at the request's `limit` param (default 20, max 100). Empty list when the user has no events yet (first-render before any module pass / book shelve / glossary lookup) or when the brownfield DB is pre-v113.
    - `id` integer, required: BIGSERIAL primary key of the event row. Used for client-side dedupe / pagination cursor.
    - `kind` string, required: Event class: one of 'module_pass' | 'module_complete' | 'book_shelved' | 'glossary_lookup'. Closed enum mirrored at the DB CHECK constraint (v113).
    - `ts` string, required: ISO-8601 timestamp of when the event was recorded. Used as the primary sort + the date-stamp label on the Reading-Log card.
    - `ref_type` string, nullable: Categorical hint for ref_id ('module' / 'book' / 'term'). NULL for ref-less event classes.
    - `ref_id` string, nullable: The module slug / book ISBN / glossary term key. Soft-ref (no FK); orphaning a moduleSlug is a non-event because the JSON-side target rename is rare and the historical record stands.
    - `meta` object, nullable: Optional JSONB payload. Today: {'quizScore': int} for module_pass; {'masteryScore': int} for module_complete; {} for the others.

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/oxfordledge/apis/oxford-ledge-api.md) · [All operations](https://skmtc.dev/oxfordledge/apis/oxford-ledge-api/llms.txt) · [OpenAPI document](https://skmtc.dev/oxfordledge/apis/oxford-ledge-api/revisions/e832a1260f0b?raw)
