---
title: "✨ Apply a structural change to a course"
method: POST
path: "/api/learning-resources/{id}/structure/"
tags: ["Learning Resources"]
---

# ✨ Apply a structural change to a course

`POST /api/learning-resources/{id}/structure/`

<Card href="https://humansignal.com/goenterprise">
        <img style="pointer-events: none; margin-left: 0px; margin-right: 0px;" src="https://docs.humansignal.com/images/badge.svg" alt="Label Studio Enterprise badge"/>
        <p style="margin-top: 10px; font-size: 14px;">
            This endpoint is not available in Label Studio Community Edition. [Learn more about Label Studio Enterprise](https://humansignal.com/goenterprise)
        </p>
    </Card>
Apply a semantic structural operation (add/delete/duplicate/reorder/move page or module, rename module) to current server state under a compare-and-swap on `structure_version`. A stale version returns 409 `structure_version_conflict` with the fresh outline so the client can resync and retry.

## Path parameters

- `id` integer, required

## Request body

- CourseStructureOpRequest
  - `dest_index` integer
  - `dest_module_id` integer
  - `module_id` integer
  - `module_ids` integer[]
  - `op` 'add_page' | 'delete_page' | 'duplicate_page' | 'reorder_pages' | 'move_page' | 'add_module' | 'delete_module' | 'duplicate_module' | 'reorder_modules' | 'rename_module', required — * `add_page` - add_page * `delete_page` - delete_page * `duplicate_page` - duplicate_page * `reorder_pages` - reorder_pages * `move_page` - move_page * `add_module` - add_module * `delete_module` - delete_module * `duplicate_module` - duplicate_module * `reorder_modules` - reorder_modules * `rename_module` - rename_module
  - `page_id` string
  - `source_module_id` integer
  - `structure_version` integer, required
  - `title` string
  - `to_index` integer

## Response `200`

- CourseStructureOpResponse
  - `module_id` integer, nullable
  - `modules` CourseModule[], required
    - `content` unknown
    - `created_at` string, date-time, required
    - `id` integer, required
    - `learning_resource` integer, required
    - `marked_stale` boolean
    - `page_count` integer, required
    - `sort_order` integer
    - `title` string
    - `updated_at` string, date-time, required
    - `updated_by` UserSimple, required — A ModelSerializer that takes additional arguments for "fields", "omit" and "expand" in order to control which fields are displayed, and whether to replace simple values with complex, nested serializations
      - `avatar` string, nullable, required
      - `email` string, email
      - `first_name` string
      - `id` integer, required
      - `last_name` string
      - `username` string, required
  - `outline` CourseOutline, required
    - `modules` CourseOutlineModule[], required
      - `id` integer, required
      - `marked_stale` boolean, required
      - `pages` CourseOutlinePage[], required
        - `id` string, required
        - `title` string, required
        - `version` integer, required
      - `sort_order` integer, required
      - `title` string, required
      - `updated_by` UserSimple, required — A ModelSerializer that takes additional arguments for "fields", "omit" and "expand" in order to control which fields are displayed, and whether to replace simple values with complex, nested serializations
        - `avatar` string, nullable, required
        - `email` string, email
        - `first_name` string
        - `id` integer, required
        - `last_name` string
        - `username` string, required
    - `structure_version` integer, required
  - `page_id` string, nullable
  - `structure_version` integer, required

---

[API](https://skmtc.net/humansignal/apis/label-studio-api.md) · [All operations](https://skmtc.net/humansignal/apis/label-studio-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/humansignal/label-studio-api/versions/1b113b8df950/schema)
