{"module":"content","surface":"alpha","status":"ok","canonicalPathPrefix":"/content/alpha/implementation/api","pathFormat":"Root-absolute paths. Call them from the deployment origin exactly as printed, including /content/alpha/implementation/api.","docs":{"architecture":"https://platform3-andymontgomery-9773s-projects.vercel.app/content/alpha/architecture","dataDictionary":"https://platform3-andymontgomery-9773s-projects.vercel.app/content/alpha/data_dictionary","customerWebsite":"https://platform3-andymontgomery-9773s-projects.vercel.app/content/alpha/customer_website","customerWebsiteStatus":"current","implementationDescriptor":"https://platform3-andymontgomery-9773s-projects.vercel.app/content/alpha/implementation/api","curriculumDataDictionary":"https://platform3-andymontgomery-9773s-projects.vercel.app/curriculum/alpha/data_dictionary","curriculumImplementation":"https://platform3-andymontgomery-9773s-projects.vercel.app/curriculum/alpha/implementation/api"},"quickstart":{"mintDemoToken":"POST /content/alpha/implementation/api/dev/mint?tenantId=demo","listContent":"GET /content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items","listTestSpecs":"GET /content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items?content_kind=test_spec","createArticle":"POST /content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items","createArticleBodyVersion":"POST /content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentId}/versions","createTestSpecBlueprint":"POST /content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items","getTestSpecBlueprint":"GET /content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentId}/blueprint","tagToKnowledgeComponent":"POST /content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentId}/kc-tags","importTimeBackProduction":"POST /content/alpha/implementation/api/tenants/{tenantId}/alpha/content/imports/timeback-production","studentView":"GET /content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentId}/student-view","checkReleaseEligibility":"GET /content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentId}/versions/{versionId}/release-eligibility?producer_surface=incept%2Falpha","checkTestServeEligibility":"GET /content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentId}/versions/{versionId}/test-serve-eligibility?producer_surface=incept%2Falpha&test_identity_id=person_reality_test_student","narrowCatalogByExpectedXpBand":"GET /content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items?expected_xp_band=10_to_20","exportCommonCartridge":"POST /content/alpha/implementation/api/tenants/{tenantId}/alpha/content/exports/common-cartridge"},"quickstartGuidance":{"articleBodyAuthoring":{"canonicalEndpoint":"POST /content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentId}/versions","requestShape":"Send student_view.blocks on the content_version. Use block objects such as {type:'heading'|'text'|'image'|'probe', text, url, alt, order}.","itemEndpointBoundary":"POST/PATCH /items are metadata commands. Top-level blocks/body/composition fields are rejected instead of ignored.","readback":"GET /content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentId}/student-view"},"testSpecBlueprint":{"listEndpoint":"GET /content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items?content_kind=test_spec","createEndpoint":"POST /content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items","readEndpoint":"GET /content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentId}/blueprint","requiredHeader":"Idempotency-Key","requiredContentKind":"test_spec","derivedAssessmentRole":"spec","nativeContentIdField":"content_id","blueprintIdField":"spec_id","requiredBlueprintFields":["kc_coverage","item_type_mix","difficulty_constraints","passing_rule","min_forms","max_item_overlap","enemy_item_rule"],"countContract":"item_type_mix and each nested kc_coverage DOK entry contain positive integer counts; both totals must match exactly.","atomicity":"The Content item, assessment_role=spec compatibility row, complete test_spec sidecar, initial version, and completed idempotency replay response commit in one transaction.","replay":"An identical completed replay returns 200 with Idempotency-Replayed=true and the same content_id. Reusing the key with a changed request returns 409 content.idempotency_conflict.","ownership":"AlphaTest stores no shadow blueprint row; Content owns the native spec_id and all seven blueprint fields."},"exportCommonCartridge":{"endpoint":"POST /content/alpha/implementation/api/tenants/{tenantId}/alpha/content/exports/common-cartridge","firstDayDemoCourseComponentId":"cur_comp_math_7_linear_equations","firstDayDemoCurriculumNodeId":"case:math:7.ee.b.4","howToFindRealCourseComponentId":"Use the Curriculum Alpha course_component root for the course subtree you want to package. The descriptor links docs.curriculumDataDictionary and docs.curriculumImplementation so a cold Content reader can discover that id without guessing.","legacyContentLinks":"content_curriculum_link is a frozen read-only archive. New Content alignment writes use weighted registry-KC tags; legacy archive rows remain available only for historical package reconciliation.","scopeValidation":"The export validates course_component_id before packaging. Unknown components, or a curriculum_node_id that is not in that component's scope, return 404 content.curriculum_node_not_found; the API never falls back to exporting all Content.","requiredRequestFields":["course_component_id","format"],"optionalRequestFields":["curriculum_node_id","max_content_refs","include_retired_versions","round_trip_check"]},"newCourseIngest":{"contentImportEndpoint":"POST /content/alpha/implementation/api/tenants/{tenantId}/alpha/content/imports/qti-package","curriculumReadEndpoint":"/curriculum/alpha/implementation/api/alpha/curriculum/v1/components/{lessonId}","curriculumLinkEndpoint":"/curriculum/alpha/implementation/api/alpha/curriculum/v1/components/{lessonId}","curriculumLinkMethod":"PATCH","curriculumLinkHeaders":["X-Curriculum-If-Match","Idempotency-Key"],"curriculumLinkField":"alpha.target_ref","singleTargetRule":"PATCH the lesson target only for its one primary object. This is replacement, not append; repeating it for a question set overwrites the prior target.","multiItemWriteEndpoint":"/curriculum/alpha/implementation/api/alpha/curriculum/v1/components","multiItemWriteMethod":"POST","multiItemRule":"While the deployed Curriculum surface is CASE-backed, create one stable ordered child practice/review component per additional item with parent_component_id={lessonId}, the lesson KC in alpha.scope_kc_refs, and that item's alpha.target_ref plus alpha.renderer_ref. The accepted target model migrates these one-for-one to course_component_member rows; no member route is advertised as live yet.","multiItemDiscoveryEndpoints":["/curriculum/alpha/implementation/api/alpha/curriculum/v1/components/{lessonId}/tree","/curriculum/alpha/implementation/api/alpha/curriculum/v1/components?parentId={lessonId}"],"discoveryOwner":"Curriculum","discoveryRule":"After QTI import, use the returned source_identifier-to-content_id mapping to create one Curriculum-owned Content use per item. Curriculum remains the routing and ordering owner. GET /items?curriculum_node_id={lessonId} is a read-only compatibility projection over both historical archive links and active Content targets on that Curriculum component and its active descendants; it never writes or copies placement rows into Content.","kcAttributionRule":"POST /items/{contentId}/kc-tags is optional lesson-independent KC attribution. It accepts only an active governed registry kc_id and never creates or discovers lesson membership. For references_linkage and other new courses, create that identity through Curriculum POST /alpha/curriculum/v1/kcs with stored_as=alpha.knowledge_component, definition, and no document_id, then require the response to repeat stored_as=alpha.knowledge_component; CASE KC ids are not accepted.","standardsRule":"Curriculum standards-framework import supplies standards_framework_refs for course authoring; it does not mint Knowledge Components because standards and KCs are separate governed stores.","archiveRetentionRule":"Existing content_curriculum_link rows have no automatic TTL. Archive GETs remain available until a separately approved migration issue proves every dependent consumer has cut over."},"itemProvenance":{"itemFields":["source_identifier","source_system","source_table","source_record_id","source_activity_ref"],"facetEndpoint":"POST /content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentId}/catalog-facets","facetShape":{"facet_key":"provenance","facet_value":"imported","provenance":{"source_test_id":"external-id"}},"rule":"Generic item metadata is rejected with content.validation_failed. Store typed source identity on the item and additional safe provenance evidence on the governed provenance facet assignment; alpha_subject_id remains only an alias for canonical subject_id.","repair":"For an existing item, PATCH the typed source identity fields with If-Match, then POST one provenance facet assignment with an Idempotency-Key. GET the item and /catalog-facets to verify both records."}},"endpoints":[{"id":"endpoint-mint-demo-token","method":"POST","path":"/content/alpha/implementation/api/dev/mint?tenantId=demo","summary":"Mint a public demo JWT scoped to tenantId=demo.","auth":"none","response":"demo_token"},{"id":"endpoint-list-content-items","method":"GET","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items","summary":"List student-touchable Content items with typed filters, catalog facet filters, and cursor paging.","auth":"role:service|demo|operator","filters":["content_kind","subtype","dok","assessment_role","subject_id","alpha_subject_id","target_grade_id","curriculum_node_id","usage_scope","test_type","is_mastery_gate","source_system","source_record_id","source_activity_ref","facet","modifiedSince","subject","grade_band","language","accessibility_profile","rights_license","provenance","quality_rating","kc_refs","standards_framework_refs","expected_xp_band","modality"],"response":"page<content_item>"},{"id":"endpoint-create-content-item","method":"POST","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items","summary":"Create a non-QTI Content item; content_kind=test_spec atomically creates the complete seven-field blueprint sidecar and returns its native content_id.","auth":"author:content","requiredHeaders":["Authorization","Content-Type","Idempotency-Key"],"request":"content_item.create","testSpecRequestFields":["kc_coverage","item_type_mix","difficulty_constraints","passing_rule","min_forms","max_item_overlap","enemy_item_rule"],"testSpecReadback":"/tenants/{tenantId}/alpha/content/items/{contentId}/blueprint","response":"content_item"},{"id":"endpoint-import-timeback-production","method":"POST","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/imports/timeback-production","summary":"Accept source-shaped TimeBack production content rows and normalize them server-side into flat Content assets.","auth":"author:content","request":"timeback_production_import.create","response":"timeback_production_import"},{"id":"endpoint-get-content-item","method":"GET","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentId}","summary":"Read one Content item and its ETag.","auth":"role:service|demo|operator","response":"content_item"},{"id":"endpoint-get-test-spec-blueprint","method":"GET","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentId}/blueprint","summary":"Read the first-class test_spec blueprint sidecar.","auth":"read:content","response":"test_spec"},{"id":"endpoint-list-test-bank-members","method":"GET","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentId}/bank-members","summary":"List test-bank forms with exact-form-version question-level canonical KC attribution and explicit readiness counts.","description":"Validates every active bank_member row before selecting members pinned to the bank's latest exact version; malformed current or historical rows fail with a typed 409 instead of disappearing from the projection.","auth":"read:content","response":"test_bank_members"},{"id":"endpoint-update-content-item","method":"PATCH","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentId}","summary":"Update editable Content metadata using If-Match.","auth":"author:content","request":"content_item.patch","response":"content_item"},{"id":"endpoint-list-content-versions","method":"GET","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentId}/versions","summary":"List append-only exact versions for one Content item, including immutable TimeBack source revisions and deployed legacy v1 history.","auth":"read:content","response":"page<content_version>"},{"id":"endpoint-create-content-version","method":"POST","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentId}/versions","summary":"Create an append-only student-view or authoring version; article bodies use student_view.blocks, while question canonical_xml atomically regenerates that version's QTI choices, answer slots, answer keys, and scoring projection.","auth":"author:content","request":"content_version.create","response":"content_version"},{"id":"endpoint-get-content-version","method":"GET","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentId}/versions/{versionId}","summary":"Read one immutable Content exact version, including historical TimeBack source revisions.","auth":"read:content","response":"content_version"},{"id":"endpoint-get-release-eligibility","method":"GET","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentId}/versions/{versionId}/release-eligibility","summary":"Read Content's current fail-closed exact-version release answer for one governed producer surface.","description":"For test_bank content, validates the complete active fixed-form membership graph before returning the trust-derived release answer.","auth":"read:content","filters":["producer_surface"],"response":"content_release_eligibility or typed Content Problem"},{"id":"endpoint-get-test-serve-eligibility","method":"GET","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentId}/versions/{versionId}/test-serve-eligibility","summary":"Check the separately governed demo/test-cohort authority for one exact draft or untrusted bank/form version without changing ordinary release eligibility.","auth":"read:content","filters":["producer_surface","test_identity_id"],"response":"content_test_serve_eligibility or typed Content Problem"},{"id":"endpoint-authorize-test-serve","method":"POST","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/test-serve-authorizations","summary":"Atomically revalidate one exact draft bank-to-form selection and append its immutable test-serve audit receipt.","auth":"read:content","request":"content_test_serve_authorization.create","response":"content_test_serve_authorization"},{"id":"endpoint-get-student-view","method":"GET","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentId}/student-view","summary":"Read the blank student-safe projection for the latest version or an immutable exact version_id; answer keys require includeAnswerKeys=true plus read:answer_key.","auth":"read:content","response":"student_view","filters":["version_id","includeAnswerKeys"]},{"id":"endpoint-list-answer-slots","method":"GET","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentId}/answer-slots","summary":"List blank answer slots for the latest effective grading version or an exact version_id, optionally with scoped answer keys.","auth":"read:content","filters":["includeAnswerKeys","version_id"],"response":"page<answer_slot>"},{"id":"endpoint-list-answer-keys","method":"GET","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentId}/answer-keys","summary":"List teacher-only answer keys for the latest effective grading version or an exact version_id. Requires read:answer_key and delegates to the QTI answer-key view; string text-entry keys stay in correct_response.values.","auth":"read:answer_key","filters":["version_id"],"response":"page<answer_key>"},{"id":"endpoint-list-assessment-components","method":"GET","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentId}/assessment-components","summary":"List first-class QTI structure for the latest effective grading version or an exact version_id, including choice/text-entry/extended-text part rows, question refs, distractors, rubrics, and preauthored feedback.","auth":"read:content","filters":["component_role","version_id"],"response":"page<assessment_component>"},{"id":"endpoint-get-interactive-composition","method":"GET","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentId}/interactive-composition","summary":"Read Content-owned typed interactive article/video composition without parsing tb-* HTML.","auth":"read:content","response":"interactive_composition"},{"id":"endpoint-set-interactive-composition","method":"PUT","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentId}/interactive-composition","summary":"Replace ordered article segment/question bindings or video cue/question bindings for one Content object.","auth":"author:content","request":"interactive_composition.replace","response":"interactive_composition"},{"id":"endpoint-get-scoring-plan","method":"GET","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentId}/scoring-plan","summary":"Read QTI scoring-plan provenance for the latest effective grading version or an exact version_id.","auth":"read:content","filters":["version_id"],"response":"page<scoring_plan>"},{"id":"endpoint-list-media","method":"GET","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentId}/media","summary":"List first-party media assets attached to one Content item.","auth":"read:content","response":"page<media_asset>"},{"id":"endpoint-attach-media","method":"POST","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentId}/media","summary":"Attach a media asset and return an authenticated first-party delivery_url.","auth":"author:content","request":"media_asset.create","response":"media_asset"},{"id":"endpoint-deliver-media","method":"GET","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentLocator}/media/{mediaLocator}","summary":"Fetch bytes for a media_asset.delivery_url value.","auth":"read:content","response":"media bytes"},{"id":"endpoint-list-content-references","method":"GET","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentId}/references","summary":"List uniform references from one Content asset to other Content assets; Content references never nest payloads.","auth":"read:content","response":"page<content_reference>"},{"id":"endpoint-create-content-reference","method":"POST","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentId}/references","summary":"Create a typed reference from one Content asset to another Content asset.","description":"bank_member requires explicit exact parent and referenced version ids owned by their corresponding artifacts, a fixed-form assessment_role=bank parent, an assessment_role=form test target, an exact ordered embeds graph, and active canonical KC attribution for every embedded question. Omitted or explicit-null version ids fail closed and never resolve mutable latest pointers.","auth":"author:content","request":"content_reference.create","response":"content_reference","bankMemberMutationRule":"bank_member is mutable only while the parent test_bank is an unretired draft with unknown trust; completed retries replay first, while a fresh create takes the exclusive graph fence, repeats replay arbitration, validates, then claims, returning 409 without a ledger or graph mutation on rejection"},{"id":"endpoint-retire-content-reference","method":"DELETE","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentId}/references/{referenceId}","summary":"Soft-retire a Content-to-Content reference without deleting the retained audit row.","auth":"author:content","response":"content_reference","bankMemberMutationRule":"bank_member is mutable only while the parent test_bank is an unretired draft with unknown trust; completed same-key retries replay after freeze"},{"id":"endpoint-get-external-link","method":"GET","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentId}/external-link","summary":"Read governed outside URL facts for content_kind=external_link.","auth":"read:content","response":"external_link"},{"id":"endpoint-set-external-link","method":"POST","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentId}/external-link","summary":"Set governed outside URL facts without storing secrets.","auth":"author:content","request":"external_link.set","response":"external_link"},{"id":"endpoint-list-curriculum-links","method":"GET","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentId}/curriculum-links","summary":"Read the frozen legacy Content-to-Curriculum link archive.","auth":"read:content","response":"page<content_curriculum_link>"},{"id":"endpoint-list-kc-tags","method":"GET","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentId}/kc-tags","summary":"List canonical weighted links from one Content item to governed registry KCs.","auth":"read:content","response":"page<content_kc_tag>"},{"id":"endpoint-upsert-kc-tag","method":"POST","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentId}/kc-tags","summary":"Create or replace a weighted Content-to-registry-KC relationship.","auth":"link:kc","request":"content_kc_tag.upsert","response":"content_kc_tag"},{"id":"endpoint-export-common-cartridge","method":"POST","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/exports/common-cartridge","aliases":["/content/alpha/implementation/api/tenants/{tenantId}/alpha/exports/common-cartridge"],"summary":"Generate a transport-only Common Cartridge or IMSCP package from Curriculum plus Content references.","auth":"read:content","request":"common_cartridge_export.create","response":"common_cartridge_export","allowedValues":{"format":["common_cartridge_1_3","common_cartridge_v1p3","imscp_v1p1"]}},{"id":"endpoint-download-common-cartridge","method":"GET","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/exports/common-cartridge/{exportId}/download","aliases":["/content/alpha/implementation/api/tenants/{tenantId}/alpha/exports/common-cartridge/{exportId}/download"],"summary":"Download generated Common Cartridge transport bytes.","auth":"read:content","response":"imscc bytes"},{"id":"endpoint-list-catalog-facets","method":"GET","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/catalog-facets","summary":"List the twelve named governed catalog discovery facets.","auth":"read:content","response":"page<content_catalog_facet>"},{"id":"endpoint-create-catalog-facet","method":"POST","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/catalog-facets","summary":"Create one of the twelve named governed catalog discovery facets in an unseeded tenant.","auth":"author:content","request":"content_catalog_facet.create","response":"content_catalog_facet"},{"id":"endpoint-list-catalog-facet-assignments","method":"GET","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentId}/catalog-facets","summary":"List sidecar catalog facet assignments for a Content item.","auth":"read:content","response":"page<content_catalog_facet_assignment>"},{"id":"endpoint-create-catalog-facet-assignment","method":"POST","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentId}/catalog-facets","summary":"Assign a governed sidecar catalog facet value.","auth":"author:content","request":"content_catalog_facet_assignment.create","response":"content_catalog_facet_assignment"},{"id":"endpoint-get-effectiveness","method":"GET","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentId}/effectiveness","summary":"Read derived content-effectiveness rollup; apps do not increment it.","auth":"read:content","response":"content_effectiveness"},{"id":"endpoint-get-trust","method":"GET","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentId}/trust","summary":"Read safe trust and validation evidence.","auth":"read:content","response":"content_trust_evidence"},{"id":"endpoint-publish-content","method":"POST","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/items/{contentId}/publish","summary":"Publish one exact immutable test_spec or test_bank after server-owned structural and dependency checks; callers cannot set trust.","auth":"publish:content plus service, reviewer, or operator role","request":"content_publication.create","response":"content_publication"},{"id":"endpoint-import-qti-package","method":"POST","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/imports/qti-package","summary":"Import QTI package bytes through the approved QTI-backed path, materializing assessment items as questions, assessment tests as test forms, scoped answer keys/components, and referenced assessmentStimulus question anatomy.","auth":"author:content","request":"application/zip","optionalHeaders":["X-QTI-Source-Name","X-Content-Subject-Id","X-Content-Target-Grade-Id","X-Content-Expected-Xp"],"response":"qti_import","nativeIdentityFields":["packageId","artifactId","artifactVersionId","qtiIdentifier","artifactKind","contentId","contentVersionId"],"identityRule":"Each artifacts[] row preserves the QTI-backed Content alias: contentId=artifactId and contentVersionId=artifactVersionId."},{"id":"endpoint-get-trust-status","method":"GET","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/trust-status","summary":"List trust evidence rows by trust_status.","auth":"read:content","response":"page<content_trust_evidence>"},{"id":"endpoint-list-policies","method":"GET","path":"/content/alpha/implementation/api/tenants/{tenantId}/alpha/content/policies","summary":"List provisioned tenant policy rows. This read projection is not the runtime authority for the bundled source-adapter policy.","auth":"read:content","response":"page<content_policy>"}],"behaviorContracts":["Content holds blank instruments, media, answer slots, scoring plan provenance, curriculum links, effectiveness reads, and trust evidence.","Student answers, attempts, scores, mastery, report cards, and gradebook rollups are outside this module.","Typed fields are set on write/import and are never derived by parsing titles, URLs, or raw XML at read time.","Generic content_item metadata is not a writable provenance bag and receives a typed validation error. Item source identity uses source_identifier, source_system, source_record_id, and source_activity_ref; additional safe evidence uses a governed provenance catalog-facet assignment.","Every Content exact version is append-only. TimeBack imports canonicalize source-table identity, reuse only a complete matching deployed legacy v1 projection or content-hash UUIDv5 exact version, and append changed canonical source bytes with a supersedes_version_id edge; historical replay never mutates stored bytes.","student-view serves the item's newest version (highest version_number) by default and serves one immutable exact version when version_id is supplied; test/form renderers use the exact-version read so a later authoring successor cannot change a pinned launch. latest_version_id advances only: a source re-import re-asserts its own version but never moves latest_version_id back off a newer integrator-authored version, so re-syncs cannot eclipse authored bodies.","Canonical Content-to-KC alignment is the weighted content_kc_tag relationship to the governed KC registry; content_curriculum_link is a frozen read-only archive.","Lesson-to-Content routing and ordering are Curriculum-owned with one ordered use per Content item. One primary lesson object may use the lesson target once; a many-item lesson currently uses one targeted child practice/review component per item. Repeatedly patching the lesson target is destructive replacement. /kc-tags never stores lesson membership. For thin-client compatibility, curriculum_node_id list filtering projects historical archive links plus active Content targets in the requested Curriculum component subtree without creating Content-owned placement rows.","A bank_member may be created or soft-retired only while its parent test_bank is an unretired draft with unknown trust; missing trust normalizes to unknown. Every other current lifecycle/trust state returns content.bank_membership_frozen. A create requires an assessment_role=bank test_bank with membership_rule=same_blueprint_fixed_forms or pp100_adaptive_shards, an assessment_role=form test shard, and explicit exact parent_version_id and referenced_version_id UUIDs owned by their corresponding artifacts; omitted or explicit-null version IDs fail closed and never resolve mutable latest pointers. qti_adaptive_selection rejects parallel bank_member rows. An already-visible completed same-key request replays immediately. A fresh create acquires the exclusive tenant graph fence, repeats replay arbitration under that fence so a just-completed request still wins, then locks lifecycle/trust, parent artifacts before reference rows, form and bank metadata, the exact form version, all active exact-version references, referenced artifacts, and all KC rows before semantic validation and its idempotency claim; the claim, insert, timestamp update, completion, and fence remain one transaction. Repository-direct writes use the same guard and lock order. Integrity reads use a shared lock on the same graph key and one transaction snapshot, so readers overlap while writers wait; they validate every active row including historical-version rows and only then select the requested exact bank version. Invalid kind, role, rule, missing or wrong-owner version, index, native-QTI parallel-row, or other active-row semantics fail with content.invalid_test_bank_member_contract. A semantically valid member with a missing, empty, or ambiguous exact question graph, or without an active canonical content_kc_tag on every question occurrence, fails with content.bank_kc_attribution_incomplete. References-linkage authors obtain governed tags through Curriculum with stored_as=alpha.knowledge_component. GET /items/{contentId}/bank-members preserves exact graph order and multiplicity and never substitutes latest, unions versions, combines facts from different committed snapshots, coerces a question into a form, or infers KC attribution.","Effectiveness counters are read-only derived rollups.","test_spec, test_bank, and script are first-class content_kind values; assessment_role remains the compatibility discriminator over the shared QTI assessmentTest storage for test/test_spec/test_bank.","POST /items with content_kind=test_spec is the canonical test-spec authoring seam: it requires all seven blueprint fields, returns the native content_id, and commits the Content identity, complete sidecar, initial version, and idempotency response atomically. GET /items/{contentId}/blueprint returns that same id as spec_id.","usage_scope is the Content-owned exposure contract for routing: routine practice, next-task, and next-form selection only choose practice_eligible Content items and bank_member rows; held_out_canary and secure_form remain readable but are not routine-routing candidates.","Grade-level positions are closed to PreK=-1, K=0, and 1..12; Content exposes catalog filters as target_grade_id/alpha_grade_id values pre_k, k, 1..12 plus postsecondary/ungraded catalog-only values.","Content HTML student_view bodies may use the governed tb-* markup contract. QTI XML and scoring semantics remain QTI-owned, and durable learner progress flows back through Caliper Events/Results rather than renderer or host private storage.","Interactive article/video composition is Content-owned typed structure: ordered article segment-to-question refs and video cue timestamp-to-question refs live in Content, reference QTI-backed Content questions and assessment_component ids, and never extend QTI or Curriculum with delivery composition.","Exact-version release eligibility IS trust: release_eligible === serveable === a published, non-retired, trusted-or-degraded Content item. Trust is set once at import/QC time (QTI/QC'd content lands trusted) and revoked by flipping trust_status to failed, which fails closed on the next read. There is no second producer-release-evidence attestation, required-quality-bar match, or owner-acceptance allowlist. Any non-serveable state returns content.version_not_serveable. Curriculum stores no copied serveability or eligibility fields.","Governed test-serve is a separate demo/test-cohort authorization, never an alternate release verdict. Content requires one active server-side grant plus an active People & Orgs person whose authoritative reality is test or synthetic, accepts only exact practice-eligible bank/form versions that are not retired, archived, failed-trust, blocked, or revoked, and appends one immutable bank/form authorization receipt before Curriculum returns a draft form. A caller flag, identity prefix, lifecycle change, or grant to a reality=real person cannot authorize this lane.","QTI import idempotency is exact-request and transaction-backed: QTI writes and the completed replay response finalize atomically; completed requests replay as 200 with Idempotency-Replayed=true; active same-key retries return 202 with Retry-After; expired unfinished claims return terminal 503 without rerunning; different requests under the key return 409. Recovery never scans Content by source name, title, or time window."],"interactiveCompositionContract":{"owner":"content","qtiRole":"question items, answer slots, answer keys, and assessment_component ids only","curriculumRole":"sequence, reference, and gate Content objects through Curriculum-owned Content targets and registry KC scope; Content owns weighted content_kc_tag attribution, and content_curriculum_link is archive-only","types":["interactive_article","interactive_video"],"validation":["interactive_video cues are strictly increasing","interactive_video cue at_seconds values are > 0 and < duration_seconds","interactive_article segments are ordered positive integers","each question_ref resolves to content_kind=question","question_ref.assessment_component_id, when supplied, resolves through the referenced question's assessment_component rows","each embedded question attests tests_prior_content=true"]},"rendererContract":{"renderer_ref":"renderer:interactive-lesson","iframe_url":"https://platform3-andymontgomery-9773s-projects.vercel.app/player","versioned_iframe_url":"https://platform3-andymontgomery-9773s-projects.vercel.app/player/versions/2026-07-27.issue-1922-test-bank-runtime/","player_version":"2026-07-27.issue-1922-test-bank-runtime","capability_matrix_url":"https://platform3-andymontgomery-9773s-projects.vercel.app/player/renderer-capabilities.json","registered_for_routing":true,"verified_rendering":true,"rendering_state":"verified_partial","rendering_note":"Matrix-verified by the issue-1593 good/broken composition fixture pairs (html bodies plus typed interactive_article/interactive_video compositions with inline-QTI checkpoints); issue #1678 behaviorally verifies the strict public Content choice-object fallback after canonical QTI and assessment-component distractors. The evidence-backed capability matrix remains the authority for exact scope.","playground_url":"https://platform3-andymontgomery-9773s-projects.vercel.app/player?demo=1","implementation_ref":"platform3:first-party-reference-player:/site/player","host_messages":["CONTENT_LOAD","TTS_GENERATE_RESPONSE"],"renderer_messages":["CONTENT_READY","CONTENT_STATE_CHANGE","CONTENT_RESIZE","CONTENT_ERROR","TTS_GENERATE_REQUEST"],"content_load_fields":["html","qtiXml","testForm","title","contentId","contentRef","gateComponentId","studentId","interactiveComposition","contentState","config"],"preview_affordances":["ad_hoc_html","ad_hoc_qti_xml_a1_text_structural","exact_test_form_fixture"]},"gradeLevelContract":{"numericPositions":[-1,0,1,2,3,4,5,6,7,8,9,10,11,12],"catalogGradeIdField":"target_grade_id","catalogGradeIds":["pre_k","k","1","2","3","4","5","6","7","8","9","10","11","12","postsecondary","ungraded"],"numericPositionByCatalogGradeId":{"1":1,"2":2,"3":3,"4":4,"5":5,"6":6,"7":7,"8":8,"9":9,"10":10,"11":11,"12":12,"pre_k":-1,"k":0},"catalogOnlyGradeIds":["postsecondary","ungraded"]},"allowedFilters":["content_kind","subtype","dok","assessment_role","subject_id","alpha_subject_id","target_grade_id","curriculum_node_id","usage_scope","test_type","is_mastery_gate","source_system","source_record_id","source_activity_ref","facet","modifiedSince","cursor","limit","subject","grade_band","language","accessibility_profile","rights_license","provenance","quality_rating","kc_refs","standards_framework_refs","expected_xp_band","modality"],"allowedValues":{"content_kind":["question","test","test_spec","test_bank","article","video","audio","image","interactive","media_asset","external_link","script"],"content_subtype":["diagram","decodable"],"dok":["dok1","dok2","dok3","dok4"],"assessment_role":["form","spec","bank"],"usage_scope":["practice_eligible","held_out_canary","secure_form"],"assessment_component_role":["test","section","part","question","question_ref","distractor","rubric","preauthored_feedback"],"interactive_composition_type":["interactive_article","interactive_video"],"test_bank_membership_rule":["same_blueprint_fixed_forms","qti_adaptive_selection","pp100_adaptive_shards"],"subject_id":["math","reading","language","science","computer_science","vocabulary","writing","social_studies"],"alpha_subject_id":["math","reading","language","science","computer_science","vocabulary","writing","social_studies"],"alpha_grade_id":["pre_k","k","1","2","3","4","5","6","7","8","9","10","11","12","postsecondary","ungraded"],"target_grade_id":["pre_k","k","1","2","3","4","5","6","7","8","9","10","11","12","postsecondary","ungraded"],"grade_level":[-1,0,1,2,3,4,5,6,7,8,9,10,11,12],"alpha_grade_id_to_numeric_position":{"1":1,"2":2,"3":3,"4":4,"5":5,"6":6,"7":7,"8":8,"9":9,"10":10,"11":11,"12":12,"pre_k":-1,"k":0},"expected_xp_band":["0_to_10","10_to_20","20_to_45","45_plus"],"expected_xp_band_legacy_alias":{"quick":"0_to_10","standard":"10_to_20","extended":"20_to_45","intensive":"45_plus"},"test_type":["end_of_course","end_of_grade","test_out","placement","diagnostic","screener"],"media_kind":["primary","supporting","thumbnail","caption","transcript","worksheet","source_file"],"content_reference_relationship_kind":["embeds","depends_on","transcript_for","caption_for","thumbnail_for","source_file_for","source_script_for","alternative_form_of","bank_member","related_material"],"common_cartridge_format":["common_cartridge_1_3","common_cartridge_v1p3","imscp_v1p1"],"common_cartridge_format_alias":{"common_cartridge_v1p3":"common_cartridge_1_3"},"tb_markup_token":["tb-instructional-content","tb-article-container","tb-segment","tb-interaction","tb-qti-assessment-item","tb-applet","tb-catalog","tb-qti-config","tb-applet-config","data-catalog-idref","practice-step","example-practice-container","headers-row","header","step-row","step","example-step","answer-box","tb-glossary-term","tb-glossary-definition","tb-narration","tb-narration-audio"],"common_cartridge_max_content_refs":{"default":25,"max":100},"curriculum_link_kind":["teaches","practices","assesses","supports","extends"],"source_system":["qti","alpha_content","external_content_import"],"content_status":["draft","published","retired","archived"],"effectiveness_status":["fresh","stale","pending","insufficient_data"],"trust_status":["trusted","degraded","failed","unknown"],"qti_cardinality":["single","multiple","ordered","record"],"qti_base_type":["boolean","directedPair","duration","file","float","identifier","integer","pair","point","string","uri"],"scoring_rule_scope":["response","outcome","template","expression"],"catalog_facet_key":["subject","grade_band","language","accessibility_profile","rights_license","provenance","quality_rating","kc_refs","standards_framework_refs","content_kind","expected_xp_band","modality"],"external_open_policy":["same_tab","new_tab","embedded_iframe_allowed","external_app_handoff"],"catalog_facet_value_type":["enum","boolean","number","text","reference"],"catalog_facet_grain":["content_item","content_version","media_asset"],"catalog_facet_status":["active","retired"]},"fieldAliases":{"alpha_subject_id":"subject_id"},"requestExamples":{"createTestSpecBlueprint":{"content_kind":"test_spec","title":"Grade 7 equations mastery blueprint","language":"en-US","subject_id":"math","target_grade_id":"7","expected_xp":0,"kc_coverage":{"case:math:7.ee.b.4":{"dok1":2,"dok2":4}},"item_type_mix":{"multiple_choice":4,"numeric_entry":2},"difficulty_constraints":{"target_mastery_probability":0.9},"passing_rule":{"policy_ref":"alpha.policy.mastery_cutoff","false_pass_cost":"higher"},"min_forms":5,"max_item_overlap":0.2,"enemy_item_rule":{"no_two_items_on_same_kc_in_one_form":true},"status":"draft"},"importTimeBackProduction":{"records":[{"activity_id":"pf_1733_0001","activity_name":"Linear equations intro","subject":"Math","app":"Math Academy"}]},"exportCommonCartridge":{"course_component_id":"cur_comp_math_7_linear_equations","curriculum_node_id":"case:math:7.ee.b.4","format":"common_cartridge_1_3","max_content_refs":25,"round_trip_check":true}}}