Skip to content
Agentmart
Submit a tool

update-course-content

Action: Update existing course content (topics, lessons, sections) by UUID via PUT /content/course/update.

Skill by thoughtindustries

IndexedMIT
Write a review

Chalk Labs

Need help deploying update-course-content?

Chalk Labs sets up agents like this inside real teams: connected to your tools, tested on your data, with a human in the loop where it matters.

Book a call

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/thoughtindustries-update-course-content

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Action: Update existing course content (topics, lessons, sections) by UUID via PUT /content/course/update. Content stays as draft.

Use cases: writing

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found
Runs as
Node.js package

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/update-course-content

What's inside

Skill name
update-course-content
Description
Action: Update existing course content (topics, lessons, sections) by UUID via PUT /content/course/update. Content stays as draft.
License
MIT
Instructions
185 lines in SKILL.md · view on GitHub

Before installing

  • Ships executable scripts

Files (2)

  • SKILL.md
  • update-course-content.js

SKILL.md (first lines)

# Update Course Content

This is an **Action** skill — a single, unambiguous API call. It is deterministic and narrowly scoped.

## Endpoint

`PUT /incoming/v2/content/course/update`

## When to use

- Updating the body of existing topics (e.g., after rewriting a lesson).
- Changing titles, positions, or metadata of sections/lessons/topics.
- Adding new child nodes (omit `id` to create under an existing parent).
- **Retiring test/junk content** — TI has **no delete endpoint**, so set a **course (session)** to `status: "archived"` here (this does not remove the parent course group). See [Removing content](#removing-content).

> **Updating pre-existing content is fully supported** — it is not limited to content you created in the same session. The only prerequisite is the correct topic/section/lesson **UUID**. Do **not** fall back to "edit it manually in the TI admin UI" just because the content already existed. The supported end-to-end flow for existing content is:
>
> 1. **`resolve-content`** — turn a course/lesson/topic title or admin URL into UUIDs.
> 2. **`get-full-content`** — read the current topic `body` (this is the only read endpoint that returns body; `get-topic`/`get-topics-by-lesson` do not).
> 3. **`update-course-content`** — PUT the changed topic(s) by `id`. This is a verified round-trip.
>
> The manual-in-TI fallback is only appropriate for the genuine limits below — never as a substitute for a supported update.

## Agent instructions

This endpoint does double duty:

- **Update** an existing entity → include its `id` (UUID). Only the fields you pass change. Use read actions first to obtain IDs.
- **Create** a new child under an existing course → **omit `id`** and instead supply the **parent link** (and, for topics, a `type`):

  | Creating a… | Omit `id`, then supply | Also required |
  |-------------|------------------------|---------------|
  | course (under a group) | `courseGroupId` | — |
  | section | `courseId` | — |
  | lesson | `sectionId` | — |
  | topic | `lessonId` | `type` (e.g. `text`) |

  Do **not** invent field names like `parentId` — the API only recognises the parent keys above. This is the correct way to "attach a section/lesson/topic" to a course that already exists.

  **New topic `type` must be lesson-safe.** Use `"text"` for HTML body content. Do **not** use `"article"` (or other standalone-only types) for a topic attached to a lesson — the API accepts it but the learner view 404s and the editor cannot open it, and there is no delete action to recover. The script blocks this locally.

1. Run `update-course-content.js --dry-run --file=update.json` first to validate — the script now fails locally with a precise message if a create is missing its parent link or a new topic is missing `type`, or if a video's source is in the wrong field.
2. Then run without `--dry-run`.
3. Confirm `restartProgress` semantics with the user if replacing SCORM on an existing topic.
4. To set/replace a **video**, target the topic by `id` with `videoAsset`/`videoUrl` — never an embed in `body`. See [Video content](#video-content).

## Limits

- The update payload is an **object** (not an array like create). It contains optional arrays: `courseGroups`, `courses`, `sections`, `lessons`, `topics`.
- Up to **100 items** total across all arrays combined.

### One payload, multiple arrays

You can mix `courseGroups`, `courses`, `sections`, `lessons`, and `topics` in a single payload, and mix different fields per item (e.g. one topic changing `title`, another changing `body`). The script always sends this as **one request**.

Historically, some server versions applied each entity array as **one SQL statement built from the union of all fields in that array**, which failed with an opaque `HTTP 400 — "A processing error occurred. Please refresh the page and try again."` whenever the update items in a single array didn't all carry the **same set of fields**. (This was a server bug, not entity-type mixing — two topics in one array, one with only `title` and one with only `body`, reproduced it on its own. It is fixed server-side.)

To stay compatible with instances that haven't picked up the server fix yet, `update-course-content.js` uses a **fallback**: it sends the combined request first (atomic, and the only request needed on a fixed server); only if the server rejects it with that specific legacy processing error does it retry by splitting the payload into the minimum number of sequential requests (parent→child order), grouping update items so each request's arrays are field-uniform. Use `--dry-run` to preview the combined request and, if relevant, the fallback split.

On a fixed server the update is a single atomic request. On the fallback path, updates are re-sent per group and are idempotent, but are **not atomic**; if a fallback request fails, the error names which entity arrays and ids were involved and how many earlier fallback requests already applied.

### Genuine limits (when manual TI editing IS the right answer)

These are the only cases where "do it in the TI admin UI" is legitimate — plain text/HTML `body` edits are **not** among them:

- **Publishing.** This action never releases content; a human publishes drafts in TI (see hard gate).
- **Quiz/assessment questions & answers.** `body` is HTML page content; it does not edit structured quiz questions, options, or scoring.
- **SCORM / media file uploads.** Binary uploads use the separate content-upload flow, not a JSON `body`. Confirm `restartProgress` semantics with the user before replacing SCORM on an existing topic.

When you hit one of these, name the specific part that must be done in TI and still apply everything the API *does* support (e.g. the text body) rather than deferring the whole task to manual editing.

## Run the script

```bash
node "${CLAUDE_PLUGIN_ROOT:+$CLAUDE_PLUGIN_ROOT/skills/actions/update-course-content/}update-course-content.js" --dry-run --file=update.json
node "${CLAUDE_PLUGIN_ROOT:+$CLAUDE_PLUGIN_ROOT/skills/actions/update-course-content/}update-course-content.js" --file=update.json
```

## Payload shape

```json
{
  "topics": [
    { "id": "TOPIC_UUID", "body": "<p>Updated content here</p>" }
  ]
}
```

Or with explicit wrapper:
```json
{
  "courseAttributes": {
    "topics": [
      { "id": "TOPIC_UUID", "title": "New Title", "body": "<p>...</p>" }
    ]
  }
}
```

Attaching a new section → lesson → topic to an existing course (each level created bottom-up needs its parent's UUID; create the section first to get its `id`, then the lesson, then the topic — or add each level in separate calls):
```json
{
  "sections": [
    { "courseId": "COURSE_UUID", "title": "New Section", "displayOrder": 3 }
  ]
}
```
```json
{
  "lessons": [
    { "sectionId": "SECTION_UUID", "title": "New Lesson", "openType": "studentsOnly" }
  ]
}
```
```json
{
  "topics": [
    { "lessonId": "LESSON_UUID", "title": "New Topic", "type": "text", "body": "<p>...</p>" }
  ]

From thoughtindustries/ti-admin-plugin, MIT.

More from thoughtindustries/ti-admin-plugin

Signals

Stars
0
Forks
0
Open issues
0
Last commit (this folder)
Aug 14, 2026 (2 months ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from thoughtindustries

Done for you

Rather not set it up yourself?

Chalk Labs scopes, builds and runs agents for your team: the task audit, the eval harness, the integrations and the weekly ops report. Fixed scope, priced before we start.

See how we build AI agents →Read the case studies

Chalk Labs is a two-founder AI and growth studio. We build AI agents, CRMs and MVPs for Web3 and AI companies, and have shipped 50+ product and token launches.

launches shipped
50+
launches shipped
media placements
500+
media placements
founders on every account
2
founders on every account

Press we've placed: Forbes · CoinDesk · Decrypt · Cointelegraph · The Block

Rahil Jain, Co-founder, Chalk Labs. Ex-Goldman Sachs engineer. You talk to the person who builds it.

Get update-course-content running in your business

Tell us what you want to automate. A founder replies within one working day with a plan, not a pitch deck.

Goes to the Chalk Labs founders, not the newsletter. Privacy

Need help deploying update-course-content?

CallGet help
Cite this page

update-course-content skill. Agent Mart. https://agentmart.dev/skills/thoughtindustries-update-course-content (last updated 2026-10-24)