- module
- curriculum
- surface
- alpha
- baseUrl
- https://platform3-andymontgomery-9773s-projects.vercel.app/curriculum/alpha/implementation/api
Contract overview
Endpoints
POST /alpha/curriculum/v1/components
Create a track, grade, course, lesson, practice, review, gate, or other component as a stock CASE CFItem. A caller-supplied component_id that matches a soft-retired component reactivates that same identity only as draft, preserving created_at, advancing its CASE version, clearing retired_at, and returning an immediately readable ETag. Every Content target supplies exact content_id, content_version_id, and content_kind values and must pass Content-owned same-tenant release eligibility before the write.
GET /alpha/curriculum/v1/components/{componentId}
Read one CASE-backed Curriculum component by id for correction workflows.
PATCH /alpha/curriculum/v1/components/{componentId}
Update mutable component fields such as name, position, target_ref, renderer_ref, and publication status with If-Match. A Content target is an exact version tuple and is independently revalidated through Content before the write; latest-version substitution is forbidden.
POST /alpha/curriculum/v1/components/{componentId}/repoint
Producer self-service repoint/attach of one component's exact Content pin: move an existing pin to its amended exact version (operation=repoint) or pin newly published content onto an unpinned component (operation=attach).
- integratorPolicy
- A producer whose course already pins a Content identity repoints that pin directly with its Platform-issued tenant-scoped credential; a platform re-pin ticket is not the steady-state path. This is the same governed exact-version target update the platform's own repin corridor executes, not a new primitive.
- authorization
- Bearer JWT with curriculum:write
- requiredHeaders
- Authorization; Content-Type: application/json; Idempotency-Key
- requestBody
- {"operation":"repoint","expected_target_ref":{"module":"content","content_kind":"article","content_id":"{contentId}","content_version_id":"{currentlyPinnedVersionId}"},"target_ref":{"module":"content","content_kind":"article","content_id":"{contentId}","content_version_id":"{amendedVersionId}"}}
- preconditions
- expected_target_ref must equal the exact current pin (409 curriculum:repoint_pin_stale); a repoint keeps content_id and content_kind (409 curriculum:repoint_identity_mismatch); the exact new version must pass Content-owned release eligibility with practice_eligible usage scope (409 curriculum:repoint_target_not_serveable); a published component pinning an approved assessment chain is frozen to the reviewed-replacement manifest path (409 curriculum:approved_chain_repoint_frozen). Every accepted operation appends one immutable audit row.
- readback
- The 200 response returns the updated component plus its immutable audit row; replaying the Idempotency-Key returns the identical response. The changed graph then needs a new immutable approval via POST /alpha/curriculum/v1/courses/{courseId}/approvals before GET /alpha/curriculum/v1/courses/{courseId}/next-lesson serves the exact repointed version.
- turnaround
- The authorized repoint transaction is synchronous; there is no repoint ticket queue.
DELETE /alpha/curriculum/v1/components/{componentId}
Soft-retire an authored component atomically: retire every incident CASE association first, then set retired_at and publication_status='retired'; ordinary component list/detail and tree reads exclude it.
POST /alpha/curriculum/v1/kcs
Create one governed registry Knowledge Component and immutable version. Retry with the original Idempotency-Key or exact canonical kc_id; source_kc_id is provenance only and never resolves an identity.
GET /alpha/curriculum/v1/kcs
Discover the active governed KC corpus: a stable updated_at/kc_id cursor list of registry Knowledge Components with their current immutable versions, filterable by subject_id, kc_kind, publication_status, and updated_since. Adaptive-diagnostics consumers read KCs here, never from CASE; retired rows are never listed and source_kc_id is not a filter.
GET /alpha/curriculum/v1/kcs/{kcId}
Read one governed registry Knowledge Component and its current immutable version by exact canonical kc_id UUID.
POST /alpha/curriculum/v1/kcs/{kcId}/versions
Append an immutable draft semantic version and advance only the KC identity current-version pointer.
GET /alpha/curriculum/v1/kcs/{kcId}/versions
List every immutable semantic version for a governed KC.
GET /alpha/curriculum/v1/kcs/{kcId}/versions/{versionId}
Read one exact immutable KC semantic version.
PATCH /alpha/curriculum/v1/kcs/{kcId}
Publish the mutable KC identity with ETag/If-Match without firming its current semantic version.
POST /alpha/curriculum/v1/kc-review-decisions
Append an immutable governed review decision for an exact KC version.
GET /alpha/curriculum/v1/kc-review-decisions
List immutable KC review decisions, optionally for an exact version.
POST /alpha/curriculum/v1/kc-firming-events
Record validated first-genuine-response evidence and atomically firm that exact draft KC version.
GET /alpha/curriculum/v1/kc-firming-events
List immutable KC firming evidence, optionally for an exact version.
POST /alpha/curriculum/v1/courses/{courseId}/approvals
Atomically approve the current course graph, snapshot every exact KC version, create firming evidence, and firm drafts.
- integratorPolicy
- An app integrator may invoke this endpoint directly; no per-course owner ruling is required when its Platform-issued tenant-scoped credential has curriculum:write.
- authorization
- Bearer JWT with curriculum:write
- requiredHeaders
- Authorization; Content-Type: application/json; Idempotency-Key
- requestBody
- {"approved_by":"integrator:ap-one","provenance":{"source":"ap-one:course-approval","course_ref":"{integratorCourseRef}"}}
- preconditions
- The course root is published; the current graph is complete; every referenced governed KC is active, published, and has an exact current version. Content trust is proved separately before each exact gate target is published.
- readback
- GET /alpha/curriculum/v1/courses/{courseId}/approvals, then GET /alpha/curriculum/v1/courses/{courseId}/next-lesson; require the exact approval and complete firm KC-version snapshot.
- turnaround
- The authorized transaction is synchronous. Missing credentials go through Platform tenant onboarding; this repository defines no credential-provisioning SLA and there is no per-course approval queue.
GET /alpha/curriculum/v1/courses/{courseId}/approvals
List immutable course approvals with complete exact KC-version snapshots.
POST /alpha/curriculum/v1/kc-prerequisites
Create one governed acyclic prerequisite edge using exact active tenant-owned registry UUID endpoints.
GET /alpha/curriculum/v1/kc-prerequisites
Read governed KC prerequisite edges by prerequisite, dependent, or either registry UUID endpoint.
DELETE /alpha/curriculum/v1/kcs/{kcId}
Require the exact canonical kc_id UUID and current ETag, then soft-retire the governed registry identity only when no active prerequisite, relation, standards map, component scope, or remediation reference remains.
POST /alpha/curriculum/v1/associations
Create a stock CASE association for component containment or framework/standard alignment. KC prerequisites use alpha.kc_prerequisite, other typed KC graph semantics use alpha.kc_relation, standards links use alpha.standard_kc_map, and KCs have no containment tree.
GET /alpha/curriculum/v1/associations
List stock CASE associations by type, endpoint, component, or updated_since for correction workflows.
GET /alpha/curriculum/v1/associations/{associationId}
Read one stock CASE association by id, including its sequence_number.
PATCH /alpha/curriculum/v1/associations/{associationId}
Update an association sequence_number with If-Match for sibling reordering.
GET /alpha/curriculum/v1/standards-frameworks
List current frozen standards releases by default; a frameworkId reads one historical release without mutating it.
GET /alpha/curriculum/v1/standard-kc-maps
Read active tenant-owned release-pinned standard-to-KC crosswalks with typed release, standard, KC, relationship, updated_since, limit, and opaque cursor filters. Rows expose only the ten governed fields; legacy TEXT provenance is losslessly wrapped as a JSON object under legacy.
POST /alpha/curriculum/v1/standards-frameworks/import
Mint or reuse an immutable standards source release, write release-scoped CASE framework/standard rows with exact source-row bindings, and persist release-and-row-pinned KC crosswalks in alpha.standard_kc_map. CASE isPartOf remains standard-to-standard only.
GET /alpha/curriculum/v1/components
List component-tree CFItems by typed filters. For tenant-wide personalized course discovery, send kind=course and one exact non-empty studentId; only course roots carrying that exact student_id are returned, while shared roots and other learners are excluded from that filtered result.
GET /alpha/curriculum/v1/renderer-registry
List registered renderer capabilities that Curriculum members may reference by renderer_ref.
GET /alpha/curriculum/v1/components/{componentId}/tree
Walk a component subtree using stock CASE isChildOf containment.
GET /alpha/curriculum/v1/courses/{courseId}/next-lesson
Resolve the first ordered shared or exact learner-owned personalized lesson/review/practice/gate only when it, every containment ancestor, and the course root are published; the exact current graph has an immutable approval with a complete firm, active KC-version snapshot; and its exact Content version still passes Content-owned release eligibility at launch. A personalized root requires its exact studentId before Content eligibility and rechecks that persisted owner after asynchronous Content work; missing and different ids return the same 404 curriculum:not_found as an unknown course. Shared-course routing is unchanged. Draft, retired, changed, unapproved, incomplete, unavailable, malformed, mismatched, or ineligible state fails closed without skipping forward. A known course with no structural frontier returns 409 curriculum:lesson_structure_missing and an unsafe current graph returns 409 curriculum:course_not_routable.
GET /alpha/curriculum/v1/tracks/{trackId}/placement-candidates
List grade-level mastery gates Policy/Results use to run bottom-up placement.
GET /alpha/curriculum/v1/gates/{componentId}
Read the Curriculum-owned gate contract without scores, thresholds, or Content body.
GET /alpha/curriculum/v1/gates/{componentId}/status
Read the typed Results-backed gate status reference for a student.
GET /alpha/curriculum/v1/gates/{componentId}/next-form
Choose the deterministic next unseen practice-eligible Content test form after independently revalidating the exact test_bank version and each exact candidate form version. Invalid gate, ineligible Content, and genuinely exhausted bank are distinct typed outcomes.
GET /alpha/curriculum/v1/gates/{componentId}/remediation
Resolve the universal gate-failure remediation map: never_learned to lesson, forgot to review, careless to practice.
POST /alpha/curriculum/v1/ingest/timeback-course-refs
Import source-shaped TimeBack courses, course_components, and reconciled component_resources membership through deterministic draft identities, exact intended-tree readback, bottom-up descendant publication, and course-root-last publication. The structural producer is TimeBack courses -> course_components -> component_resources -> resources; resources first pass through Content's timeback-production adapter and each target carries exact content_id, content_version_id, and content_kind values that must pass Content-owned release eligibility. Each lesson membership supplies a non-empty authored array of active Knowledge Component UUIDs in scope_kc_refs; Platform3 preserves multi-KC clustering grain. Course refs, source-empty structure, KC-unscoped structure, partial publication, absent approval/firm snapshots, and Content versions that do not pass release eligibility remain non-routable and are not called Jump-In-ready.