Skip to main content
DocsAPI ReferenceCurriculum API
Back to docs

Curriculum API

Frameworks, stages, subjects, units, topics, objectives

api
curriculum

Curriculum API Reference

Base path: /api/curriculum

The Curriculum API provides access to curriculum framework hierarchies (synced from the Central Curriculum API) and manages the attachment of curriculum metadata to H5P content items.


Endpoints

GET /api/curriculum/status

Check connectivity to the Central Curriculum (CC) API.

Auth: Authenticated user (JWT, authMiddleware)

The user's Bearer token is forwarded to the CC API for authentication.

Response (200):

{
  "success": true,
  "data": {
    "connected": true
  }
}
{
  "success": true,
  "data": {
    "connected": false,
    "error": "API request failed (401): Unauthorized"
  }
}

Errors:

StatusErrorCause
500Failed to check connection statusInternal error

Sync Endpoints (Admin Only)

These endpoints fetch data from the Central Curriculum API and upsert it into the local PostgreSQL database. They require admin role (requireAdmin middleware).

POST /api/curriculum/sync/frameworks

Sync all frameworks from the Central Curriculum API. Performs upsert: existing frameworks are updated, new ones are inserted.

Auth: Admin (JWT, authMiddleware + requireAdmin)

Headers: Authorization: Bearer <keycloak-token> (required; forwarded to CC API)

Response (200):

{
  "success": true,
  "data": {
    "synced": 5,
    "errors": []
  },
  "message": "Synced 5 frameworks"
}

Errors:

StatusErrorCause
401Bearer token requiredMissing Authorization header
403Admin access requiredUser role is not admin
500Failed to sync frameworksCC API unreachable or internal error

POST /api/curriculum/sync/frameworks/:code

Sync a single framework with its complete hierarchy: stages, grades, subjects, units, topics, and learning objectives. Creates a sync log entry for auditing.

Auth: Admin (JWT, authMiddleware + requireAdmin)

Headers: Authorization: Bearer <keycloak-token> (required; forwarded to CC API)

URL Parameters:

ParamTypeDescription
codestringFramework code (e.g., TR-MEB-2024)

Response (200):

{
  "success": true,
  "data": {
    "stages": 3,
    "grades": 12,
    "subjects": 8,
    "units": 45,
    "topics": 180,
    "objectives": 720,
    "errors": []
  },
  "message": "Synced framework TR-MEB-2024"
}

The sync log entry status is set to completed if there are no errors, or completed_with_errors if some items failed to upsert.

Errors:

StatusErrorCause
401Bearer token requiredMissing Authorization header
403Admin access requiredUser role is not admin
500Failed to sync frameworkCC API unreachable or internal error

GET /api/curriculum/sync/history

Get recent sync log entries.

Auth: None (public endpoint)

Query Parameters:

ParamTypeDefaultDescription
limitinteger10Number of entries to return

Response (200):

{
  "success": true,
  "data": [
    {
      "id": 1,
      "framework_code": "TR-MEB-2024",
      "sync_type": "full",
      "status": "completed",
      "items_synced": 968,
      "error_message": null,
      "started_at": "2025-01-15T10:00:00.000Z",
      "completed_at": "2025-01-15T10:02:30.000Z"
    }
  ]
}

Sync log status values:

StatusMeaning
in_progressSync currently running
completedAll items synced successfully
completed_with_errorsSync finished but some items failed

Errors:

StatusErrorCause
500Failed to get sync historyInternal error

Framework Hierarchy Endpoints (Public)

These endpoints read from the local database (populated by sync). No authentication is required.

GET /api/curriculum/frameworks

List all active curriculum frameworks.

Auth: None

Response (200):

{
  "success": true,
  "data": [
    {
      "code": "TR-MEB-2024",
      "name": "MEB 2024 Curriculum",
      "description": "Turkish Ministry of Education curriculum",
      "framework_type": "national",
      "country_code": "TR",
      "organization": "MEB",
      "version": "2024",
      "language": "tr",
      "valid_from": "2024-01-01",
      "valid_until": null,
      "is_active": true,
      "is_published": true
    }
  ]
}

Only frameworks with is_active = true are returned. Results are ordered by name.

Framework types: national, international, regional, enrichment

Errors:

StatusErrorCause
500Failed to get frameworksInternal error

GET /api/curriculum/frameworks/:code/stages

List stages (education levels) for a framework.

Auth: None

URL Parameters:

ParamTypeDescription
codestringFramework code

Response (200):

{
  "success": true,
  "data": [
    {
      "framework_code": "TR-MEB-2024",
      "code": "primary",
      "name": "Primary Education",
      "description": "Grades 1-4",
      "age_start": 6,
      "age_end": 10,
      "sequence": 0
    },
    {
      "framework_code": "TR-MEB-2024",
      "code": "middle",
      "name": "Middle School",
      "description": "Grades 5-8",
      "age_start": 10,
      "age_end": 14,
      "sequence": 1
    }
  ]
}

Results are ordered by sequence.

Errors:

StatusErrorCause
500Failed to get stagesInternal error

GET /api/curriculum/frameworks/:frameworkCode/stages/:stageCode/grades

List grade levels for a specific stage within a framework.

Auth: None

URL Parameters:

ParamTypeDescription
frameworkCodestringFramework code
stageCodestringStage code

Response (200):

{
  "success": true,
  "data": [
    {
      "framework_code": "TR-MEB-2024",
      "stage_code": "middle",
      "code": "grade-5",
      "name": "5th Grade",
      "typical_age": 10,
      "sequence": 0
    }
  ]
}

Results are ordered by sequence.

Errors:

StatusErrorCause
500Failed to get gradesInternal error

GET /api/curriculum/frameworks/:code/subjects

List subjects for a framework.

Auth: None

URL Parameters:

ParamTypeDescription
codestringFramework code

Response (200):

{
  "success": true,
  "data": [
    {
      "framework_code": "TR-MEB-2024",
      "code": "math",
      "name": "Mathematics",
      "description": "Mathematics curriculum",
      "icon": "calculator",
      "color": "#2196F3",
      "is_core": true,
      "sequence": 0
    }
  ]
}

Results are ordered by sequence.

Errors:

StatusErrorCause
500Failed to get subjectsInternal error

GET /api/curriculum/frameworks/:frameworkCode/subjects/:subjectCode/grades/:gradeCode/units

List units for a specific subject and grade combination.

Auth: None

URL Parameters:

ParamTypeDescription
frameworkCodestringFramework code
subjectCodestringSubject code
gradeCodestringGrade code

Response (200):

{
  "success": true,
  "data": [
    {
      "framework_code": "TR-MEB-2024",
      "subject_code": "math",
      "grade_code": "grade-8",
      "code": "unit-1",
      "name": "Numbers and Operations",
      "description": "Fundamental number concepts",
      "estimated_hours": 20,
      "sequence": 0
    }
  ]
}

Results are ordered by sequence.

Errors:

StatusErrorCause
500Failed to get unitsInternal error

GET /api/curriculum/frameworks/:frameworkCode/subjects/:subjectCode/grades/:gradeCode/units/:unitCode/topics

List topics within a unit.

Auth: None

URL Parameters:

ParamTypeDescription
frameworkCodestringFramework code
subjectCodestringSubject code
gradeCodestringGrade code
unitCodestringUnit code

Response (200):

{
  "success": true,
  "data": [
    {
      "framework_code": "TR-MEB-2024",
      "subject_code": "math",
      "grade_code": "grade-8",
      "unit_code": "unit-1",
      "code": "topic-1",
      "name": "Integer Operations",
      "description": "Addition, subtraction, multiplication of integers",
      "base_difficulty": 0.5,
      "estimated_minutes": 45,
      "sequence": 0
    }
  ]
}

Results are ordered by sequence.

Errors:

StatusErrorCause
500Failed to get topicsInternal error

GET /api/curriculum/frameworks/:frameworkCode/subjects/:subjectCode/grades/:gradeCode/units/:unitCode/topics/:topicCode/objectives

List learning objectives for a topic.

Auth: None

URL Parameters:

ParamTypeDescription
frameworkCodestringFramework code
subjectCodestringSubject code
gradeCodestringGrade code
unitCodestringUnit code
topicCodestringTopic code

Response (200):

{
  "success": true,
  "data": [
    {
      "framework_code": "TR-MEB-2024",
      "subject_code": "math",
      "grade_code": "grade-8",
      "unit_code": "unit-1",
      "topic_code": "topic-1",
      "code": "obj-1",
      "objective": "Students can add and subtract integers fluently",
      "bloom_level": "apply",
      "mastery_threshold": 0.7,
      "sequence": 0
    }
  ]
}

Results are ordered by sequence.

Bloom's levels: remember, understand, apply, analyze, evaluate, create

Errors:

StatusErrorCause
500Failed to get objectivesInternal error

Content Metadata Endpoints

These endpoints link H5P content to curriculum frameworks.

POST /api/curriculum/content/:contentId/metadata

Save or update curriculum metadata for an H5P content item. Uses upsert: if metadata already exists for the content ID, it is replaced.

Auth: Authenticated user (JWT, authMiddleware)

URL Parameters:

ParamTypeDescription
contentIdstringH5P content ID

Request Body:

{
  "frameworkCode": "TR-MEB-2024",
  "frameworkName": "MEB 2024 Curriculum",
  "countryCode": "TR",
  "stageCode": "middle",
  "stageName": "Middle School",
  "gradeCode": "grade-8",
  "gradeName": "8th Grade",
  "subjectCode": "math",
  "subjectName": "Mathematics",
  "topicCodes": ["topic-1", "topic-2"],
  "topicNames": ["Integer Operations", "Fractions"],
  "objectiveCodes": ["obj-1", "obj-2"],
  "objectiveDescriptions": [
    "Students can add and subtract integers",
    "Students can multiply fractions"
  ],
  "difficulty": "medium",
  "language": "tr"
}
FieldTypeRequiredConstraints
frameworkCodestringYesmax 100 chars
frameworkNamestringYesmax 255 chars
countryCodestringYesmax 10 chars
stageCodestringNomax 100 chars
stageNamestringNomax 255 chars
gradeCodestringYesmax 100 chars
gradeNamestringYesmax 255 chars
subjectCodestringYesmax 100 chars
subjectNamestringYesmax 255 chars
topicCodesstring[]Nomax 50 items, each max 100 chars; default []
topicNamesstring[]Nomax 50 items, each max 255 chars; default []
objectiveCodesstring[]Nomax 200 items, each max 100 chars; default []
objectiveDescriptionsstring[]Nomax 200 items, each max 500 chars; default []
difficultystringNomax 50 chars; default "medium"
languagestringNomax 10 chars; default "en"

Response (200):

{
  "success": true,
  "message": "Content curriculum metadata saved"
}

Errors:

StatusErrorCause
400Validation error: ...Invalid request body
500Failed to save metadataInternal error

GET /api/curriculum/content/:contentId/metadata

Get curriculum metadata for an H5P content item.

Auth: None (public endpoint)

URL Parameters:

ParamTypeDescription
contentIdstringH5P content ID

Response (200):

{
  "success": true,
  "data": {
    "content_id": "42",
    "framework_code": "TR-MEB-2024",
    "framework_name": "MEB 2024 Curriculum",
    "country_code": "TR",
    "stage_code": "middle",
    "stage_name": "Middle School",
    "grade_code": "grade-8",
    "grade_name": "8th Grade",
    "subject_code": "math",
    "subject_name": "Mathematics",
    "topic_codes": ["topic-1"],
    "topic_names": ["Integer Operations"],
    "objective_codes": ["obj-1"],
    "objective_descriptions": ["Students can add and subtract integers"],
    "difficulty": "medium",
    "language": "tr",
    "created_at": "2025-01-15T10:00:00.000Z",
    "updated_at": "2025-01-15T10:00:00.000Z"
  }
}

Returns null in data if no metadata exists for the content ID.

Errors:

StatusErrorCause
500Failed to get metadataInternal error

DELETE /api/curriculum/content/:contentId/metadata

Delete curriculum metadata for an H5P content item.

Auth: Authenticated user (JWT, authMiddleware)

URL Parameters:

ParamTypeDescription
contentIdstringH5P content ID

Response (200):

{
  "success": true,
  "message": "Content curriculum metadata deleted"
}

Errors:

StatusErrorCause
500Failed to delete metadataInternal error

Data Model

Curriculum Hierarchy

The curriculum data follows a strict hierarchy:

Framework
  -> Stage (education level, e.g., Primary, Middle School)
       -> Grade (e.g., 5th Grade, 8th Grade)
  -> Subject (e.g., Mathematics, Science)
       -> Unit (per subject + grade combination)
            -> Topic (specific learning area)
                 -> Learning Objective (with Bloom's level)

Framework

FieldTypeDescription
codestring (PK)Unique framework identifier
namestringDisplay name
descriptionstringFramework description
framework_typeenumnational, international, regional, enrichment
country_codestringISO country code
organizationstringPublishing organization
versionstringVersion identifier
languagestringPrimary language
valid_fromdateEffective start date
valid_untildateEffective end date (null if current)
is_activebooleanWhether framework is active
is_publishedbooleanWhether framework is published

Learning Objective

FieldTypeDescription
codestringUnique code within topic scope
objectivestringObjective description text
bloom_levelenumremember, understand, apply, analyze, evaluate, create
mastery_thresholddecimalRequired mastery score (0.0-1.0, default 0.7)
sequenceintegerDisplay order

Content Curriculum Metadata

FieldTypeDescription
content_idstring (PK)H5P content ID
framework_codestringFramework code
framework_namestringFramework display name
country_codestringISO country code
stage_codestringStage code (optional)
stage_namestringStage display name (optional)
grade_codestringGrade code
grade_namestringGrade display name
subject_codestringSubject code
subject_namestringSubject display name
topic_codesstring[]Associated topic codes
topic_namesstring[]Associated topic display names
objective_codesstring[]Associated objective codes
objective_descriptionsstring[]Associated objective descriptions
difficultystringDifficulty level (default "medium")
languagestringLanguage code (default "en")
created_attimestampCreation timestamp
updated_attimestampLast update timestamp
Back to docsdocs/product/api/curriculum.md