---
title: "Create course"
method: POST
path: "/courses"
tags: ["Courses"]
---

# Create course

`POST /courses`

Create a new course within an experience, with optional chapters, lessons, and a certificate.

Required permissions:
 - `courses:update`

## Request body

- object — Parameters for CreateCourse
  - `certificate_after_completion_enabled` boolean, nullable — Whether the course awards students a PDF certificate after completing all lessons.
  - `experience_id` string, required — The unique identifier of the experience to create the course in (e.g., "exp_XXXXX").
  - `order` string, nullable — The decimal order position of the course within its experience. Use fractional values (e.g., "1.5") to place between existing courses.
  - `require_completing_lessons_in_order` boolean, nullable — Whether students must complete each lesson sequentially before advancing to the next one.
  - `tagline` string, nullable — A short tagline displayed beneath the course title (e.g., "Master the fundamentals of design").
  - `thumbnail` object, nullable — The thumbnail image for the course in PNG, JPEG, or GIF format.
    - `id` string, required — The ID of an existing file object.
  - `title` string, required — The display title of the course (e.g., "Introduction to Web Development").
  - `visibility` 'visible' | 'hidden' — The available visibilities for a course. Determines how / whether a course is visible to users.

## Response `200`

A successful response

- Course — A structured learning module containing chapters and lessons, belonging to an experience.
  - `certificate_after_completion_enabled` boolean, nullable, required — Whether students receive a PDF certificate after completing all lessons in this course. Null if the setting has not been configured.
  - `chapters` object[], required — An ordered list of all chapters in this course, sorted by their display position.
    - `id` string, required — The unique identifier for the chapter.
    - `lessons` object[], required — An ordered list of lessons in this chapter, sorted by display position. Hidden lessons are excluded for non-admin users.
      - `id` string, required — The unique identifier for the lesson.
      - `lesson_type` 'text' | 'video' | 'pdf' | 'multi' | 'quiz' | 'knowledge_check', required — The available types for a lesson
      - `order` integer, required — The sort position of this lesson within its parent chapter, starting from zero.
      - `thumbnail` object, nullable, required — The thumbnail image displayed on lesson cards and previews. Null if no thumbnail has been uploaded.
        - `url` string, nullable, required — A pre-optimized URL for rendering this attachment on the client. This should be used for displaying attachments in apps.
      - `title` string, required — The display name of the lesson shown to students. Maximum 120 characters.
      - `video_asset` object, nullable, required — The Mux video asset for video-type lessons, used for streaming playback. Null if this lesson has no hosted video.
        - `duration_seconds` integer, nullable, required — The duration of the video in seconds
        - `signed_playback_id` string, nullable, required — The signed playback ID of the Mux asset
        - `signed_thumbnail_playback_token` string, nullable, required — The signed thumbnail playback token of the Mux asset
    - `order` integer, required — The sort position of this chapter within its parent course, starting from zero.
    - `title` string, required — The display name of the chapter shown to students. Maximum 150 characters.
  - `chapters_count` integer, required — The total number of chapters in this course, including chapters whose lessons are all hidden from the current user.
  - `completed_lessons_count` integer, required — The number of lessons in this course that the current user has marked as completed. Zero when the request is not made on behalf of a user.
  - `cover_image` string, nullable, required — The URL of the course cover image shown on preview cards. Null if no cover image has been uploaded.
  - `created_at` string, date-time, required — The datetime the course was created.
  - `description` string, nullable, required — A brief summary of the course content and objectives. Null if no description has been set.
  - `id` string, required — The unique identifier for the course.
  - `language` 'en' | 'es' | 'it' | 'pt' | 'de' | 'fr' | 'pl' | 'ru' | 'nl' | 'ca' | 'tr' | 'sv' | 'uk' | 'no' | 'fi' | 'sk' | 'el' | 'cs' | 'hr' | 'da' | 'ro' | 'bg', required — The available languages for a course
  - `latest_lesson_created_at` string, date-time, nullable, required — The creation timestamp of the most recently added lesson visible to the current user. Null if the course has no lessons.
  - `lesson_unlock_days` integer[], required — The distinct drip schedules, in days after the course start, of lessons visible to the current user. Combine with startedAt to work out which have unlocked. Empty when the user has not started the course or no lesson is on a schedule.
  - `order` string, required — The sort position of this course within its parent experience, as a decimal for flexible ordering.
  - `require_completing_lessons_in_order` boolean, required — Whether students must complete each lesson sequentially before advancing to the next one.
  - `resume_lesson` object, nullable, required — The lesson the current user should continue from: their first incomplete lesson, or the first lesson when they have finished the course, have not started it, or can edit it. Null if the course has no lessons.
    - `id` string, required — The unique identifier for the lesson.
  - `started_at` string, date-time, nullable, required — The earliest time the current user is known to have started this course. Null if they have not started it. Drip unlock schedules are measured from this point.
  - `tagline` string, nullable, required — A short marketing tagline displayed beneath the course title. Null if no tagline has been set.
  - `thumbnail` object, nullable, required — The thumbnail image displayed on course cards and previews. Null if no thumbnail has been uploaded.
    - `content_type` string, nullable, required — Uploaded file MIME type, such as image/jpeg, video/mp4, or audio/mpeg.
    - `filename` string, nullable, required — The original filename of the uploaded attachment, including its file extension.
    - `id` string, required — Represents a unique identifier that is Base64 obfuscated. It is often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `"VXNlci0xMA=="`) or integer (such as `4`) input value will be accepted as an ID.
    - `optimized_url` string, nullable, required — A pre-optimized URL for rendering this attachment on the client. This should be used for displaying attachments in apps.
    - `source_url` string, nullable, required — The original source URL of the attachment, such as a direct link to S3. This should never be displayed on the client and should always be passed through an Imgproxy transformer.
  - `title` string, nullable, required — The display name of the course shown to students. Null if no title has been set.
  - `total_duration_seconds` integer, required — The combined duration in seconds of every hosted video across the lessons visible to the current user.
  - `total_lessons_count` integer, required — The number of lessons in this course visible to the current user.
  - `updated_at` string, date-time, required — The datetime the course was last updated.
  - `visibility` 'visible' | 'hidden', required — The available visibilities for a course. Determines how / whether a course is visible to users.

## Other responses

- `400` — Bad request
- `401` — Unauthorized
- `403` — Forbidden
- `404` — Not found
- `422` — Verification required
- `429` — Too many requests
- `500` — Internal server error

---

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