---
title: "Upsert courses"
method: POST
path: "/lms/courses/bulk"
tags: ["Unified LMS API"]
---

# Upsert courses

`POST /lms/courses/bulk`

Create or update multiple courses in the LMS.

<Info>
  **Note:** This endpoint is asynchronous – it returns a `task_id` immediately and processes the request in the background. Use the corresponding `GET` endpoint to poll for the task status until it reaches `COMPLETED` or `FAILED`. Learn more in our [async endpoints guide](/lms/guides/async-endpoints).
</Info>

<Note>
  This endpoint requires the permission **Upsert courses** to be enabled in [your scope config](/scopes).
</Note>

### Example Request Body

```json
{
  "items": [
    {
      "origin_id": "course-1",
      "course": {
        "type": "EXTERNAL",
        "title": "Building LMS integrations with Kombo",
        "description": "Learn how to build and integrate Learning Management System (LMS) integrations with Kombo. This course covers the unified LMS API, course management, user enrollment, progress tracking, and best practices for building robust LMS connectors.",
        "course_url": "https://docs.kombo.dev/lms/introduction",
        "thumbnail_url": "https://kombo.dev/images/courses/lms-integrations-thumbnail.png",
        "duration": 45,
        "languages": [
          "en",
          "de-CH"
        ]
      }
    },
    {
      "origin_id": "course-2",
      "course": {
        "type": "EXTERNAL",
        "title": "Introduction to TypeScript",
        "description": "Learn one of the most popular programming languages of the recent years quickly and efficiently. Results guaranteed!",
        "course_url": "https://example.com",
        "thumbnail_url": "https://example.com/images/thumbnail.jpg",
        "duration": 60,
        "languages": [
          "en-US",
          "pl-PL"
        ]
      }
    }
  ]
}
```

## Headers

- `X-Integration-Id` string, required

## Request body

- PostLmsCoursesBulkRequestBody
  - `items` object[], required — Array of courses to create or update.
    - `origin_id` string, required — A unique identifier for this item in the batch, used to correlate results and as a stable identifier for matching existing courses.
    - `course` object, required
      - `type` 'EXTERNAL', required — `EXTERNAL` indicates that the content is not sent to the LMS, but the `course_url` links to the content in your system.
      - `title` string, required — The title of the course revision.
      - `description` string, nullable — A description of the course revision.
      - `course_url` string, required — URL to the course page. For content providers, this should be a deeplink into your product that allows users to access the course directly.
      - `thumbnail_url` string, nullable — URL to the thumbnail image for the course.
      - `duration` integer, nullable — The duration of the course in minutes.
      - `languages` string[], nullable — A array containing the supported languages for the course content. If only one language is accepted by remote tool we default to the first one.

## Response `200`

POST /lms/courses/bulk Positive response

- PostLmsCoursesBulkPositiveResponse
  - `status` 'success', required
  - `data` object, required
    - `task_id` string, required — The ID of the created task. Poll this to get the status and results.
  - `warnings` object[], required — These are the interaction warnings that are shown in the dashboard. They are meant to provide debug information to you. We recommend logging them to the console.
    - `message` string, required

## Other responses

- `default` — The standard error response with just the platform error codes.

---

[API](https://skmtc.net/kombo/apis/kombo-api.md) · [All operations](https://skmtc.net/kombo/apis/kombo-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/kombo/kombo-api/revisions/0cfc9fa971c0/schema)
