---
openapi: 3.0.1
info:
  title: Canvas Catalog API
  version: v1
  description: "Catalog JSON API Documentation\n=====================\n\nSo, you want
    to develop some tooling around the Catalog API - perhaps some custom reports?
    Great! This API gives you everything that Catalog has to offer.\n\n## Authentication\n\nVisit
    Catalog Admin API page to create an API key. Once you've received your key, **treat
    it like a password**.\n\nUse SSL for all requests to the API. Non-SSL requests
    will result in redirects, and your API key will be sent in the clear.\n\nTo authenticate,
    send the API key as a request header. Here's an example using cURL:\n\n    curl
    https://[URL]/api/v1/products -H 'Authorization: Token token=\"my-api-key\"'\n\n##
    Pagination\n\nAll index endpoints support pagination. Specifically, we implement
    [RFC5988](http://tools.ietf.org/html/rfc5988).\n\n#### Pagination Options\n\nYou
    can use ```?page=``` to set the page of data you want to retrieve. If no items
    exist for that page, the response will be a root key with an empty array.\n\n
    \   curl https://[URL]/api/v1/courses?page=2\n\n    {\n      \"courses\": []\n
    \   }\n\nTo change the number of items returned for each page, you can use ```?per_page=```.
    This defaults to 20 and has a max of 100.\n\n    curl https://[URL]/api/v1/courses?per_page=40&page=2\n\n####
    Link Headers\n\nInformation about pagination is provided in the Link header. Here
    is an example of what the header could look like\n\n    curl -I https://[URL]/api/v1/courses?page=3\n\n
    \   Link: <https://[URL]/api/v1/courses?page=4>; rel=\"next\",  \n          <https://[URL]/api/v1/courses?page=15>;
    rel=\"last\",\n          <https://[URL]/api/v1/courses?page=1>; rel=\"first\",\n
    \         <https://[URL]/api/v1/courses?page=2>; rel=\"prev\"\n\n\nLet's talk
    about what each link means. ```rel=\"next\"``` lets us know that the next page
    of data is ```page=4```. This make sense given that we requested page 3.\n```rel=\"prev\"```
    lets us know that the page previous to the one we requested is ```page=2```. ```rel=\"next\"```
    indicates the next page of data to request.\n```rel=\"last\"``` tells us the last
    and total number of pages of data that currently exist.\n\nNot all ```rel=```
    links will exist on every response. For instance, the response for the first page
    of data will not have ```rel=\"first\"``` or ```rel=\"prev\"```. The same is true
    for\nthe last page of data. This means that you can programmatically traverse
    all pages of data by requesting the first page and continuing to request the ```rel=\"next\"```
    until\nthe response does not contain a ```rel=\"next\"```.\n\nIt's important to
    note that altering the ```per_page=``` will change the total number of pages.\n\n####
    Listing Image\nIf you are uploading a product image in SVG format. You will need
    to specify the file type.\n\n    curl https://[URL]/api/v1/products -F \"course[listing_image]=@somefile.svg;type=image/svg+xml\"'"
servers:
- url: https://{domain}
  description: Your Catalog account domain
  variables:
    domain:
      default: catalog.example.edu
      description: The domain you use to access your Catalog account (e.g. catalog.your-school.edu)
components:
  securitySchemes:
    api_key:
      type: apiKey
      name: Authorization
      in: header
security:
- api_key: []
paths:
  "/api/v1/account_admins":
    get:
      summary: List account admins
      tags:
      - Account Admins
      parameters:
      - name: page
        in: query
        required: false
        schema:
          type: integer
        description: Page number (defaults to 0)
      - name: sort
        in: query
        required: false
        schema:
          type: string
        description: Sort field (only 'name')
      - name: search
        in: query
        required: false
        schema:
          type: string
        description: Search query to filter account admins
      - name: per_page
        in: query
        required: false
        schema:
          type: integer
        description: Results per page
      responses:
        '200':
          description: account admins listed
          content:
            application/json:
              schema:
                type: object
                properties:
                  content:
                    type: array
                    items:
                      type: object
                      properties:
                        user:
                          type: object
                          description: The Canvas user who is an admin
                          properties:
                            id:
                              type: integer
                              description: Catalog user id
                            canvas_user_id:
                              type: integer
                              description: Canvas user id
                            canvas_user_uuid:
                              type: string
                              description: Canvas user UUID (omitted when not available)
                            name:
                              type: string
                              description: Full name of the account admin
                            email:
                              type: string
                              description: Email address
                            profile_link:
                              type: string
                              description: Link to the user profile (omitted when
                                not available)
                            canvas_user_id_string:
                              type: string
                              description: Canvas user id as a string
                          required:
                          - id
                          - canvas_user_id
                          - name
                          - email
                          - canvas_user_id_string
                        accounts:
                          type: array
                          description: Accounts this user administers
                          items:
                            type: object
                            properties:
                              id:
                                type: integer
                              name:
                                type: string
                            required:
                            - id
                            - name
                        permissions:
                          type: array
                          description: Permission settings for this admin
                          items:
                            type: object
                            properties:
                              key:
                                type: string
                              value:
                                type: string
                            required:
                            - key
                            - value
                      required:
                      - user
                      - accounts
                      - permissions
                  total_elements:
                    type: integer
                    description: Total number of admins across all pages
                  page_number:
                    type: integer
                    description: Current page number (0-based)
                  size:
                    type: integer
                    description: Page size
                  permission_keys:
                    type: array
                    items:
                      type: string
                    description: All available permission keys
                  total_pages:
                    type: integer
                    description: Total number of pages
                required:
                - content
                - total_elements
                - page_number
                - size
                - permission_keys
                - total_pages
    post:
      summary: Create an account admin association
      tags:
      - Account Admins
      description: Creates a new account admin or adds account associations to an
        existing admin. account_ids may contain multiple account IDs.
      parameters: []
      responses:
        '201':
          description: account admin created
          content:
            application/json:
              schema:
                type: object
                properties:
                  canvas_user_id:
                    type: integer
                    description: Canvas user ID of the admin
                  account_ids:
                    type: array
                    items:
                      type: integer
                    description: Account IDs the user now administers
                required:
                - canvas_user_id
                - account_ids
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                canvas_user_id:
                  type: string
                  description: Canvas user ID
                user_name:
                  type: string
                  description: Full name of the user
                email_address:
                  type: string
                  description: Email address of the user
                account_ids:
                  type: array
                  items:
                    type: integer
                  description: Account IDs to associate with the user
              required:
              - canvas_user_id
              - user_name
              - email_address
              - account_ids
  "/api/v1/account_admins/{id}/accounts/{account_id}":
    delete:
      summary: Remove an admin from a specific account
      tags:
      - Account Admins
      description: Removes the association between a user and a specific account.
      parameters:
      - name: id
        in: path
        schema:
          type: string
        description: Canvas user ID of the admin
        required: true
      - name: account_id
        in: path
        schema:
          type: integer
        description: Account ID to remove
        required: true
      responses:
        '204':
          description: association removed
  "/api/v1/account_admins/{id}":
    delete:
      summary: Remove all account associations for an admin
      tags:
      - Account Admins
      description: Removes all account associations for the specified user.
      parameters:
      - name: id
        in: path
        schema:
          type: string
        description: Canvas user ID of the admin
        required: true
      responses:
        '204':
          description: all associations removed
  "/api/v1/analytics/products":
    post:
      summary: Get products analytics
      tags:
      - Analytics
      parameters: []
      responses:
        '200':
          description: product analytics rows
          content:
            application/json:
              schema:
                type: object
                properties:
                  products:
                    type: array
                    items:
                      type: object
                      properties:
                        account_id:
                          type: integer
                          description: Sub-account id
                        account_name:
                          type: string
                        product:
                          type: object
                          description: The listing
                          properties:
                            name:
                              type: string
                            id:
                              type: integer
                            url:
                              type: string
                            sku:
                              type: string
                              nullable: true
                          required:
                          - id
                        product_status:
                          type: string
                        created_at:
                          type: string
                        canvas_course_id:
                          type: integer
                        canvas_section_id:
                          type: integer
                        enrollment_count:
                          type: integer
                        dropped_count:
                          type: integer
                        completion_count:
                          type: integer
                        currency:
                          type: string
                        list_price:
                          type: number
                          description: Listing price
                        promo_codes:
                          type: array
                          items:
                            type: string
                        discount:
                          type: number
                        revenue:
                          type: number
                          description: Total revenue for this listing
                        credits:
                          type: number
                        certificate_offered:
                          type: boolean
                        instructor_names:
                          type: array
                          items:
                            type: string
                        primary_instructor_name:
                          type: string
                        archived_at:
                          type: string
                          nullable: true
                        total_rows:
                          type: integer
                          description: Total number of matching rows (pagination total)
                      required:
                      - account_id
                      - product
                      - created_at
                      - enrollment_count
                      - dropped_count
                      - completion_count
                      - list_price
                      - promo_codes
                      - discount
                      - revenue
                      - certificate_offered
                required:
                - products
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                account_ids:
                  type: array
                  items:
                    type: integer
                  description: Restrict to these account ids
                product_ids:
                  type: array
                  items:
                    type: integer
                  description: Restrict to these product ids
                product_statuses:
                  type: array
                  items:
                    type: string
                    enum:
                    - OPEN
                    - CLOSED
                    - ARCHIVED
                    - DELETED
                promo_codes:
                  type: array
                  items:
                    type: string
                    enum:
                    - APPLIED
                    - NOT_APPLIED
                creation_date_from:
                  type: string
                  format: date-time
                creation_date_to:
                  type: string
                  format: date-time
                enrollment_count_min:
                  type: integer
                enrollment_count_max:
                  type: integer
                completion_count_min:
                  type: integer
                completion_count_max:
                  type: integer
                dropped_count_min:
                  type: integer
                dropped_count_max:
                  type: integer
                listing_price_min:
                  type: number
                listing_price_max:
                  type: number
                revenue_min:
                  type: number
                revenue_max:
                  type: number
                certificate_offered:
                  type: boolean
  "/api/v1/analytics/enrollments":
    post:
      summary: Get enrollments analytics
      tags:
      - Analytics
      parameters: []
      responses:
        '200':
          description: enrollment analytics rows
          content:
            application/json:
              schema:
                type: object
                properties:
                  enrollments:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                        account_id:
                          type: integer
                        account_name:
                          type: string
                        product:
                          type: object
                          description: The listing
                          properties:
                            name:
                              type: string
                            id:
                              type: integer
                            url:
                              type: string
                            sku:
                              type: string
                              nullable: true
                          required:
                          - id
                        product_status:
                          type: string
                        canvas_course_id:
                          type: integer
                        canvas_section_id:
                          type: integer
                        student:
                          type: object
                          properties:
                            canvas_user_id:
                              type: integer
                            name:
                              type: string
                            email:
                              type: string
                            canvas_user_id_string:
                              type: string
                        requirement_count:
                          type: integer
                        requirement_completed_count:
                          type: integer
                        requirement_completed_percentage:
                          type: integer
                        created_at:
                          type: string
                        completed_at:
                          type: string
                          nullable: true
                        enrollment_status:
                          type: string
                          description: ACTIVE, COMPLETED, DROPPED or CONCLUDED
                        certificate_attainable:
                          type: boolean
                        certificate_offered:
                          type: boolean
                        custom_fields:
                          type: array
                          description: User-defined field values
                          items:
                            type: object
                            properties:
                              key:
                                type: string
                              value:
                                type: string
                        certificate_url:
                          type: string
                          nullable: true
                        archived_at:
                          type: string
                          nullable: true
                        total_rows:
                          type: integer
                          description: Total number of matching rows (pagination total)
                      required:
                      - id
                      - account_id
                      - product
                      - created_at
                      - certificate_attainable
                      - certificate_offered
                      - custom_fields
                required:
                - enrollments
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                account_ids:
                  type: array
                  items:
                    type: integer
                  description: Restrict to these account ids
                product_ids:
                  type: array
                  items:
                    type: integer
                  description: Restrict to these product ids
                product_statuses:
                  type: array
                  items:
                    type: string
                    enum:
                    - OPEN
                    - CLOSED
                    - ARCHIVED
                    - DELETED
                promo_codes:
                  type: array
                  items:
                    type: string
                    enum:
                    - APPLIED
                    - NOT_APPLIED
                student_ids:
                  type: array
                  items:
                    type: integer
                student_canvas_user_ids:
                  type: array
                  items:
                    type: integer
                enrollment_date_from:
                  type: string
                  format: date-time
                enrollment_date_to:
                  type: string
                  format: date-time
                enrollment_statuses:
                  type: array
                  items:
                    type: string
                    enum:
                    - ACTIVE
                    - COMPLETED
                    - DROPPED
                    - CONCLUDED
                completion_date_from:
                  type: string
                  format: date-time
                completion_date_to:
                  type: string
                  format: date-time
  "/api/v1/analytics/orders":
    post:
      summary: Get orders analytics
      tags:
      - Analytics
      parameters: []
      responses:
        '200':
          description: order analytics rows
          content:
            application/json:
              schema:
                type: object
                properties:
                  orders:
                    type: array
                    items:
                      type: object
                      properties:
                        account_id:
                          type: integer
                        account_name:
                          type: string
                        product:
                          type: object
                          description: The listing
                          properties:
                            name:
                              type: string
                            id:
                              type: integer
                            url:
                              type: string
                            sku:
                              type: string
                              nullable: true
                          required:
                          - id
                        product_status:
                          type: string
                        canvas_course_id:
                          type: integer
                        canvas_section_id:
                          type: integer
                        purchaser:
                          type: object
                          properties:
                            id:
                              type: integer
                            canvas_user_id:
                              type: integer
                            name:
                              type: string
                            email:
                              type: string
                            canvas_user_id_string:
                              type: string
                        purchased_at:
                          type: string
                        order_id:
                          type: integer
                        order_item_id:
                          type: integer
                        reference_id:
                          type: string
                        list_price:
                          type: number
                        currency:
                          type: string
                        promo_codes:
                          type: array
                          items:
                            type: string
                        discount:
                          type: number
                        revenue:
                          type: number
                        bulk_purchase:
                          type: boolean
                        seat_count:
                          type: integer
                        bulk_enrollments:
                          type: array
                          description: Seats invited for a bulk purchase
                          items:
                            type: object
                            properties:
                              id:
                                type: integer
                              canvas_user_id:
                                type: integer
                              name:
                                type: string
                              email:
                                type: string
                              canvas_user_id_string:
                                type: string
                        last_modification_date:
                          type: string
                          nullable: true
                        revenue_change_history:
                          type: array
                          description: Audit trail of revenue changes
                          items:
                            type: object
                            properties:
                              modification_date:
                                type: string
                              new_value:
                                type: number
                              new_value_currency:
                                type: string
                              old_value:
                                type: number
                              old_value_currency:
                                type: string
                              reason:
                                type: string
                              user_name:
                                type: string
                              user_profile_link:
                                type: string
                        total_rows:
                          type: integer
                          description: Total number of matching rows (pagination total)
                      required:
                      - account_id
                      - product
                      - purchased_at
                      - order_id
                      - order_item_id
                      - promo_codes
                      - bulk_purchase
                      - revenue_change_history
                required:
                - orders
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                account_ids:
                  type: array
                  items:
                    type: integer
                  description: Restrict to these account ids
                product_ids:
                  type: array
                  items:
                    type: integer
                  description: Restrict to these product ids
                product_statuses:
                  type: array
                  items:
                    type: string
                    enum:
                    - OPEN
                    - CLOSED
                    - ARCHIVED
                    - DELETED
                promo_codes:
                  type: array
                  items:
                    type: string
                    enum:
                    - APPLIED
                    - NOT_APPLIED
                student_ids:
                  type: array
                  items:
                    type: integer
                student_canvas_user_ids:
                  type: array
                  items:
                    type: integer
                purchaser_ids:
                  type: array
                  items:
                    type: integer
                purchaser_canvas_user_ids:
                  type: array
                  items:
                    type: integer
                bulk_purchases_only:
                  type: boolean
                purchase_date_from:
                  type: string
                  format: date-time
                purchase_date_to:
                  type: string
                  format: date-time
                order_fee:
                  type: number
                listing_price_min:
                  type: number
                listing_price_max:
                  type: number
                revenue_min:
                  type: number
                revenue_max:
                  type: number
  "/api/v1/analytics/users":
    post:
      summary: Get users analytics
      tags:
      - Analytics
      parameters: []
      responses:
        '200':
          description: user analytics rows
          content:
            application/json:
              schema:
                type: object
                properties:
                  users:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                        canvas_user_id:
                          type: integer
                        name:
                          type: string
                        email:
                          type: string
                        account_id:
                          type: integer
                        account_name:
                          type: string
                        registered_through:
                          type: string
                          description: CANVAS or CATALOG
                        registered_at:
                          type: string
                        enrollment_count:
                          type: integer
                        last_enrolled_at:
                          type: string
                          nullable: true
                        custom_fields:
                          type: array
                          description: User-defined field values
                          items:
                            type: object
                            properties:
                              key:
                                type: string
                              value:
                                type: string
                        total_rows:
                          type: integer
                          description: Total number of matching rows (pagination total)
                      required:
                      - id
                      - canvas_user_id
                      - registered_through
                      - registered_at
                      - enrollment_count
                      - custom_fields
                required:
                - users
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                account_ids:
                  type: array
                  items:
                    type: integer
                  description: Restrict to these account ids
                product_ids:
                  type: array
                  items:
                    type: integer
                  description: Restrict to these product ids
                product_statuses:
                  type: array
                  items:
                    type: string
                    enum:
                    - OPEN
                    - CLOSED
                    - ARCHIVED
                    - DELETED
                promo_codes:
                  type: array
                  items:
                    type: string
                    enum:
                    - APPLIED
                    - NOT_APPLIED
                student_ids:
                  type: array
                  items:
                    type: integer
                student_canvas_user_ids:
                  type: array
                  items:
                    type: integer
                enrollment_count_min:
                  type: integer
                enrollment_count_max:
                  type: integer
                last_enrollment_date_from:
                  type: string
                  format: date-time
                last_enrollment_date_to:
                  type: string
                  format: date-time
                registration_date_from:
                  type: string
                  format: date-time
                registration_date_to:
                  type: string
                  format: date-time
                registered_through:
                  type: array
                  items:
                    type: string
                    enum:
                    - CANVAS
                    - CATALOG
  "/api/v1/applicants/{id}":
    get:
      summary: Get a specific applicant record
      tags:
      - Waitlist applicants
      parameters:
      - name: id
        in: path
        schema:
          type: integer
        description: Identifier for this applicant
        required: true
      responses:
        '200':
          description: applicant found
          content:
            application/json:
              schema:
                type: object
                properties:
                  applicant:
                    type: object
                    properties:
                      id:
                        type: integer
                        description: Identifier for this applicant
                      user:
                        type: object
                        description: The applicant user
                        properties:
                          id:
                            type: integer
                            description: User ID
                          name:
                            type: string
                            description: Full name
                          email:
                            type: string
                            description: E-mail address
                        required:
                        - id
                        - name
                        - email
                      listing:
                        type: object
                        description: The waitlisted listing
                        properties:
                          id:
                            type: integer
                            description: Identifier for listing
                          title:
                            type: string
                            description: Listing title
                        required:
                        - id
                        - title
                      notified_of_opening_at:
                        type: string
                        nullable: true
                        description: Time the user was notified of an opening
                      status:
                        type: string
                        description: 'Status: waitlist, accepted, expired, or error'
                      created_at:
                        type: string
                        description: Creation timestamp (ISO 8601)
                      updated_at:
                        type: string
                        description: Last-updated timestamp (ISO 8601)
                    required:
                    - id
                    - user
                    - listing
                    - notified_of_opening_at
                    - status
                    - created_at
                    - updated_at
                required:
                - applicant
  "/api/v1/applicants":
    get:
      summary: List applicants
      tags:
      - Waitlist applicants
      parameters:
      - name: listing_id
        in: query
        required: false
        schema:
          type: integer
        description: Only include applicants for the specified listing
      - name: status
        in: query
        required: false
        schema:
          type: string
        description: Only include applicants with the specified status (waitlist,
          accepted, declined, or expired)
      responses:
        '200':
          description: applicants listed
          content:
            application/json:
              schema:
                type: object
                properties:
                  applicants:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                          description: Identifier for this applicant
                        user:
                          type: object
                          description: The applicant user
                          properties:
                            id:
                              type: integer
                              description: User ID
                            name:
                              type: string
                              description: Full name
                            email:
                              type: string
                              description: E-mail address
                          required:
                          - id
                          - name
                          - email
                        listing:
                          type: object
                          description: The waitlisted listing
                          properties:
                            id:
                              type: integer
                              description: Identifier for listing
                            title:
                              type: string
                              description: Listing title
                          required:
                          - id
                          - title
                        notified_of_opening_at:
                          type: string
                          nullable: true
                          description: Time the user was notified of an opening
                        status:
                          type: string
                          description: 'Status: waitlist, accepted, expired, or error'
                        created_at:
                          type: string
                          description: Creation timestamp (ISO 8601)
                        updated_at:
                          type: string
                          description: Last-updated timestamp (ISO 8601)
                      required:
                      - id
                      - user
                      - listing
                      - notified_of_opening_at
                      - status
                      - created_at
                      - updated_at
                required:
                - applicants
    delete:
      summary: Delete applicants
      tags:
      - Waitlist applicants
      parameters:
      - name: listing_id
        in: query
        required: true
        schema:
          type: integer
        description: Only delete applicants for the specified listing
      - name: canvas_user_id
        in: query
        required: false
        schema:
          type: integer
        description: Only delete applicants with the specified Canvas user ID
      responses:
        '204':
          description: applicants deleted
  "/api/v1/order_items/history/bulk_enrollments/{id}":
    get:
      summary: Get a specific bulk enrollment
      tags:
      - Bulk enrollments
      parameters:
      - name: id
        in: path
        schema:
          type: integer
        description: Order ID
        required: true
      responses:
        '200':
          description: bulk enrollment found
          content:
            application/json:
              schema:
                type: object
                properties:
                  bulk_purchase:
                    type: object
                    properties:
                      order:
                        type: object
                        properties:
                          id:
                            type: integer
                          created_at:
                            type: string
                          updated_at:
                            type: string
                          full_id:
                            type: string
                          account_id:
                            type: integer
                          user_id:
                            type: integer
                          canvas_user_id:
                            type: integer
                          canvas_root_account_uuid:
                            type: string
                          source:
                            type: string
                          currency:
                            type: string
                          purchased_at:
                            type: string
                          total:
                            type: number
                            description: Order total (decimal)
                          email:
                            type: string
                          name:
                            type: string
                          items:
                            type: array
                            items:
                              type: object
                              properties:
                                id:
                                  type: integer
                                created_at:
                                  type: string
                                updated_at:
                                  type: string
                                order_id:
                                  type: integer
                                item_id:
                                  type: integer
                                amount:
                                  type: number
                                canvas_root_account_uuid:
                                  type: string
                                discounted_amount:
                                  type: number
                                quantity:
                                  type: integer
                                unit_price:
                                  type: number
                              required:
                              - id
                              - created_at
                              - updated_at
                        required:
                        - id
                        - created_at
                        - updated_at
                        - items
                      product:
                        type: object
                        properties:
                          id:
                            type: integer
                          visibility:
                            type: string
                          enrollment_open:
                            type: boolean
                          title:
                            type: string
                          enrollment_fee:
                            type: number
                            description: Enrollment fee (decimal)
                          account_id:
                            type: integer
                          type:
                            type: string
                          canvas_root_account_uuid:
                            type: string
                          waitlist:
                            type: boolean
                          limited:
                            type: boolean
                          started:
                            type: boolean
                          program:
                            type: boolean
                          course:
                            type: boolean
                          ended:
                            type: boolean
                          days_to_complete:
                            type: integer
                            nullable: true
                          enrollment_cap:
                            type: integer
                            nullable: true
                        required:
                        - id
                        - enrollment_open
                        - enrollment_fee
                        - waitlist
                        - limited
                        - started
                        - ended
                      bulk_invitations:
                        type: array
                        items:
                          type: object
                          properties:
                            order_item_id:
                              type: integer
                            invitation_id:
                              type: integer
                            status:
                              type: string
                              description: Invitation status
                          required:
                          - invitation_id
                    required:
                    - order
                    - bulk_invitations
                required:
                - bulk_purchase
  "/api/v1/order_items/history/bulk_enrollments":
    get:
      summary: List bulk enrollments
      tags:
      - Bulk enrollments
      parameters:
      - name: from
        in: query
        required: false
        schema:
          type: string
          format: date-time
        description: Only include bulk enrollments from this date
      - name: to
        in: query
        required: false
        schema:
          type: string
          format: date-time
        description: Only include bulk enrollments to this date
      - name: canvas_user_ids
        in: query
        required: false
        schema:
          type: array
          items:
            type: integer
        description: Only include bulk enrollments for the specified Canvas user IDs
      responses:
        '200':
          description: bulk enrollments listed
          content:
            application/json:
              schema:
                type: object
                properties:
                  bulk_enrollments:
                    type: array
                    items:
                      type: object
                      properties:
                        bulk_purchase:
                          type: object
                          properties:
                            order:
                              type: object
                              properties:
                                id:
                                  type: integer
                                created_at:
                                  type: string
                                updated_at:
                                  type: string
                                full_id:
                                  type: string
                                account_id:
                                  type: integer
                                user_id:
                                  type: integer
                                canvas_user_id:
                                  type: integer
                                canvas_root_account_uuid:
                                  type: string
                                source:
                                  type: string
                                currency:
                                  type: string
                                purchased_at:
                                  type: string
                                total:
                                  type: number
                                  description: Order total (decimal)
                                email:
                                  type: string
                                name:
                                  type: string
                                items:
                                  type: array
                                  items:
                                    type: object
                                    properties:
                                      id:
                                        type: integer
                                      created_at:
                                        type: string
                                      updated_at:
                                        type: string
                                      order_id:
                                        type: integer
                                      item_id:
                                        type: integer
                                      amount:
                                        type: number
                                      canvas_root_account_uuid:
                                        type: string
                                      discounted_amount:
                                        type: number
                                      quantity:
                                        type: integer
                                      unit_price:
                                        type: number
                                    required:
                                    - id
                                    - created_at
                                    - updated_at
                              required:
                              - id
                              - created_at
                              - updated_at
                              - items
                            product:
                              type: object
                              properties:
                                id:
                                  type: integer
                                visibility:
                                  type: string
                                enrollment_open:
                                  type: boolean
                                title:
                                  type: string
                                enrollment_fee:
                                  type: number
                                  description: Enrollment fee (decimal)
                                account_id:
                                  type: integer
                                type:
                                  type: string
                                canvas_root_account_uuid:
                                  type: string
                                waitlist:
                                  type: boolean
                                limited:
                                  type: boolean
                                started:
                                  type: boolean
                                program:
                                  type: boolean
                                course:
                                  type: boolean
                                ended:
                                  type: boolean
                                days_to_complete:
                                  type: integer
                                  nullable: true
                                enrollment_cap:
                                  type: integer
                                  nullable: true
                              required:
                              - id
                              - enrollment_open
                              - enrollment_fee
                              - waitlist
                              - limited
                              - started
                              - ended
                            bulk_invitations:
                              type: array
                              items:
                                type: object
                                properties:
                                  order_item_id:
                                    type: integer
                                  invitation_id:
                                    type: integer
                                  status:
                                    type: string
                                    description: Invitation status
                                required:
                                - invitation_id
                          required:
                          - order
                          - bulk_invitations
                      required:
                      - bulk_purchase
                required:
                - bulk_enrollments
  "/api/v1/catalogs":
    get:
      summary: List catalogs
      tags:
      - Catalogs
      responses:
        '200':
          description: catalogs listed
          content:
            application/json:
              schema:
                type: object
                required:
                - catalogs
                properties:
                  catalogs:
                    type: array
                    items:
                      type: object
                      required:
                      - id
                      - name
                      - parent
                      - created_at
                      - updated_at
                      - canvas_domain
                      - canvas_id
                      - settings
                      - user_defined_fields
                      - logo
                      - locale
                      - url
                      - measurement
                      - storefront_theme_id
                      properties:
                        id:
                          type: integer
                          description: Identifier for this catalog
                        name:
                          type: string
                          description: The name of the catalog
                        parent:
                          type: object
                          nullable: true
                          description: Parent catalog (id and name), or null for a
                            root catalog
                          properties:
                            id:
                              type: integer
                            name:
                              type: string
                          required:
                          - id
                          - name
                        created_at:
                          type: string
                          description: Creation timestamp (ISO 8601)
                        updated_at:
                          type: string
                          description: Last-updated timestamp (ISO 8601)
                        canvas_domain:
                          type: string
                          description: Domain of the corresponding Canvas account
                        canvas_id:
                          type: integer
                          description: Id of the corresponding Canvas account
                        settings:
                          type: object
                          description: Catalog settings (inherited from ancestors
                            unless overridden)
                          required:
                          - privacy_policy_url
                          - terms_url
                          - currency
                          - supported_payment_types
                          - time_zone
                          - country
                          - measurement
                          - email_from_name
                          - email_from_address
                          - allow_user_registration
                          - title_tag
                          - meta_description
                          - custom_head_content
                          - custom_body_content
                          - show_listings_in_parent
                          - order_id_prefix
                          - inherit_categories
                          - inherit_user_defined_fields
                          - inherit_purchase_order_institution_details
                          - beta_canvas_domain
                          - skus_enabled
                          - canvas_enrollment_events
                          - include_noncatalog_courses_in_dashboard
                          - external_idp_logout_workflow
                          - private_catalog
                          - bulk_purchase_disabled
                          - enroll_button_behavior
                          - external_registration_url
                          - external_registration_public_key
                          - redirect_external_registration_condition
                          - include_captcha
                          - user_registration_domain_restriction_type
                          - user_registration_domain_deny_list
                          - user_registration_domain_allow_list
                          - restrict_enrollment_to_user_registration_domain
                          - frame_ancestors
                          - email_reply_to
                          - has_sso_warning
                          - measurement_id
                          - redirect_non_admins_to_root_url
                          - canvas_feature_send_usage_metrics
                          - disable_passive_login
                          - new_storefront
                          - tags_permission_default_value
                          - cross_listing_permission_default_value
                          - inherit_storefront_theme
                          - canvas_authentication_provider_id
                          - udf_collection_level
                          - disable_drop_course_button
                          - google_tag_manager_id
                          - linkedin_partner_id
                          - enable_credentials
                          - enable_impact
                          - enable_pathways
                          - hide_missing_pathway
                          - storefront_product_recommendation_behavior
                          - storefront_product_recommendation_count
                          - enable_recommendations
                          - product_page_recommendation_fallback
                          - product_page_recommendation_count
                          - enable_recommendations_for_product_page
                          - hide_self_paced_label
                          - login_auth_providers
                          - multiple_promo_codes_enabled
                          - custom_instructor_label
                          - custom_instructor_label_plural
                          - purchase_seats_for_others_enabled
                          - hide_no_badges_text
                          - load_custom_scripts
                          - enable_purchase_orders
                          properties:
                            privacy_policy_url:
                              type: string
                            terms_url:
                              type: string
                            currency:
                              type: string
                              description: Three-character ISO currency code
                            supported_payment_types:
                              type: string
                            time_zone:
                              type: string
                              nullable: true
                            country:
                              type: string
                              description: Two-character ISO country code
                            measurement:
                              type: string
                            email_from_name:
                              type: string
                              description: Sender name on outgoing emails
                            email_from_address:
                              type: string
                            allow_user_registration:
                              type: boolean
                              description: Whether new users may self-register
                            title_tag:
                              type: string
                              nullable: true
                            meta_description:
                              type: string
                              nullable: true
                            custom_head_content:
                              type: string
                              nullable: true
                            custom_body_content:
                              type: string
                              nullable: true
                            show_listings_in_parent:
                              type: boolean
                            order_id_prefix:
                              type: string
                              nullable: true
                            inherit_categories:
                              type: boolean
                              description: Inherit categories from the parent catalog
                            inherit_user_defined_fields:
                              type: boolean
                              description: Inherit user-defined fields from the parent
                                catalog
                            inherit_purchase_order_institution_details:
                              type: boolean
                            beta_canvas_domain:
                              type: string
                              nullable: true
                            skus_enabled:
                              type: boolean
                            canvas_enrollment_events:
                              type: boolean
                            include_noncatalog_courses_in_dashboard:
                              type: boolean
                            external_idp_logout_workflow:
                              type: boolean
                            private_catalog:
                              type: boolean
                            bulk_purchase_disabled:
                              type: boolean
                            enroll_button_behavior:
                              type: string
                            external_registration_url:
                              type: string
                              nullable: true
                            external_registration_public_key:
                              type: string
                              nullable: true
                            redirect_external_registration_condition:
                              type: string
                            include_captcha:
                              type: boolean
                            user_registration_domain_restriction_type:
                              type: string
                            user_registration_domain_deny_list:
                              type: string
                            user_registration_domain_allow_list:
                              type: string
                            restrict_enrollment_to_user_registration_domain:
                              type: boolean
                            frame_ancestors:
                              type: string
                            email_reply_to:
                              type: string
                            has_sso_warning:
                              type: boolean
                            measurement_id:
                              type: string
                              nullable: true
                            redirect_non_admins_to_root_url:
                              type: boolean
                            canvas_feature_send_usage_metrics:
                              type: boolean
                            disable_passive_login:
                              type: boolean
                            new_storefront:
                              type: boolean
                            tags_permission_default_value:
                              type: boolean
                            cross_listing_permission_default_value:
                              type: boolean
                            inherit_storefront_theme:
                              type: boolean
                            canvas_authentication_provider_id:
                              type: string
                            udf_collection_level:
                              type: string
                            disable_drop_course_button:
                              type: boolean
                            google_tag_manager_id:
                              type: string
                              nullable: true
                            linkedin_partner_id:
                              type: string
                              nullable: true
                            enable_credentials:
                              type: boolean
                            enable_impact:
                              type: boolean
                            enable_pathways:
                              type: boolean
                            hide_missing_pathway:
                              type: boolean
                            storefront_product_recommendation_behavior:
                              type: string
                            storefront_product_recommendation_count:
                              type: integer
                            enable_recommendations:
                              type: boolean
                            product_page_recommendation_fallback:
                              type: string
                            product_page_recommendation_count:
                              type: integer
                            enable_recommendations_for_product_page:
                              type: boolean
                            hide_self_paced_label:
                              type: boolean
                            login_auth_providers:
                              type: string
                            multiple_promo_codes_enabled:
                              type: boolean
                            custom_instructor_label:
                              type: string
                              nullable: true
                            custom_instructor_label_plural:
                              type: string
                              nullable: true
                            purchase_seats_for_others_enabled:
                              type: boolean
                            hide_no_badges_text:
                              type: boolean
                            load_custom_scripts:
                              type: boolean
                            enable_purchase_orders:
                              type: boolean
                        user_defined_fields:
                          type: array
                          description: Custom fields collected from users, by direct
                            assignment or inheritance
                          items:
                            type: object
                            required:
                            - list_order
                            - name
                            - label
                            - field_type
                            - required
                            - required_message
                            - metadata
                            - hide_in_user_workflow
                            properties:
                              list_order:
                                type: integer
                                description: Display order
                              name:
                                type: string
                                description: Field name
                              label:
                                type: string
                                description: Label shown to the user
                              field_type:
                                type: string
                                description: HTML input type
                              required:
                                type: boolean
                                description: Whether the field is required
                              required_message:
                                type: string
                              metadata:
                                type: object
                                description: Field-type-specific metadata (e.g. options
                                  for dropdown fields)
                              hide_in_user_workflow:
                                type: boolean
                        logo:
                          type: string
                          nullable: true
                          description: URL of the catalog logo
                        locale:
                          type: string
                          description: Three-character locale for the catalog
                        url:
                          type: string
                          description: Public URL of the catalog
                        measurement:
                          type: string
                        storefront_theme_id:
                          type: string
                          nullable: true
  "/api/v1/catalogs/{id}":
    get:
      summary: Get a specific catalog
      tags:
      - Catalogs
      parameters:
      - name: id
        in: path
        schema:
          type: integer
        description: Identifier for this catalog
        required: true
      responses:
        '200':
          description: catalog found
          content:
            application/json:
              schema:
                type: object
                required:
                - account
                properties:
                  account:
                    type: object
                    required:
                    - id
                    - name
                    - parent
                    - created_at
                    - updated_at
                    - canvas_domain
                    - canvas_id
                    - settings
                    - user_defined_fields
                    - logo
                    - locale
                    - url
                    - measurement
                    - storefront_theme_id
                    properties:
                      id:
                        type: integer
                        description: Identifier for this catalog
                      name:
                        type: string
                        description: The name of the catalog
                      parent:
                        type: object
                        nullable: true
                        description: Parent catalog (id and name), or null for a root
                          catalog
                        properties:
                          id:
                            type: integer
                          name:
                            type: string
                        required:
                        - id
                        - name
                      created_at:
                        type: string
                        description: Creation timestamp (ISO 8601)
                      updated_at:
                        type: string
                        description: Last-updated timestamp (ISO 8601)
                      canvas_domain:
                        type: string
                        description: Domain of the corresponding Canvas account
                      canvas_id:
                        type: integer
                        description: Id of the corresponding Canvas account
                      settings:
                        type: object
                        description: Catalog settings (inherited from ancestors unless
                          overridden)
                        required:
                        - privacy_policy_url
                        - terms_url
                        - currency
                        - supported_payment_types
                        - time_zone
                        - country
                        - measurement
                        - email_from_name
                        - email_from_address
                        - allow_user_registration
                        - title_tag
                        - meta_description
                        - custom_head_content
                        - custom_body_content
                        - show_listings_in_parent
                        - order_id_prefix
                        - inherit_categories
                        - inherit_user_defined_fields
                        - inherit_purchase_order_institution_details
                        - beta_canvas_domain
                        - skus_enabled
                        - canvas_enrollment_events
                        - include_noncatalog_courses_in_dashboard
                        - external_idp_logout_workflow
                        - private_catalog
                        - bulk_purchase_disabled
                        - enroll_button_behavior
                        - external_registration_url
                        - external_registration_public_key
                        - redirect_external_registration_condition
                        - include_captcha
                        - user_registration_domain_restriction_type
                        - user_registration_domain_deny_list
                        - user_registration_domain_allow_list
                        - restrict_enrollment_to_user_registration_domain
                        - frame_ancestors
                        - email_reply_to
                        - has_sso_warning
                        - measurement_id
                        - redirect_non_admins_to_root_url
                        - canvas_feature_send_usage_metrics
                        - disable_passive_login
                        - new_storefront
                        - tags_permission_default_value
                        - cross_listing_permission_default_value
                        - inherit_storefront_theme
                        - canvas_authentication_provider_id
                        - udf_collection_level
                        - disable_drop_course_button
                        - google_tag_manager_id
                        - linkedin_partner_id
                        - enable_credentials
                        - enable_impact
                        - enable_pathways
                        - hide_missing_pathway
                        - storefront_product_recommendation_behavior
                        - storefront_product_recommendation_count
                        - enable_recommendations
                        - product_page_recommendation_fallback
                        - product_page_recommendation_count
                        - enable_recommendations_for_product_page
                        - hide_self_paced_label
                        - login_auth_providers
                        - multiple_promo_codes_enabled
                        - custom_instructor_label
                        - custom_instructor_label_plural
                        - purchase_seats_for_others_enabled
                        - hide_no_badges_text
                        - load_custom_scripts
                        - enable_purchase_orders
                        properties:
                          privacy_policy_url:
                            type: string
                          terms_url:
                            type: string
                          currency:
                            type: string
                            description: Three-character ISO currency code
                          supported_payment_types:
                            type: string
                          time_zone:
                            type: string
                            nullable: true
                          country:
                            type: string
                            description: Two-character ISO country code
                          measurement:
                            type: string
                          email_from_name:
                            type: string
                            description: Sender name on outgoing emails
                          email_from_address:
                            type: string
                          allow_user_registration:
                            type: boolean
                            description: Whether new users may self-register
                          title_tag:
                            type: string
                            nullable: true
                          meta_description:
                            type: string
                            nullable: true
                          custom_head_content:
                            type: string
                            nullable: true
                          custom_body_content:
                            type: string
                            nullable: true
                          show_listings_in_parent:
                            type: boolean
                          order_id_prefix:
                            type: string
                            nullable: true
                          inherit_categories:
                            type: boolean
                            description: Inherit categories from the parent catalog
                          inherit_user_defined_fields:
                            type: boolean
                            description: Inherit user-defined fields from the parent
                              catalog
                          inherit_purchase_order_institution_details:
                            type: boolean
                          beta_canvas_domain:
                            type: string
                            nullable: true
                          skus_enabled:
                            type: boolean
                          canvas_enrollment_events:
                            type: boolean
                          include_noncatalog_courses_in_dashboard:
                            type: boolean
                          external_idp_logout_workflow:
                            type: boolean
                          private_catalog:
                            type: boolean
                          bulk_purchase_disabled:
                            type: boolean
                          enroll_button_behavior:
                            type: string
                          external_registration_url:
                            type: string
                            nullable: true
                          external_registration_public_key:
                            type: string
                            nullable: true
                          redirect_external_registration_condition:
                            type: string
                          include_captcha:
                            type: boolean
                          user_registration_domain_restriction_type:
                            type: string
                          user_registration_domain_deny_list:
                            type: string
                          user_registration_domain_allow_list:
                            type: string
                          restrict_enrollment_to_user_registration_domain:
                            type: boolean
                          frame_ancestors:
                            type: string
                          email_reply_to:
                            type: string
                          has_sso_warning:
                            type: boolean
                          measurement_id:
                            type: string
                            nullable: true
                          redirect_non_admins_to_root_url:
                            type: boolean
                          canvas_feature_send_usage_metrics:
                            type: boolean
                          disable_passive_login:
                            type: boolean
                          new_storefront:
                            type: boolean
                          tags_permission_default_value:
                            type: boolean
                          cross_listing_permission_default_value:
                            type: boolean
                          inherit_storefront_theme:
                            type: boolean
                          canvas_authentication_provider_id:
                            type: string
                          udf_collection_level:
                            type: string
                          disable_drop_course_button:
                            type: boolean
                          google_tag_manager_id:
                            type: string
                            nullable: true
                          linkedin_partner_id:
                            type: string
                            nullable: true
                          enable_credentials:
                            type: boolean
                          enable_impact:
                            type: boolean
                          enable_pathways:
                            type: boolean
                          hide_missing_pathway:
                            type: boolean
                          storefront_product_recommendation_behavior:
                            type: string
                          storefront_product_recommendation_count:
                            type: integer
                          enable_recommendations:
                            type: boolean
                          product_page_recommendation_fallback:
                            type: string
                          product_page_recommendation_count:
                            type: integer
                          enable_recommendations_for_product_page:
                            type: boolean
                          hide_self_paced_label:
                            type: boolean
                          login_auth_providers:
                            type: string
                          multiple_promo_codes_enabled:
                            type: boolean
                          custom_instructor_label:
                            type: string
                            nullable: true
                          custom_instructor_label_plural:
                            type: string
                            nullable: true
                          purchase_seats_for_others_enabled:
                            type: boolean
                          hide_no_badges_text:
                            type: boolean
                          load_custom_scripts:
                            type: boolean
                          enable_purchase_orders:
                            type: boolean
                      user_defined_fields:
                        type: array
                        description: Custom fields collected from users, by direct
                          assignment or inheritance
                        items:
                          type: object
                          required:
                          - list_order
                          - name
                          - label
                          - field_type
                          - required
                          - required_message
                          - metadata
                          - hide_in_user_workflow
                          properties:
                            list_order:
                              type: integer
                              description: Display order
                            name:
                              type: string
                              description: Field name
                            label:
                              type: string
                              description: Label shown to the user
                            field_type:
                              type: string
                              description: HTML input type
                            required:
                              type: boolean
                              description: Whether the field is required
                            required_message:
                              type: string
                            metadata:
                              type: object
                              description: Field-type-specific metadata (e.g. options
                                for dropdown fields)
                            hide_in_user_workflow:
                              type: boolean
                      logo:
                        type: string
                        nullable: true
                        description: URL of the catalog logo
                      locale:
                        type: string
                        description: Three-character locale for the catalog
                      url:
                        type: string
                        description: Public URL of the catalog
                      measurement:
                        type: string
                      storefront_theme_id:
                        type: string
                        nullable: true
  "/api/v1/certificates":
    get:
      summary: Get a listing certificate
      tags:
      - Certificates
      parameters:
      - name: certificate[listing_id]
        in: query
        required: true
        schema:
          type: integer
        description: Id of the listing
      responses:
        '200':
          description: certificate found
          content:
            application/json:
              schema:
                type: object
                properties:
                  certificate:
                    type: object
                    properties:
                      id:
                        type: integer
                        description: Certificate ID
                      listing_id:
                        type: integer
                        description: Corresponding listing ID
                      name:
                        type: string
                        description: Certificate name
                      active:
                        type: boolean
                        description: Whether the certificate is enabled
                      template:
                        type: string
                        description: HTML template used to generate issued certificates
                      pdf_settings:
                        type: object
                        description: Extra params for PDF generation
                        properties:
                          orientation:
                            type: string
                            description: "'Landscape' or 'Portrait'"
                      created_at:
                        type: string
                        description: Creation timestamp (ISO 8601)
                      updated_at:
                        type: string
                        description: Last-updated timestamp (ISO 8601)
                      days_to_expire:
                        type: integer
                        nullable: true
                        description: Days until an issued certificate expires
                      expires_at:
                        type: string
                        nullable: true
                        description: Fixed datetime when issued certificates expire
                    required:
                    - id
                    - listing_id
                    - name
                    - active
                    - template
                    - pdf_settings
                    - created_at
                    - updated_at
                required:
                - certificate
    post:
      summary: Create a certificate
      tags:
      - Certificates
      parameters: []
      responses:
        '201':
          description: certificate created
          content:
            application/json:
              schema:
                type: object
                properties:
                  certificate:
                    type: object
                    properties:
                      id:
                        type: integer
                        description: Certificate ID
                      listing_id:
                        type: integer
                        description: Corresponding listing ID
                      name:
                        type: string
                        description: Certificate name
                      active:
                        type: boolean
                        description: Whether the certificate is enabled
                      template:
                        type: string
                        description: HTML template used to generate issued certificates
                      pdf_settings:
                        type: object
                        description: Extra params for PDF generation
                        properties:
                          orientation:
                            type: string
                            description: "'Landscape' or 'Portrait'"
                      created_at:
                        type: string
                        description: Creation timestamp (ISO 8601)
                      updated_at:
                        type: string
                        description: Last-updated timestamp (ISO 8601)
                      days_to_expire:
                        type: integer
                        nullable: true
                        description: Days until an issued certificate expires
                      expires_at:
                        type: string
                        nullable: true
                        description: Fixed datetime when issued certificates expire
                    required:
                    - id
                    - listing_id
                    - name
                    - active
                    - template
                    - pdf_settings
                    - created_at
                    - updated_at
                required:
                - certificate
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                certificate:
                  type: object
                  properties:
                    listing_id:
                      type: integer
                      description: Id of the listing
                    name:
                      type: string
                      description: Name of the certificate
                    active:
                      type: boolean
                      description: 'State of the certificate (default: true)'
                    template:
                      type: string
                      description: Template for certificate contents
                    pdf_settings:
                      type: object
                      description: PDF settings
                      properties:
                        orientation:
                          type: string
                          description: "'Landscape' or 'Portrait' (default: Landscape)"
                  required:
                  - listing_id
                  - name
                  - template
                days_to_expire:
                  type: integer
                  description: Days until expiry after award; mutually exclusive with
                    expires_at
                expires_at:
                  type: string
                  description: Fixed expiry datetime; mutually exclusive with days_to_expire
    delete:
      summary: Delete a certificate
      tags:
      - Certificates
      parameters: []
      responses:
        '204':
          description: certificate deleted
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                certificate:
                  type: object
                  properties:
                    listing_id:
                      type: integer
                      description: Id of the listing
                  required:
                  - listing_id
                nullify_requirements_completed_at:
                  type: boolean
                  description: 'Nullify requirements_completed_at for enrollments
                    (default: false)'
  "/api/v1/certificates/revoke_users_certificate":
    put:
      summary: Revoke users' certificates
      tags:
      - Certificates
      parameters: []
      responses:
        '200':
          description: certificates revoked
          content:
            application/json:
              schema:
                type: object
                properties:
                  revoked_certificates:
                    type: array
                    items:
                      type: object
                      properties:
                        canvas_user_id:
                          type: integer
                          description: Canvas user ID
                        canvas_course_id:
                          type: integer
                          description: Canvas course ID
                        listing_id:
                          type: integer
                          description: Catalog product listing ID
                      required:
                      - canvas_user_id
                      - canvas_course_id
                      - listing_id
                required:
                - revoked_certificates
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                certificate:
                  type: object
                  properties:
                    listing_id:
                      type: integer
                      description: Id of the listing
                    canvas_user_ids:
                      type: array
                      items:
                        type: integer
                      description: Canvas user IDs to revoke
                  required:
                  - listing_id
                  - canvas_user_ids
  "/api/v1/completed_certificates":
    get:
      summary: List completed certificates
      tags:
      - Completed certificates
      parameters:
      - name: user_id
        in: query
        required: false
        schema:
          type: integer
        description: Canvas ID of the user (required unless canvas_course_id is given)
      - name: canvas_course_id
        in: query
        required: false
        schema:
          type: integer
        description: Canvas course ID; filter completions to a specific course
      - name: only_certificates
        in: query
        required: false
        schema:
          type: boolean
        description: 'When true, exclude courses without certificates (default: include
          all)'
      responses:
        '200':
          description: completions listed
          content:
            application/json:
              schema:
                type: object
                properties:
                  completed_certificates:
                    type: array
                    items:
                      type: object
                      properties:
                        user_id:
                          type: integer
                          description: Canvas user ID
                        canvas_course_id:
                          type: integer
                          description: Canvas course ID
                        catalog_title:
                          type: string
                          description: Catalog course title
                        canvas_course_name:
                          type: string
                          description: Canvas course name
                        certificate_id:
                          type: integer
                          nullable: true
                          description: Catalog certificate ID (null when the course
                            has no certificate)
                        verification_code:
                          type: string
                          nullable: true
                          description: Verification code derived from the user and
                            completion date (null when no certificate or completion
                            date is available)
                        verification_code_alt:
                          type: string
                          nullable: true
                        certificate_url:
                          type: string
                          nullable: true
                          description: URL for the course certificate (null when the
                            user has no certificate)
                        canvas_course_workflow_state:
                          type: string
                          description: Canvas course workflow state
                        completed_at:
                          type: string
                          description: Canvas course completion date (ISO 8601)
                      required:
                      - user_id
                      - canvas_course_id
                      - completed_at
                required:
                - completed_certificates
  "/api/v1/courses":
    get:
      summary: List courses
      tags:
      - Courses
      parameters:
      - name: query
        in: query
        required: false
        schema:
          type: string
        description: General search query (title OR description OR tags)
      - name: title
        in: query
        required: false
        schema:
          type: string
        description: Search by title
      - name: tag_name
        in: query
        required: false
        schema:
          type: string
        description: Search by tag name
      - name: is_enrollable
        in: query
        required: false
        schema:
          type: boolean
        description: Filter by whether currently open for enrollment
      responses:
        '200':
          description: courses listed
          content:
            application/json:
              schema:
                type: object
                properties:
                  courses:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                          description: Identifier for this listing
                        visibility:
                          type: string
                          description: 'Visibility in the web UI: listed, unlisted,
                            or hidden'
                        enrollment_open:
                          type: boolean
                          description: Open for enrollment
                        enrollment_open_from:
                          type: string
                          nullable: true
                          description: Enrollment open from this date-time, if specified
                        enrollment_open_to:
                          type: string
                          nullable: true
                          description: Enrollment open until this date-time, if specified
                        enrollment_cap:
                          type: integer
                          nullable: true
                          description: Limit for the total number of enrollments
                        hide_enrollment_info:
                          type: boolean
                          description: Hide enrollment info when closed
                        description:
                          type: string
                          description: Full listing description
                        enrollment_fee:
                          type: number
                          description: Enrollment fee
                        created_at:
                          type: string
                          description: Creation timestamp (ISO 8601)
                        credits:
                          type: number
                          nullable: true
                          description: Credit value
                        measurement:
                          type: string
                        updated_at:
                          type: string
                          description: Last-updated timestamp (ISO 8601)
                        short_description:
                          type: string
                          description: A short description for this listing
                        listing_path:
                          type: string
                          description: Path to the listing, used in URLs
                        listing_image:
                          type: string
                          nullable: true
                        currency:
                          type: string
                          description: Three-character currency code for the enrollment
                            fee
                        catalog:
                          type: object
                          description: Catalog that owns this listing
                          properties:
                            id:
                              type: integer
                            name:
                              type: string
                          required:
                          - id
                          - name
                        type:
                          type: string
                          description: Listing type (Course or Program)
                        title:
                          type: string
                          description: Title of the listing
                        list_order:
                          type: integer
                          nullable: true
                          description: Order in which the listing is shown
                        waitlist:
                          type: boolean
                          description: Waitlist enabled
                        waitlist_cap:
                          type: integer
                          nullable: true
                          description: Waitlist limit
                        sku:
                          type: string
                          nullable: true
                          description: Listing SKU
                        show_free_banner:
                          type: boolean
                          description: Show the 'FREE' mark when free
                        image_alt_text:
                          type: string
                          nullable: true
                        allowed_payment_types:
                          type: array
                          items:
                            type: string
                          description: Allowed payment methods
                        tag_names:
                          type: array
                          items:
                            type: string
                          description: Tags applied to this listing
                        listing_url:
                          type: string
                          description: The URL of the listing
                        start_date:
                          type: string
                          nullable: true
                          description: When the Canvas course starts, if specified
                        end_date:
                          type: string
                          nullable: true
                          description: When the Canvas course ends, if specified
                        canvas_section_id:
                          type: integer
                          nullable: true
                          description: The Canvas course section's id
                        associated_account_ids:
                          type: array
                          items:
                            type: integer
                          description: Other account ids where this product is listed
                        archived_at:
                          type: string
                          nullable: true
                          description: Archival date (null if not archived)
                        canvas_course:
                          type: object
                          description: Corresponding Canvas course
                          properties:
                            id:
                              type: integer
                              nullable: true
                              description: Corresponding Canvas id (null if the Canvas
                                course is unavailable)
                          required:
                          - id
                        instructor_names:
                          type: array
                          items:
                            type: string
                          description: Names of the course instructors
                        primary_instructor_name:
                          type: string
                          nullable: true
                          description: Name of the primary instructor
                      required:
                      - id
                      - visibility
                      - enrollment_open
                      - enrollment_open_from
                      - enrollment_open_to
                      - enrollment_cap
                      - hide_enrollment_info
                      - description
                      - enrollment_fee
                      - created_at
                      - credits
                      - measurement
                      - updated_at
                      - short_description
                      - listing_path
                      - listing_image
                      - currency
                      - catalog
                      - type
                      - title
                      - list_order
                      - waitlist
                      - waitlist_cap
                      - sku
                      - show_free_banner
                      - image_alt_text
                      - allowed_payment_types
                      - tag_names
                      - listing_url
                      - start_date
                      - end_date
                      - canvas_section_id
                      - associated_account_ids
                      - archived_at
                      - canvas_course
                      - instructor_names
                      - primary_instructor_name
                required:
                - courses
    post:
      summary: Create a course
      tags:
      - Courses
      parameters: []
      responses:
        '201':
          description: course created
          content:
            application/json:
              schema:
                type: object
                properties:
                  course:
                    type: object
                    properties:
                      id:
                        type: integer
                        description: Identifier for this listing
                      visibility:
                        type: string
                        description: 'Visibility in the web UI: listed, unlisted,
                          or hidden'
                      enrollment_open:
                        type: boolean
                        description: Open for enrollment
                      enrollment_open_from:
                        type: string
                        nullable: true
                        description: Enrollment open from this date-time, if specified
                      enrollment_open_to:
                        type: string
                        nullable: true
                        description: Enrollment open until this date-time, if specified
                      enrollment_cap:
                        type: integer
                        nullable: true
                        description: Limit for the total number of enrollments
                      hide_enrollment_info:
                        type: boolean
                        description: Hide enrollment info when closed
                      description:
                        type: string
                        description: Full listing description
                      enrollment_fee:
                        type: number
                        description: Enrollment fee
                      created_at:
                        type: string
                        description: Creation timestamp (ISO 8601)
                      credits:
                        type: number
                        nullable: true
                        description: Credit value
                      measurement:
                        type: string
                      updated_at:
                        type: string
                        description: Last-updated timestamp (ISO 8601)
                      short_description:
                        type: string
                        description: A short description for this listing
                      listing_path:
                        type: string
                        description: Path to the listing, used in URLs
                      listing_image:
                        type: string
                        nullable: true
                      currency:
                        type: string
                        description: Three-character currency code for the enrollment
                          fee
                      catalog:
                        type: object
                        description: Catalog that owns this listing
                        properties:
                          id:
                            type: integer
                          name:
                            type: string
                        required:
                        - id
                        - name
                      type:
                        type: string
                        description: Listing type (Course or Program)
                      title:
                        type: string
                        description: Title of the listing
                      list_order:
                        type: integer
                        nullable: true
                        description: Order in which the listing is shown
                      waitlist:
                        type: boolean
                        description: Waitlist enabled
                      waitlist_cap:
                        type: integer
                        nullable: true
                        description: Waitlist limit
                      sku:
                        type: string
                        nullable: true
                        description: Listing SKU
                      show_free_banner:
                        type: boolean
                        description: Show the 'FREE' mark when free
                      image_alt_text:
                        type: string
                        nullable: true
                      allowed_payment_types:
                        type: array
                        items:
                          type: string
                        description: Allowed payment methods
                      tag_names:
                        type: array
                        items:
                          type: string
                        description: Tags applied to this listing
                      listing_url:
                        type: string
                        description: The URL of the listing
                      start_date:
                        type: string
                        nullable: true
                        description: When the Canvas course starts, if specified
                      end_date:
                        type: string
                        nullable: true
                        description: When the Canvas course ends, if specified
                      canvas_section_id:
                        type: integer
                        nullable: true
                        description: The Canvas course section's id
                      associated_account_ids:
                        type: array
                        items:
                          type: integer
                        description: Other account ids where this product is listed
                      archived_at:
                        type: string
                        nullable: true
                        description: Archival date (null if not archived)
                      canvas_course:
                        type: object
                        description: Corresponding Canvas course
                        properties:
                          id:
                            type: integer
                            nullable: true
                            description: Corresponding Canvas id (null if the Canvas
                              course is unavailable)
                        required:
                        - id
                      instructor_names:
                        type: array
                        items:
                          type: string
                        description: Names of the course instructors
                      primary_instructor_name:
                        type: string
                        nullable: true
                        description: Name of the primary instructor
                    required:
                    - id
                    - visibility
                    - enrollment_open
                    - enrollment_open_from
                    - enrollment_open_to
                    - enrollment_cap
                    - hide_enrollment_info
                    - description
                    - enrollment_fee
                    - created_at
                    - credits
                    - measurement
                    - updated_at
                    - short_description
                    - listing_path
                    - listing_image
                    - currency
                    - catalog
                    - type
                    - title
                    - list_order
                    - waitlist
                    - waitlist_cap
                    - sku
                    - show_free_banner
                    - image_alt_text
                    - allowed_payment_types
                    - tag_names
                    - listing_url
                    - start_date
                    - end_date
                    - canvas_section_id
                    - associated_account_ids
                    - archived_at
                    - canvas_course
                    - instructor_names
                    - primary_instructor_name
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                course:
                  type: object
                  properties:
                    title:
                      type: string
                      description: Listing title
                    description:
                      type: string
                      description: Full listing description
                    path:
                      type: string
                      description: Path to the listing, used in URLs
                    teaser:
                      type: string
                      description: A shorter description of the listing
                    enrollment_open:
                      type: boolean
                    visibility:
                      type: string
                      description: listed, unlisted, or hidden
                    enrollment_cap:
                      type: integer
                    enrollment_fee:
                      type: number
                      description: Enrollment fee
                    days_to_complete:
                      type: integer
                    waitlist:
                      type: boolean
                    waitlist_cap:
                      type: integer
                    list_order:
                      type: integer
                    sku:
                      type: string
                    canvas_course_id:
                      type: integer
                      description: Id of the related Canvas course
                    canvas_section_id:
                      type: integer
                      description: The Canvas course section's id
                    credits:
                      type: number
                      description: Credit value of the course
                    instructor_names:
                      type: array
                      items:
                        type: string
                    primary_instructor_name:
                      type: string
                    tag_names:
                      type: array
                      items:
                        type: string
                  required:
                  - title
                  - description
                  - path
                  - canvas_course_id
  "/api/v1/courses/{id}":
    get:
      summary: Get a specific course
      tags:
      - Courses
      parameters:
      - name: id
        in: path
        schema:
          type: integer
        description: Identifier for this course
        required: true
      responses:
        '200':
          description: course found
          content:
            application/json:
              schema:
                type: object
                properties:
                  course:
                    type: object
                    properties:
                      id:
                        type: integer
                        description: Identifier for this listing
                      visibility:
                        type: string
                        description: 'Visibility in the web UI: listed, unlisted,
                          or hidden'
                      enrollment_open:
                        type: boolean
                        description: Open for enrollment
                      enrollment_open_from:
                        type: string
                        nullable: true
                        description: Enrollment open from this date-time, if specified
                      enrollment_open_to:
                        type: string
                        nullable: true
                        description: Enrollment open until this date-time, if specified
                      enrollment_cap:
                        type: integer
                        nullable: true
                        description: Limit for the total number of enrollments
                      hide_enrollment_info:
                        type: boolean
                        description: Hide enrollment info when closed
                      description:
                        type: string
                        description: Full listing description
                      enrollment_fee:
                        type: number
                        description: Enrollment fee
                      created_at:
                        type: string
                        description: Creation timestamp (ISO 8601)
                      credits:
                        type: number
                        nullable: true
                        description: Credit value
                      measurement:
                        type: string
                      updated_at:
                        type: string
                        description: Last-updated timestamp (ISO 8601)
                      short_description:
                        type: string
                        description: A short description for this listing
                      listing_path:
                        type: string
                        description: Path to the listing, used in URLs
                      listing_image:
                        type: string
                        nullable: true
                      currency:
                        type: string
                        description: Three-character currency code for the enrollment
                          fee
                      catalog:
                        type: object
                        description: Catalog that owns this listing
                        properties:
                          id:
                            type: integer
                          name:
                            type: string
                        required:
                        - id
                        - name
                      type:
                        type: string
                        description: Listing type (Course or Program)
                      title:
                        type: string
                        description: Title of the listing
                      list_order:
                        type: integer
                        nullable: true
                        description: Order in which the listing is shown
                      waitlist:
                        type: boolean
                        description: Waitlist enabled
                      waitlist_cap:
                        type: integer
                        nullable: true
                        description: Waitlist limit
                      sku:
                        type: string
                        nullable: true
                        description: Listing SKU
                      show_free_banner:
                        type: boolean
                        description: Show the 'FREE' mark when free
                      image_alt_text:
                        type: string
                        nullable: true
                      allowed_payment_types:
                        type: array
                        items:
                          type: string
                        description: Allowed payment methods
                      tag_names:
                        type: array
                        items:
                          type: string
                        description: Tags applied to this listing
                      listing_url:
                        type: string
                        description: The URL of the listing
                      start_date:
                        type: string
                        nullable: true
                        description: When the Canvas course starts, if specified
                      end_date:
                        type: string
                        nullable: true
                        description: When the Canvas course ends, if specified
                      canvas_section_id:
                        type: integer
                        nullable: true
                        description: The Canvas course section's id
                      associated_account_ids:
                        type: array
                        items:
                          type: integer
                        description: Other account ids where this product is listed
                      archived_at:
                        type: string
                        nullable: true
                        description: Archival date (null if not archived)
                      canvas_course:
                        type: object
                        description: Corresponding Canvas course
                        properties:
                          id:
                            type: integer
                            nullable: true
                            description: Corresponding Canvas id (null if the Canvas
                              course is unavailable)
                        required:
                        - id
                      instructor_names:
                        type: array
                        items:
                          type: string
                        description: Names of the course instructors
                      primary_instructor_name:
                        type: string
                        nullable: true
                        description: Name of the primary instructor
                    required:
                    - id
                    - visibility
                    - enrollment_open
                    - enrollment_open_from
                    - enrollment_open_to
                    - enrollment_cap
                    - hide_enrollment_info
                    - description
                    - enrollment_fee
                    - created_at
                    - credits
                    - measurement
                    - updated_at
                    - short_description
                    - listing_path
                    - listing_image
                    - currency
                    - catalog
                    - type
                    - title
                    - list_order
                    - waitlist
                    - waitlist_cap
                    - sku
                    - show_free_banner
                    - image_alt_text
                    - allowed_payment_types
                    - tag_names
                    - listing_url
                    - start_date
                    - end_date
                    - canvas_section_id
                    - associated_account_ids
                    - archived_at
                    - canvas_course
                    - instructor_names
                    - primary_instructor_name
                required:
                - course
    put:
      summary: Update a course
      tags:
      - Courses
      parameters:
      - name: id
        in: path
        schema:
          type: integer
        description: Identifier for this course
        required: true
      responses:
        '204':
          description: course updated
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                course:
                  type: object
                  properties:
                    title:
                      type: string
                      description: Listing title
                    description:
                      type: string
                      description: Full listing description
                    path:
                      type: string
                      description: Path to the listing, used in URLs
                    teaser:
                      type: string
                      description: A shorter description of the listing
                    enrollment_open:
                      type: boolean
                    visibility:
                      type: string
                      description: listed, unlisted, or hidden
                    enrollment_cap:
                      type: integer
                    enrollment_fee:
                      type: number
                      description: Enrollment fee
                    days_to_complete:
                      type: integer
                    waitlist:
                      type: boolean
                    waitlist_cap:
                      type: integer
                    list_order:
                      type: integer
                    sku:
                      type: string
                    canvas_course_id:
                      type: integer
                      description: Id of the related Canvas course
                    canvas_section_id:
                      type: integer
                      description: The Canvas course section's id
                    credits:
                      type: number
                      description: Credit value of the course
                    instructor_names:
                      type: array
                      items:
                        type: string
                    primary_instructor_name:
                      type: string
                    tag_names:
                      type: array
                      items:
                        type: string
    delete:
      summary: Delete a course
      tags:
      - Courses
      parameters:
      - name: id
        in: path
        schema:
          type: integer
        description: Identifier for this course
        required: true
      responses:
        '204':
          description: course deleted
  "/api/v1/courses/archived":
    put:
      summary: Archive or reactivate courses
      tags:
      - Courses
      parameters: []
      responses:
        '200':
          description: all courses processed
        '422':
          description: some courses could not be processed
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                product_action:
                  type: string
                  description: 'Action to perform: archive or reactivate'
                product_ids:
                  type: array
                  items:
                    type: integer
                  description: Product ids to act on
              required:
              - product_action
              - product_ids
  "/api/v1/courses/update_skus":
    put:
      summary: Update course SKUs from CSV
      tags:
      - Courses
      parameters: []
      responses:
        '200':
          description: SKU import enqueued
      requestBody:
        content:
          multipart/form-data:
            schema:
              type: string
              format: binary
        required: true
        description: CSV with Catalog Course ID and SKU header columns
  "/api/v1/email_domain_sets":
    get:
      summary: List email domain sets
      tags:
      - Email domain sets
      parameters:
      - name: search
        in: query
        required: false
        schema:
          type: string
        description: Filter email domain sets by name
      - name: exact
        in: query
        required: false
        schema:
          type: string
        description: When set, only return exact name matches
      responses:
        '200':
          description: email domain sets listed
          content:
            application/json:
              schema:
                type: object
                required:
                - email_domain_sets
                - meta
                properties:
                  email_domain_sets:
                    type: array
                    items:
                      type: object
                      required:
                      - id
                      - name
                      - account_id
                      - email_domains
                      properties:
                        id:
                          type: integer
                          description: Email domain set ID
                        name:
                          type: string
                          description: Name of the email domain set
                        account_id:
                          type: integer
                          description: Owning account ID
                        email_domains:
                          type: array
                          description: Domains in this set
                          items:
                            type: object
                            required:
                            - id
                            - domain
                            - email_domain_set_id
                            - canvas_root_account_uuid
                            - created_at
                            - updated_at
                            - deleted_at
                            properties:
                              id:
                                type: integer
                              domain:
                                type: string
                                description: Email domain (e.g. example.com)
                              email_domain_set_id:
                                type: integer
                              canvas_root_account_uuid:
                                type: string
                              created_at:
                                type: string
                              updated_at:
                                type: string
                              deleted_at:
                                type: string
                                nullable: true
                  meta:
                    type: object
                    required:
                    - total_pages
                    properties:
                      total_pages:
                        type: integer
                        description: Total number of pages
  "/api/v1/email_domain_sets/{id}":
    get:
      summary: Get a specific email domain set
      tags:
      - Email domain sets
      parameters:
      - name: id
        in: path
        schema:
          type: integer
        description: Email domain set ID
        required: true
      responses:
        '200':
          description: email domain set found
          content:
            application/json:
              schema:
                type: object
                required:
                - id
                - name
                - account_id
                - canvas_root_account_uuid
                - created_at
                - updated_at
                - deleted_at
                properties:
                  id:
                    type: integer
                    description: Email domain set ID
                  name:
                    type: string
                    description: Name of the email domain set
                  account_id:
                    type: integer
                    description: Owning account ID
                  canvas_root_account_uuid:
                    type: string
                  created_at:
                    type: string
                  updated_at:
                    type: string
                  deleted_at:
                    type: string
                    nullable: true
    put:
      summary: Update an email domain set
      tags:
      - Email domain sets
      parameters:
      - name: id
        in: path
        schema:
          type: integer
        description: Email domain set ID
        required: true
      responses:
        '200':
          description: email domain set updated
          content:
            application/json:
              schema:
                type: object
                required:
                - email_domain_set
                properties:
                  email_domain_set:
                    type: object
                    required:
                    - id
                    - name
                    - account_id
                    - email_domains
                    properties:
                      id:
                        type: integer
                        description: Email domain set ID
                      name:
                        type: string
                        description: Name of the email domain set
                      account_id:
                        type: integer
                        description: Owning account ID
                      email_domains:
                        type: array
                        description: Domains in this set
                        items:
                          type: object
                          required:
                          - id
                          - domain
                          - email_domain_set_id
                          - canvas_root_account_uuid
                          - created_at
                          - updated_at
                          - deleted_at
                          properties:
                            id:
                              type: integer
                            domain:
                              type: string
                              description: Email domain (e.g. example.com)
                            email_domain_set_id:
                              type: integer
                            canvas_root_account_uuid:
                              type: string
                            created_at:
                              type: string
                            updated_at:
                              type: string
                            deleted_at:
                              type: string
                              nullable: true
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                email_domain_set:
                  type: object
                  properties:
                    name:
                      type: string
                      description: New name for the email domain set
                    email_domains_attributes:
                      type: array
                      description: Email domains to set (objects with a `domain` key)
                      items:
                        type: object
                        properties:
                          domain:
                            type: string
  "/api/v1/email_domain_sets/{id}/promotions":
    get:
      summary: List promotions for an email domain set
      tags:
      - Email domain sets
      parameters:
      - name: id
        in: path
        schema:
          type: integer
        description: Email domain set ID
        required: true
      responses:
        '200':
          description: promotions listed
          content:
            application/json:
              schema:
                type: object
                required:
                - promotions
                properties:
                  promotions:
                    type: array
                    items:
                      type: object
                      required:
                      - id
                      - account_id
                      - product_id
                      - product_title
                      - product_archived_at
                      - account_name
                      - currency
                      - amount
                      - discount_type
                      - code
                      - name
                      - description
                      - active
                      - start_date
                      - end_date
                      - created_at
                      - updated_at
                      - deleted_at
                      - usage_type
                      - canvas_root_account_uuid
                      - email_domain_set_id
                      - email_domain_set_name
                      - email_domains
                      - status
                      - max_per_user
                      - max_total_use
                      - enable_for_multi_seat_purchases
                      properties:
                        id:
                          type: integer
                          description: Promotion ID
                        account_id:
                          type: integer
                        product_id:
                          type: integer
                          nullable: true
                        product_title:
                          type: string
                          nullable: true
                        product_archived_at:
                          type: string
                          nullable: true
                        account_name:
                          type: string
                        currency:
                          type: string
                        amount:
                          type: string
                          description: Discount amount (decimal)
                        discount_type:
                          type: string
                          description: Type of discount
                        code:
                          type: string
                          description: Code used to apply the discount
                        name:
                          type: string
                        description:
                          type: string
                          nullable: true
                        active:
                          type: boolean
                        start_date:
                          type: string
                          nullable: true
                        end_date:
                          type: string
                          nullable: true
                        created_at:
                          type: string
                        updated_at:
                          type: string
                        deleted_at:
                          type: string
                          nullable: true
                        usage_type:
                          type: string
                        canvas_root_account_uuid:
                          type: string
                        email_domain_set_id:
                          type: integer
                          description: Email domain set the promotion is restricted
                            to
                        email_domain_set_name:
                          type: string
                        email_domains:
                          type: array
                          items:
                            type: object
                            required:
                            - id
                            - domain
                            - email_domain_set_id
                            - canvas_root_account_uuid
                            - created_at
                            - updated_at
                            - deleted_at
                            properties:
                              id:
                                type: integer
                              domain:
                                type: string
                                description: Email domain (e.g. example.com)
                              email_domain_set_id:
                                type: integer
                              canvas_root_account_uuid:
                                type: string
                              created_at:
                                type: string
                              updated_at:
                                type: string
                              deleted_at:
                                type: string
                                nullable: true
                        status:
                          type: string
                        max_per_user:
                          type: integer
                          nullable: true
                        max_total_use:
                          type: integer
                          nullable: true
                        enable_for_multi_seat_purchases:
                          type: boolean
  "/api/v1/enrollments":
    get:
      summary: List enrollments
      tags:
      - Enrollments
      parameters:
      - name: listing_id
        in: query
        required: false
        schema:
          type: integer
        description: Only include enrollments for the specified listing
      responses:
        '200':
          description: enrollments listed
          content:
            application/json:
              schema:
                type: object
                properties:
                  enrollments:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                          description: Identifier for this enrollment
                        user:
                          type: object
                          description: The enrolled user
                          properties:
                            id:
                              type: integer
                              description: Corresponding Canvas user id for this enrollment
                          required:
                          - id
                        listing:
                          type: object
                          description: The listing enrolled in
                          properties:
                            id:
                              type: integer
                              description: Identifier for the listing
                            title:
                              type: string
                              description: The name of the listing
                            type:
                              type: string
                              description: The type of listing (Course or Program)
                            canvas_course_id:
                              type: integer
                              nullable: true
                              description: Canvas course ID (null for Program enrollments)
                          required:
                          - id
                          - title
                          - type
                          - canvas_course_id
                        enrolled_at:
                          type: string
                          description: The time of enrollment (UTC)
                        status:
                          type: string
                          description: Enrollment status (active, dropped or concluded)
                        requirement_details:
                          type: object
                          description: Requirement completion details
                          properties:
                            requirement_count:
                              type: integer
                              nullable: true
                              description: Total number of requirements for the enrollment
                            requirement_completed_count:
                              type: integer
                              nullable: true
                              description: Number of completed requirements
                            requirement_completed_percentage:
                              type: integer
                              nullable: true
                              description: Percentage of completed requirements (0-100)
                          required:
                          - requirement_count
                          - requirement_completed_count
                          - requirement_completed_percentage
                      required:
                      - id
                      - user
                      - listing
                      - enrolled_at
                      - status
                      - requirement_details
                required:
                - enrollments
    post:
      summary: Create an enrollment
      tags:
      - Enrollments
      parameters:
      - name: create_order
        in: query
        required: false
        schema:
          type: boolean
        description: 'Create an order record for this enrollment (default: true)'
      - name: send_email
        in: query
        required: false
        schema:
          type: boolean
        description: 'Send an enrollment email to the user (default: true)'
      responses:
        '201':
          description: enrollment created
          content:
            application/json:
              schema:
                type: object
                properties:
                  enrollment:
                    type: object
                    properties:
                      id:
                        type: integer
                        description: Identifier for this enrollment
                      user:
                        type: object
                        description: The enrolled user
                        properties:
                          id:
                            type: integer
                            description: Corresponding Canvas user id for this enrollment
                        required:
                        - id
                      listing:
                        type: object
                        description: The listing enrolled in
                        properties:
                          id:
                            type: integer
                            description: Identifier for the listing
                          title:
                            type: string
                            description: The name of the listing
                          type:
                            type: string
                            description: The type of listing (Course or Program)
                          canvas_course_id:
                            type: integer
                            nullable: true
                            description: Canvas course ID (null for Program enrollments)
                        required:
                        - id
                        - title
                        - type
                        - canvas_course_id
                      enrolled_at:
                        type: string
                        description: The time of enrollment (UTC)
                      status:
                        type: string
                        description: Enrollment status (active, dropped or concluded)
                      requirement_details:
                        type: object
                        description: Requirement completion details
                        properties:
                          requirement_count:
                            type: integer
                            nullable: true
                            description: Total number of requirements for the enrollment
                          requirement_completed_count:
                            type: integer
                            nullable: true
                            description: Number of completed requirements
                          requirement_completed_percentage:
                            type: integer
                            nullable: true
                            description: Percentage of completed requirements (0-100)
                        required:
                        - requirement_count
                        - requirement_completed_count
                        - requirement_completed_percentage
                    required:
                    - id
                    - user
                    - listing
                    - enrolled_at
                    - status
                    - requirement_details
                required:
                - enrollment
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                enrollment:
                  type: object
                  properties:
                    listing_id:
                      type: integer
                      description: Id of the Listing
                    canvas_user_id:
                      type: integer
                      description: Id of the Canvas user
                  required:
                  - listing_id
                  - canvas_user_id
  "/api/v1/enrollments/{id}":
    get:
      summary: Get a specific enrollment
      tags:
      - Enrollments
      parameters:
      - name: id
        in: path
        schema:
          type: integer
        description: Identifier for this enrollment
        required: true
      responses:
        '200':
          description: enrollment found
          content:
            application/json:
              schema:
                type: object
                properties:
                  enrollment:
                    type: object
                    properties:
                      id:
                        type: integer
                        description: Identifier for this enrollment
                      user:
                        type: object
                        description: The enrolled user
                        properties:
                          id:
                            type: integer
                            description: Corresponding Canvas user id for this enrollment
                        required:
                        - id
                      listing:
                        type: object
                        description: The listing enrolled in
                        properties:
                          id:
                            type: integer
                            description: Identifier for the listing
                          title:
                            type: string
                            description: The name of the listing
                          type:
                            type: string
                            description: The type of listing (Course or Program)
                          canvas_course_id:
                            type: integer
                            nullable: true
                            description: Canvas course ID (null for Program enrollments)
                        required:
                        - id
                        - title
                        - type
                        - canvas_course_id
                      enrolled_at:
                        type: string
                        description: The time of enrollment (UTC)
                      status:
                        type: string
                        description: Enrollment status (active, dropped or concluded)
                      requirement_details:
                        type: object
                        description: Requirement completion details
                        properties:
                          requirement_count:
                            type: integer
                            nullable: true
                            description: Total number of requirements for the enrollment
                          requirement_completed_count:
                            type: integer
                            nullable: true
                            description: Number of completed requirements
                          requirement_completed_percentage:
                            type: integer
                            nullable: true
                            description: Percentage of completed requirements (0-100)
                        required:
                        - requirement_count
                        - requirement_completed_count
                        - requirement_completed_percentage
                    required:
                    - id
                    - user
                    - listing
                    - enrolled_at
                    - status
                    - requirement_details
                required:
                - enrollment
    delete:
      summary: Delete an enrollment
      tags:
      - Enrollments
      description: An additional request must be made to Canvas to delete the enrollment
        and remove it from the Catalog Student Dashboard.
      parameters:
      - name: id
        in: path
        schema:
          type: integer
        description: Identifier for this enrollment
        required: true
      responses:
        '204':
          description: enrollment deleted
  "/api/v1/orders":
    get:
      summary: List orders
      tags:
      - Orders
      parameters:
      - name: from
        in: query
        required: false
        schema:
          type: string
          format: date-time
        description: Earliest date/time to return (e.g. 2018-01-01T00:00:00Z, UTC)
      - name: to
        in: query
        required: false
        schema:
          type: string
          format: date-time
        description: Latest date/time to return
      - name: canvas_user_id
        in: query
        required: false
        schema:
          type: integer
        description: Return only orders for the specified Canvas user ID
      - name: completed
        in: query
        required: false
        schema:
          type: boolean
        description: When set, only return orders completed successfully
      responses:
        '200':
          description: orders listed
          content:
            application/json:
              schema:
                type: object
                required:
                - orders
                properties:
                  orders:
                    type: array
                    items:
                      type: object
                      required:
                      - id
                      - full_id
                      - catalog_id
                      - catalog
                      - user
                      - listings
                      - promotions
                      - payments
                      - total
                      - currency
                      - purchased_at
                      - created_at
                      properties:
                        id:
                          type: integer
                          description: Identifier for this order
                        full_id:
                          type: string
                          description: Full ID for this order, including prefix
                        catalog_id:
                          type: integer
                          description: 'DEPRECATED: use catalog[''id''] instead'
                        catalog:
                          type: object
                          description: Catalog the order is linked to
                          required:
                          - id
                          - name
                          properties:
                            id:
                              type: integer
                              description: Identifier for the catalog the order is
                                linked to
                            name:
                              type: string
                              description: Name of the catalog this order is linked
                                to
                        user:
                          type: object
                          description: User who placed the order
                          required:
                          - id
                          - name
                          - email
                          properties:
                            id:
                              type: integer
                              description: Canvas ID of the user who placed the order
                            name:
                              type: string
                              description: Name of the user who placed the order
                            email:
                              type: string
                              description: E-mail address of the user who placed the
                                order
                        listings:
                          type: array
                          description: Purchased listings (courses and programs)
                          items:
                            type: object
                            required:
                            - id
                            - canvas_course_id
                            - title
                            - amount
                            - discounted_amount
                            - catalog_id
                            properties:
                              id:
                                type: integer
                                description: Identifier for a listing purchased with
                                  this order
                              canvas_course_id:
                                type: integer
                                description: Canvas course ID for this listing (null
                                  for programs)
                              title:
                                type: string
                                description: The name of the listing
                              amount:
                                type: string
                                description: Listing price at the time of purchase
                                  (decimal)
                              discounted_amount:
                                type: string
                                description: Discounted price after promotions (decimal)
                              catalog_id:
                                type: integer
                                description: Catalog ID associated to this listing
                        promotions:
                          type: array
                          description: Promotions used
                          items:
                            type: object
                            required:
                            - id
                            - listing_id
                            - code
                            - amount
                            properties:
                              id:
                                type: integer
                                description: Identifier for a promotion used with
                                  this order
                              listing_id:
                                type: integer
                                description: Identifier for the listing this promotion
                                  is used for
                              code:
                                type: string
                                description: Promo code used for this order
                              amount:
                                type: string
                                description: Discount amount (decimal)
                        payments:
                          type: array
                          description: Payments
                          items:
                            type: object
                            required:
                            - reference_id
                            - status
                            - amount
                            properties:
                              reference_id:
                                type: string
                                description: Identifier from the payment redirector
                              status:
                                type: string
                                description: 'Status of the payment: success, error,
                                  or pending'
                              amount:
                                type: string
                                description: Amount of the payment (decimal)
                        total:
                          type: string
                          description: Total cost charged to the user (decimal)
                        currency:
                          type: string
                          description: Currency used for the transaction
                        purchased_at:
                          type: string
                          nullable: true
                          description: Time the transaction completed successfully;
                            null for unsuccessful or unpaid orders
                        created_at:
                          type: string
                          description: Time the order was initiated
  "/api/v1/orders/{id}":
    get:
      summary: Get a specific order
      tags:
      - Orders
      parameters:
      - name: id
        in: path
        schema:
          type: integer
        description: Identifier for this order
        required: true
      responses:
        '200':
          description: order found
          content:
            application/json:
              schema:
                type: object
                required:
                - order
                properties:
                  order:
                    type: object
                    required:
                    - id
                    - full_id
                    - catalog_id
                    - catalog
                    - user
                    - listings
                    - promotions
                    - payments
                    - total
                    - currency
                    - purchased_at
                    - created_at
                    properties:
                      id:
                        type: integer
                        description: Identifier for this order
                      full_id:
                        type: string
                        description: Full ID for this order, including prefix
                      catalog_id:
                        type: integer
                        description: 'DEPRECATED: use catalog[''id''] instead'
                      catalog:
                        type: object
                        description: Catalog the order is linked to
                        required:
                        - id
                        - name
                        properties:
                          id:
                            type: integer
                            description: Identifier for the catalog the order is linked
                              to
                          name:
                            type: string
                            description: Name of the catalog this order is linked
                              to
                      user:
                        type: object
                        description: User who placed the order
                        required:
                        - id
                        - name
                        - email
                        properties:
                          id:
                            type: integer
                            description: Canvas ID of the user who placed the order
                          name:
                            type: string
                            description: Name of the user who placed the order
                          email:
                            type: string
                            description: E-mail address of the user who placed the
                              order
                      listings:
                        type: array
                        description: Purchased listings (courses and programs)
                        items:
                          type: object
                          required:
                          - id
                          - canvas_course_id
                          - title
                          - amount
                          - discounted_amount
                          - catalog_id
                          properties:
                            id:
                              type: integer
                              description: Identifier for a listing purchased with
                                this order
                            canvas_course_id:
                              type: integer
                              description: Canvas course ID for this listing (null
                                for programs)
                            title:
                              type: string
                              description: The name of the listing
                            amount:
                              type: string
                              description: Listing price at the time of purchase (decimal)
                            discounted_amount:
                              type: string
                              description: Discounted price after promotions (decimal)
                            catalog_id:
                              type: integer
                              description: Catalog ID associated to this listing
                      promotions:
                        type: array
                        description: Promotions used
                        items:
                          type: object
                          required:
                          - id
                          - listing_id
                          - code
                          - amount
                          properties:
                            id:
                              type: integer
                              description: Identifier for a promotion used with this
                                order
                            listing_id:
                              type: integer
                              description: Identifier for the listing this promotion
                                is used for
                            code:
                              type: string
                              description: Promo code used for this order
                            amount:
                              type: string
                              description: Discount amount (decimal)
                      payments:
                        type: array
                        description: Payments
                        items:
                          type: object
                          required:
                          - reference_id
                          - status
                          - amount
                          properties:
                            reference_id:
                              type: string
                              description: Identifier from the payment redirector
                            status:
                              type: string
                              description: 'Status of the payment: success, error,
                                or pending'
                            amount:
                              type: string
                              description: Amount of the payment (decimal)
                      total:
                        type: string
                        description: Total cost charged to the user (decimal)
                      currency:
                        type: string
                        description: Currency used for the transaction
                      purchased_at:
                        type: string
                        nullable: true
                        description: Time the transaction completed successfully;
                          null for unsuccessful or unpaid orders
                      created_at:
                        type: string
                        description: Time the order was initiated
  "/api/v1/programs":
    get:
      summary: List programs
      tags:
      - Programs
      parameters:
      - name: query
        in: query
        required: false
        schema:
          type: string
        description: General search query
      - name: tag_name
        in: query
        required: false
        schema:
          type: string
        description: Search by tag name
      responses:
        '200':
          description: programs listed
          content:
            application/json:
              schema:
                type: object
                properties:
                  programs:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                          description: Identifier for this listing
                        visibility:
                          type: string
                          description: 'Visibility in the web UI: listed, unlisted,
                            or hidden'
                        enrollment_open:
                          type: boolean
                          description: Open for enrollment
                        enrollment_open_from:
                          type: string
                          nullable: true
                          description: Enrollment open from this date-time, if specified
                        enrollment_open_to:
                          type: string
                          nullable: true
                          description: Enrollment open until this date-time, if specified
                        enrollment_cap:
                          type: integer
                          nullable: true
                          description: Limit for the total number of enrollments
                        hide_enrollment_info:
                          type: boolean
                          description: Hide enrollment info when closed
                        description:
                          type: string
                          description: Full listing description
                        enrollment_fee:
                          type: number
                          description: Enrollment fee
                        created_at:
                          type: string
                          description: Creation timestamp (ISO 8601)
                        credits:
                          type: number
                          nullable: true
                          description: Cumulative credit value of the program's requirements
                        measurement:
                          type: string
                        updated_at:
                          type: string
                          description: Last-updated timestamp (ISO 8601)
                        short_description:
                          type: string
                          description: A short description for this listing
                        listing_path:
                          type: string
                          description: Path to the listing, used in URLs
                        listing_image:
                          type: string
                          nullable: true
                        currency:
                          type: string
                          description: Three-character currency code for the enrollment
                            fee
                        catalog:
                          type: object
                          description: Catalog that owns this listing
                          properties:
                            id:
                              type: integer
                            name:
                              type: string
                          required:
                          - id
                          - name
                        type:
                          type: string
                          description: Listing type (Course or Program)
                        title:
                          type: string
                          description: Title of the listing
                        list_order:
                          type: integer
                          nullable: true
                          description: Order in which the listing is shown
                        waitlist:
                          type: boolean
                          description: Waitlist enabled
                        waitlist_cap:
                          type: integer
                          nullable: true
                          description: Waitlist limit
                        sku:
                          type: string
                          nullable: true
                          description: Listing SKU
                        show_free_banner:
                          type: boolean
                          description: Show the 'FREE' mark when free
                        image_alt_text:
                          type: string
                          nullable: true
                        allowed_payment_types:
                          type: array
                          items:
                            type: string
                          description: Allowed payment methods
                        tag_names:
                          type: array
                          items:
                            type: string
                          description: Tags applied to this listing
                        listing_url:
                          type: string
                          description: The URL of the listing
                        start_date:
                          type: string
                          nullable: true
                          description: When the Canvas course starts, if specified
                        end_date:
                          type: string
                          nullable: true
                          description: When the Canvas course ends, if specified
                        canvas_section_id:
                          type: integer
                          nullable: true
                          description: The Canvas course section's id
                        associated_account_ids:
                          type: array
                          items:
                            type: integer
                          description: Other account ids where this product is listed
                        archived_at:
                          type: string
                          nullable: true
                          description: Archival date (null if not archived)
                        sequential:
                          type: boolean
                          description: Whether requirements must be completed in order
                        auto_enroll_courses:
                          type: boolean
                        requirements:
                          type: array
                          description: The program's requirements (courses and subprograms;
                            distinguish by the type key)
                          items:
                            type: object
                            properties:
                              id:
                                type: integer
                                description: Identifier for this listing
                              visibility:
                                type: string
                                description: 'Visibility in the web UI: listed, unlisted,
                                  or hidden'
                              enrollment_open:
                                type: boolean
                                description: Open for enrollment
                              enrollment_open_from:
                                type: string
                                nullable: true
                                description: Enrollment open from this date-time,
                                  if specified
                              enrollment_open_to:
                                type: string
                                nullable: true
                                description: Enrollment open until this date-time,
                                  if specified
                              enrollment_cap:
                                type: integer
                                nullable: true
                                description: Limit for the total number of enrollments
                              hide_enrollment_info:
                                type: boolean
                                description: Hide enrollment info when closed
                              description:
                                type: string
                                description: Full listing description
                              enrollment_fee:
                                type: number
                                description: Enrollment fee
                              created_at:
                                type: string
                                description: Creation timestamp (ISO 8601)
                              credits:
                                type: number
                                nullable: true
                                description: Cumulative credit value of the program's
                                  requirements
                              measurement:
                                type: string
                              updated_at:
                                type: string
                                description: Last-updated timestamp (ISO 8601)
                              short_description:
                                type: string
                                description: A short description for this listing
                              listing_path:
                                type: string
                                description: Path to the listing, used in URLs
                              listing_image:
                                type: string
                                nullable: true
                              currency:
                                type: string
                                description: Three-character currency code for the
                                  enrollment fee
                              catalog:
                                type: object
                                description: Catalog that owns this listing
                                properties:
                                  id:
                                    type: integer
                                  name:
                                    type: string
                                required:
                                - id
                                - name
                              type:
                                type: string
                                description: Listing type (Course or Program)
                              title:
                                type: string
                                description: Title of the listing
                              list_order:
                                type: integer
                                nullable: true
                                description: Order in which the listing is shown
                              waitlist:
                                type: boolean
                                description: Waitlist enabled
                              waitlist_cap:
                                type: integer
                                nullable: true
                                description: Waitlist limit
                              sku:
                                type: string
                                nullable: true
                                description: Listing SKU
                              show_free_banner:
                                type: boolean
                                description: Show the 'FREE' mark when free
                              image_alt_text:
                                type: string
                                nullable: true
                              allowed_payment_types:
                                type: array
                                items:
                                  type: string
                                description: Allowed payment methods
                              tag_names:
                                type: array
                                items:
                                  type: string
                                description: Tags applied to this listing
                              listing_url:
                                type: string
                                description: The URL of the listing
                              start_date:
                                type: string
                                nullable: true
                                description: When the Canvas course starts, if specified
                              end_date:
                                type: string
                                nullable: true
                                description: When the Canvas course ends, if specified
                              canvas_section_id:
                                type: integer
                                nullable: true
                                description: The Canvas course section's id
                              associated_account_ids:
                                type: array
                                items:
                                  type: integer
                                description: Other account ids where this product
                                  is listed
                              archived_at:
                                type: string
                                nullable: true
                                description: Archival date (null if not archived)
                              sequential:
                                type: boolean
                              auto_enroll_courses:
                                type: boolean
                              canvas_course:
                                type: object
                                properties:
                                  id:
                                    type: integer
                                required:
                                - id
                              instructor_names:
                                type: array
                                items:
                                  type: string
                              primary_instructor_name:
                                type: string
                                nullable: true
                              requirements:
                                type: array
                                items:
                                  type: object
                                description: Nested requirements for subprograms
                            required:
                            - id
                            - visibility
                            - enrollment_open
                            - enrollment_open_from
                            - enrollment_open_to
                            - enrollment_cap
                            - hide_enrollment_info
                            - description
                            - enrollment_fee
                            - created_at
                            - credits
                            - measurement
                            - updated_at
                            - short_description
                            - listing_path
                            - listing_image
                            - currency
                            - catalog
                            - type
                            - title
                            - list_order
                            - waitlist
                            - waitlist_cap
                            - sku
                            - show_free_banner
                            - image_alt_text
                            - allowed_payment_types
                            - tag_names
                            - listing_url
                            - start_date
                            - end_date
                            - canvas_section_id
                            - associated_account_ids
                            - archived_at
                      required:
                      - id
                      - visibility
                      - enrollment_open
                      - enrollment_open_from
                      - enrollment_open_to
                      - enrollment_cap
                      - hide_enrollment_info
                      - description
                      - enrollment_fee
                      - created_at
                      - credits
                      - measurement
                      - updated_at
                      - short_description
                      - listing_path
                      - listing_image
                      - currency
                      - catalog
                      - type
                      - title
                      - list_order
                      - waitlist
                      - waitlist_cap
                      - sku
                      - show_free_banner
                      - image_alt_text
                      - allowed_payment_types
                      - tag_names
                      - listing_url
                      - start_date
                      - end_date
                      - canvas_section_id
                      - associated_account_ids
                      - archived_at
                      - sequential
                      - auto_enroll_courses
                      - requirements
                required:
                - programs
    post:
      summary: Create a program
      tags:
      - Programs
      parameters: []
      responses:
        '201':
          description: program created
          content:
            application/json:
              schema:
                type: object
                properties:
                  program:
                    type: object
                    properties:
                      id:
                        type: integer
                        description: Identifier for this listing
                      visibility:
                        type: string
                        description: 'Visibility in the web UI: listed, unlisted,
                          or hidden'
                      enrollment_open:
                        type: boolean
                        description: Open for enrollment
                      enrollment_open_from:
                        type: string
                        nullable: true
                        description: Enrollment open from this date-time, if specified
                      enrollment_open_to:
                        type: string
                        nullable: true
                        description: Enrollment open until this date-time, if specified
                      enrollment_cap:
                        type: integer
                        nullable: true
                        description: Limit for the total number of enrollments
                      hide_enrollment_info:
                        type: boolean
                        description: Hide enrollment info when closed
                      description:
                        type: string
                        description: Full listing description
                      enrollment_fee:
                        type: number
                        description: Enrollment fee
                      created_at:
                        type: string
                        description: Creation timestamp (ISO 8601)
                      credits:
                        type: number
                        nullable: true
                        description: Cumulative credit value of the program's requirements
                      measurement:
                        type: string
                      updated_at:
                        type: string
                        description: Last-updated timestamp (ISO 8601)
                      short_description:
                        type: string
                        description: A short description for this listing
                      listing_path:
                        type: string
                        description: Path to the listing, used in URLs
                      listing_image:
                        type: string
                        nullable: true
                      currency:
                        type: string
                        description: Three-character currency code for the enrollment
                          fee
                      catalog:
                        type: object
                        description: Catalog that owns this listing
                        properties:
                          id:
                            type: integer
                          name:
                            type: string
                        required:
                        - id
                        - name
                      type:
                        type: string
                        description: Listing type (Course or Program)
                      title:
                        type: string
                        description: Title of the listing
                      list_order:
                        type: integer
                        nullable: true
                        description: Order in which the listing is shown
                      waitlist:
                        type: boolean
                        description: Waitlist enabled
                      waitlist_cap:
                        type: integer
                        nullable: true
                        description: Waitlist limit
                      sku:
                        type: string
                        nullable: true
                        description: Listing SKU
                      show_free_banner:
                        type: boolean
                        description: Show the 'FREE' mark when free
                      image_alt_text:
                        type: string
                        nullable: true
                      allowed_payment_types:
                        type: array
                        items:
                          type: string
                        description: Allowed payment methods
                      tag_names:
                        type: array
                        items:
                          type: string
                        description: Tags applied to this listing
                      listing_url:
                        type: string
                        description: The URL of the listing
                      start_date:
                        type: string
                        nullable: true
                        description: When the Canvas course starts, if specified
                      end_date:
                        type: string
                        nullable: true
                        description: When the Canvas course ends, if specified
                      canvas_section_id:
                        type: integer
                        nullable: true
                        description: The Canvas course section's id
                      associated_account_ids:
                        type: array
                        items:
                          type: integer
                        description: Other account ids where this product is listed
                      archived_at:
                        type: string
                        nullable: true
                        description: Archival date (null if not archived)
                      sequential:
                        type: boolean
                        description: Whether requirements must be completed in order
                      auto_enroll_courses:
                        type: boolean
                      requirements:
                        type: array
                        description: The program's requirements (courses and subprograms;
                          distinguish by the type key)
                        items:
                          type: object
                          properties:
                            id:
                              type: integer
                              description: Identifier for this listing
                            visibility:
                              type: string
                              description: 'Visibility in the web UI: listed, unlisted,
                                or hidden'
                            enrollment_open:
                              type: boolean
                              description: Open for enrollment
                            enrollment_open_from:
                              type: string
                              nullable: true
                              description: Enrollment open from this date-time, if
                                specified
                            enrollment_open_to:
                              type: string
                              nullable: true
                              description: Enrollment open until this date-time, if
                                specified
                            enrollment_cap:
                              type: integer
                              nullable: true
                              description: Limit for the total number of enrollments
                            hide_enrollment_info:
                              type: boolean
                              description: Hide enrollment info when closed
                            description:
                              type: string
                              description: Full listing description
                            enrollment_fee:
                              type: number
                              description: Enrollment fee
                            created_at:
                              type: string
                              description: Creation timestamp (ISO 8601)
                            credits:
                              type: number
                              nullable: true
                              description: Cumulative credit value of the program's
                                requirements
                            measurement:
                              type: string
                            updated_at:
                              type: string
                              description: Last-updated timestamp (ISO 8601)
                            short_description:
                              type: string
                              description: A short description for this listing
                            listing_path:
                              type: string
                              description: Path to the listing, used in URLs
                            listing_image:
                              type: string
                              nullable: true
                            currency:
                              type: string
                              description: Three-character currency code for the enrollment
                                fee
                            catalog:
                              type: object
                              description: Catalog that owns this listing
                              properties:
                                id:
                                  type: integer
                                name:
                                  type: string
                              required:
                              - id
                              - name
                            type:
                              type: string
                              description: Listing type (Course or Program)
                            title:
                              type: string
                              description: Title of the listing
                            list_order:
                              type: integer
                              nullable: true
                              description: Order in which the listing is shown
                            waitlist:
                              type: boolean
                              description: Waitlist enabled
                            waitlist_cap:
                              type: integer
                              nullable: true
                              description: Waitlist limit
                            sku:
                              type: string
                              nullable: true
                              description: Listing SKU
                            show_free_banner:
                              type: boolean
                              description: Show the 'FREE' mark when free
                            image_alt_text:
                              type: string
                              nullable: true
                            allowed_payment_types:
                              type: array
                              items:
                                type: string
                              description: Allowed payment methods
                            tag_names:
                              type: array
                              items:
                                type: string
                              description: Tags applied to this listing
                            listing_url:
                              type: string
                              description: The URL of the listing
                            start_date:
                              type: string
                              nullable: true
                              description: When the Canvas course starts, if specified
                            end_date:
                              type: string
                              nullable: true
                              description: When the Canvas course ends, if specified
                            canvas_section_id:
                              type: integer
                              nullable: true
                              description: The Canvas course section's id
                            associated_account_ids:
                              type: array
                              items:
                                type: integer
                              description: Other account ids where this product is
                                listed
                            archived_at:
                              type: string
                              nullable: true
                              description: Archival date (null if not archived)
                            sequential:
                              type: boolean
                            auto_enroll_courses:
                              type: boolean
                            canvas_course:
                              type: object
                              properties:
                                id:
                                  type: integer
                              required:
                              - id
                            instructor_names:
                              type: array
                              items:
                                type: string
                            primary_instructor_name:
                              type: string
                              nullable: true
                            requirements:
                              type: array
                              items:
                                type: object
                              description: Nested requirements for subprograms
                          required:
                          - id
                          - visibility
                          - enrollment_open
                          - enrollment_open_from
                          - enrollment_open_to
                          - enrollment_cap
                          - hide_enrollment_info
                          - description
                          - enrollment_fee
                          - created_at
                          - credits
                          - measurement
                          - updated_at
                          - short_description
                          - listing_path
                          - listing_image
                          - currency
                          - catalog
                          - type
                          - title
                          - list_order
                          - waitlist
                          - waitlist_cap
                          - sku
                          - show_free_banner
                          - image_alt_text
                          - allowed_payment_types
                          - tag_names
                          - listing_url
                          - start_date
                          - end_date
                          - canvas_section_id
                          - associated_account_ids
                          - archived_at
                    required:
                    - id
                    - visibility
                    - enrollment_open
                    - enrollment_open_from
                    - enrollment_open_to
                    - enrollment_cap
                    - hide_enrollment_info
                    - description
                    - enrollment_fee
                    - created_at
                    - credits
                    - measurement
                    - updated_at
                    - short_description
                    - listing_path
                    - listing_image
                    - currency
                    - catalog
                    - type
                    - title
                    - list_order
                    - waitlist
                    - waitlist_cap
                    - sku
                    - show_free_banner
                    - image_alt_text
                    - allowed_payment_types
                    - tag_names
                    - listing_url
                    - start_date
                    - end_date
                    - canvas_section_id
                    - associated_account_ids
                    - archived_at
                    - sequential
                    - auto_enroll_courses
                    - requirements
                required:
                - program
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                program:
                  type: object
                  properties:
                    title:
                      type: string
                      description: Listing title
                    description:
                      type: string
                      description: Full listing description
                    path:
                      type: string
                      description: Path to the listing, used in URLs
                    teaser:
                      type: string
                      description: A shorter description of the listing
                    enrollment_open:
                      type: boolean
                    visibility:
                      type: string
                      description: listed, unlisted, or hidden
                    enrollment_cap:
                      type: integer
                    enrollment_fee:
                      type: number
                      description: Enrollment fee
                    days_to_complete:
                      type: integer
                    waitlist:
                      type: boolean
                    waitlist_cap:
                      type: integer
                    list_order:
                      type: integer
                    sku:
                      type: string
                    requirement_ids:
                      type: array
                      items:
                        type: integer
                      description: Ordered listing IDs that are requirements
                    sequential:
                      type: boolean
                      description: Require completing requirements in order
                    tag_names:
                      type: array
                      items:
                        type: string
                  required:
                  - title
                  - description
                  - path
  "/api/v1/programs/{id}":
    get:
      summary: Get a specific program
      tags:
      - Programs
      parameters:
      - name: id
        in: path
        schema:
          type: integer
        description: Identifier for this program
        required: true
      responses:
        '200':
          description: program found
          content:
            application/json:
              schema:
                type: object
                properties:
                  program:
                    type: object
                    properties:
                      id:
                        type: integer
                        description: Identifier for this listing
                      visibility:
                        type: string
                        description: 'Visibility in the web UI: listed, unlisted,
                          or hidden'
                      enrollment_open:
                        type: boolean
                        description: Open for enrollment
                      enrollment_open_from:
                        type: string
                        nullable: true
                        description: Enrollment open from this date-time, if specified
                      enrollment_open_to:
                        type: string
                        nullable: true
                        description: Enrollment open until this date-time, if specified
                      enrollment_cap:
                        type: integer
                        nullable: true
                        description: Limit for the total number of enrollments
                      hide_enrollment_info:
                        type: boolean
                        description: Hide enrollment info when closed
                      description:
                        type: string
                        description: Full listing description
                      enrollment_fee:
                        type: number
                        description: Enrollment fee
                      created_at:
                        type: string
                        description: Creation timestamp (ISO 8601)
                      credits:
                        type: number
                        nullable: true
                        description: Cumulative credit value of the program's requirements
                      measurement:
                        type: string
                      updated_at:
                        type: string
                        description: Last-updated timestamp (ISO 8601)
                      short_description:
                        type: string
                        description: A short description for this listing
                      listing_path:
                        type: string
                        description: Path to the listing, used in URLs
                      listing_image:
                        type: string
                        nullable: true
                      currency:
                        type: string
                        description: Three-character currency code for the enrollment
                          fee
                      catalog:
                        type: object
                        description: Catalog that owns this listing
                        properties:
                          id:
                            type: integer
                          name:
                            type: string
                        required:
                        - id
                        - name
                      type:
                        type: string
                        description: Listing type (Course or Program)
                      title:
                        type: string
                        description: Title of the listing
                      list_order:
                        type: integer
                        nullable: true
                        description: Order in which the listing is shown
                      waitlist:
                        type: boolean
                        description: Waitlist enabled
                      waitlist_cap:
                        type: integer
                        nullable: true
                        description: Waitlist limit
                      sku:
                        type: string
                        nullable: true
                        description: Listing SKU
                      show_free_banner:
                        type: boolean
                        description: Show the 'FREE' mark when free
                      image_alt_text:
                        type: string
                        nullable: true
                      allowed_payment_types:
                        type: array
                        items:
                          type: string
                        description: Allowed payment methods
                      tag_names:
                        type: array
                        items:
                          type: string
                        description: Tags applied to this listing
                      listing_url:
                        type: string
                        description: The URL of the listing
                      start_date:
                        type: string
                        nullable: true
                        description: When the Canvas course starts, if specified
                      end_date:
                        type: string
                        nullable: true
                        description: When the Canvas course ends, if specified
                      canvas_section_id:
                        type: integer
                        nullable: true
                        description: The Canvas course section's id
                      associated_account_ids:
                        type: array
                        items:
                          type: integer
                        description: Other account ids where this product is listed
                      archived_at:
                        type: string
                        nullable: true
                        description: Archival date (null if not archived)
                      sequential:
                        type: boolean
                        description: Whether requirements must be completed in order
                      auto_enroll_courses:
                        type: boolean
                      requirements:
                        type: array
                        description: The program's requirements (courses and subprograms;
                          distinguish by the type key)
                        items:
                          type: object
                          properties:
                            id:
                              type: integer
                              description: Identifier for this listing
                            visibility:
                              type: string
                              description: 'Visibility in the web UI: listed, unlisted,
                                or hidden'
                            enrollment_open:
                              type: boolean
                              description: Open for enrollment
                            enrollment_open_from:
                              type: string
                              nullable: true
                              description: Enrollment open from this date-time, if
                                specified
                            enrollment_open_to:
                              type: string
                              nullable: true
                              description: Enrollment open until this date-time, if
                                specified
                            enrollment_cap:
                              type: integer
                              nullable: true
                              description: Limit for the total number of enrollments
                            hide_enrollment_info:
                              type: boolean
                              description: Hide enrollment info when closed
                            description:
                              type: string
                              description: Full listing description
                            enrollment_fee:
                              type: number
                              description: Enrollment fee
                            created_at:
                              type: string
                              description: Creation timestamp (ISO 8601)
                            credits:
                              type: number
                              nullable: true
                              description: Cumulative credit value of the program's
                                requirements
                            measurement:
                              type: string
                            updated_at:
                              type: string
                              description: Last-updated timestamp (ISO 8601)
                            short_description:
                              type: string
                              description: A short description for this listing
                            listing_path:
                              type: string
                              description: Path to the listing, used in URLs
                            listing_image:
                              type: string
                              nullable: true
                            currency:
                              type: string
                              description: Three-character currency code for the enrollment
                                fee
                            catalog:
                              type: object
                              description: Catalog that owns this listing
                              properties:
                                id:
                                  type: integer
                                name:
                                  type: string
                              required:
                              - id
                              - name
                            type:
                              type: string
                              description: Listing type (Course or Program)
                            title:
                              type: string
                              description: Title of the listing
                            list_order:
                              type: integer
                              nullable: true
                              description: Order in which the listing is shown
                            waitlist:
                              type: boolean
                              description: Waitlist enabled
                            waitlist_cap:
                              type: integer
                              nullable: true
                              description: Waitlist limit
                            sku:
                              type: string
                              nullable: true
                              description: Listing SKU
                            show_free_banner:
                              type: boolean
                              description: Show the 'FREE' mark when free
                            image_alt_text:
                              type: string
                              nullable: true
                            allowed_payment_types:
                              type: array
                              items:
                                type: string
                              description: Allowed payment methods
                            tag_names:
                              type: array
                              items:
                                type: string
                              description: Tags applied to this listing
                            listing_url:
                              type: string
                              description: The URL of the listing
                            start_date:
                              type: string
                              nullable: true
                              description: When the Canvas course starts, if specified
                            end_date:
                              type: string
                              nullable: true
                              description: When the Canvas course ends, if specified
                            canvas_section_id:
                              type: integer
                              nullable: true
                              description: The Canvas course section's id
                            associated_account_ids:
                              type: array
                              items:
                                type: integer
                              description: Other account ids where this product is
                                listed
                            archived_at:
                              type: string
                              nullable: true
                              description: Archival date (null if not archived)
                            sequential:
                              type: boolean
                            auto_enroll_courses:
                              type: boolean
                            canvas_course:
                              type: object
                              properties:
                                id:
                                  type: integer
                              required:
                              - id
                            instructor_names:
                              type: array
                              items:
                                type: string
                            primary_instructor_name:
                              type: string
                              nullable: true
                            requirements:
                              type: array
                              items:
                                type: object
                              description: Nested requirements for subprograms
                          required:
                          - id
                          - visibility
                          - enrollment_open
                          - enrollment_open_from
                          - enrollment_open_to
                          - enrollment_cap
                          - hide_enrollment_info
                          - description
                          - enrollment_fee
                          - created_at
                          - credits
                          - measurement
                          - updated_at
                          - short_description
                          - listing_path
                          - listing_image
                          - currency
                          - catalog
                          - type
                          - title
                          - list_order
                          - waitlist
                          - waitlist_cap
                          - sku
                          - show_free_banner
                          - image_alt_text
                          - allowed_payment_types
                          - tag_names
                          - listing_url
                          - start_date
                          - end_date
                          - canvas_section_id
                          - associated_account_ids
                          - archived_at
                    required:
                    - id
                    - visibility
                    - enrollment_open
                    - enrollment_open_from
                    - enrollment_open_to
                    - enrollment_cap
                    - hide_enrollment_info
                    - description
                    - enrollment_fee
                    - created_at
                    - credits
                    - measurement
                    - updated_at
                    - short_description
                    - listing_path
                    - listing_image
                    - currency
                    - catalog
                    - type
                    - title
                    - list_order
                    - waitlist
                    - waitlist_cap
                    - sku
                    - show_free_banner
                    - image_alt_text
                    - allowed_payment_types
                    - tag_names
                    - listing_url
                    - start_date
                    - end_date
                    - canvas_section_id
                    - associated_account_ids
                    - archived_at
                    - sequential
                    - auto_enroll_courses
                    - requirements
                required:
                - program
    put:
      summary: Update a program
      tags:
      - Programs
      parameters:
      - name: id
        in: path
        schema:
          type: integer
        description: Identifier for this program
        required: true
      responses:
        '204':
          description: program updated
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                program:
                  type: object
                  properties:
                    title:
                      type: string
                      description: Listing title
                    description:
                      type: string
                      description: Full listing description
                    path:
                      type: string
                      description: Path to the listing, used in URLs
                    teaser:
                      type: string
                      description: A shorter description of the listing
                    enrollment_open:
                      type: boolean
                    visibility:
                      type: string
                      description: listed, unlisted, or hidden
                    enrollment_cap:
                      type: integer
                    enrollment_fee:
                      type: number
                      description: Enrollment fee
                    days_to_complete:
                      type: integer
                    waitlist:
                      type: boolean
                    waitlist_cap:
                      type: integer
                    list_order:
                      type: integer
                    sku:
                      type: string
                    requirement_ids:
                      type: array
                      items:
                        type: integer
                      description: Ordered listing IDs that are requirements
                    sequential:
                      type: boolean
                      description: Require completing requirements in order
                    tag_names:
                      type: array
                      items:
                        type: string
    delete:
      summary: Delete a program
      tags:
      - Programs
      parameters:
      - name: id
        in: path
        schema:
          type: integer
        description: Identifier for this program
        required: true
      responses:
        '204':
          description: program deleted
  "/api/v1/programs/archived":
    put:
      summary: Archive or reactivate programs
      tags:
      - Programs
      parameters: []
      responses:
        '200':
          description: all programs processed
        '422':
          description: some programs could not be processed
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                product_action:
                  type: string
                  description: archive or reactivate
                product_ids:
                  type: array
                  items:
                    type: integer
              required:
              - product_action
              - product_ids
  "/api/v1/progresses/{id}":
    get:
      summary: Get a specific progress
      tags:
      - Progresses
      parameters:
      - name: id
        in: path
        schema:
          type: integer
        description: Progress ID
        required: true
      responses:
        '200':
          description: progress found
          content:
            application/json:
              schema:
                type: object
                required:
                - progress
                properties:
                  progress:
                    type: object
                    required:
                    - id
                    - account_id
                    - canvas_user_id
                    - completion_percent
                    - workflow_state
                    - payload
                    - created_at
                    - updated_at
                    properties:
                      id:
                        type: integer
                        description: Progress ID
                      account_id:
                        type: integer
                        description: Catalog account ID
                      canvas_user_id:
                        type: integer
                        nullable: true
                        description: Canvas user ID of the user who initiated the
                          job
                      completion_percent:
                        type: integer
                        nullable: true
                        description: Completion percent of the job
                      workflow_state:
                        type: string
                        description: Status of the progress job
                      payload:
                        type: object
                        properties: {}
                        description: Any data or errors returned by the job
                      created_at:
                        type: string
                        description: Creation timestamp (ISO 8601)
                      updated_at:
                        type: string
                        description: Last-updated timestamp (ISO 8601)
  "/api/v1/promotions/bulk":
    post:
      summary: Bulk-create promotional codes
      tags:
      - Promotions
      description: |
        Creates many promotions in a single request, all sharing the configuration in `promotion`.
        Supply the codes explicitly via `codes`, OR ask the server to generate them via `generate`
        (exactly one of the two is required). Up to 1000 codes may be created per request.

        The response reports partial success: every requested code appears either in `created`
        or in `failed` with a reason (e.g. already taken, duplicate in request). A `201` is
        returned when all codes were created, `207` when some failed.
      parameters: []
      responses:
        '201':
          description: all codes created
          content:
            application/json:
              schema:
                type: object
                properties:
                  summary:
                    type: object
                    properties:
                      requested:
                        type: integer
                        description: Total codes requested
                      created:
                        type: integer
                        description: Number of promotions created
                      failed:
                        type: integer
                        description: Number of codes that failed
                    required:
                    - requested
                    - created
                    - failed
                  created:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                          description: Identifier for the promotion
                        listing_id:
                          type: integer
                          nullable: true
                          description: Listing the promotion is scoped to (null =
                            account-wide)
                        code:
                          type: string
                          description: The promotional code (always upper-cased)
                        name:
                          type: string
                          description: Display name shared across the batch
                        description:
                          type: string
                          nullable: true
                          description: Optional description
                        amount:
                          type: string
                          description: Discount amount (percent 0-100, or a fixed
                            currency amount)
                        discount_type:
                          type: string
                          enum:
                          - flat
                          - percent
                          description: Whether the amount is a flat value or a percentage
                        usage_type:
                          type: string
                          enum:
                          - once-per-user
                          - unlimited
                          - one-time
                          description: How often the code may be redeemed
                        active:
                          type: boolean
                          description: Whether the promotion is active
                        start_date:
                          type: string
                          nullable: true
                          description: When the promotion becomes valid (UTC)
                        end_date:
                          type: string
                          nullable: true
                          description: When the promotion expires (UTC)
                        max_per_user:
                          type: integer
                          nullable: true
                          description: Maximum redemptions per user
                        max_total_use:
                          type: integer
                          nullable: true
                          description: Maximum total redemptions
                        status:
                          type: string
                          description: Derived status (inactive, upcoming, active
                            or expired)
                        created_at:
                          type: string
                          description: When the promotion was created (UTC)
                      required:
                      - id
                      - code
                      - name
                      - amount
                      - discount_type
                      - usage_type
                      - active
                  failed:
                    type: array
                    items:
                      type: object
                      properties:
                        code:
                          type: string
                          nullable: true
                          description: The code that could not be created (null for
                            generation failures)
                        errors:
                          type: array
                          items:
                            type: string
                          description: Why this code was not created
                      required:
                      - errors
                required:
                - summary
                - created
                - failed
        '207':
          description: some codes created, some failed
          content:
            application/json:
              schema:
                type: object
                properties:
                  summary:
                    type: object
                    properties:
                      requested:
                        type: integer
                        description: Total codes requested
                      created:
                        type: integer
                        description: Number of promotions created
                      failed:
                        type: integer
                        description: Number of codes that failed
                    required:
                    - requested
                    - created
                    - failed
                  created:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                          description: Identifier for the promotion
                        listing_id:
                          type: integer
                          nullable: true
                          description: Listing the promotion is scoped to (null =
                            account-wide)
                        code:
                          type: string
                          description: The promotional code (always upper-cased)
                        name:
                          type: string
                          description: Display name shared across the batch
                        description:
                          type: string
                          nullable: true
                          description: Optional description
                        amount:
                          type: string
                          description: Discount amount (percent 0-100, or a fixed
                            currency amount)
                        discount_type:
                          type: string
                          enum:
                          - flat
                          - percent
                          description: Whether the amount is a flat value or a percentage
                        usage_type:
                          type: string
                          enum:
                          - once-per-user
                          - unlimited
                          - one-time
                          description: How often the code may be redeemed
                        active:
                          type: boolean
                          description: Whether the promotion is active
                        start_date:
                          type: string
                          nullable: true
                          description: When the promotion becomes valid (UTC)
                        end_date:
                          type: string
                          nullable: true
                          description: When the promotion expires (UTC)
                        max_per_user:
                          type: integer
                          nullable: true
                          description: Maximum redemptions per user
                        max_total_use:
                          type: integer
                          nullable: true
                          description: Maximum total redemptions
                        status:
                          type: string
                          description: Derived status (inactive, upcoming, active
                            or expired)
                        created_at:
                          type: string
                          description: When the promotion was created (UTC)
                      required:
                      - id
                      - code
                      - name
                      - amount
                      - discount_type
                      - usage_type
                      - active
                  failed:
                    type: array
                    items:
                      type: object
                      properties:
                        code:
                          type: string
                          nullable: true
                          description: The code that could not be created (null for
                            generation failures)
                        errors:
                          type: array
                          items:
                            type: string
                          description: Why this code was not created
                      required:
                      - errors
                required:
                - summary
                - created
                - failed
        '422':
          description: shared configuration invalid, or code source missing/ambiguous
          content:
            application/json:
              schema:
                type: object
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                promotion:
                  type: object
                  description: Shared configuration applied to every code
                  properties:
                    account_id:
                      type: integer
                      description: Target catalog (defaults to the key account; must
                        be it or a subcatalog)
                    listing_id:
                      type: integer
                      description: Listing to scope the promotions to (omit for account-wide)
                    name:
                      type: string
                      description: Display name
                    description:
                      type: string
                      description: Optional description
                    amount:
                      type: number
                      description: Discount amount (0-100 when discount_type is percent)
                    discount_type:
                      type: string
                      enum:
                      - flat
                      - percent
                    usage_type:
                      type: string
                      enum:
                      - once-per-user
                      - unlimited
                      - one-time
                    active:
                      type: boolean
                    start_date:
                      type: string
                      description: ISO-8601 start (UTC)
                    end_date:
                      type: string
                      description: ISO-8601 end (UTC)
                    max_per_user:
                      type: integer
                    max_total_use:
                      type: integer
                    enable_for_multi_seat_purchases:
                      type: boolean
                  required:
                  - name
                  - amount
                  - discount_type
                  - usage_type
                codes:
                  type: array
                  items:
                    type: string
                  description: Explicit list of codes to create (mutually exclusive
                    with generate)
                generate:
                  type: object
                  description: Server-side generation spec (mutually exclusive with
                    codes)
                  properties:
                    count:
                      type: integer
                      description: How many codes to generate (1-1000)
                    prefix:
                      type: string
                      description: Optional prefix prepended to every generated code
                    length:
                      type: integer
                      description: Length of the random portion (default 8)
                    charset:
                      type: string
                      enum:
                      - alphanumeric
                      - alpha
                      - numeric
                      description: Character set (default alphanumeric)
                  required:
                  - count
              required:
              - promotion
  "/api/v1/tags":
    get:
      summary: List tags
      tags:
      - Tags
      parameters:
      - name: product_ids
        in: query
        required: false
        schema:
          type: string
        description: Comma-separated product ids (max 20)
      - name: name
        in: query
        required: false
        schema:
          type: string
        description: Search tag name and associated product names
      - name: has_category
        in: query
        required: false
        schema:
          type: boolean
        description: Tag has a category or not
      responses:
        '200':
          description: tags listed
          content:
            application/json:
              schema:
                type: object
                properties:
                  tags:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                          description: Tag id
                        account_id:
                          type: integer
                          description: Account id
                        name:
                          type: string
                          description: Tag name
                        assigned_listings:
                          type: array
                          items:
                            type: object
                            properties:
                              id:
                                type: integer
                                description: Product id
                              title:
                                type: string
                                description: Product title
                              type:
                                type: string
                                description: Product type (COURSE or PROGRAM)
                              canvas_course_id:
                                type: integer
                                description: Product Canvas course id
                              archived_at:
                                type: string
                                description: Archival date (if product is archived)
                            required:
                            - id
                          description: Products associated to this tag
                        assigned_categories:
                          type: array
                          items:
                            type: object
                            properties:
                              id:
                                type: integer
                                description: Category id
                              account_id:
                                type: integer
                                description: Account id
                              tag_id:
                                type: integer
                                description: Tag id
                              created_at:
                                type: string
                              updated_at:
                                type: string
                            required:
                            - id
                            - tag_id
                            - created_at
                            - updated_at
                          description: Categories associated to this tag
                        created_at:
                          type: string
                          description: Tag created at
                        updated_at:
                          type: string
                          description: Tag updated at
                      required:
                      - id
                      - assigned_listings
                      - assigned_categories
                      - created_at
                      - updated_at
                required:
                - tags
    post:
      summary: Create a tag
      tags:
      - Tags
      parameters: []
      responses:
        '200':
          description: tag created
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: integer
                    description: Tag id
                  account_id:
                    type: integer
                    description: Account id
                  name:
                    type: string
                    description: Tag name
                  assigned_listings:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                          description: Product id
                        title:
                          type: string
                          description: Product title
                        type:
                          type: string
                          description: Product type (COURSE or PROGRAM)
                        canvas_course_id:
                          type: integer
                          description: Product Canvas course id
                        archived_at:
                          type: string
                          description: Archival date (if product is archived)
                      required:
                      - id
                    description: Products associated to this tag
                  assigned_categories:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                          description: Category id
                        account_id:
                          type: integer
                          description: Account id
                        tag_id:
                          type: integer
                          description: Tag id
                        created_at:
                          type: string
                        updated_at:
                          type: string
                      required:
                      - id
                      - tag_id
                      - created_at
                      - updated_at
                    description: Categories associated to this tag
                  created_at:
                    type: string
                    description: Tag created at
                  updated_at:
                    type: string
                    description: Tag updated at
                required:
                - id
                - assigned_listings
                - assigned_categories
                - created_at
                - updated_at
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  description: Tag name (1-255 characters)
                product_ids:
                  type: array
                  items:
                    type: integer
                  description: Product ids to associate
              required:
              - name
  "/api/v1/tags/{id}":
    get:
      summary: Get a specific tag
      tags:
      - Tags
      parameters:
      - name: id
        in: path
        schema:
          type: integer
        description: Tag id
        required: true
      responses:
        '200':
          description: tag found
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: integer
                    description: Tag id
                  account_id:
                    type: integer
                    description: Account id
                  name:
                    type: string
                    description: Tag name
                  assigned_listings:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                          description: Product id
                        title:
                          type: string
                          description: Product title
                        type:
                          type: string
                          description: Product type (COURSE or PROGRAM)
                        canvas_course_id:
                          type: integer
                          description: Product Canvas course id
                        archived_at:
                          type: string
                          description: Archival date (if product is archived)
                      required:
                      - id
                    description: Products associated to this tag
                  assigned_categories:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                          description: Category id
                        account_id:
                          type: integer
                          description: Account id
                        tag_id:
                          type: integer
                          description: Tag id
                        created_at:
                          type: string
                        updated_at:
                          type: string
                      required:
                      - id
                      - tag_id
                      - created_at
                      - updated_at
                    description: Categories associated to this tag
                  created_at:
                    type: string
                    description: Tag created at
                  updated_at:
                    type: string
                    description: Tag updated at
                required:
                - id
                - assigned_listings
                - assigned_categories
                - created_at
                - updated_at
    put:
      summary: Update a tag
      tags:
      - Tags
      parameters:
      - name: id
        in: path
        schema:
          type: integer
        description: Tag id
        required: true
      responses:
        '200':
          description: tag updated
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: integer
                    description: Tag id
                  account_id:
                    type: integer
                    description: Account id
                  name:
                    type: string
                    description: Tag name
                  assigned_listings:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                          description: Product id
                        title:
                          type: string
                          description: Product title
                        type:
                          type: string
                          description: Product type (COURSE or PROGRAM)
                        canvas_course_id:
                          type: integer
                          description: Product Canvas course id
                        archived_at:
                          type: string
                          description: Archival date (if product is archived)
                      required:
                      - id
                    description: Products associated to this tag
                  assigned_categories:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                          description: Category id
                        account_id:
                          type: integer
                          description: Account id
                        tag_id:
                          type: integer
                          description: Tag id
                        created_at:
                          type: string
                        updated_at:
                          type: string
                      required:
                      - id
                      - tag_id
                      - created_at
                      - updated_at
                    description: Categories associated to this tag
                  created_at:
                    type: string
                    description: Tag created at
                  updated_at:
                    type: string
                    description: Tag updated at
                required:
                - id
                - assigned_listings
                - assigned_categories
                - created_at
                - updated_at
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  description: New tag name (1-255 characters)
              required:
              - name
    delete:
      summary: Delete a specific tag
      tags:
      - Tags
      parameters:
      - name: id
        in: path
        schema:
          type: integer
        description: Tag id
        required: true
      responses:
        '200':
          description: tag deleted
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: integer
                    description: Tag id
                  account_id:
                    type: integer
                    description: Account id
                  name:
                    type: string
                    description: Tag name
                  assigned_listings:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                          description: Product id
                        title:
                          type: string
                          description: Product title
                        type:
                          type: string
                          description: Product type (COURSE or PROGRAM)
                        canvas_course_id:
                          type: integer
                          description: Product Canvas course id
                        archived_at:
                          type: string
                          description: Archival date (if product is archived)
                      required:
                      - id
                    description: Products associated to this tag
                  assigned_categories:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                          description: Category id
                        account_id:
                          type: integer
                          description: Account id
                        tag_id:
                          type: integer
                          description: Tag id
                        created_at:
                          type: string
                        updated_at:
                          type: string
                      required:
                      - id
                      - tag_id
                      - created_at
                      - updated_at
                    description: Categories associated to this tag
                  created_at:
                    type: string
                    description: Tag created at
                  updated_at:
                    type: string
                    description: Tag updated at
                  is_deleted:
                    type: boolean
                    description: True to indicate the tag is deleted
                required:
                - id
                - assigned_listings
                - assigned_categories
                - created_at
                - updated_at
                - is_deleted
  "/api/v1/tags/bulk":
    delete:
      summary: Delete multiple tags
      tags:
      - Tags
      parameters: []
      responses:
        '200':
          description: tags deleted
          content:
            application/json:
              schema:
                type: object
                properties:
                  tags:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                          description: Tag id
                        account_id:
                          type: integer
                          description: Account id
                        name:
                          type: string
                          description: Tag name
                        assigned_listings:
                          type: array
                          items:
                            type: object
                            properties:
                              id:
                                type: integer
                                description: Product id
                              title:
                                type: string
                                description: Product title
                              type:
                                type: string
                                description: Product type (COURSE or PROGRAM)
                              canvas_course_id:
                                type: integer
                                description: Product Canvas course id
                              archived_at:
                                type: string
                                description: Archival date (if product is archived)
                            required:
                            - id
                          description: Products associated to this tag
                        assigned_categories:
                          type: array
                          items:
                            type: object
                            properties:
                              id:
                                type: integer
                                description: Category id
                              account_id:
                                type: integer
                                description: Account id
                              tag_id:
                                type: integer
                                description: Tag id
                              created_at:
                                type: string
                              updated_at:
                                type: string
                            required:
                            - id
                            - tag_id
                            - created_at
                            - updated_at
                          description: Categories associated to this tag
                        created_at:
                          type: string
                          description: Tag created at
                        updated_at:
                          type: string
                          description: Tag updated at
                        is_deleted:
                          type: boolean
                          description: True to indicate the tag is deleted
                      required:
                      - id
                      - assigned_listings
                      - assigned_categories
                      - created_at
                      - updated_at
                      - is_deleted
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                ids:
                  type: array
                  items:
                    type: integer
                  description: Tag IDs to delete
              required:
              - ids
  "/api/v1/users/{id}":
    get:
      summary: Get a specific user
      tags:
      - Users
      parameters:
      - name: id
        in: path
        schema:
          type: integer
        description: Catalog user id
        required: true
      responses:
        '200':
          description: user found
          content:
            application/json:
              schema:
                type: object
                properties:
                  user:
                    type: object
                    properties:
                      id:
                        type: integer
                        description: Catalog user id
                      root_account_id:
                        type: integer
                        description: Root account id
                      canvas_user_id:
                        type: integer
                        description: Canvas user id
                      registered_account_id:
                        type: integer
                        description: Account where the user was registered
                      canvas_root_account_uuid:
                        type: string
                        description: Canvas root account UUID
                      canvas_user_uuid:
                        type: string
                        description: Canvas user UUID
                      user_name:
                        type: string
                        description: Full name
                      first_name:
                        type: string
                        description: First name
                      last_name:
                        type: string
                        description: Last name
                      email_address:
                        type: string
                        description: E-mail address
                      custom_fields:
                        type: object
                        description: 'Custom field values, e.g. { "phone": "(999)
                          123-4567" }'
                      created_at:
                        type: string
                        description: Date/time of creation
                      updated_at:
                        type: string
                        description: Date/time of last update
                      time_zone:
                        type: string
                        description: User timezone
                      merged_into_user_id:
                        type: integer
                        nullable: true
                        description: The user this user was merged into
                      disable_alert_timeouts:
                        type: boolean
                        description: Whether UI alert auto-dismiss timeouts are disabled
                          for this user
                    required:
                    - id
                    - root_account_id
                    - canvas_user_id
                    - custom_fields
                    - created_at
                    - updated_at
                required:
                - user
    put:
      summary: Update a specific user
      tags:
      - Users
      description: Set clear_merged_into_user_id to true to resolve the "Current user
        has been deleted or merged. Please re-login" login error.
      parameters:
      - name: id
        in: path
        schema:
          type: integer
        description: Catalog user id
        required: true
      responses:
        '200':
          description: user updated
          content:
            application/json:
              schema:
                type: object
                properties:
                  user:
                    type: object
                    properties:
                      id:
                        type: integer
                        description: Catalog user id
                      root_account_id:
                        type: integer
                        description: Root account id
                      canvas_user_id:
                        type: integer
                        description: Canvas user id
                      registered_account_id:
                        type: integer
                        description: Account where the user was registered
                      canvas_root_account_uuid:
                        type: string
                        description: Canvas root account UUID
                      canvas_user_uuid:
                        type: string
                        description: Canvas user UUID
                      user_name:
                        type: string
                        description: Full name
                      first_name:
                        type: string
                        description: First name
                      last_name:
                        type: string
                        description: Last name
                      email_address:
                        type: string
                        description: E-mail address
                      custom_fields:
                        type: object
                        description: 'Custom field values, e.g. { "phone": "(999)
                          123-4567" }'
                      created_at:
                        type: string
                        description: Date/time of creation
                      updated_at:
                        type: string
                        description: Date/time of last update
                      time_zone:
                        type: string
                        description: User timezone
                      merged_into_user_id:
                        type: integer
                        nullable: true
                        description: The user this user was merged into
                      disable_alert_timeouts:
                        type: boolean
                        description: Whether UI alert auto-dismiss timeouts are disabled
                          for this user
                    required:
                    - id
                    - root_account_id
                    - canvas_user_id
                    - custom_fields
                    - created_at
                    - updated_at
                required:
                - user
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                clear_merged_into_user_id:
                  type: boolean
                  description: Clear the merged_into_user_id field when true
                custom_fields:
                  type: object
                  description: Custom field values (strings or null); omitted keys
                    are unchanged
    delete:
      summary: Delete a specific user with dependencies
      tags:
      - Users
      description: Deletes the user and dependencies. When only_orders_and_enrollments
        is true, deletes only orders, enrollments, payments, bulk invitations, and
        applicants — not the user or related account admins.
      parameters:
      - name: id
        in: path
        schema:
          type: integer
        description: Catalog user id
        required: true
      - name: only_orders_and_enrollments
        in: query
        required: false
        schema:
          type: boolean
        description: Delete only user dependencies, not the user itself
      responses:
        '200':
          description: user (and/or dependencies) deleted
  "/api/v1/users":
    get:
      summary: List users
      tags:
      - Users
      parameters:
      - name: registered_in_catalog
        in: query
        required: false
        schema:
          type: boolean
        description: true = Catalog-registered only; false = Canvas-registered only;
          omit for all
      - name: canvas_user_id
        in: query
        required: false
        schema:
          type: integer
        description: Canvas user id
      - name: created_at_from
        in: query
        required: false
        schema:
          type: string
          format: date-time
        description: Created at from (UTC)
      - name: created_at_to
        in: query
        required: false
        schema:
          type: string
          format: date-time
        description: Created at to (UTC)
      responses:
        '200':
          description: users listed
          content:
            application/json:
              schema:
                type: object
                properties:
                  users:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: integer
                          description: Catalog user id
                        root_account_id:
                          type: integer
                          description: Root account id
                        canvas_user_id:
                          type: integer
                          description: Canvas user id
                        registered_account_id:
                          type: integer
                          description: Account where the user was registered
                        canvas_root_account_uuid:
                          type: string
                          description: Canvas root account UUID
                        canvas_user_uuid:
                          type: string
                          description: Canvas user UUID
                        user_name:
                          type: string
                          description: Full name
                        first_name:
                          type: string
                          description: First name
                        last_name:
                          type: string
                          description: Last name
                        email_address:
                          type: string
                          description: E-mail address
                        custom_fields:
                          type: object
                          description: 'Custom field values, e.g. { "phone": "(999)
                            123-4567" }'
                        created_at:
                          type: string
                          description: Date/time of creation
                        updated_at:
                          type: string
                          description: Date/time of last update
                        time_zone:
                          type: string
                          description: User timezone
                        merged_into_user_id:
                          type: integer
                          nullable: true
                          description: The user this user was merged into
                        disable_alert_timeouts:
                          type: boolean
                          description: Whether UI alert auto-dismiss timeouts are
                            disabled for this user
                      required:
                      - id
                      - root_account_id
                      - canvas_user_id
                      - custom_fields
                      - created_at
                      - updated_at
                required:
                - users
    post:
      summary: Register a user
      tags:
      - Users
      parameters: []
      responses:
        '200':
          description: user registered
          content:
            application/json:
              schema:
                type: object
                properties:
                  user:
                    type: object
                    properties:
                      id:
                        type: integer
                        description: Catalog user id
                      root_account_id:
                        type: integer
                        description: Root account id
                      canvas_user_id:
                        type: integer
                        description: Canvas user id
                      registered_account_id:
                        type: integer
                        description: Account where the user was registered
                      canvas_root_account_uuid:
                        type: string
                        description: Canvas root account UUID
                      canvas_user_uuid:
                        type: string
                        description: Canvas user UUID
                      user_name:
                        type: string
                        description: Full name
                      first_name:
                        type: string
                        description: First name
                      last_name:
                        type: string
                        description: Last name
                      email_address:
                        type: string
                        description: E-mail address
                      custom_fields:
                        type: object
                        description: 'Custom field values, e.g. { "phone": "(999)
                          123-4567" }'
                      created_at:
                        type: string
                        description: Date/time of creation
                      updated_at:
                        type: string
                        description: Date/time of last update
                      confirmation_url:
                        type: string
                        description: User confirmation URL
                      terms_of_use:
                        type: boolean
                        description: Terms-of-use flag
                      locale:
                        type: string
                        description: User locale based on registered account
                    required:
                    - id
                    - root_account_id
                    - canvas_user_id
                    - custom_fields
                    - created_at
                    - updated_at
                required:
                - user
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                user_name:
                  type: string
                  description: Full user name
                first_name:
                  type: string
                last_name:
                  type: string
                email_address:
                  type: string
                  description: E-mail address (also the login)
                registered_account_id:
                  type: integer
                  description: Subcatalog to associate (defaults to the API key root
                    account)
                custom_fields:
                  type: object
                  description: Custom field values
              required:
              - user_name
              - email_address
