---
title: "Upsert external courses"
method: PUT
path: "/api/v2/bulk/integrations/{integrationId}/courses"
tags: ["Integrations"]
---

# Upsert external courses

`PUT /api/v2/bulk/integrations/{integrationId}/courses`

> 🔑
>
> Required OAuth scope: `integrations:bulk`.

> 🚜
>
> This endpoint processes up to 10,000 objects asynchronously. For more information, see the [Bulk operations guide](https://360learning.readme.io/docs/bulk-operations-1).

Adds or replaces multiple external courses based on the given `integrationId` and the courses's `externalId`.
- If a provided `externalId` matches an existing external course, the course is replaced with the new data.
- If no match is found, a new course is created and added to the group catalog and library.

Upon submission, the request is queued. Use the provided URL in the response header to check the status of the bulk operation.

## Path parameters

- `integrationId` string, ObjectId, required

## Headers

- `360-api-version` 'v2.0', required

## Request body

- ImportExternalCoursesBody
  - `input` ExternalCourseDTO[], required — An array of objects, each specifying details for external course to be imported.
    - `defaultLang` 'bg' | 'cs' | 'da' | 'de' | 'el' | 'en' | 'es' | 'fi' | 'fr' | 'hr' | 'ht_HT' | 'hu' | 'id' | 'it' | 'ja' | 'kar_MM' | 'ko' | 'lt' | 'mh_MH' | 'nl' | 'nl_BE' | 'no' | 'pl' | 'pt' | 'ro' | 'ru' | 'rw_RW' | 'sk' | 'sl' | 'so_SO' | 'sv' | 'sw_KE' | 'th' | 'ti_ET' | 'tr' | 'uk' | 'zh' | 'am_ET' | 'bn' | 'bs' | 'ca' | 'cy' | 'en_CA' | 'en_GB' | 'es_AR' | 'es_MX' | 'et' | 'fr_CA' | 'gu' | 'he_IL' | 'hy' | 'kk' | 'km' | 'lo' | 'lv' | 'mi' | 'mn_MN' | 'mr' | 'ms' | 'my_MM' | 'nn_NO' | 'or' | 'pa' | 'pt_BR' | 'pt_MZ' | 'rn_BI' | 'si' | 'ta' | 'te' | 'tl_PH' | 'ur' | 'uz' | 'yo_NG' | 'zh_tw' | 'el' | 'hi' | 'sr' | 'ar' | 'vi' | 'zh_HANT', required — The language of the external course which is displayed by default when the learner’s profile language is not available. The `name`, `description`, `subjects`, `launchUrl`, and `mobileLaunchUrl` values must be coherent with this language.
    - `externalId` string, required — The unique external ID of the external course.
    - `launchUrl` string, required — The URL to launch and play the external course.
    - `name` string, required — The title of the external course.
    - `sources` ExternalCourseSourceDTO[], required — The list of sources of the external course.
      - `name` string, required — The name of the source.
      - `logoUrl` string — The logo URL of the source.
    - `subjects` string[], required — The list of subjects of the external course.
    - `contentType` 'article' | 'assessment' | 'audiobook' | 'book' | 'certificate' | 'channel' | 'course' | 'curriculum' | 'interactive' | 'journey' | 'labs' | 'linkedContent' | 'mooc' | 'podcast' | 'program' | 'roleplay' | 'specialization' | 'topvoice' | 'video' — The type of the external course. If not set, `course` type is used.
    - `description` string — The description of the external course.
    - `difficultyLevel` 'advanced' | 'beginner' | 'intermediate' — The level of difficulty of the external course.
    - `duration` integer — The duration of the external course, in minutes.
    - `imageUrl` string — The URL of the image of the external course.
    - `mobileLaunchUrl` string — The URL to launch and play the external course from a mobile. If not set, the `launchUrl` is used.
    - `authorId` string, ObjectId — The unique ID of the author. If not set, the `authorId` from the integration is used.
    - `translations` ExternalCourseTranslationDTO[] — The different translations available for the external course.
      - `lang` 'bg' | 'cs' | 'da' | 'de' | 'el' | 'en' | 'es' | 'fi' | 'fr' | 'hr' | 'ht_HT' | 'hu' | 'id' | 'it' | 'ja' | 'kar_MM' | 'ko' | 'lt' | 'mh_MH' | 'nl' | 'nl_BE' | 'no' | 'pl' | 'pt' | 'ro' | 'ru' | 'rw_RW' | 'sk' | 'sl' | 'so_SO' | 'sv' | 'sw_KE' | 'th' | 'ti_ET' | 'tr' | 'uk' | 'zh' | 'am_ET' | 'bn' | 'bs' | 'ca' | 'cy' | 'en_CA' | 'en_GB' | 'es_AR' | 'es_MX' | 'et' | 'fr_CA' | 'gu' | 'he_IL' | 'hy' | 'kk' | 'km' | 'lo' | 'lv' | 'mi' | 'mn_MN' | 'mr' | 'ms' | 'my_MM' | 'nn_NO' | 'or' | 'pa' | 'pt_BR' | 'pt_MZ' | 'rn_BI' | 'si' | 'ta' | 'te' | 'tl_PH' | 'ur' | 'uz' | 'yo_NG' | 'zh_tw' | 'el' | 'hi' | 'sr' | 'ar' | 'vi' | 'zh_HANT', required — The language of the translation.
      - `translatedFields` ExternalCourseTranslatedFields, required
        - `description` string — The translation of the field `description` for this language.
        - `launchUrl` string — The URL to launch and play the external course in this language.
        - `mobileLaunchUrl` string — The URL to launch and play the external course from a mobile in this language.
        - `name` string — The translation of the field `name` for this language.
        - `subjects` string[] — The translation of the field `subjects` for this language.

## Response `202`

The operation is successfully created.

## Other responses

- `400` — The server cannot or will not process the request due to something that is perceived to be a client error.
- `401` — The given access token is either missing, invalid, has expired, or has been revoked.
- `403` — The given access token does not have the required OAuth scope to execute the request.
- `404` — The given `integrationId` does not correspond to any existing integration.
- `429` — The maximum number of concurrent operations has been reached.
- `503` — The bulk API is temporarily disabled.

---

[API](https://skmtc.dev/360learning/apis/core-api.md) · [All operations](https://skmtc.dev/360learning/apis/core-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/360learning/core-api/revisions/94b691b0b72c/schema)
