> ## Documentation Index
> Fetch the complete documentation index at: https://docs.soludesks.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create Course

> Create course through SoluDesks APIs.

Tenant API keys operate inside the tenant LearnHub workspace. Service-provider API keys use the same endpoint family for service-provider-owned admin training content where supported. Create requests require a unique `Idempotency-Key` header.



## OpenAPI

````yaml api-reference/openapi.json POST /v1/external/learnhub/courses
openapi: 3.0.3
info:
  title: SoluDesks APIs
  version: 1.0.0
  description: >-
    REST API reference for documented SoluDesks API families. This generated
    file currently includes the LearnHub external endpoints.
servers:
  - url: https://staging.api.soludesks.com
    description: SoluDesks staging API
security:
  - apiKeyAuth: []
tags:
  - name: Categories
  - name: Courses
  - name: Sections
  - name: Lessons
  - name: Assessments
  - name: Assignments
  - name: Quizzes
  - name: Uploads
paths:
  /v1/external/learnhub/courses:
    post:
      tags:
        - Courses
      summary: Create course
      description: >-
        Create course through SoluDesks APIs.


        Tenant API keys operate inside the tenant LearnHub workspace.
        Service-provider API keys use the same endpoint family for
        service-provider-owned admin training content where supported. Create
        requests require a unique `Idempotency-Key` header.
      operationId: v1_external_learnhub_courses_create
      parameters:
        - in: header
          name: Idempotency-Key
          schema:
            type: string
          description: Unique client-generated key used to safely retry create requests.
          required: true
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ExternalLearnHubCourseCreateUpdateRequest'
            examples:
              course:
                summary: Course
                value:
                  name: Customer Support Foundations
                  description: A practical onboarding course for support teams.
                  level: BEGINNER
                  categories: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: >-
                  #/components/schemas/ExternalLearnHubCourseCreateExternalLearnHubAPIResponse
          description: ''
        '400':
          description: Bad request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExternalLearnHubErrorResponse'
              examples:
                error:
                  summary: Bad request.
                  value:
                    status: 400
                    success: false
                    code: REQUEST_FAILED
                    message: Bad request.
                    data: null
                    errors: []
        '401':
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExternalLearnHubErrorResponse'
              examples:
                error:
                  summary: Missing or invalid API key.
                  value:
                    status: 401
                    success: false
                    code: REQUEST_FAILED
                    message: Missing or invalid API key.
                    data: null
                    errors: []
        '403':
          description: >-
            Permission denied, inactive service provider, or unsupported key
            mode.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExternalLearnHubErrorResponse'
              examples:
                error:
                  summary: >-
                    Permission denied, inactive service provider, or unsupported
                    key mode.
                  value:
                    status: 403
                    success: false
                    code: REQUEST_FAILED
                    message: >-
                      Permission denied, inactive service provider, or
                      unsupported key mode.
                    data: null
                    errors: []
        '404':
          description: Resource not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExternalLearnHubErrorResponse'
              examples:
                error:
                  summary: Resource not found.
                  value:
                    status: 404
                    success: false
                    code: REQUEST_FAILED
                    message: Resource not found.
                    data: null
                    errors: []
        '409':
          description: Idempotency conflict or request already in progress.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExternalLearnHubErrorResponse'
              examples:
                error:
                  summary: Idempotency conflict or request already in progress.
                  value:
                    status: 409
                    success: false
                    code: REQUEST_FAILED
                    message: Idempotency conflict or request already in progress.
                    data: null
                    errors: []
        '422':
          description: Validation failed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExternalLearnHubErrorResponse'
              examples:
                error:
                  summary: Validation failed.
                  value:
                    status: 422
                    success: false
                    code: REQUEST_FAILED
                    message: Validation failed.
                    data: null
                    errors: []
        '429':
          description: Rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExternalLearnHubErrorResponse'
              examples:
                error:
                  summary: Rate limit exceeded.
                  value:
                    status: 429
                    success: false
                    code: REQUEST_FAILED
                    message: Rate limit exceeded.
                    data: null
                    errors: []
        '500':
          description: Internal server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExternalLearnHubErrorResponse'
              examples:
                error:
                  summary: Internal server error.
                  value:
                    status: 500
                    success: false
                    code: REQUEST_FAILED
                    message: Internal server error.
                    data: null
                    errors: []
      security:
        - apiKeyAuth: []
components:
  schemas:
    ExternalLearnHubCourseCreateUpdateRequest:
      type: object
      properties:
        name:
          type: string
          maxLength: 255
        description:
          type: string
        requirements:
          type: string
        status:
          $ref: '#/components/schemas/Status0b2Enum'
        level:
          $ref: '#/components/schemas/LevelEnum'
        categories:
          type: array
          items:
            type: string
            format: uuid
        cover_image_upload_session_id:
          type: string
          format: uuid
          writeOnly: true
        preview_video_upload_session_id:
          type: string
          format: uuid
          writeOnly: true
    ExternalLearnHubCourseCreateExternalLearnHubAPIResponse:
      type: object
      properties:
        status:
          type: integer
        success:
          type: boolean
        code:
          type: string
        message:
          type: string
        data:
          $ref: '#/components/schemas/ExternalLearnHubCourseDetail'
        errors:
          type: array
          items:
            type: object
            additionalProperties: {}
      required:
        - code
        - data
        - errors
        - message
        - status
        - success
    ExternalLearnHubErrorResponse:
      type: object
      required:
        - status
        - success
        - code
        - message
        - data
        - errors
      properties:
        status:
          type: integer
          example: 422
        success:
          type: boolean
          example: false
        code:
          type: string
          example: VALIDATION_ERROR
        message:
          type: string
          example: Some fields contain invalid values.
        data:
          nullable: true
          example: null
        errors:
          type: array
          items:
            $ref: '#/components/schemas/ExternalLearnHubErrorItem'
    Status0b2Enum:
      enum:
        - DRAFT
        - PUBLISHED
        - ARCHIVED
      type: string
      description: |-
        * `DRAFT` - Draft
        * `PUBLISHED` - Published
        * `ARCHIVED` - Archived
    LevelEnum:
      enum:
        - beginner
        - intermediate
        - advanced
      type: string
      description: |-
        * `beginner` - Beginner
        * `intermediate` - Intermediate
        * `advanced` - Advanced
    ExternalLearnHubCourseDetail:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        name:
          type: string
          readOnly: true
        level:
          allOf:
            - $ref: '#/components/schemas/LevelEnum'
          readOnly: true
        description:
          type: string
          readOnly: true
        source:
          readOnly: true
          nullable: true
          oneOf:
            - $ref: '#/components/schemas/Source41fEnum'
            - $ref: '#/components/schemas/NullEnum'
        requirements:
          type: string
          readOnly: true
          description: Optional prerequisites or requirements for the course.
        status:
          allOf:
            - $ref: '#/components/schemas/Status0b2Enum'
          readOnly: true
        categories:
          type: array
          items:
            $ref: '#/components/schemas/CourseCategoryResponse'
          readOnly: true
        has_enrollments:
          type: boolean
          readOnly: true
        quizzes_count:
          type: integer
          readOnly: true
        cover_image_url:
          type: string
          readOnly: true
        preview_video_url:
          type: string
          readOnly: true
        preview_video_status:
          type: string
          readOnly: true
        preview_video_ready:
          type: string
          readOnly: true
        preview_video_error:
          type: string
          nullable: true
          readOnly: true
        preview_video_has_subtitles:
          type: boolean
          readOnly: true
        preview_video_playback_endpoint:
          type: string
          nullable: true
          readOnly: true
        instructors:
          type: string
          readOnly: true
        overall_duration_seconds:
          type: integer
          readOnly: true
        created_datetime:
          type: string
          format: date-time
          readOnly: true
          description: datetime of object creation
        updated_datetime:
          type: string
          format: date-time
          readOnly: true
          description: datetime of object update
        sections:
          type: array
          items:
            $ref: '#/components/schemas/ExternalLearnHubSectionResponse'
          readOnly: true
      required:
        - categories
        - cover_image_url
        - created_datetime
        - description
        - has_enrollments
        - id
        - instructors
        - level
        - name
        - overall_duration_seconds
        - preview_video_error
        - preview_video_has_subtitles
        - preview_video_playback_endpoint
        - preview_video_ready
        - preview_video_status
        - preview_video_url
        - quizzes_count
        - requirements
        - sections
        - source
        - status
        - updated_datetime
    ExternalLearnHubErrorItem:
      type: object
      properties:
        field:
          type: string
          example: title
        code:
          type: string
          example: required
        message:
          type: string
          example: This field is required.
    Source41fEnum:
      enum:
        - MANUAL_CREATION
        - AI_GENERATED
        - DOCUMENT_EXTRACTION
      type: string
      description: |-
        * `MANUAL_CREATION` - Manual Creation
        * `AI_GENERATED` - AI Generated
        * `DOCUMENT_EXTRACTION` - Document Extraction
    NullEnum:
      enum:
        - null
    CourseCategoryResponse:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        name:
          type: string
          readOnly: true
        created_datetime:
          type: string
          format: date-time
          readOnly: true
          description: datetime of object creation
        updated_datetime:
          type: string
          format: date-time
          readOnly: true
          description: datetime of object update
      required:
        - created_datetime
        - id
        - name
        - updated_datetime
    ExternalLearnHubSectionResponse:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        title:
          type: string
          readOnly: true
        description:
          type: string
          readOnly: true
        order:
          type: integer
          readOnly: true
        lessons:
          type: array
          items:
            $ref: '#/components/schemas/ExternalLearnHubLessonResponse'
          readOnly: true
        created_datetime:
          type: string
          format: date-time
          readOnly: true
          description: datetime of object creation
        updated_datetime:
          type: string
          format: date-time
          readOnly: true
          description: datetime of object update
      required:
        - created_datetime
        - description
        - id
        - lessons
        - order
        - title
        - updated_datetime
    ExternalLearnHubLessonResponse:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        title:
          type: string
          readOnly: true
        description:
          type: string
          readOnly: true
        source:
          readOnly: true
          nullable: true
          oneOf:
            - $ref: '#/components/schemas/Source41fEnum'
            - $ref: '#/components/schemas/NullEnum'
        lesson_type:
          allOf:
            - $ref: '#/components/schemas/LessonType56fEnum'
          readOnly: true
        order:
          type: integer
          readOnly: true
        text_content:
          type: string
          readOnly: true
        video_content_url:
          type: string
          format: uri
          readOnly: true
        video_url:
          type: string
          readOnly: true
        video_status:
          type: string
          readOnly: true
        video_ready:
          type: string
          readOnly: true
        video_error:
          type: string
          readOnly: true
        video_has_subtitles:
          type: string
          readOnly: true
        video_playback_endpoint:
          type: string
          readOnly: true
        video_caption:
          type: string
          readOnly: true
        duration_seconds:
          type: integer
          readOnly: true
          nullable: true
        document_url:
          type: string
          readOnly: true
        document_name:
          type: string
          readOnly: true
        image_url:
          type: string
          readOnly: true
        image_name:
          type: string
          readOnly: true
        content_media:
          type: array
          items:
            $ref: '#/components/schemas/CourseSectionLessonContentMediaResponse'
          readOnly: true
        resources:
          type: array
          items:
            type: object
            additionalProperties: {}
          readOnly: true
        quiz:
          allOf:
            - $ref: '#/components/schemas/QuizResponse'
          readOnly: true
        created_datetime:
          type: string
          format: date-time
          readOnly: true
          description: datetime of object creation
        updated_datetime:
          type: string
          format: date-time
          readOnly: true
          description: datetime of object update
      required:
        - content_media
        - created_datetime
        - description
        - document_name
        - document_url
        - duration_seconds
        - id
        - image_name
        - image_url
        - lesson_type
        - order
        - quiz
        - resources
        - source
        - text_content
        - title
        - updated_datetime
        - video_caption
        - video_content_url
        - video_error
        - video_has_subtitles
        - video_playback_endpoint
        - video_ready
        - video_status
        - video_url
    LessonType56fEnum:
      enum:
        - VIDEO
        - DOCUMENT
        - TEXT
        - IMAGE
        - QUIZ
      type: string
      description: |-
        * `VIDEO` - Video
        * `DOCUMENT` - Document
        * `TEXT` - Text
        * `IMAGE` - Image
        * `QUIZ` - Quiz
    CourseSectionLessonContentMediaResponse:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        media_type:
          allOf:
            - $ref: '#/components/schemas/MediaTypeEnum'
          readOnly: true
        position:
          type: integer
          readOnly: true
        file_name:
          type: string
          readOnly: true
        content_type:
          type: string
          readOnly: true
        duration_seconds:
          type: integer
          readOnly: true
          nullable: true
        image_url:
          type: string
          readOnly: true
        video_url:
          type: string
          readOnly: true
        video_status:
          type: string
          readOnly: true
        video_ready:
          type: string
          readOnly: true
        video_error:
          type: string
          readOnly: true
        video_has_subtitles:
          type: string
          readOnly: true
        video_playback_endpoint:
          type: string
          readOnly: true
      required:
        - content_type
        - duration_seconds
        - file_name
        - id
        - image_url
        - media_type
        - position
        - video_error
        - video_has_subtitles
        - video_playback_endpoint
        - video_ready
        - video_status
        - video_url
    QuizResponse:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        lesson_id:
          type: string
          format: uuid
          readOnly: true
        lesson:
          allOf:
            - $ref: '#/components/schemas/QuizLessonSummary'
          readOnly: true
        status:
          allOf:
            - $ref: '#/components/schemas/Status0b2Enum'
          readOnly: true
        total_points:
          type: string
          format: decimal
          pattern: ^-?\d{0,8}(?:\.\d{0,2})?$
          readOnly: true
        created_datetime:
          type: string
          format: date-time
          readOnly: true
          description: datetime of object creation
        updated_datetime:
          type: string
          format: date-time
          readOnly: true
          description: datetime of object update
      required:
        - created_datetime
        - id
        - lesson
        - lesson_id
        - status
        - total_points
        - updated_datetime
    MediaTypeEnum:
      enum:
        - VIDEO
        - PROCTORING_VIDEO
        - DOCUMENT
        - IMAGE
      type: string
      description: |-
        * `VIDEO` - Video
        * `PROCTORING_VIDEO` - Proctoring Video
        * `DOCUMENT` - Document
        * `IMAGE` - Image
    QuizLessonSummary:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        title:
          type: string
          readOnly: true
        lesson_type:
          allOf:
            - $ref: '#/components/schemas/LessonType56fEnum'
          readOnly: true
        duration_seconds:
          type: integer
          readOnly: true
          nullable: true
        order:
          type: integer
          readOnly: true
        section_id:
          type: string
          format: uuid
          readOnly: true
        course_id:
          type: string
          format: uuid
          readOnly: true
      required:
        - course_id
        - duration_seconds
        - id
        - lesson_type
        - order
        - section_id
        - title
  securitySchemes:
    apiKeyAuth:
      type: apiKey
      in: header
      name: Authorization
      description: 'External API key. Format: Bearer <API_KEY>'

````