Update Courses
Updates existing course content. Supports partial updates — only provided fields are updated. Can also create new sections, lessons, topics, or course groups by omitting the `id` field. The update endpoint accepts up to 100 total items across all entity types combined.
Updates existing course content. Supports partial updates - only provided fields are updated. Can also create new sections, lessons, topics, or course groups by omitting the id field.
The update endpoint accepts up to 100 total items across all entity types combined.
Authentication & Permissions
Authenticate with Authorization: Bearer YOUR_API_KEY. This endpoint requires the courses.edit permission. This route is not rate limited.
Update Course Attributes
| Property | Type | Required? | Description |
|---|---|---|---|
sections | array | no | Array of section updates |
courseGroups | array | no | Array of course group updates |
courses | array | no | Array of course updates |
lessons | array | no | Array of lesson updates |
topics | array | no | Array of topic updates |
Update Section Object
| Property | Type | Required? | Description |
|---|---|---|---|
id | UUID | no | Section ID (omit to create new section) |
courseId | UUID | if creating | Required when creating new section |
title | string | no | Section title |
releaseDate | date | no | When section is released |
displayOrder | integer | no | Display order in course |
Update Course Group Object
| Property | Type | Required? | Description |
|---|---|---|---|
id | UUID | no | Course group ID (omit to create new) |
title | string | no | Course group title |
slug | string | no | URL slug |
description | string | no | Course description (max 5,000 characters). Pass null to clear; omit to leave unchanged |
tagIds | array | no | Tag UUIDs (max 10). Replaces the entire array; pass null or [] to clear |
authors | array | no | Catalog author names. Replaces the entire array; omit to leave unchanged; pass null or [] to clear. Empty or whitespace-only strings are invalid |
source | string | no | Catalog source label. Pass null to clear; omit to leave unchanged |
customFields | JSON | no | Custom field values. Replaces the entire object; pass null or {} to clear |
asset | URL | no | Catalog image URL. Pass null to clear |
assetAltText | string | no | Catalog image alt text |
detailAsset | URL | no | Detail page image URL. Pass null to clear |
detailAssetAltText | string | no | Detail image alt text |
ribbon | string | no | Ribbon badge slug. Pass null to clear |
metaTitle | string | no | SEO meta title (max 200 characters) |
metaDescription | string | no | SEO meta description (max 500 characters) |
archived | boolean | no | Archive status (update only — cannot be set on create) |
relatedCourseGroupIds | array | no | Related course group UUIDs. Replaces the entire array |
Update Course Object
| Property | Type | Required? | Description |
|---|---|---|---|
id | UUID | no | Course ID (omit to create new course) |
courseGroupId | UUID | if creating | Required when creating new course |
title | string | no | Course title |
kind | string | no | Course kind |
priceInCents | integer | no | Price in cents (max 99,999,999) |
freeWithRegistration | boolean | no | Free for registered users |
purchasable | boolean | no | Enable purchasing |
status | string | no | Course status: draft, published, archived |
customFields | JSON | no | Session custom fields. Replaces the entire object |
forceLinearProgress | boolean | no | Require sequential page completion |
showProgress | boolean | no | Show progress indicator |
prerequisiteCourseIds | array | no | Prerequisite course UUIDs |
prerequisiteLearningPathIds | array | no | Prerequisite learning path UUIDs |
Update Lesson Object
| Property | Type | Required? | Description |
|---|---|---|---|
id | UUID | no | Lesson ID (omit to create new lesson) |
sectionId | UUID | if creating | Required when creating new lesson |
title | string | no | Lesson title |
openType | string | no | Access level: studentsOnly, open, emailCaptureOpen |
Update Topic Object
| Property | Type | Required? | Description |
|---|---|---|---|
id | UUID | yes/no | Topic ID (required for update, omit for create) |
lessonId | UUID | if creating | Required when creating new topic |
title | string | no | Topic title |
type | string | if creating | Topic type (required when creating) |
body | string | no | HTML content |
languages | array | no | Multi-language variants |
preTextBlock | string | no | Pre-content text |
postTextBlock | string | no | Post-content text |
width | integer | no | Display width (pixels) |
height | integer | no | Display height (pixels) |
embeddedEnabled | boolean | no | Enable embedded display |
fullscreenEmbed | boolean | no | Enable fullscreen embed |
preventProgression | boolean | no | Prevent progression until complete |
resetSessionAfterComplete | boolean | no | Reset session after completion |
caption | string | no | Caption text |
searchDisabled | boolean | no | Exclude from search |
printDisabled | boolean | no | Disable printing |
fileDownloadDisabled | boolean | no | Disable file download |
scormUrl | URL | no | URL to SCORM/xAPI package |
scoTitle | string | no | SCORM title |
objectType | string | no | SCORM standard type |
restartProgress | boolean | no | Restart user progress when replacing SCORM |
pdfUrl | URL | no | URL to PDF file |
videoUrl | URL | no | External URL to a video file (for video type) — uploaded to Wistia by a background job |
videoAsset | ID | no | Existing Wistia media ID or Synthesia UUID. Mutually exclusive with videoUrl |
assetType | string | no | Video provider: wistia (default) or synthesia |
preAsset | ID | no | Wistia media ID for pre-roll video |
postAsset | ID | no | Wistia media ID for post-roll video |
posterImageAsset | URL | no | Poster image URL displayed before the video plays |
audioUrl | URL | no | External URL to an audio file (for audio type) — downloaded and stored by a background job, replacing any existing audio on the topic. Supported formats: MP3, WAV, OGG (max 200 MB) |
PUT https://example.thoughtindustries.com/incoming/v2/content/course/updateExample request - Update Course Group Title
curl -X "PUT" "https://example.thoughtindustries.com/incoming/v2/content/course/update" \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"courseAttributes": {
"courseGroups": [
{
"id": "1e7a0ab5-9e13-44d5-90bf-e7c61e7448f8",
"title": "Updated Course Title"
}
]
}
}'Example request - Update authors or source independently
Only provided fields are written. Omitting source leaves it unchanged; the same applies to authors. Pass authors: [] or authors: null to clear authors; pass source: null to clear source.
curl -X "PUT" "https://example.thoughtindustries.com/incoming/v2/content/course/update" \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"courseAttributes": {
"courseGroups": [
{
"id": "1e7a0ab5-9e13-44d5-90bf-e7c61e7448f8",
"authors": ["Updated Author"]
}
]
}
}'Example response
trueExample request - Update Topic Content
curl -X "PUT" "https://example.thoughtindustries.com/incoming/v2/content/course/update" \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"courseAttributes": {
"topics": [
{
"id": "1366501c-3740-4a30-9464-1a2f111499ee",
"body": "<p>Updated content here</p>"
}
]
}
}'Example request - Add New Section to Existing Course
curl -X "PUT" "https://example.thoughtindustries.com/incoming/v2/content/course/update" \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"courseAttributes": {
"sections": [
{
"courseId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"title": "New Section",
"displayOrder": 3
}
]
}
}'Example request - Upload SCORM to Existing Topic
curl -X "PUT" "https://example.thoughtindustries.com/incoming/v2/content/course/update" \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"courseAttributes": {
"topics": [
{
"id": "fdbec9af-e134-4c42-81c4-05a056dd40ca",
"scormUrl": "https://example.com/scorm-packages/updated-module.zip",
"restartProgress": true
}
]
}
}'Example response - SCORM Update with Background Job
{
"success": true,
"backgroundJob": {
"id": "job-uuid-here",
"type": "contentBulkUpload",
"status": "queued",
"contentUploads": [
{
"topicId": "fdbec9af-e134-4c42-81c4-05a056dd40ca",
"contentType": "scorm"
}
]
}
}Example request - Add PDF Topic to Existing Lesson
curl -X "PUT" "https://example.thoughtindustries.com/incoming/v2/content/course/update" \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"courseAttributes": {
"topics": [
{
"lessonId": "93e6076b-ba84-4012-84ff-73c0367006e0",
"title": "Course Materials PDF",
"type": "pdfViewer",
"pdfUrl": "https://example.com/materials/course-materials.pdf"
}
]
}
}'Errors
Validation failures return HTTP 400 with an errors array. If a topic id does not belong to your company, the response reports Topics not found: <ids>. Empty or whitespace-only authors entries return authors cannot contain empty strings.
{
"errors": [
"Topics not found: 1366501c-3740-4a30-9464-1a2f111499ee"
]
}