You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Retrieves the course outline/index for a given course ID. Returns JSON including course release date, course structure, deprecated blocks info, proctoring URLs, discussions links, initial state of expanded locators, initial user clipboard, LMS link, reindex link, notification IDs, and custom relative dates status. Optional query parameter show can set initial expanded state of the outline. Supports AI tools in visualizing course hierarchy, analyzing course structure, or dynamically rendering content navigation.
PR:#39229 — feat: serve the course outline from authoring v2 State: open
What this does
This PR standardizes the Course Index functional area (#39066, umbrella #38137) as a new resource, GET /api/authoring/v2/courses/{course_key}/outline/, following the API standardization ADRs docs/decisions/0025 to 0038 and OEP-69. GET /api/contentstore/v1/course_index/{course_id} stays mounted and unchanged, and is marked deprecated.
ADRs applied
10 of 16 decisions applied on this pass; every one left open carries its reason.
0025 serializers
0026 permissions
0027 schema / docs
0028 viewsets
0030 GET idempotence
0034 authentication
0036 nested JSON
0037 versioning
0038 URL structure
OEP-69 conventions
0029 errors — envelope on every 400/401/403/404 this view raises, and no input crashes it. Open and pinned by tests that flip when fixed: (1) a malformed or slash-form course key gets the routing-level HTML 404 (no authoring catch-all yet); (2) 405 and 406 are typed internal until edx-drf-extensions catalogues them.
0031 merged endpoints — n/a: a single read operation
0032 pagination — n/a: one tree-shaped resource; depth is capped instead (ADR 0036 Pattern A)
0033 filtering — n/a: no list; the query parameters choose a representation and a subtree, and are serializer-validated
0035 MFE config — n/a: authenticated and per-course, not configuration
OEP-66 queryset scoping — n/a: not a list endpoint
The evidence for each tick is the compliance matrix in the PR body; nothing is ticked without a named test or gate line.
Backward compatibility
Versions gate: PASS. v1 course_index.py changes only in docstring lines; with docstrings stripped, its AST equals master. v2/authoring_urls.py gains one route. Protected, untouched: utils.py, views/course.py, xblock_storage_handlers/view_handlers.py (the shared outline builder), rest_api/serializers/common.py, the content-staging API and models, view_utils.py, the authz decorators, the CourseOverview model, docs/cms-openapi.yaml.
URLs gate: PASS. One route added; every base route still resolves.
Schema gate: PASS, 0 breaking. Two additions: the v2 GET, and the v1 GET newly deprecated: true. Warnings:
two new ones: the platform-default authenticator warnings that every default-auth view emits;
three that look new: ContainerChildrenView's existing warnings, moved by the docstring lines.
v1 tests: untouched and green.
Parity (?view=full vs v1, through the test client). The comparison is typed, keeps empty containers, and fails on a difference that is not declared or a declared one that does not occur. Declared differences:
initial_user_clipboard: always absent in v2.
For courses whose blocks have pre-1900 start dates: course_release_date, start, release_date, released_to_students and visibility_state (v1 repairs these dates on read and reports "Set Date"/unscheduled; v2 reports them as stored).
course_structure stays a free-form object, as in v1. The shared create_xblock_info builds it, and OVERRIDE_CREATE_XBLOCK_INFO plugins can extend it. Its node keys are documented in the schema. OutlineFullViewNodeKeysTest pins the key set per block role, so a change to the shared builder fails loudly.
GET /api/contentstore/v1/course_index/{course_id} is deprecated: true in the CMS schema, and its docstrings name the v2 successor. No runtime header (frozen route). The DEPR record is an entry on #39128: this comment. Folding this entry, and the ones for #39102, #39186 and #39227, into the issue body is pending. Window, per #39128: the marking ships in the next named release after Verawood, and v1 stays mounted until one named release after that.
Follow-ups
Authoring v2: a JSON catch-all for malformed keys.
edx-drf-extensions: catalogue 405 and 406.
content_staging: the clipboard GET can save a CourseOverview row.
Pre-1900 start dates: a non-GET home for the date repair.
frontend-app-authoring: migrate the outline and competency-management screens to v2 ?view=full.
Activity
taimoor-ahmed-1 commentedon Oct 14, 2026
Standardization PR open: #39229
PR: #39229 — feat: serve the course outline from authoring v2
State: open
What this does
This PR standardizes the Course Index functional area (#39066, umbrella #38137) as a new resource,
GET /api/authoring/v2/courses/{course_key}/outline/, following the API standardization ADRsdocs/decisions/0025to0038and OEP-69.GET /api/contentstore/v1/course_index/{course_id}stays mounted and unchanged, and is marked deprecated.ADRs applied
10 of 16 decisions applied on this pass; every one left open carries its reason.
internaluntil edx-drf-extensions catalogues them.The evidence for each tick is the compliance matrix in the PR body; nothing is ticked without a named test or gate line.
Backward compatibility
course_index.pychanges only in docstring lines; with docstrings stripped, its AST equals master.v2/authoring_urls.pygains one route. Protected, untouched:utils.py,views/course.py,xblock_storage_handlers/view_handlers.py(the shared outline builder),rest_api/serializers/common.py, the content-staging API and models,view_utils.py, the authz decorators, the CourseOverview model,docs/cms-openapi.yaml.deprecated: true. Warnings:ContainerChildrenView's existing warnings, moved by the docstring lines.?view=fullvs v1, through the test client). The comparison is typed, keeps empty containers, and fails on a difference that is not declared or a declared one that does not occur. Declared differences:initial_user_clipboard: always absent in v2.course_release_date,start,release_date,released_to_studentsandvisibility_state(v1 repairs these dates on read and reports "Set Date"/unscheduled; v2 reports them as stored).course_structurestays a free-form object, as in v1. The sharedcreate_xblock_infobuilds it, andOVERRIDE_CREATE_XBLOCK_INFOplugins can extend it. Its node keys are documented in the schema.OutlineFullViewNodeKeysTestpins the key set per block role, so a change to the shared builder fails loudly.Gates
Deprecations
GET /api/contentstore/v1/course_index/{course_id}isdeprecated: truein the CMS schema, and its docstrings name the v2 successor. No runtime header (frozen route). The DEPR record is an entry on #39128: this comment. Folding this entry, and the ones for #39102, #39186 and #39227, into the issue body is pending. Window, per #39128: the marking ships in the next named release after Verawood, and v1 stays mounted until one named release after that.Follow-ups
CourseOverviewrow.?view=full.🤖 Generated with Claude Code
Review on the PR, please — this issue stays open until it merges.