openapi: 3.0.0
paths:
  /realtime/health:
    get:
      operationId: realtime_health
      parameters: []
      responses:
        '200':
          description: ''
      summary: Realtime gateway health
      tags:
        - realtime
  /boards:
    post:
      description: >-
        Creates a board owned by the authenticated user, who is added as its
        first member and administrator.


        Rate limit: at most 20 boards per hour may be created through this
        endpoint. Only boards created through the public API count towards the
        limit; boards created through the private API do not. Exceeding it
        returns 429.


        Required Body Parameters:

        - name: Name of the board


        Optional Body Parameters:

        - description: Description of the board

        - visibility: Visibility of the board (public, private, hidden).
        Defaults to public

        - safety: Safety level of the board (sfw, nsfw). Defaults to sfw

        - challengeDeadline: ISO date string for the challenge deadline
      operationId: public_board_create
      parameters: []
      requestBody:
        required: true
        description: Board creation parameters.
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BoardCreateRequest'
      responses:
        '201':
          description: The board was successfully created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BoardDto'
        '400':
          description: |-
            Bad Request. Possible reasons:

                  - `name`: Must be a non-empty string.
                  - `description`: Must be a string.
                  - `visibility`: Must be one of [public, private, hidden].
                  - `safety`: Must be one of [sfw, nsfw].
                  - `challengeDeadline`: Must be a valid ISO date string.
                
        '401':
          description: Unauthorized. Authentication token is missing or invalid.
        '422':
          description: Unprocessable Entity. The request payload contains invalid data.
        '429':
          description: >-
            Too Many Requests. The hourly board creation limit for the API has
            been reached.
        '500':
          description: Internal Server Error. An unexpected error occurred.
      security:
        - bearer: []
      summary: Create a new board
      tags:
        - boards
    get:
      description: >-
        Retrieves a paginated list of boards visible to the authenticated user:
        every public board plus the private boards the user is a member of.


        Optional Query Parameters:

        - page: Page number (default: 1)

        - limit: Items per page (1-50, default: 10)

        - sortBy: Field to sort by

        - sortOrder: "ASC" or "DESC"

        - search: Search term matched on the board name

        - name: Filter by exact board name

        - visibility: Filter by board visibility

        - safety: Filter by board safety

        - ownerId: Filter by board owner

        - isMember: Filter by board membership

        - isOwner: Filter by board ownership


        Response Headers:

        - X-Total-Count: Total count of items

        - X-Current-Page: Current page of pagination

        - X-Per-Page: Results per page

        - X-Total-Pages: Total count of pages
      operationId: public_board_list
      parameters:
        - name: page
          required: false
          in: query
          description: Page number
          schema:
            default: 1
            type: number
        - name: limit
          required: false
          in: query
          description: Number of items per page
          schema:
            default: 10
            type: number
        - name: sortBy
          required: false
          in: query
          description: Field to sort by
          schema:
            type: string
        - name: sortOrder
          required: false
          in: query
          description: Sort order (case insensitive)
          schema:
            example: ASC
            type: string
            enum:
              - ASC
              - DESC
              - asc
              - desc
        - name: search
          required: false
          in: query
          description: Search term matched on name
          schema:
            type: string
        - name: name
          required: false
          in: query
          description: Filter by exact board name
          schema:
            type: string
        - name: visibility
          required: false
          in: query
          schema:
            type: string
            enum:
              - public
              - private
              - hidden
        - name: safety
          required: false
          in: query
          schema:
            type: string
            enum:
              - nsfw
              - sfw
        - name: ownerId
          required: false
          in: query
          description: Filter by board owner
          schema:
            type: string
        - name: isMember
          required: false
          in: query
          description: Only boards the authenticated user is (not) a member of
          schema:
            type: boolean
        - name: isOwner
          required: false
          in: query
          description: Only boards the authenticated user does (not) own
          schema:
            type: boolean
      responses:
        '200':
          headers:
            X-Total-Count:
              description: Total count of items
              type: number
            X-Current-Page:
              description: Current page of pagination
              type: number
            X-Per-Page:
              description: Results per page
              type: number
            X-Total-Pages:
              description: Total count of pages
              type: number
          description: Paginated list of boards.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/BoardDto'
        '400':
          description: |-
            Bad Request. Possible reasons:

                  - Pagination parameters (`page`, `limit`) must be positive integers between 1 and 50.
                  - Sort parameters (`sortBy`, `sortOrder`) must be valid values.
                  - `visibility`: Must be one of [public, private, hidden].
                  - `safety`: Must be one of [nsfw, sfw].
                  - `ownerId`: Must be a valid UUID.
                
        '401':
          description: Unauthorized. Authentication token is missing or invalid.
        '500':
          description: Internal Server Error. An unexpected error occurred.
      security:
        - bearer: []
      summary: List boards
      tags:
        - boards
  /boards/{boardId}:
    get:
      description: >-
        Retrieves a single board by its UUID — its name, description, owner,
        thumbnail, member count, visibility and safety. Boards that are not
        public are only accessible to their members.


        Required Parameters:

        - boardId: UUID of the board


        Use `GET /boards/{boardId}/feed` for the board's images and videos.
      operationId: public_board_get
      parameters:
        - name: boardId
          required: true
          in: path
          description: UUID of the board to retrieve.
          schema:
            type: string
      responses:
        '200':
          description: The board with the specified ID.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BoardDto'
        '400':
          description: Bad Request. `boardId` must be a valid UUID.
        '401':
          description: Unauthorized. Authentication token is missing or invalid.
        '403':
          description: Forbidden. The user does not have access to this board.
        '404':
          description: Not Found. The board could not be found.
        '500':
          description: Internal Server Error. An unexpected error occurred.
      security:
        - bearer: []
      summary: Get a board by ID
      tags:
        - boards
  /boards/{boardId}/feed:
    get:
      description: >-
        Retrieves the content of a board — its images and its videos — as one
        ranked, paginated list. Boards that are not public are only accessible
        to their members. Only content that has finished generating is returned.


        Required Parameters:

        - boardId: UUID of the board


        Optional Query Parameters:

        - page: Page number (default: 1)

        - limit: Items per page (1-50, default: 10)

        - entityType: "image", "video" or "all" (default: all)

        - sortBy: "score", "createdAt", "likes" or "comments" (default: score)

        - sortOrder: "ASC" or "DESC" (default: DESC)

        - includeNsfw: Include content flagged as NSFW (default: false). Ignored
        on boards whose safety is `sfw`


        Response Headers:

        - X-Total-Count: Total count of items

        - X-Current-Page: Current page of pagination

        - X-Per-Page: Results per page

        - X-Total-Pages: Total count of pages
      operationId: public_board_feed
      parameters:
        - name: boardId
          required: true
          in: path
          description: UUID of the board.
          schema:
            format: uuid
            type: string
        - name: page
          required: false
          in: query
          description: Page number
          schema:
            default: 1
            type: number
        - name: limit
          required: false
          in: query
          description: Number of items per page
          schema:
            default: 10
            type: number
        - name: sortBy
          required: false
          in: query
          description: Field to sort by. `score` ranks by engagement and recency combined.
          schema:
            default: score
            type: string
            enum:
              - score
              - createdAt
              - likes
              - comments
        - name: sortOrder
          required: false
          in: query
          description: Sort order (case insensitive)
          schema:
            default: DESC
            example: ASC
            type: string
            enum:
              - ASC
              - DESC
              - asc
              - desc
        - name: entityType
          required: false
          in: query
          description: Restrict the feed to images only, videos only, or both
          schema:
            default: all
            type: string
            enum:
              - image
              - video
              - all
        - name: includeNsfw
          required: false
          in: query
          description: >-
            Include content flagged as NSFW. Ignored on boards whose safety is
            `sfw`.
          schema:
            default: false
            type: boolean
      responses:
        '200':
          headers:
            X-Total-Count:
              description: Total count of items
              type: number
            X-Current-Page:
              description: Current page of pagination
              type: number
            X-Per-Page:
              description: Results per page
              type: number
            X-Total-Pages:
              description: Total count of pages
              type: number
          description: Paginated feed of the board.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/BoardFeedItemDto'
        '400':
          description: |-
            Bad Request. Possible reasons:

                  - `boardId`: Must be a valid UUID.
                  - Pagination parameters (`page`, `limit`) must be positive integers between 1 and 50.
                  - `entityType`: Must be one of [image, video, all].
                  - `sortBy`: Must be one of [score, createdAt, likes, comments].
                  - `sortOrder`: Must be one of [ASC, DESC].
                
        '401':
          description: Unauthorized. Authentication token is missing or invalid.
        '403':
          description: Forbidden. The user does not have access to this board.
        '404':
          description: Not Found. The board could not be found.
        '500':
          description: Internal Server Error. An unexpected error occurred.
      security:
        - bearer: []
      summary: Get the feed of a board
      tags:
        - boards
  /images:
    post:
      description: >-
        Creates a new image generation task from a text prompt.


        Supports both user integration and organization integration tokens.


        Required Parameters:

        - prompt: Text description of the desired image


        Optional Parameters:

        - width: Image width in pixels (480-2160, default: 1600)

        - height: Image height in pixels (480-2160, default: 1600)

        - quality: Generation quality level (1-6, default: 2)

        - creativity: Creative variation level (1-6, default: 2)

        - hasWatermark: Apply watermark (default: true)

        - webhookUrl: Optional URL to receive a POST notification when
        generation is complete

        - baseModel: Base model identifier used for generation (max 255
        characters)

        - systemVersion: AI system version (2 or 3)

        - mode: Generation mode ("default" or "sigma")

        - hidePrompt: Whether to hide prompt in public listings (default: false)

        - organizationId: Organization UUID to deduct credits from (user must be
        a member)


        Credit Deduction:

        - If organizationId is provided, credits will be deducted from the
        organization account

        - If organizationId is not provided, credits will be deducted from the
        user account

        - User must be a member of the organization to use organization credits


        Monitor the generation status using the GET /images/{id} endpoint.
      operationId: images_create
      parameters: []
      requestBody:
        required: true
        description: >-
          The image creation request parameters including prompt, dimensions,
          and quality settings
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ImageRequest'
      responses:
        '201':
          description: >-
            The image generation request was successfully created and queued for
            processing
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ImageDto'
        '400':
          description: |2-

                  Bad Request. Possible reasons:
                  - `width`: Must be between 480 and 2160 pixels.
                  - `height`: Must be between 480 and 2160 pixels.
                  - `quality`: Must be between 1 and 6.
                  - `creativity`: Must be between 1 and 6.
                  - `systemVersion`: Must be either 2 or 3.
                  - `mode`: Must be a valid value from the `ModeEnum`.
                  - `organizationId`: Must be a valid UUID format.
                  - Invalid or unavailable model referenced in prompt.
                  - Failed to analyze prompt or parameters.
                
        '401':
          description: >-
            Unauthorized. Authentication token is missing or invalid, or user is
            not a member of the specified organization
        '402':
          description: >-
            Payment Required. Insufficient credits to create the image (either
            user or organization credits depending on request)
        '500':
          description: >-
            Internal Server Error. An unexpected error occurred during image
            creation
      security:
        - bearer: []
      summary: Create a new image
      tags:
        - images
    get:
      description: |-
        Retrieves a paginated list of images.

        Query Parameters:
        - page: Page number (default: 1)
        - limit: Items per page (1-50, default: 10)
        - sortBy: Field to sort by
        - sortOrder: "ASC" or "DESC"
        - userId: Filter by user ID
        - username: Filter by username
        - privacy: Filter by privacy level
        - systemVersion: Filter by system version
        - isHot: Filter by hot images
        - includeNsfw: Include NSFW content (default: false)
        - onlyFollowing: Show only images from followed users
        - modelIds: Filter by model IDs
        - status: Filter by status (see Status Values)

        Status Values:
        - new: Initial state, waiting to be processed
        - generating: Currently being generated
        - ready: Generation completed successfully
        - failed: Generation failed
        - interrupted: Generation was interrupted
        - not_allowed: Generation was rejected

        Response Headers:
        - X-Total-Count: Total count of items
        - X-Current-Page: Current page of pagination
        - X-Per-Page: Results per page
        - X-Total-Pages: Total count of pages
      operationId: images_find
      parameters:
        - name: page
          required: false
          in: query
          description: Page number
          schema:
            default: 1
            type: number
        - name: limit
          required: false
          in: query
          description: Number of items per page
          schema:
            default: 10
            type: number
        - name: sortBy
          required: false
          in: query
          description: Field to sort by
          schema:
            type: string
        - name: sortOrder
          required: false
          in: query
          description: Sort order (case insensitive)
          schema:
            example: ASC
            type: string
            enum:
              - ASC
              - DESC
              - asc
              - desc
        - name: userId
          required: false
          in: query
          schema:
            type: string
        - name: username
          required: false
          in: query
          schema:
            type: string
        - name: privacy
          required: true
          in: query
          schema:
            type: string
            enum:
              - public
              - private
              - licensed
        - name: status
          required: true
          in: query
          schema:
            type: string
            enum:
              - new
              - generating
              - ready
              - hidden
              - failed
              - interrupted
              - not_allowed
        - name: systemVersion
          required: false
          in: query
          schema:
            type: number
        - name: isHot
          required: false
          in: query
          schema:
            type: boolean
        - name: includeNsfw
          required: true
          in: query
          schema:
            type: boolean
        - name: onlyFollowing
          required: false
          in: query
          schema:
            type: boolean
        - name: modelIds
          required: false
          in: query
          schema:
            type: array
            items:
              type: string
        - description: Page number
          required: false
          name: page
          in: query
          schema:
            default: 1
            type: number
        - description: Number of items per page
          required: false
          name: limit
          in: query
          schema:
            default: 10
            type: number
        - description: Field to sort by
          required: false
          name: sortBy
          in: query
          schema:
            type: string
        - description: Sort order (case insensitive)
          required: false
          name: sortOrder
          in: query
          schema:
            example: ASC
            type: string
        - required: false
          name: userId
          in: query
          schema:
            type: string
        - required: false
          name: username
          in: query
          schema:
            type: string
        - name: privacy
          in: query
          required: true
          schema:
            type: string
        - name: status
          in: query
          required: true
          schema:
            type: string
        - required: false
          name: systemVersion
          in: query
          schema:
            type: number
        - required: false
          name: isHot
          in: query
          schema:
            type: boolean
        - name: includeNsfw
          in: query
          required: true
          schema:
            type: boolean
        - required: false
          name: onlyFollowing
          in: query
          schema:
            type: boolean
        - required: false
          name: modelIds
          in: query
          schema:
            type: array
            items:
              type: string
      responses:
        '200':
          headers:
            X-Total-Count:
              description: Total count of items
              type: number
            X-Current-Page:
              description: Current page of pagination
              type: number
            X-Per-Page:
              description: Results per page
              type: number
            X-Total-Pages:
              description: Total count of pages
              type: number
          description: Successfully retrieved the list of images
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ImageDto'
        '400':
          description: |2-

                  Bad Request. Possible reasons:
                  - `page`: Must be a positive integer.
                  - `limit`: Must be a positive integer between 1 and 50.
                  - `sortBy`: Must be one of the allowed sort fields.
                  - `sortOrder`: Must be either 'ASC' or 'DESC'.
                  - Invalid filter parameters provided.
                  - Malformed query parameters.
                
        '401':
          description: Unauthorized. Authentication token is missing or invalid
        '500':
          description: >-
            Internal Server Error. An unexpected error occurred while retrieving
            images
      security:
        - bearer: []
      summary: Find and filter images
      tags:
        - images
  /images/{id}:
    get:
      description: |-
        Retrieves information about a specific image by ID.

        Path Parameters:
        - id: UUID of the image
      operationId: images_get
      parameters:
        - name: id
          required: true
          in: path
          description: The unique identifier of the image
          schema:
            format: uuid
            type: string
      responses:
        '200':
          description: Successfully retrieved the image details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ImageDto'
        '400':
          description: |2-

                  Bad Request. Possible reasons:
                  - `id`: Must be a valid UUID format.
                
        '401':
          description: Unauthorized. Authentication token is missing or invalid
        '404':
          description: >-
            Not Found. The requested image does not exist, or is not public and
            belongs to someone else
        '500':
          description: >-
            Internal Server Error. An unexpected error occurred while retrieving
            the image
      security:
        - bearer: []
      summary: Get detailed image information
      tags:
        - images
  /images/{id}/interruption:
    put:
      description: |-
        Stops the ongoing generation process for a specific image.

        Path Parameters:
        - id: UUID of the image to interrupt

        The endpoint will:
        - Stop the generation process
        - Update image status to interrupted

        This endpoint only works for images in NEW or GENERATING status.
      operationId: images_interrupt
      parameters:
        - name: id
          required: true
          in: path
          description: The unique identifier of the image to interrupt
          schema:
            format: uuid
            type: string
      responses:
        '204':
          description: The image generation was successfully interrupted.
        '400':
          description: |2-

                  Bad Request. Possible reasons:
                  - Image is not in NEW or GENERATING state
                  - Image does not exist
                  - Image belongs to another user
                
        '401':
          description: Unauthorized. The user is not authenticated.
        '404':
          description: Not Found. The requested image could not be found.
        '500':
          description: Internal Server Error. An unexpected error occurred.
      security:
        - bearer: []
      summary: Interrupt image generation
      tags:
        - images
  /images/{id}/privacy:
    put:
      description: |-
        Changes the privacy settings of an image.

        Path Parameters:
        - id: UUID of the image

        Request Body:
        - privacy: New privacy level (public, private, organization)

        This endpoint only works for images in READY status.
      operationId: images_privacy_change
      parameters:
        - name: id
          required: true
          in: path
          description: The unique identifier of the image to update
          schema:
            format: uuid
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ImagePrivacyRequest'
      responses:
        '204':
          description: The image privacy was successfully updated.
        '400':
          description: |2-

                  Bad Request. Possible reasons:
                  - Image is not in READY state
                  - Image contains NSFW content
                  - Image uses private models
                  - Invalid privacy value
                
        '401':
          description: Unauthorized. The user is not authenticated.
        '404':
          description: Not Found. The requested image could not be found.
        '500':
          description: Internal Server Error. An unexpected error occurred.
      security:
        - bearer: []
      summary: Update image privacy
      tags:
        - images
  /images/{id}/prompt-privacy:
    put:
      description: |-
        Changes the prompt privacy settings of an image.

        Path Parameters:
        - id: UUID of the image

        Request Body:
        - hidePrompt: Boolean indicating if the prompt should be hidden

        This endpoint only works for images owned by the authenticated user.
      operationId: images_prompt_privacy_change
      parameters:
        - name: id
          required: true
          in: path
          description: The unique identifier of the image to update prompt privacy
          schema:
            format: uuid
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ImagePromptPrivacyRequest'
      responses:
        '204':
          description: The image prompt privacy was successfully updated.
        '400':
          description: |2-

                  Bad Request. Possible reasons:
                  - Invalid prompt privacy value
                
        '401':
          description: Unauthorized. The user is not authenticated.
        '404':
          description: Not Found. The requested image could not be found.
        '500':
          description: Internal Server Error. An unexpected error occurred.
      security:
        - bearer: []
      summary: Update image prompt privacy
      tags:
        - images
  /image-edits:
    post:
      description: >-
        Creates an image edit task that modifies an existing image using
        inpainting, outpainting, or skin editing.


        Required Parameters:

        - mode: "in" for inpainting (modify within image), "out" for outpainting
        (extend image), "skin" for skin editing, or "context" for context
        editing


        Optional Parameters:

        - originalImageCompletionIds: Array of UUIDs of original image
        completions

        - inputImageUrls: Array of source image URLs to edit

        - originalImageCompletionId: UUID of the original image completion to
        edit (alternative to inputImageUrls)

        - imageUrl: Source image URL to edit (alternative to
        originalImageCompletionIds)

        - prompt: Text description of the desired modifications

        - baseModel: Base model identifier for generation (max 255 characters)

        - mask: Base64 encoded image mask (required for inpainting)

        - width/height: Target dimensions for the edited image in pixels

        - imageCompletionsCount: Number of variations to generate (1-5, default:
        3)

        - organizationId: Organization UUID to deduct credits from (user must be
        a member)

        - settings: Additional generation settings object

        - hidePrompt: Whether to hide prompt in public listings (default: false)

        - webhookUrl: Optional URL to receive a POST notification when edit is
        complete


        Credit Deduction:

        - If organizationId is provided, credits will be deducted from the
        organization account

        - If organizationId is not provided, credits will be deducted from the
        user account

        - User must be a member of the organization to use organization credits


        Response includes:

        - originalImageCompletions: Array of original image completions used as
        source

        - originalImageCompletionIds: Array of UUIDs of original image
        completions


        Monitor the edit status using the GET /image-edits/{id} endpoint.
      operationId: image_edit_create
      parameters: []
      requestBody:
        required: true
        description: The image edit request parameters
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ImageEditRequest'
      responses:
        '201':
          description: The image edit was successfully created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ImageEditDto'
        '400':
          description: |2-

                  Bad Request. Possible reasons:
                  - Invalid input parameters
                  - Source image does not exist
                  - Source image is not in a valid state
                  - Invalid edit settings
                  - organizationId: Must be a valid UUID format
                
        '401':
          description: >-
            Unauthorized. The user is not authenticated, or user is not a member
            of the specified organization.
        '402':
          description: >-
            Payment Required. Insufficient credits to create the image edit
            (either user or organization credits depending on request).
        '500':
          description: >-
            Internal Server Error. An unexpected error occurred during image
            edit creation.
      security:
        - bearer: []
      summary: Create a new image edit
      tags:
        - image-edit
    get:
      description: |-
        Retrieves a paginated list of image edits.

        Query Parameters:
        - page: Page number (default: 1)
        - limit: Items per page (default: 20)
        - sortBy: Field to sort by (createdAt, status)
        - sortOrder: "ASC" or "DESC"
        - status: Filter by status (see Status Values)

        Status Values:
        - new: Edit task created but not started
        - generating: Currently processing the edit
        - ready: Edit completed successfully
        - saved: Edit has been saved by user
        - failed: Edit failed to process
        - interrupted: Edit was stopped by user

        Response Headers:
        - X-Total-Count: Total count of items
        - X-Current-Page: Current page of pagination
        - X-Per-Page: Results per page
        - X-Total-Pages: Total count of pages
      operationId: image_edit_find
      parameters:
        - name: page
          required: false
          in: query
          description: Page number
          schema:
            default: 1
            type: number
        - name: limit
          required: false
          in: query
          description: Number of items per page
          schema:
            default: 10
            type: number
        - name: sortBy
          required: false
          in: query
          description: Field to sort by
          schema:
            type: string
        - name: sortOrder
          required: false
          in: query
          description: Sort order (case insensitive)
          schema:
            example: ASC
            type: string
            enum:
              - ASC
              - DESC
              - asc
              - desc
        - name: status
          required: true
          in: query
          schema:
            type: string
            enum:
              - new
              - generating
              - ready
              - saved
              - failed
              - interrupted
        - description: Page number
          required: false
          name: page
          in: query
          schema:
            default: 1
            type: number
        - description: Number of items per page
          required: false
          name: limit
          in: query
          schema:
            default: 10
            type: number
        - description: Field to sort by
          required: false
          name: sortBy
          in: query
          schema:
            type: string
        - description: Sort order (case insensitive)
          required: false
          name: sortOrder
          in: query
          schema:
            example: ASC
            type: string
        - name: status
          in: query
          required: true
          schema:
            type: string
      responses:
        '200':
          description: List of image edits successfully retrieved.
          headers:
            X-Total-Count:
              description: Total count of items
              type: number
            X-Current-Page:
              description: Current page of pagination
              type: number
            X-Per-Page:
              description: Results per page
              type: number
            X-Total-Pages:
              description: Total count of pages
              type: number
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ImageEditDto'
        '400':
          description: |2-

                  Bad Request. Possible reasons:
                  - Invalid pagination parameters
                  - Invalid sort parameters
                  - Invalid filter values
                
        '401':
          description: Unauthorized. The user is not authenticated.
        '500':
          description: >-
            Internal Server Error. An unexpected error occurred while retrieving
            the image edits.
      security:
        - bearer: []
      summary: Find image edits
      tags:
        - image-edit
  /image-edits/{id}:
    get:
      description: |+
        Retrieves a specific image edit by ID.

        Path Parameters:
        - id: UUID of the image edit

      operationId: image_edit_get
      parameters:
        - name: id
          required: true
          in: path
          description: The unique identifier of the image edit to retrieve
          schema:
            type: string
      responses:
        '200':
          description: The image edit was successfully retrieved.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ImageEditDto'
        '400':
          description: |2-

                  Bad Request. Possible reasons:
                  - Invalid ID format
                
        '401':
          description: Unauthorized. The user is not authenticated.
        '404':
          description: Not Found. The requested image edit could not be found.
        '500':
          description: >-
            Internal Server Error. An unexpected error occurred while retrieving
            the image edit.
      security:
        - bearer: []
      summary: Get an image edit
      tags:
        - image-edit
  /image-edits/{imageCompletionId}/mask:
    get:
      description: >-
        Retrieves the mask associated with an image completion.


        Path Parameters:

        - imageCompletionId: UUID of the image completion


        Returns the mask data that was used for the image edit. This endpoint is
        useful for retrieving the original mask used in inpainting operations.
      operationId: image_edit_get_mask
      parameters:
        - name: imageCompletionId
          required: true
          in: path
          description: ID of the image completion to retrieve the mask for
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ImageEditMaskDto'
        '400':
          description: ''
      security:
        - bearer: []
      summary: Get mask for image completion
      tags:
        - image-edit
  /models:
    get:
      description: |-
        Retrieves a list of models based on search criteria.

        Query Parameters:
        - page: Page number
        - limit: Items per page
        - sortBy: Field to sort by
        - sortOrder: Sort direction (ASC, DESC)
        - search: General search term
        - name: Filter by model name
        - userId: Filter by user ID
        - username: Filter by username
        - class: Filter by model class
        - type: Filter by model type
        - description: Filter by model description
        - privacy: Filter by privacy level (public, private, licensed)
        - systemVersion: Filter by system version
        - isActive: Filter by active status
        - status: Filter by status (see Status Values)

        Status Values:
        - new: Initial state after creation
        - pending: Waiting for training to start
        - training: Currently being trained
        - finished: Training completed
        - available: Ready for public use
        - failed: Training failed

        Response Headers:
        - X-Total-Count: Total count of items
        - X-Current-Page: Current page of pagination
        - X-Per-Page: Results per page
        - X-Total-Pages: Total count of pages
      operationId: models_find
      parameters:
        - name: page
          required: false
          in: query
          description: Page number
          schema:
            default: 1
            type: number
        - name: limit
          required: false
          in: query
          description: Number of items per page
          schema:
            default: 10
            type: number
        - name: sortBy
          required: false
          in: query
          description: Field to sort by
          schema:
            type: string
        - name: sortOrder
          required: false
          in: query
          description: Sort order (case insensitive)
          schema:
            example: ASC
            type: string
            enum:
              - ASC
              - DESC
              - asc
              - desc
        - name: search
          required: false
          in: query
          schema:
            type: string
        - name: name
          required: false
          in: query
          schema:
            type: string
        - name: userId
          required: false
          in: query
          schema:
            type: string
        - name: username
          required: false
          in: query
          schema:
            type: string
        - name: class
          required: false
          in: query
          schema:
            type: string
        - name: type
          required: false
          in: query
          schema:
            type: string
        - name: description
          required: false
          in: query
          schema:
            type: string
        - name: privacy
          required: false
          in: query
          schema:
            type: string
            enum:
              - public
              - private
              - licensed
        - name: systemVersion
          required: false
          in: query
          schema:
            type: number
        - name: status
          required: false
          in: query
          schema:
            type: string
            enum:
              - new
              - pending
              - training
              - finished
              - available
              - failed
        - name: isActive
          required: false
          in: query
          schema:
            type: boolean
        - description: Page number
          required: false
          name: page
          in: query
          schema:
            default: 1
            type: number
        - description: Number of items per page
          required: false
          name: limit
          in: query
          schema:
            default: 10
            type: number
        - description: Field to sort by
          required: false
          name: sortBy
          in: query
          schema:
            type: string
        - description: Sort order (case insensitive)
          required: false
          name: sortOrder
          in: query
          schema:
            example: ASC
            type: string
        - required: false
          name: search
          in: query
          schema:
            type: string
        - required: false
          name: name
          in: query
          schema:
            type: string
        - required: false
          name: userId
          in: query
          schema:
            type: string
        - required: false
          name: username
          in: query
          schema:
            type: string
        - required: false
          name: class
          in: query
          schema:
            type: string
        - required: false
          name: type
          in: query
          schema:
            type: string
        - required: false
          name: description
          in: query
          schema:
            type: string
        - required: false
          name: privacy
          in: query
          schema:
            type: string
        - required: false
          name: systemVersion
          in: query
          schema:
            type: number
        - required: false
          name: status
          in: query
          schema:
            type: string
        - required: false
          name: isActive
          in: query
          schema:
            type: boolean
      responses:
        '200':
          headers:
            X-Total-Count:
              description: Total count of items
              type: number
            X-Current-Page:
              description: Current page of pagination
              type: number
            X-Per-Page:
              description: Results per page
              type: number
            X-Total-Pages:
              description: Total count of pages
              type: number
          description: List of models matching the search criteria.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ModelDto'
        '400':
          description: |2-

                  Bad Request. Possible reasons:
                  - Invalid query parameters
                  - Invalid pagination values
                  - Invalid sort parameters
                  - Malformed filters
                
        '401':
          description: Unauthorized. The user is not authenticated.
        '422':
          description: Unprocessable Entity. The search request contains invalid data.
        '500':
          description: >-
            Internal Server Error. An unexpected error occurred while retrieving
            models.
      security:
        - bearer: []
      summary: Find models
      tags:
        - models
    post:
      description: >-
        Creates a new AI model for image generation.


        Request Body Parameters:

        - name: Model identifier (alphanumeric, underscores, dots)

        - privacy: Access level (public, private, organization)

        - type: Model type classification

        - class: Model category

        - description: Optional description of the model

        - website: Optional website URL

        - settings: Optional array of settings (NO_ADULT_CONTENT, NO_VIOLENCE,
        etc)

        - trainingDataUrls: Optional array of image URLs for training (when
        provided: 1-50 URLs)

        - webhookUrl: Optional URL to receive a POST notification when training
        is complete

        - trainingMode: Optional training mode (e.g., "default", "sigma")

        - organizationId: Organization UUID to deduct credits from (user must be
        a member)


        Credit Deduction:

        - If organizationId is provided, credits will be deducted from the
        organization account

        - If organizationId is not provided, credits will be deducted from the
        user account

        - User must be a member of the organization to use organization credits


        Training starts automatically after creation.
      operationId: models_create
      parameters: []
      requestBody:
        required: true
        description: The model creation request payload
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ModelCreateRequest'
      responses:
        '201':
          description: The model was successfully created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ModelDto'
        '400':
          description: |2-

                  Bad Request. Possible reasons:
                  - `name`: Must contain only alphanumeric characters, underscores, and dots.
                  - `name`: Must be shorter than or equal to 255 characters.
                  - `privacy`: Must be a valid value from the `PrivacyEnum`.
                  - `type`: Must contain only allowed characters (alphanumeric, commas, hyphens, etc.).
                  - `class`: Must be a valid value from the `ClassEnum`.
                  - `trainingDataUrls`: Must be an array of valid URLs (max 50).
                  - `webhookUrl`: Must be a valid URL.
                  - `trainingMode`: Must be a valid value from the `TrainingModeEnum`.
                  - `organizationId`: Must be a valid UUID format.
                  - Missing or invalid `class` field (mandatory).
                  - Failed to analyze model type due to invalid training data URLs.
                
        '401':
          description: >-
            Unauthorized. The user is not authenticated, or user is not a member
            of the specified organization.
        '402':
          description: >-
            Payment Required. Insufficient credits to create the model (either
            user or organization credits depending on request).
        '404':
          description: Not Found. The requested resource could not be found.
        '500':
          description: Internal Server Error. An unexpected error occurred.
      security:
        - bearer: []
      summary: Create a new model
      tags:
        - models
  /models/{id}:
    get:
      description: |
        Retrieves detailed information about a specific model.

        Path Parameters:
        - id: UUID of the model to retrieve
      operationId: models_get
      parameters:
        - name: id
          required: true
          in: path
          description: The unique identifier of the model to retrieve
          schema:
            format: uuid
            type: string
      responses:
        '200':
          description: The requested model details.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ModelDto'
        '400':
          description: |2-

                  Bad Request. Possible reasons:
                  - Invalid ID format
                
        '401':
          description: Unauthorized. The user is not authenticated.
        '404':
          description: Not Found. The requested model could not be found.
        '500':
          description: >-
            Internal Server Error. An unexpected error occurred while retrieving
            the model.
      security:
        - bearer: []
      summary: Get a model
      tags:
        - models
    patch:
      description: |-
        Updates the information of an existing model.

        Path Parameters:
        - id: UUID of the model

        Request Body:
        - privacy: New privacy setting (public, private, licensed)
        - type: New model type
        - description: New model description
        - website: New website URL
        - settings: New model settings
      operationId: model_update
      parameters:
        - name: id
          required: true
          in: path
          description: Model ID
          schema:
            format: uuid
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ModelUpdateRequest'
      responses:
        '200':
          description: The model was successfully updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ModelDto'
        '400':
          description: Invalid request parameters or model ID format
        '401':
          description: Unauthorized. The user is not authenticated
        '404':
          description: Not Found. The model to update could not be found
      security:
        - bearer: []
      summary: Update model information
      tags:
        - models
    delete:
      description: |-
        Permanently deletes a model.

        Path Parameters:
        - id: UUID of the model to delete
      operationId: models_delete
      parameters:
        - name: id
          required: true
          in: path
          description: The unique identifier of the model to delete
          schema:
            format: uuid
            type: string
      responses:
        '204':
          description: The model was successfully deleted.
        '400':
          description: |2-

                  Bad Request. Possible reasons:
                  - Invalid ID format
                  - Model is in use by active generations
                
        '401':
          description: Unauthorized. The user is not authenticated.
        '404':
          description: Not Found. The requested model could not be found.
        '409':
          description: >-
            Conflict. The model cannot be deleted because it is being used by
            other resources.
        '500':
          description: >-
            Internal Server Error. An unexpected error occurred while deleting
            the model.
      security:
        - bearer: []
      summary: Delete a model
      tags:
        - models
  /models/{id}/thumbnail:
    put:
      description: |-
        Updates the thumbnail of a model.

        Path Parameters:
        - id: UUID of the model

        Request Body:
        - imageCompletionId: UUID of the image to use as thumbnail
      operationId: model_thumbnail
      parameters:
        - name: id
          required: true
          in: path
          description: The unique identifier of the model to update
          schema:
            format: uuid
            type: string
      requestBody:
        required: true
        description: The thumbnail update request containing the image completion ID
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ModelThumbnailRequest'
      responses:
        '200':
          description: The model thumbnail was successfully updated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ModelDto'
        '400':
          description: |2-

                  Bad Request. Possible reasons:
                  - Invalid model ID format
                  - Invalid image completion ID
                  - Image completion not ready
                  - Image completion does not belong to this model
                
        '401':
          description: Unauthorized. The user is not authenticated.
        '404':
          description: Not Found. The model to update could not be found.
        '409':
          description: |2-

                  Conflict. Possible reasons:
                  - Model is currently being processed
                  - Model is in an invalid state for updates
                
        '422':
          description: Unprocessable Entity. The request payload contains invalid data.
        '500':
          description: >-
            Internal Server Error. An unexpected error occurred while updating
            the thumbnail.
      security:
        - bearer: []
      summary: Update model thumbnail
      tags:
        - models
  /upscale:
    post:
      description: >-
        Creates a new upscale request for an existing image.


        Request Body:

        - prompt: Optional text prompt to guide the upscale

        - mode: Upscale mode (any string, max 32 characters; default: default)

        - imageId: UUID of the source image (required if imageUrl not provided)

        - imageUrl: Direct URL to the image (required if imageId not provided)

        - type: Asset type (image or video; default: image)

        - assetUrl: Direct URL to the source asset

        - assetId: UUID of the source asset

        - size: Optional size of the upscale

        - strength: Upscale strength factor from 1 to 5 (default: 1)

        - organizationId: Organization UUID to deduct credits from (user must be
        a member)

        - webhookUrl: Optional URL to receive a POST notification when upscale
        is complete


        Credit Deduction:

        - If organizationId is provided, credits will be deducted from the
        organization account

        - If organizationId is not provided, credits will be deducted from the
        user account

        - User must be a member of the organization to use organization credits
      operationId: upscale_create
      parameters: []
      requestBody:
        required: true
        description: The upscale request parameters
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpscaleRequest'
      responses:
        '201':
          description: The upscale request was successfully created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UpscaleDto'
        '400':
          description: |2-

                  Bad Request. Possible reasons:
                  - Invalid image ID
                  - Invalid upscale parameters
                  - Source image not in ready state
                  - organizationId: Must be a valid UUID format
                  - Organization does not exist
                  - Size must be at least 2
                  - Size must be at most 1024
                  - mode: Must be a string (max 32 characters).
                
        '401':
          description: >-
            Unauthorized. The user is not authenticated, or user is not a member
            of the specified organization.
        '402':
          description: >-
            Payment Required. Insufficient credit balance (either user or
            organization credits depending on request).
        '422':
          description: Unprocessable Entity. The request payload contains invalid data.
        '500':
          description: Internal Server Error. An unexpected error occurred.
      security:
        - bearer: []
      summary: Generate a new upscale
      tags:
        - upscale
    get:
      description: |-
        Retrieves a paginated list of upscales.

        Query Parameters:
        - page: Page number (default: 1)
        - limit: Items per page (1-50, default: 10)
        - sortBy: Field to sort by
        - sortOrder: "ASC" or "DESC"
        - userId: Filter by user ID
        - username: Filter by username
        - imageId: Filter by source image ID
        - onlyFollowing: Show only upscales from followed users
        - status: Filter by status (see Status Values)

        Status Values:
        - new: Initial state, waiting to be processed
        - generating: Currently being upscaled
        - ready: Upscale completed successfully
        - failed: Upscale failed

        Response Headers:
        - X-Total-Count: Total count of items
        - X-Current-Page: Current page of pagination
        - X-Per-Page: Results per page
        - X-Total-Pages: Total count of pages
      operationId: upscale_find
      parameters:
        - name: page
          required: false
          in: query
          description: Page number
          schema:
            default: 1
            type: number
        - name: limit
          required: false
          in: query
          description: Number of items per page
          schema:
            default: 10
            type: number
        - name: sortBy
          required: false
          in: query
          description: Field to sort by
          schema:
            type: string
        - name: sortOrder
          required: false
          in: query
          description: Sort order (case insensitive)
          schema:
            example: ASC
            type: string
            enum:
              - ASC
              - DESC
              - asc
              - desc
        - name: userId
          required: false
          in: query
          schema:
            type: string
        - name: username
          required: false
          in: query
          schema:
            type: string
        - name: imageId
          required: false
          in: query
          schema:
            type: string
        - name: status
          required: false
          in: query
          schema:
            type: string
            enum:
              - new
              - generating
              - ready
              - failed
        - name: onlyFollowing
          required: false
          in: query
          schema:
            type: boolean
        - description: Page number
          required: false
          name: page
          in: query
          schema:
            default: 1
            type: number
        - description: Number of items per page
          required: false
          name: limit
          in: query
          schema:
            default: 10
            type: number
        - description: Field to sort by
          required: false
          name: sortBy
          in: query
          schema:
            type: string
        - description: Sort order (case insensitive)
          required: false
          name: sortOrder
          in: query
          schema:
            example: ASC
            type: string
        - required: false
          name: userId
          in: query
          schema:
            type: string
        - required: false
          name: username
          in: query
          schema:
            type: string
        - required: false
          name: imageId
          in: query
          schema:
            type: string
        - required: false
          name: status
          in: query
          schema:
            type: string
        - required: false
          name: onlyFollowing
          in: query
          schema:
            type: boolean
      responses:
        '200':
          headers:
            X-Total-Count:
              description: Total count of items
              type: number
            X-Current-Page:
              description: Current page of pagination
              type: number
            X-Per-Page:
              description: Results per page
              type: number
            X-Total-Pages:
              description: Total count of pages
              type: number
          description: List of upscales matching the search criteria.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/UpscaleDto'
        '400':
          description: Bad Request. The request parameters are invalid.
        '401':
          description: Unauthorized. The user is not authenticated.
        '422':
          description: Unprocessable Entity. Invalid search parameters.
        '500':
          description: Internal Server Error. An unexpected error occurred.
      security:
        - bearer: []
      summary: Find upscales
      tags:
        - upscale
  /upscale/{id}:
    get:
      description: |-
        Retrieves details of a specific upscale.

        Path Parameters:
        - id: UUID of the upscale to retrieve
      operationId: upscale_get
      parameters:
        - name: id
          required: true
          in: path
          description: The unique identifier of the upscale to retrieve
          schema:
            format: uuid
            type: string
      responses:
        '200':
          description: The requested upscale details.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UpscaleDto'
        '400':
          description: Bad Request. The request parameters are invalid.
        '401':
          description: Unauthorized. The user is not authenticated.
        '404':
          description: Not Found. The requested upscale could not be found.
        '500':
          description: Internal Server Error. An unexpected error occurred.
      security:
        - bearer: []
      summary: Get upscale details
      tags:
        - upscale
    delete:
      description: |-
        Deletes an existing upscale request.

        Path Parameters:
        - id: UUID of the upscale to delete
      operationId: upscale_delete
      parameters:
        - name: id
          required: true
          in: path
          description: The unique identifier of the upscale to delete
          schema:
            format: uuid
            type: string
      responses:
        '204':
          description: The upscale was successfully deleted.
        '400':
          description: Bad Request. The request parameters are invalid.
        '401':
          description: Unauthorized. The user is not authenticated.
        '404':
          description: Not Found. The upscale to delete could not be found.
        '422':
          description: Unprocessable Entity. Invalid request parameters.
        '500':
          description: Internal Server Error. An unexpected error occurred.
      security:
        - bearer: []
      summary: Delete an upscale
      tags:
        - upscale
  /user-images:
    post:
      description: >-
        Creates a new image or video entry and generates an upload URL.


        Supported formats:

        - Images: jpg, jpeg, png, gif, webp

        - Videos: mp4, webm, mov, avi


        The response includes an 'uploadUrl' property which is a pre-signed S3
        URL that can be used to upload the file.


        To upload the file:

        1. Make a PUT request to the uploadUrl with the file as the request body

        2. Set the Content-Type header to match the file type (e.g.,
        'image/jpeg', 'image/png', 'video/mp4', 'video/webm')

        3. No authentication is required for this PUT request as the URL is
        pre-signed


        Example uploading an image using curl:

        ```

        curl -X PUT -H "Content-Type: image/jpeg" --data-binary
        "@/path/to/image.jpg" "https://pre-signed-url-from-response"

        ```


        Example uploading a video using curl:

        ```

        curl -X PUT -H "Content-Type: video/mp4" --data-binary
        "@/path/to/video.mp4" "https://pre-signed-url-from-response"

        ```


        Example using JavaScript fetch:

        ```javascript

        const response = await fetch(uploadUrl, {
          method: 'PUT',
          headers: {
            'Content-Type': 'video/mp4' // or 'image/jpeg', etc.
          },
          body: file // File or Blob object
        });

        ```


        After successful upload, the file will be accessible via the 'imageUrl'
        property in the response.
      operationId: user_image_create
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UserImageRequest'
      responses:
        '201':
          description: The user image asset record was successfully created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserImageDto'
        '400':
          description: Invalid request parameters
        '401':
          description: Unauthorized. The user is not authenticated
        '402':
          description: Payment Required. Insufficient credit balance.
        '404':
          description: Not Found. The requested resource could not be found.
        '422':
          description: Unprocessable Entity. The request payload contains invalid data.
        '429':
          description: Too Many Requests. Please try again later.
        '500':
          description: Internal Server Error. An unexpected error occurred.
      security:
        - bearer: []
      summary: Create a new user image or video
      tags:
        - user-images
    get:
      description: >-
        Returns a list of images and videos uploaded by the authenticated user.


        The list is sorted by creation date in descending order, with a maximum
        of 100 items per page.
      operationId: user_image_list
      parameters: []
      responses:
        '200':
          description: List of user images and videos retrieved successfully
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/UserImageDto'
        '400':
          description: Invalid request parameters
        '401':
          description: Unauthorized. The user is not authenticated
        '422':
          description: Unprocessable Entity. Invalid request parameters
        '429':
          description: Too Many Requests. Please try again later
        '500':
          description: Internal Server Error. An unexpected error occurred
      security:
        - bearer: []
      summary: List user images and videos
      tags:
        - user-images
  /user-images/{id}:
    get:
      description: |-
        Returns details of a specific image or video from your library.

        Path Parameters:
        - id: UUID of the file
      operationId: user_image_get
      parameters:
        - name: id
          required: true
          in: path
          description: File ID
          schema:
            format: uuid
            type: string
      responses:
        '200':
          description: The user image or video was successfully retrieved
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserImageDto'
        '400':
          description: Invalid file ID format
        '401':
          description: Unauthorized. The user is not authenticated
        '404':
          description: Not Found. The requested file could not be found
        '422':
          description: Unprocessable Entity. Invalid request parameters
        '429':
          description: Too Many Requests. Please try again later
        '500':
          description: Internal Server Error. An unexpected error occurred
      security:
        - bearer: []
      summary: Get a user image or video
      tags:
        - user-images
    delete:
      description: |-
        Deletes a user image from your library.

        Path Parameters:
        - id: UUID of the image to delete
      operationId: user_image_delete
      parameters:
        - name: id
          required: true
          in: path
          description: Image ID
          schema:
            format: uuid
            type: string
      responses:
        '204':
          description: The image was successfully deleted
        '400':
          description: Invalid image ID format
        '401':
          description: Unauthorized. The user is not authenticated
        '404':
          description: Not Found. The image to delete could not be found
        '422':
          description: Unprocessable Entity. Invalid request parameters
        '500':
          description: >-
            Internal Server Error. An unexpected error occurred while deleting
            the image
      security:
        - bearer: []
      summary: Delete a user image
      tags:
        - user-images
  /user-assets:
    post:
      description: >-
        Creates a new asset entry and generates an upload URL.


        Supported formats:

        - Images: jpg, jpeg, png, gif, webp

        - Videos: mp4, webm, mov, avi

        - Audio: mp3, wav, ogg, m4a, aac, flac


        The response includes an 'uploadUrl' property which is a pre-signed S3
        URL that can be used to upload the file.


        To upload the file:

        1. Make a PUT request to the uploadUrl with the file as the request body

        2. Set the Content-Type header to match the file type (e.g.,
        'image/jpeg', 'video/mp4', 'audio/mpeg')

        3. No authentication is required for this PUT request as the URL is
        pre-signed


        Example uploading an image using curl:

        ```

        curl -X PUT -H "Content-Type: image/jpeg" --data-binary
        "@/path/to/image.jpg" "https://pre-signed-url-from-response"

        ```


        Example uploading a video using curl:

        ```

        curl -X PUT -H "Content-Type: video/mp4" --data-binary
        "@/path/to/video.mp4" "https://pre-signed-url-from-response"

        ```


        Example uploading an audio file using curl:

        ```

        curl -X PUT -H "Content-Type: audio/mpeg" --data-binary
        "@/path/to/audio.mp3" "https://pre-signed-url-from-response"

        ```


        Example using JavaScript fetch:

        ```javascript

        const response = await fetch(uploadUrl, {
          method: 'PUT',
          headers: {
            'Content-Type': 'audio/mpeg' // or 'image/jpeg', 'video/mp4', etc.
          },
          body: file // File or Blob object
        });

        ```


        After successful upload, the file will be accessible via the 'imageUrl'
        property in the response.
      operationId: user_asset_create
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UserAssetRequest'
      responses:
        '201':
          description: The user asset record was successfully created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserAssetDto'
        '400':
          description: Invalid request parameters
        '401':
          description: Unauthorized. The user is not authenticated
        '402':
          description: Payment Required. Insufficient credit balance.
        '404':
          description: Not Found. The requested resource could not be found.
        '422':
          description: Unprocessable Entity. The request payload contains invalid data.
        '429':
          description: Too Many Requests. Please try again later.
        '500':
          description: Internal Server Error. An unexpected error occurred.
      security:
        - bearer: []
      summary: Create a new user asset (image, video, or audio)
      tags:
        - user-assets
    get:
      description: >-
        Returns a list of images and videos uploaded by the authenticated user.


        The list is sorted by creation date in descending order, with a maximum
        of 100 items per page.
      operationId: user_asset_list
      parameters: []
      responses:
        '200':
          description: List of user assets (images and videos) retrieved successfully
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/UserAssetDto'
        '400':
          description: Invalid request parameters
        '401':
          description: Unauthorized. The user is not authenticated
        '422':
          description: Unprocessable Entity. Invalid request parameters
        '429':
          description: Too Many Requests. Please try again later
        '500':
          description: Internal Server Error. An unexpected error occurred
      security:
        - bearer: []
      summary: List user assets (images and videos)
      tags:
        - user-assets
  /user-assets/{id}:
    get:
      description: |-
        Returns details of a specific image or video from your library.

        Path Parameters:
        - id: UUID of the file
      operationId: user_asset_get
      parameters:
        - name: id
          required: true
          in: path
          description: File ID
          schema:
            format: uuid
            type: string
      responses:
        '200':
          description: The user asset (image or video) was successfully retrieved
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserAssetDto'
        '400':
          description: Invalid file ID format
        '401':
          description: Unauthorized. The user is not authenticated
        '404':
          description: Not Found. The requested file could not be found
        '422':
          description: Unprocessable Entity. Invalid request parameters
        '429':
          description: Too Many Requests. Please try again later
        '500':
          description: Internal Server Error. An unexpected error occurred
      security:
        - bearer: []
      summary: Get a user asset (image or video)
      tags:
        - user-assets
    patch:
      description: >-
        Updates editable fields of a user asset from your library. Currently
        supports caption updates.
      operationId: public_user_asset_update
      parameters:
        - name: id
          required: true
          in: path
          description: Asset ID
          schema:
            format: uuid
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UserAssetUpdateRequest'
      responses:
        '200':
          description: The asset was successfully updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserAssetDto'
        '400':
          description: Invalid request parameters
        '401':
          description: Unauthorized. The user is not authenticated
        '403':
          description: Forbidden. User does not have permission to update this asset
        '404':
          description: Not Found. The asset to update could not be found
        '422':
          description: Unprocessable Entity. Invalid request parameters
        '500':
          description: >-
            Internal Server Error. An unexpected error occurred while updating
            the asset
      security:
        - bearer: []
      summary: Update a user asset
      tags:
        - user-assets
    delete:
      description: |-
        Deletes a user asset from your library.

        Path Parameters:
        - id: UUID of the asset to delete
      operationId: user_asset_delete
      parameters:
        - name: id
          required: true
          in: path
          description: Asset ID
          schema:
            format: uuid
            type: string
      responses:
        '204':
          description: The asset was successfully deleted
        '400':
          description: Invalid asset ID format
        '401':
          description: Unauthorized. The user is not authenticated
        '404':
          description: Not Found. The asset to delete could not be found
        '422':
          description: Unprocessable Entity. Invalid request parameters
        '500':
          description: >-
            Internal Server Error. An unexpected error occurred while deleting
            the asset
      security:
        - bearer: []
      summary: Delete a user asset
      tags:
        - user-assets
  /videos:
    get:
      description: |-
        Retrieves a paginated list of videos.

        Optional Query Parameters:
        - page: Page number (default: 1)
        - limit: Items per page (1-50, default: 10)
        - sortBy: Field to sort by
        - sortOrder: "ASC" or "DESC"
        - userId: Filter by user ID
        - username: Filter by username
        - status: Filter by video status
        - width: Filter by video width
        - height: Filter by video height
        - resolution: Filter by video resolution
        - prompt: Filter by prompt text
        - hidePrompt: Filter by hidden prompts
      operationId: public_video_list
      parameters:
        - name: page
          required: false
          in: query
          description: Page number
          schema:
            default: 1
            type: number
        - name: limit
          required: false
          in: query
          description: Number of items per page
          schema:
            default: 10
            type: number
        - name: sortBy
          required: false
          in: query
          description: Field to sort by
          schema:
            type: string
        - name: sortOrder
          required: false
          in: query
          description: Sort order (case insensitive)
          schema:
            example: ASC
            type: string
            enum:
              - ASC
              - DESC
              - asc
              - desc
        - name: userId
          required: false
          in: query
          description: Filter by user ID
          schema:
            type: string
        - name: username
          required: false
          in: query
          description: Filter by username
          schema:
            type: string
        - name: organizationId
          required: false
          in: query
          description: Filter by organization ID
          schema:
            type: string
        - name: originalImageCompletionId
          required: false
          in: query
          description: Filter by original image completion ID
          schema:
            type: string
        - name: prompt
          required: false
          in: query
          description: Filter by prompt text
          schema:
            type: string
        - name: status
          required: false
          in: query
          description: Filter by video status
          schema:
            type: string
            enum:
              - new
              - generating
              - ready
              - saved
              - failed
              - interrupted
        - name: width
          required: false
          in: query
          description: Filter by width
          schema:
            type: number
        - name: height
          required: false
          in: query
          description: Filter by height
          schema:
            type: number
        - name: resolution
          required: false
          in: query
          description: Filter by resolution
          schema:
            type: number
        - name: isNsfw
          required: false
          in: query
          description: Filter by NSFW content
          schema:
            type: boolean
        - name: isHot
          required: false
          in: query
          description: Filter by hot content
          schema:
            type: boolean
        - name: isUnsafe
          required: false
          in: query
          description: Filter by unsafe content
          schema:
            type: boolean
        - name: hidePrompt
          required: false
          in: query
          description: Filter by hidden prompts
          schema:
            type: boolean
        - name: modelIds
          required: false
          in: query
          description: Array of model IDs to filter by
          schema:
            type: array
            items:
              type: string
        - description: Page number
          required: false
          name: page
          in: query
          schema:
            default: 1
            type: number
        - description: Number of items per page
          required: false
          name: limit
          in: query
          schema:
            default: 10
            type: number
        - description: Field to sort by
          required: false
          name: sortBy
          in: query
          schema:
            type: string
        - description: Sort order (case insensitive)
          required: false
          name: sortOrder
          in: query
          schema:
            example: ASC
            type: string
        - description: Filter by user ID
          required: false
          name: userId
          in: query
          schema:
            type: string
        - description: Filter by username
          required: false
          name: username
          in: query
          schema:
            type: string
        - description: Filter by organization ID
          required: false
          name: organizationId
          in: query
          schema:
            type: string
        - description: Filter by original image completion ID
          required: false
          name: originalImageCompletionId
          in: query
          schema:
            type: string
        - description: Filter by prompt text
          required: false
          name: prompt
          in: query
          schema:
            type: string
        - description: Filter by video status
          required: false
          name: status
          in: query
          schema:
            type: string
        - description: Filter by width
          required: false
          name: width
          in: query
          schema:
            type: number
        - description: Filter by height
          required: false
          name: height
          in: query
          schema:
            type: number
        - description: Filter by resolution
          required: false
          name: resolution
          in: query
          schema:
            type: number
        - description: Filter by NSFW content
          required: false
          name: isNsfw
          in: query
          schema:
            type: boolean
        - description: Filter by hot content
          required: false
          name: isHot
          in: query
          schema:
            type: boolean
        - description: Filter by unsafe content
          required: false
          name: isUnsafe
          in: query
          schema:
            type: boolean
        - description: Filter by hidden prompts
          required: false
          name: hidePrompt
          in: query
          schema:
            type: boolean
        - description: Array of model IDs to filter by
          required: false
          name: modelIds
          in: query
          schema:
            type: array
            items:
              type: string
      responses:
        '200':
          description: Paginated list of videos
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/VideoDto'
        '400':
          description: |-
            Bad Request. Possible reasons:

                  - Pagination parameters (page, limit) must be positive integers between 1 and 50.
                  - Sort parameters (sortBy, sortOrder) must be valid values.
                  - Filter parameters must be valid values.
                  - userId: Must be a valid UUID.
                  - username: Must be a valid username.
                  - status: Must be a valid video status.
                  - width/height/resolution: Must be valid numbers.
                
        '401':
          description: Unauthorized. Authentication token is missing or invalid.
        '500':
          description: >-
            Internal Server Error. An unexpected error occurred while retrieving
            videos.
      security:
        - bearer: []
      summary: List videos (public API)
      tags:
        - videos
    post:
      description: >-
        Creates a new video generation request.


        Required Parameters:

        - prompt: Text description for the video


        Input Source (Optional):

        - originalImageCompletionId, imageUrl, or imageUrls can be provided for
        image-to-video flows

        - If none are provided, text-to-video generation is used


        Optional Parameters:

        - assetUrls: Additional input asset URLs used by some video models

        - organizationId: Organization ID for organization accounts

        - width: Video width in pixels

        - height: Video height in pixels

        - resolution: Video resolution

        - baseModel: Base model identifier for video generation (max 255
        characters)

        - webhookUrl: URL to receive progress notifications

        - hidePrompt: Whether to hide prompt in public listings (default: false)

        - settings: Additional generation settings


        Authentication: Requires valid JWT token.


        Rate Limits: Subject to user account limits.
      operationId: public_video_create
      parameters: []
      requestBody:
        required: true
        description: Video creation request parameters
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PublicVideoRequest'
      responses:
        '201':
          description: Video creation request submitted successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VideoDto'
        '400':
          description: |-
            Bad Request. Possible reasons:

                  - Missing required field (prompt)
                  - Invalid field values or formats
                  - Invalid UUID format for originalImageCompletionId or organizationId
                  - Invalid URL format for imageUrl or webhookUrl
                  - Width, height, resolution must be positive integers
                  - Settings must be a valid object
                
        '401':
          description: Unauthorized. Valid JWT token required.
        '402':
          description: Payment Required. Insufficient credit balance.
        '404':
          description: Not Found. Referenced originalImageCompletionId does not exist.
        '429':
          description: Too Many Requests. Rate limit exceeded.
        '500':
          description: >-
            Internal Server Error. An unexpected error occurred during video
            creation.
      security:
        - bearer: []
      summary: Create a new video (public API)
      tags:
        - videos
  /videos/{id}:
    get:
      description: |-
        Retrieves a specific video by its UUID.

        Required Parameters:
        - id: UUID of the video
      operationId: public_video_get
      parameters:
        - name: id
          required: true
          in: path
          description: UUID of the video to retrieve.
          schema:
            type: string
      responses:
        '200':
          description: Returns the video with the specified ID.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VideoDto'
        '400':
          description: |-
            Bad Request. Possible reasons:

                  - id: Must be a valid UUID.
                  - Invalid or unavailable parameters.
                
        '401':
          description: Unauthorized. Authentication token is missing or invalid.
        '404':
          description: >-
            Not Found. Video with the specified ID does not exist, or is not
            public (private or licensed) and owned by someone else.
        '500':
          description: >-
            Internal Server Error. An unexpected error occurred while retrieving
            the video.
      security:
        - bearer: []
      summary: Get video by ID (public API)
      tags:
        - videos
  /videos/{id}/privacy:
    put:
      description: |-
        Changes the privacy settings of a video.

        Path Parameters:
        - id: UUID of the video

        Request Body:
        - privacy: New privacy level (public, private, organization)

        This endpoint only works for videos owned by the authenticated user.
      operationId: public_videos_privacy_change
      parameters:
        - name: id
          required: true
          in: path
          description: The unique identifier of the video to update
          schema:
            format: uuid
            type: string
      requestBody:
        required: true
        description: Privacy update parameters.
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VideoPrivacyRequest'
      responses:
        '204':
          description: Video privacy updated successfully
        '400':
          description: Bad Request. Invalid video ID or parameters
        '401':
          description: Unauthorized. Authentication required
        '404':
          description: Not Found. The video could not be found
        '500':
          description: Internal Server Error. Unexpected error occurred
      security:
        - bearer: []
      summary: Update video privacy
      tags:
        - videos
  /videos/{id}/prompt-privacy:
    put:
      description: |-
        Changes the prompt privacy settings of a video.

        Path Parameters:
        - id: UUID of the video

        Request Body:
        - hidePrompt: Boolean indicating if the prompt should be hidden

        This endpoint only works for videos owned by the authenticated user.
      operationId: public_videos_prompt_privacy_change
      parameters:
        - name: id
          required: true
          in: path
          description: The unique identifier of the video to update
          schema:
            format: uuid
            type: string
      requestBody:
        required: true
        description: Prompt privacy update parameters.
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VideoPromptPrivacyRequest'
      responses:
        '204':
          description: Video prompt privacy updated successfully
        '400':
          description: Bad Request. Invalid video ID or parameters
        '401':
          description: Unauthorized. Authentication required
        '404':
          description: Not Found. The video could not be found
        '500':
          description: Internal Server Error. Unexpected error occurred
      security:
        - bearer: []
      summary: Update video prompt privacy
      tags:
        - videos
  /audios:
    post:
      description: >-
        Starts a speech, music or sound effect generation. Poll GET /audios/:id
        until the status is ready or failed.


        - kind: speech, music or sfx

        - text: the words to speak (speech)

        - prompt: what the sound should be (music, sound effects; optional
        direction for speech)

        - baseModel: model identifier

        - organizationId: bill an organization you belong to
      operationId: public_audio_create
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PublicAudioRequest'
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicAudioDto'
        '400':
          description: Invalid parameters.
        '401':
          description: Missing or invalid token, or not a member of the organization.
        '402':
          description: Insufficient credit balance.
        '503':
          description: Audio generation is not configured on this environment.
      security:
        - bearer: []
      summary: Generate audio (public API)
      tags:
        - audios
    get:
      description: Your generated audio, newest first. Filter by status or kind.
      operationId: public_audio_list
      parameters:
        - name: page
          required: false
          in: query
          description: Page number
          schema:
            default: 1
            type: number
        - name: limit
          required: false
          in: query
          description: Number of items per page
          schema:
            default: 10
            type: number
        - name: sortBy
          required: false
          in: query
          description: Field to sort by
          schema:
            type: string
        - name: sortOrder
          required: false
          in: query
          description: Sort order (case insensitive)
          schema:
            example: ASC
            type: string
            enum:
              - ASC
              - DESC
              - asc
              - desc
        - name: status
          required: false
          in: query
          schema:
            type: string
            enum:
              - new
              - generating
              - ready
              - failed
        - name: kind
          required: false
          in: query
          schema:
            type: string
            enum:
              - speech
              - music
              - sound_effect
        - description: Page number
          required: false
          name: page
          in: query
          schema:
            default: 1
            type: number
        - description: Number of items per page
          required: false
          name: limit
          in: query
          schema:
            default: 10
            type: number
        - description: Field to sort by
          required: false
          name: sortBy
          in: query
          schema:
            type: string
        - description: Sort order (case insensitive)
          required: false
          name: sortOrder
          in: query
          schema:
            example: ASC
            type: string
        - required: false
          name: status
          in: query
          schema:
            type: string
        - required: false
          name: kind
          in: query
          schema:
            type: string
      responses:
        '200':
          headers:
            X-Total-Count:
              description: Total count of items
              type: number
            X-Current-Page:
              description: Current page of pagination
              type: number
            X-Per-Page:
              description: Results per page
              type: number
            X-Total-Pages:
              description: Total count of pages
              type: number
          description: ''
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/PublicAudioDto'
      security:
        - bearer: []
      summary: List your audio (public API)
      tags:
        - audios
  /audios/{id}:
    get:
      operationId: public_audio_get
      parameters:
        - name: id
          required: true
          in: path
          description: UUID of the audio job
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicAudioDto'
        '404':
          description: Not found, or not yours.
      security:
        - bearer: []
      summary: Get one of your audio jobs (public API)
      tags:
        - audios
    delete:
      operationId: public_audio_delete
      parameters:
        - name: id
          required: true
          in: path
          description: UUID of the audio job
          schema:
            type: string
      responses:
        '204':
          description: Deleted.
        '404':
          description: Not found, or not yours.
      security:
        - bearer: []
      summary: Delete one of your audio jobs (public API)
      tags:
        - audios
  /video-edits:
    post:
      description: >-
        Starts a video edit from source videos (originalVideoIds or
        inputVideoUrls), optionally with input images. Poll GET /video-edits/:id
        until the status is ready or failed.
      operationId: public_video_edit_create
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PublicVideoEditRequest'
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicVideoEditDto'
        '400':
          description: Invalid parameters.
        '401':
          description: Missing or invalid token, or not a member of the organization.
        '402':
          description: Insufficient credit balance.
        '404':
          description: >-
            An originalVideoIds entry does not exist, or is not public and owned
            by someone else.
      security:
        - bearer: []
      summary: Edit a video (public API)
      tags:
        - video-edits
    get:
      operationId: public_video_edit_list
      parameters:
        - name: page
          required: false
          in: query
          description: Page number
          schema:
            default: 1
            type: number
        - name: limit
          required: false
          in: query
          description: Number of items per page
          schema:
            default: 10
            type: number
        - name: sortBy
          required: false
          in: query
          description: Field to sort by
          schema:
            type: string
        - name: sortOrder
          required: false
          in: query
          description: Sort order (case insensitive)
          schema:
            example: ASC
            type: string
            enum:
              - ASC
              - DESC
              - asc
              - desc
        - name: status
          required: true
          in: query
          schema:
            type: string
            enum:
              - new
              - generating
              - ready
              - saved
              - failed
              - interrupted
        - description: Page number
          required: false
          name: page
          in: query
          schema:
            default: 1
            type: number
        - description: Number of items per page
          required: false
          name: limit
          in: query
          schema:
            default: 10
            type: number
        - description: Field to sort by
          required: false
          name: sortBy
          in: query
          schema:
            type: string
        - description: Sort order (case insensitive)
          required: false
          name: sortOrder
          in: query
          schema:
            example: ASC
            type: string
        - name: status
          in: query
          required: true
          schema:
            type: string
      responses:
        '200':
          headers:
            X-Total-Count:
              description: Total count of items
              type: number
            X-Current-Page:
              description: Current page of pagination
              type: number
            X-Per-Page:
              description: Results per page
              type: number
            X-Total-Pages:
              description: Total count of pages
              type: number
          description: ''
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/PublicVideoEditDto'
      security:
        - bearer: []
      summary: List your video edits (public API)
      tags:
        - video-edits
  /video-edits/{id}:
    get:
      operationId: public_video_edit_get
      parameters:
        - name: id
          required: true
          in: path
          description: UUID of the video edit
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicVideoEditDto'
        '404':
          description: Not found, or not yours.
      security:
        - bearer: []
      summary: Get one of your video edits (public API)
      tags:
        - video-edits
    delete:
      operationId: public_video_edit_delete
      parameters:
        - name: id
          required: true
          in: path
          description: UUID of the video edit
          schema:
            type: string
      responses:
        '204':
          description: Deleted.
        '404':
          description: Not found, or not yours.
      security:
        - bearer: []
      summary: Delete one of your video edits (public API)
      tags:
        - video-edits
  /video-edits/{id}/interrupt:
    put:
      operationId: public_video_edit_interrupt
      parameters:
        - name: id
          required: true
          in: path
          description: UUID of the video edit
          schema:
            type: string
      responses:
        '204':
          description: Interrupted.
        '400':
          description: The edit is not being generated.
        '404':
          description: Not found, or not yours.
      security:
        - bearer: []
      summary: Interrupt one of your video edits (public API)
      tags:
        - video-edits
  /video-edits/{id}/save/{videoId}:
    patch:
      operationId: public_video_edit_save_video_choice
      parameters:
        - name: id
          required: true
          in: path
          description: UUID of the video edit
          schema:
            type: string
        - name: videoId
          required: true
          in: path
          description: UUID of the chosen video
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicVideoEditDto'
        '404':
          description: Edit not found or not yours, or not one of its choices.
      security:
        - bearer: []
      summary: Keep one of the generated choices (public API)
      tags:
        - video-edits
  /search:
    get:
      description: >-
        Searches finished images and videos by prompt, user, model, date range
        and type. Returns your own items (private included) and everybody’s
        public items; `privacy=private` narrows to your own private items,
        `privacy=public` to public ones.


        Pagination is cursor-based: pass `pagination.nextCursor` back as
        `cursor`.
      operationId: public_search
      parameters:
        - name: userId
          required: false
          in: query
          description: Filter by user id (UUID)
          schema:
            type: string
        - name: username
          required: false
          in: query
          description: Filter by username
          schema:
            type: string
        - name: modelId
          required: false
          in: query
          description: Filter by model id (UUID)
          schema:
            type: string
        - name: prompt
          required: false
          in: query
          description: Filter by prompt
          schema:
            type: string
        - name: startDate
          required: false
          in: query
          description: Filter start date (ISO-8601)
          schema:
            example: '2026-01-01T00:00:00.000Z'
            type: string
        - name: endDate
          required: false
          in: query
          description: Filter end date (ISO-8601)
          schema:
            example: '2026-01-31T23:59:59.999Z'
            type: string
        - name: assetType
          required: false
          in: query
          schema:
            default: all
            type: string
            enum:
              - image
              - video
              - all
        - name: privacy
          required: false
          in: query
          schema:
            default: all
            type: string
            enum:
              - private
              - public
              - all
        - name: cursor
          required: false
          in: query
          description: Opaque cursor from previous response (base64 encoded JSON)
          schema:
            type: string
        - name: limit
          required: false
          in: query
          description: Items per page
          schema:
            default: 20
            type: number
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicSearchResponseDto'
        '400':
          description: Invalid query parameters.
      security:
        - bearer: []
      summary: Search images and videos (public API)
      tags:
        - search
  /feed/me:
    get:
      description: >-
        Everything you generated, private included, newest first by default.
        Sounds (`entityType: audio`) carry `audioUrl`, `audioKind` and
        `durationSeconds`; `entityType=audio` returns only them. Use
        `status=generating,failed,ready` to include jobs still running or that
        failed (`generating` covers new + generating, `failed` covers failed +
        interrupted); without it only finished items are returned.


        Pagination is cursor-based: pass `pagination.nextCursor` back as
        `cursor`.
      operationId: public_feed_me
      parameters:
        - name: limit
          required: false
          in: query
          description: Number of items to return (1-100)
          schema:
            minimum: 1
            maximum: 100
            type: number
        - name: cursor
          required: false
          in: query
          description: Pagination cursor (compound base64 cursor)
          schema:
            type: string
        - name: entityType
          required: false
          in: query
          description: Filter by entity type
          schema:
            type: string
            enum:
              - image
              - video
              - audio
        - name: privacy
          required: false
          in: query
          description: Privacy filter (only works for own profile)
          schema:
            type: string
            enum:
              - public
              - private
              - all
        - name: status
          required: false
          in: query
          description: >-
            Filter by generation status, comma-separated or repeated.
            `generating` covers new + generating, `failed` covers failed +
            interrupted. Only works for your own profile; defaults to ready.
          schema:
            type: array
            items:
              type: string
              enum:
                - ready
                - generating
                - failed
                - new
                - interrupted
        - name: modelIds
          required: false
          in: query
          description: Filter by model IDs (UUID array)
          schema:
            type: array
            items:
              type: string
        - name: baseModels
          required: false
          in: query
          description: >-
            Only items made with one of these base models. Repeated
            (`baseModels=a&baseModels=b`), bracketed (`baseModels[]=a`), single
            or comma-separated; at most 25 values of up to 100 characters,
            matched exactly. The values `GET /v2/feed/user/:userId/facets` lists
            are the ones that match. For a video this is usually the model of
            the still it was animated from, not its video model.
          schema:
            maxItems: 25
            example:
              - gemini-3-pro-image
              - audio-eleven-music
            type: array
            items:
              type: string
        - name: sortOrder
          required: false
          in: query
          description: 'Sort order (default: asc). random ignores sortBy/cursor.'
          schema:
            type: string
            enum:
              - asc
              - desc
              - random
        - name: sortBy
          required: false
          in: query
          description: 'Sort field (default: contentCreatedAt)'
          schema:
            type: string
            enum:
              - likes
              - comments
              - regenerations
              - engagementScore
              - trendingScore
              - createdAt
              - contentCreatedAt
        - name: startDate
          required: false
          in: query
          description: Start date filter (ISO 8601)
          schema:
            type: string
        - name: endDate
          required: false
          in: query
          description: End date filter (ISO 8601)
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnifiedFeedResponseDto'
        '400':
          description: Invalid query parameters.
      security:
        - bearer: []
      summary: Your own images, videos and sounds (public API)
      tags:
        - feed
  /skills:
    get:
      operationId: public_skill_list
      parameters:
        - name: page
          required: false
          in: query
          description: Page number
          schema:
            default: 1
            type: number
        - name: limit
          required: false
          in: query
          description: Number of items per page
          schema:
            default: 10
            type: number
        - name: sortBy
          required: false
          in: query
          description: Field to sort by
          schema:
            type: string
        - name: sortOrder
          required: false
          in: query
          description: Sort order (case insensitive)
          schema:
            example: ASC
            type: string
            enum:
              - ASC
              - DESC
              - asc
              - desc
        - name: search
          required: false
          in: query
          description: Case-insensitive match against name and description.
          schema:
            type: string
        - name: surface
          required: false
          in: query
          description: Only skills declaring this surface.
          schema:
            type: string
            enum:
              - canvas
              - chat
              - worker
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SkillListDto'
      security:
        - bearer: []
      summary: List skills visible to you (public API)
      tags:
        - skills
  /skills/effective:
    get:
      description: >-
        Your active skills plus the skills active on `canvasId` (if given), for
        one surface, ordered by (priority, name). Metadata only; fetch a body
        with GET /skills/:id/body.
      operationId: public_skill_effective
      parameters:
        - name: canvasId
          required: false
          in: query
          description: >-
            Canvas context. Omit for a chat with no canvas — only the USER scope
            is then resolved.
          schema:
            type: string
        - name: surface
          required: true
          in: query
          description: The agent surface asking. Skills not declaring it are excluded.
          schema:
            type: string
            enum:
              - canvas
              - chat
              - worker
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SkillDto'
      security:
        - bearer: []
      summary: Resolve the effective skill set for a chat (public API)
      tags:
        - skills
  /skills/{id}/body:
    get:
      description: >-
        Readable if you own the skill, or — passing `canvasId` — if the skill is
        active on a canvas you can see.
      operationId: public_skill_body
      parameters:
        - name: id
          required: true
          in: path
          schema:
            type: string
        - name: canvasId
          required: false
          in: query
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SkillBodyDto'
        '404':
          description: ''
      security:
        - bearer: []
      summary: Read a skill body (public API)
      tags:
        - skills
  /skills/{id}/files:
    get:
      operationId: public_skill_file_list
      parameters:
        - name: id
          required: true
          in: path
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SkillFileDto'
      security:
        - bearer: []
      summary: List the bundled files of a skill you own (public API)
      tags:
        - skills
  /skills/{id}/file:
    get:
      description: Paths contain slashes, so the path travels as a query parameter.
      operationId: public_skill_file_get
      parameters:
        - name: id
          required: true
          in: path
          schema:
            type: string
        - name: path
          required: true
          in: query
          schema:
            example: references/models/flux2.md
            type: string
        - name: canvasId
          required: false
          in: query
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SkillFileDto'
        '404':
          description: ''
      security:
        - bearer: []
      summary: Read one bundled file (public API)
      tags:
        - skills
  /skills/{id}:
    get:
      operationId: public_skill_get
      parameters:
        - name: id
          required: true
          in: path
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SkillDto'
        '404':
          description: ''
      security:
        - bearer: []
      summary: Read a skill’s metadata (public API)
      tags:
        - skills
  /organizations:
    get:
      description: >-
        The accounts you can bill: pass an id as `organizationId` when
        generating.
      operationId: public_organization_list
      parameters:
        - name: page
          required: false
          in: query
          description: Page number
          schema:
            default: 1
            type: number
        - name: limit
          required: false
          in: query
          description: Number of items per page
          schema:
            default: 10
            type: number
        - name: sortBy
          required: false
          in: query
          description: Field to sort by
          schema:
            type: string
        - name: sortOrder
          required: false
          in: query
          description: Sort order (case insensitive)
          schema:
            example: ASC
            type: string
            enum:
              - ASC
              - DESC
              - asc
              - desc
        - name: name
          required: true
          in: query
          schema:
            type: string
        - description: Page number
          required: false
          name: page
          in: query
          schema:
            default: 1
            type: number
        - description: Number of items per page
          required: false
          name: limit
          in: query
          schema:
            default: 10
            type: number
        - description: Field to sort by
          required: false
          name: sortBy
          in: query
          schema:
            type: string
        - description: Sort order (case insensitive)
          required: false
          name: sortOrder
          in: query
          schema:
            example: ASC
            type: string
        - name: name
          in: query
          required: true
          schema:
            type: string
      responses:
        '200':
          headers:
            X-Total-Count:
              description: Total count of items
              type: number
            X-Current-Page:
              description: Current page of pagination
              type: number
            X-Per-Page:
              description: Results per page
              type: number
            X-Total-Pages:
              description: Total count of pages
              type: number
          description: ''
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/PublicApiOrganizationDto'
      security:
        - bearer: []
      summary: List the organizations you belong to (public API)
      tags:
        - organizations
  /organizations/{id}/credit-balances:
    get:
      description: >-
        Unexpired balances per credit type, as you see them: when the
        organization allocates credits per member, this is your share.
      operationId: public_organization_credit_balances
      parameters:
        - name: id
          required: true
          in: path
          description: Organization UUID
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/OrganizationCreditBalanceDto'
        '404':
          description: Not found, or you are not a member.
      security:
        - bearer: []
      summary: Credit balances of an organization you belong to (public API)
      tags:
        - organizations
  /organizations/{id}:
    get:
      operationId: public_organization_get
      parameters:
        - name: id
          required: true
          in: path
          description: Organization UUID
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicApiOrganizationDto'
        '404':
          description: Not found, or you are not a member.
      security:
        - bearer: []
      summary: Get an organization you belong to (public API)
      tags:
        - organizations
  /conversations/{conversationId}/designs:
    get:
      description: Newest first; rows omit `files` (use filesCount).
      operationId: public_studio_designs_list
      parameters:
        - name: conversationId
          required: true
          in: path
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StudioDesignListResponseDto'
        '404':
          description: Conversation not found.
      security:
        - bearer: []
      summary: List the designs in one of your conversations (public API)
      tags:
        - studio designs
  /conversations/{conversationId}/designs/{designId}:
    get:
      operationId: public_studio_design_get
      parameters:
        - name: conversationId
          required: true
          in: path
          schema:
            type: string
        - name: designId
          required: true
          in: path
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StudioDesignGetResponseDto'
        '404':
          description: Conversation or design not found.
      security:
        - bearer: []
      summary: Get a design with its files (public API)
      tags:
        - studio designs
    put:
      description: >-
        designId is minted by the client (^[A-Za-z0-9_-]{1,64}$) and must equal
        body.designId. If-Match is required (0 creates). Send snapshotVersion:
        true on checkpoints only.
      operationId: public_studio_design_put
      parameters:
        - name: conversationId
          required: true
          in: path
          schema:
            type: string
        - name: designId
          required: true
          in: path
          schema:
            type: string
        - name: if-match
          required: true
          in: header
          schema:
            type: string
        - name: idempotency-key
          required: true
          in: header
          schema:
            type: string
        - name: Idempotency-Key
          in: header
          description: Replays the first response for a retried identical write.
          required: false
          schema:
            type: string
        - name: If-Match
          in: header
          description: The design version you last saw; 0 to create.
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StudioDesignPutRequest'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StudioDesignPutResponseDto'
        '400':
          description: Invalid design payload or If-Match.
        '404':
          description: Conversation not found.
        '409':
          description: VERSION_MISMATCH (with currentDesign) or IDEMPOTENCY_IN_PROGRESS.
        '429':
          description: Rate limit exceeded.
      security:
        - bearer: []
      summary: Create or replace a design (public API)
      tags:
        - studio designs
    delete:
      description: Unpublishes it first. If-Match is required.
      operationId: public_studio_design_delete
      parameters:
        - name: conversationId
          required: true
          in: path
          schema:
            type: string
        - name: designId
          required: true
          in: path
          schema:
            type: string
        - name: if-match
          required: true
          in: header
          schema:
            type: string
        - name: If-Match
          in: header
          description: The design version you last saw; 0 to create.
          required: true
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StudioDesignDeleteResponseDto'
        '404':
          description: Conversation or design not found.
        '409':
          description: VERSION_MISMATCH.
      security:
        - bearer: []
      summary: Delete a design (public API)
      tags:
        - studio designs
  /conversations/{conversationId}/designs/{designId}/versions:
    get:
      operationId: public_studio_design_versions_list
      parameters:
        - name: conversationId
          required: true
          in: path
          schema:
            type: string
        - name: designId
          required: true
          in: path
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StudioDesignVersionsResponseDto'
        '404':
          description: Conversation or design not found.
      security:
        - bearer: []
      summary: List a design’s version history (public API)
      tags:
        - studio designs
  /conversations/{conversationId}/designs/{designId}/versions/{versionId}:
    get:
      operationId: public_studio_design_version_get
      parameters:
        - name: conversationId
          required: true
          in: path
          schema:
            type: string
        - name: designId
          required: true
          in: path
          schema:
            type: string
        - name: versionId
          required: true
          in: path
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StudioDesignVersionResponseDto'
        '404':
          description: Design or version not found.
      security:
        - bearer: []
      summary: Get one design version with its files (public API)
      tags:
        - studio designs
  /conversations/{conversationId}/designs/{designId}/restore:
    post:
      description: A restore bumps the version and is itself undoable.
      operationId: public_studio_design_restore
      parameters:
        - name: conversationId
          required: true
          in: path
          schema:
            type: string
        - name: designId
          required: true
          in: path
          schema:
            type: string
        - name: if-match
          required: true
          in: header
          schema:
            type: string
        - name: If-Match
          in: header
          description: The design version you last saw; 0 to create.
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StudioDesignRestoreRequest'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StudioDesignPutResponseDto'
        '404':
          description: Design or version not found.
        '409':
          description: VERSION_MISMATCH.
        '429':
          description: Rate limit exceeded.
      security:
        - bearer: []
      summary: Restore a design from a version (public API)
      tags:
        - studio designs
  /conversations/{conversationId}/designs/{designId}/to-canvas:
    post:
      description: >-
        Requires edit access to the target canvas. If-Match is optional here
        and, when sent, is the expected version of the target canvas design.
      operationId: public_studio_design_to_canvas
      parameters:
        - name: conversationId
          required: true
          in: path
          schema:
            type: string
        - name: designId
          required: true
          in: path
          schema:
            type: string
        - name: if-match
          required: true
          in: header
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StudioDesignToCanvasRequest'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StudioDesignToCanvasResponseDto'
        '404':
          description: Design, canvas, page or node not found.
      security:
        - bearer: []
      summary: Copy a design onto a canvas design node (public API)
      tags:
        - studio designs
  /conversations/{conversationId}/designs/{designId}/publish:
    get:
      operationId: public_studio_design_publish_get
      parameters:
        - name: conversationId
          required: true
          in: path
          schema:
            type: string
        - name: designId
          required: true
          in: path
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DesignPublishResponseDto'
        '404':
          description: Design has not been published.
      security:
        - bearer: []
      summary: Get publish metadata for a design (public API)
      tags:
        - studio designs
    post:
      description: >-
        Visibility private (default), unlisted or public; optional slug, unique
        product-wide.
      operationId: public_studio_design_publish_create
      parameters:
        - name: conversationId
          required: true
          in: path
          schema:
            type: string
        - name: designId
          required: true
          in: path
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DesignPublishRequest'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DesignPublishResponseDto'
        '404':
          description: Design not found.
      security:
        - bearer: []
      summary: Publish or re-publish a design (public API)
      tags:
        - studio designs
    patch:
      operationId: public_studio_design_publish_patch
      parameters:
        - name: conversationId
          required: true
          in: path
          schema:
            type: string
        - name: designId
          required: true
          in: path
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DesignPublishPatchRequest'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DesignPublishResponseDto'
        '404':
          description: Design has not been published.
      security:
        - bearer: []
      summary: Change publish visibility and/or slug (public API)
      tags:
        - studio designs
    delete:
      operationId: public_studio_design_publish_delete
      parameters:
        - name: conversationId
          required: true
          in: path
          schema:
            type: string
        - name: designId
          required: true
          in: path
          schema:
            type: string
      responses:
        '204':
          description: Unpublished.
        '404':
          description: Design has not been published.
      security:
        - bearer: []
      summary: Unpublish a design (public API)
      tags:
        - studio designs
  /canvas:
    get:
      operationId: public_canvas_list
      parameters:
        - name: page
          required: false
          in: query
          description: Page number
          schema:
            default: 1
            type: number
        - name: limit
          required: false
          in: query
          description: Number of items per page
          schema:
            default: 10
            type: number
        - name: sortBy
          required: false
          in: query
          description: Field to sort by
          schema:
            type: string
        - name: sortOrder
          required: false
          in: query
          description: Sort order (case insensitive)
          schema:
            example: ASC
            type: string
            enum:
              - ASC
              - DESC
              - asc
              - desc
        - name: search
          required: false
          in: query
          schema:
            type: string
        - name: name
          required: false
          in: query
          schema:
            type: string
        - name: visibility
          required: false
          in: query
          schema:
            type: string
            enum:
              - private
              - unlisted
              - public
        - name: isMember
          required: false
          in: query
          schema:
            default: false
            type: boolean
        - name: organizationId
          required: false
          in: query
          schema:
            type: string
        - description: Page number
          required: false
          name: page
          in: query
          schema:
            default: 1
            type: number
        - description: Number of items per page
          required: false
          name: limit
          in: query
          schema:
            default: 10
            type: number
        - description: Field to sort by
          required: false
          name: sortBy
          in: query
          schema:
            type: string
        - description: Sort order (case insensitive)
          required: false
          name: sortOrder
          in: query
          schema:
            example: ASC
            type: string
        - required: false
          name: search
          in: query
          schema:
            type: string
        - required: false
          name: name
          in: query
          schema:
            type: string
        - required: false
          name: visibility
          in: query
          schema:
            type: string
        - required: false
          name: isMember
          in: query
          schema:
            default: false
            type: boolean
        - required: false
          name: organizationId
          in: query
          schema:
            type: string
      responses:
        '200':
          headers:
            X-Total-Count:
              description: Total count of items
              type: number
            X-Current-Page:
              description: Current page of pagination
              type: number
            X-Per-Page:
              description: Results per page
              type: number
            X-Total-Pages:
              description: Total count of pages
              type: number
          description: ''
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/CanvasListItemDto'
      security:
        - bearer: []
      summary: List the canvases you can see (public API)
      tags:
        - canvas
  /canvas/{canvasId}:
    get:
      operationId: public_canvas_get
      parameters:
        - name: canvasId
          required: true
          in: path
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CanvasDto'
        '403':
          description: No access; the body carries an access preview.
      security:
        - bearer: []
      summary: Get a canvas and its page summaries (public API)
      tags:
        - canvas
  /canvas/{canvasId}/pages:
    get:
      operationId: public_canvas_page_list
      parameters:
        - name: canvasId
          required: true
          in: path
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/CanvasPageSummaryDto'
      security:
        - bearer: []
      summary: List a canvas’s pages (public API)
      tags:
        - canvas
  /canvas/{canvasId}/pages/{pageId}:
    get:
      description: >-
        Use the returned page `version` and node `version`s for optimistic
        writes.
      operationId: public_canvas_page_get
      parameters:
        - name: canvasId
          required: true
          in: path
          schema:
            type: string
        - name: pageId
          required: true
          in: path
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PageDto'
      security:
        - bearer: []
      summary: 'Get a page snapshot: every node and the order (public API)'
      tags:
        - canvas
  /canvas/{canvasId}/pages/{pageId}/nodes:
    post:
      description: >-
        Send a clientNodeId to make retries idempotent: a repeat returns the
        existing node.
      operationId: public_canvas_node_create
      parameters:
        - name: canvasId
          required: true
          in: path
          schema:
            type: string
        - name: pageId
          required: true
          in: path
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/NodeRequest'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NodeResponseDto'
        '403':
          description: You cannot edit this canvas.
      security:
        - bearer: []
      summary: Create a node (public API)
      tags:
        - canvas
    patch:
      operationId: public_canvas_node_patch_many
      parameters:
        - name: canvasId
          required: true
          in: path
          schema:
            type: string
        - name: pageId
          required: true
          in: path
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/NodesBatchUpdateRequest'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NodesResponseDto'
        '403':
          description: You cannot edit this canvas.
      security:
        - bearer: []
      summary: Patch several nodes in one page version (public API)
      tags:
        - canvas
    delete:
      operationId: public_canvas_node_delete_many
      parameters:
        - name: canvasId
          required: true
          in: path
          schema:
            type: string
        - name: pageId
          required: true
          in: path
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/NodesBulkDeleteRequest'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NodesDeleteResponseDto'
        '403':
          description: You cannot edit this canvas.
      security:
        - bearer: []
      summary: Delete several nodes (public API)
      tags:
        - canvas
  /canvas/{canvasId}/pages/{pageId}/nodes/batch:
    post:
      operationId: public_canvas_node_create_batch
      parameters:
        - name: canvasId
          required: true
          in: path
          schema:
            type: string
        - name: pageId
          required: true
          in: path
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/NodesBatchCreateRequest'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NodesResponseDto'
        '403':
          description: You cannot edit this canvas.
      security:
        - bearer: []
      summary: Create several nodes in one page version (public API)
      tags:
        - canvas
  /canvas/{canvasId}/pages/{pageId}/nodes/ops:
    post:
      operationId: public_canvas_node_ops
      parameters:
        - name: canvasId
          required: true
          in: path
          schema:
            type: string
        - name: pageId
          required: true
          in: path
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/NodesOpsRequest'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NodesOpsResponseDto'
        '403':
          description: You cannot edit this canvas.
      security:
        - bearer: []
      summary: >-
        Apply creates, patches, deletes, restores and a reorder atomically
        (public API)
      tags:
        - canvas
  /canvas/{canvasId}/pages/{pageId}/nodes/{nodeId}:
    patch:
      operationId: public_canvas_node_patch
      parameters:
        - name: canvasId
          required: true
          in: path
          schema:
            type: string
        - name: pageId
          required: true
          in: path
          schema:
            type: string
        - name: nodeId
          required: true
          in: path
          schema:
            type: string
        - name: if-match
          required: true
          in: header
          schema:
            type: string
        - name: If-Match
          in: header
          description: The node version you last saw; 409 with the current node if stale.
          required: false
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/NodePatchRequest'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NodeResponseDto'
        '403':
          description: You cannot edit this canvas.
        '409':
          description: Stale If-Match; body has currentNode.
      security:
        - bearer: []
      summary: Patch a node (public API)
      tags:
        - canvas
    delete:
      operationId: public_canvas_node_delete
      parameters:
        - name: canvasId
          required: true
          in: path
          schema:
            type: string
        - name: pageId
          required: true
          in: path
          schema:
            type: string
        - name: nodeId
          required: true
          in: path
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NodesDeleteResponseDto'
        '403':
          description: You cannot edit this canvas.
      security:
        - bearer: []
      summary: Delete a node (public API)
      tags:
        - canvas
  /canvas/{canvasId}/pages/{pageId}/nodes/{nodeId}/design:
    get:
      operationId: public_canvas_node_design_get
      parameters:
        - name: canvasId
          required: true
          in: path
          schema:
            type: string
        - name: pageId
          required: true
          in: path
          schema:
            type: string
        - name: nodeId
          required: true
          in: path
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DesignGetResponseDto'
        '404':
          description: Canvas, page, node or design not found.
      security:
        - bearer: []
      summary: Get a design node’s files (public API)
      tags:
        - canvas
    put:
      description: If-Match is required (0 creates). artifactId must match the node body.
      operationId: public_canvas_node_design_put
      parameters:
        - name: canvasId
          required: true
          in: path
          schema:
            type: string
        - name: pageId
          required: true
          in: path
          schema:
            type: string
        - name: nodeId
          required: true
          in: path
          schema:
            type: string
        - name: if-match
          required: true
          in: header
          schema:
            type: string
        - name: idempotency-key
          required: true
          in: header
          schema:
            type: string
        - name: Idempotency-Key
          in: header
          description: Replays the first response for a retried identical write.
          required: false
          schema:
            type: string
        - name: If-Match
          in: header
          description: The design version you last saw; 0 to create.
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DesignPutRequest'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DesignPutResponseDto'
        '409':
          description: VERSION_MISMATCH (with currentDesign).
        '429':
          description: Rate limit exceeded.
      security:
        - bearer: []
      summary: Create or replace a design node’s files (public API)
      tags:
        - canvas
  /generations/quote:
    post:
      description: >-
        Estimates the credits a generation would cost, from the API-owned price
        table. Send the canonical parameters you would send to the create route.
        Nothing is reserved or charged; the actual charge is the price the
        worker reports when the job is ready. A job that would run on the paying
        account's own provider key (BYOK, on a plan that allows it) costs 1
        credit. `breakdown.notes` lists what was assumed where the request left
        something open.
      operationId: public_generation_quote
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GenerationQuoteRequest'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GenerationQuoteDto'
        '400':
          description: >-
            `generation_quote.unknown_model`, `generation_quote.unpriced`,
            `generation_quote.characters_required`, or invalid parameters.
        '404':
          description: organizationId is not yours.
      security:
        - bearer: []
      summary: Quote a generation (public API)
      tags:
        - generations
  /.well-known/oauth-authorization-server:
    get:
      description: >-
        How an MCP client discovers this authorization server: endpoints,
        supported scopes and registration methods. No authentication.


        Two values matter more than they look. Claude only uses Client ID
        Metadata Documents when it sees **both**
        `client_id_metadata_document_supported: true` **and** `"none"` in
        `token_endpoint_auth_methods_supported`; otherwise it silently falls
        back to dynamic registration. And it only asks for a refresh token when
        `offline_access` is listed in `scopes_supported`.
      operationId: oauth_authorization_server_metadata
      parameters: []
      responses:
        '200':
          description: The metadata document.
      summary: Authorization server metadata (RFC 8414)
      tags:
        - oauth
  /oauth/authorize:
    get:
      description: >-
        Where an MCP client sends the user's browser to start a connection.
        Validates the request, stores it for ten minutes, and redirects to the
        LetzAI consent page — this endpoint never shows UI itself and never
        authenticates the user.


        Errors detected **before** the client and its `redirect_uri` are
        validated are shown to the user on letz.ai; redirecting to an
        unvalidated URI would make this an open redirector. Errors after that
        point return to `redirect_uri` with `error`, `error_description`,
        `state` and `iss`.
      operationId: oauth_authorize
      parameters:
        - name: state
          required: false
          in: query
          description: Opaque; echoed back.
          schema: {}
        - name: scope
          required: false
          in: query
          description: Space-separated. Defaults to `letzai:read`.
          schema: {}
        - name: resource
          required: true
          in: query
          description: Canonical URI of the MCP server the token is for (RFC 8707).
          schema: {}
        - name: code_challenge_method
          required: true
          in: query
          description: Must be `S256`.
          schema: {}
        - name: code_challenge
          required: true
          in: query
          description: PKCE challenge (RFC 7636).
          schema: {}
        - name: redirect_uri
          required: true
          in: query
          description: >-
            Exact match against the client's registered URIs; on a loopback host
            the port is ignored (RFC 8252 §7.3).
          schema: {}
        - name: client_id
          required: true
          in: query
          description: A Client ID Metadata Document URL, or a registered client id.
          schema: {}
        - name: response_type
          required: true
          in: query
          description: Must be `code`.
          schema: {}
      responses:
        '302':
          description: >-
            To the consent page, to letz.ai's error page, or back to the client
            with an error.
        '429':
          description: Too many requests.
      summary: Authorization endpoint
      tags:
        - oauth
  /oauth/token:
    post:
      description: >-
        Exchanges an authorization code, a refresh token, or (LetzAI
        applications only) another token for an access token.


        **`grant_type=authorization_code`** — `code`, `code_verifier`,
        `redirect_uri`, `client_id`, and `resource`. The code is single-use and
        lives 60 seconds. Presenting a code twice revokes the connection and
        every token already issued from it.


        **`grant_type=refresh_token`** — `refresh_token`, `client_id`,
        optionally a narrower `scope`. Refresh tokens rotate: the response
        carries a new one and the old one stops working. Presenting an old one
        again revokes the connection.


        **`grant_type=urn:ietf:params:oauth:grant-type:token-exchange`** (RFC
        8693) — first-party clients only, no refresh token issued:

        - `subject_token_type=urn:letzai:params:oauth:token-type:session`,
        `subject_token` = a web-session access token; optional
        `organization_id`, `resource`, `scope` (default `letzai:read
        letzai:generate letzai:manage letzai:agent`). Returns a connector token.

        - `subject_token_type=urn:ietf:params:oauth:token-type:access_token`,
        `subject_token` = a connector access token, `run_id` (UUID), optional
        narrower `scope`. Confidential clients only. Returns a run token bound
        to the same connection.


        Third-party clients are public — there is no client secret, presenting
        one is refused, and PKCE protects the code. Confidential first-party
        clients authenticate with `client_secret_basic` or `client_secret_post`.
        Errors are RFC 6749 §5.2 JSON: `{ "error", "error_description" }`. A
        dead code or refresh token is always `invalid_grant`.
      operationId: oauth_token
      parameters: []
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              required:
                - grant_type
              properties:
                grant_type:
                  type: string
                  enum:
                    - authorization_code
                    - refresh_token
                    - urn:ietf:params:oauth:grant-type:token-exchange
                client_id:
                  type: string
                client_secret:
                  type: string
                code:
                  type: string
                code_verifier:
                  type: string
                redirect_uri:
                  type: string
                resource:
                  type: string
                refresh_token:
                  type: string
                scope:
                  type: string
                subject_token:
                  type: string
                subject_token_type:
                  type: string
                  enum:
                    - urn:letzai:params:oauth:token-type:session
                    - urn:ietf:params:oauth:token-type:access_token
                requested_token_type:
                  type: string
                  enum:
                    - urn:ietf:params:oauth:token-type:access_token
                organization_id:
                  type: string
                  format: uuid
                run_id:
                  type: string
                  format: uuid
      responses:
        '200':
          description: >-
            access_token, token_type, expires_in, scope; refresh_token for the
            code and refresh grants; issued_token_type for token exchange.
        '400':
          description: >-
            `invalid_request`, `invalid_grant`, `invalid_scope`,
            `invalid_target`, `unauthorized_client`, `unsupported_grant_type`.
        '401':
          description: '`invalid_client`.'
        '429':
          description: '`slow_down`.'
      summary: Token endpoint
      tags:
        - oauth
  /oauth/revoke:
    post:
      description: >-
        Body: `token` and `client_id`. Revoking a refresh token ends the whole
        connection; revoking an access token ends that token. The MCP server (a
        confidential client, authenticating with `client_secret_basic` or
        `client_secret_post`) may revoke the run tokens it minted.


        Always answers 200, including for a token that is unknown, expired or
        not the caller's. That is RFC 7009 §2.2, and it is deliberate: a
        different answer would let anyone test whether a token is valid.
      operationId: oauth_revoke
      parameters: []
      responses:
        '200':
          description: Always.
      summary: Token revocation (RFC 7009)
      tags:
        - oauth
  /oauth/tokeninfo:
    get:
      description: >-
        How an MCP server validates a connector token: send it as the bearer,
        and get back who it is for (`aud`), what it may do (`scope`), and when
        it expires. An invalid, expired or revoked token gets a 401 — there is
        no `active: false` body to mishandle.


        The token authenticates itself, so the MCP server needs no credential of
        its own. That is the point: it is a stateless proxy in a public
        repository, and should hold no secrets. A resource server must still
        check that `aud` is its own canonical URI.


        Connector tokens only. Integration tokens and web sessions get a 401.
      operationId: oauth_tokeninfo
      parameters: []
      responses:
        '200':
          description: >-
            `active`, `aud`, `scope`, `sub`, `client_id`, `exp`; and
            `organization_id` (the paying account, null for personal),
            `grant_id` (the connection), `token_kind` (`oauth` or `run`),
            `run_id` (run tokens only), `first_party` (whether the connection
            belongs to a LetzAI application).
        '401':
          description: Not a valid connector token.
      security:
        - bearer: []
      summary: Describe the presented access token
      tags:
        - oauth
  /oauth/register:
    post:
      description: >-
        A fallback for MCP clients that do not yet support Client ID Metadata
        Documents, which are the preferred way to identify a client and need no
        registration at all. The MCP specification has deprecated this endpoint;
        it exists only when `OAUTH_DCR_ENABLED` is set, and only then is it
        advertised in the server metadata.


        JSON body: `client_name` and `redirect_uris` (https, or http on a
        loopback host) are required; `client_uri` and `logo_uri` are optional.
        Only public clients are registered: `token_endpoint_auth_method`, if
        sent, must be `none`. No secret is issued.


        Rate-limited per caller. Clients that never complete a connection are
        deleted after a week.
      operationId: oauth_register
      parameters: []
      responses:
        '201':
          description: The registered client, including its `client_id`.
        '400':
          description: '`invalid_redirect_uri` or `invalid_client_metadata`.'
        '429':
          description: '`slow_down`.'
      summary: Dynamic Client Registration (RFC 7591)
      tags:
        - oauth
  /catalog:
    get:
      description: >-
        Every model with its capabilities, limits and prices, the providers that
        run it and whether a customer key can, keyed by model id. `version`
        changes with any edit.


        Pricing rules are described in `_pricingSchema`; `POST
        /generations/quote` prices a concrete request with them.
      operationId: catalog_public
      parameters: []
      responses:
        '200':
          description: The public catalogue.
      summary: The model catalogue
      tags:
        - catalog
  /agent-runs/prefs:
    get:
      operationId: agent_run_prefs_get
      parameters: []
      responses:
        '200':
          description: '`{prefs}`; `{}` when none were stored.'
      security:
        - bearer: []
      summary: Your agent session preferences
      tags:
        - agent-runs
    put:
      description: >-
        An opaque JSON object (at most 64 KB), returned to the agent as
        `context.prefs` on every run.
      operationId: agent_run_prefs_put
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AgentRunPrefsRequest'
      responses:
        '200':
          description: '`{prefs}` as stored.'
      security:
        - bearer: []
      summary: Replace your agent session preferences
      tags:
        - agent-runs
  /agent-runs:
    post:
      description: >-
        Stores the message, queues the first model step and returns the run.
        Watch it on the realtime socket (`run:join`) or replay `GET
        /agent-runs/:id/events`.


        Connector tokens need `letzai:agent`; the paying account is the
        connection’s. API keys cannot start runs. On the web app the run bills
        through the `letzai-web` connection of (you, organizationId).
      operationId: agent_run_create
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AgentRunRequest'
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AgentRunEnvelopeDto'
        '400':
          description: Invalid body; `unknown_model` for a model without a price.
        '403':
          description: >-
            Not a member of `organizationId`, missing `letzai:agent`, or an API
            key.
        '404':
          description: '`conversation_not_found`, `canvas_not_found`.'
      security:
        - bearer: []
      summary: Start an agent run
      tags:
        - agent-runs
    get:
      description: >-
        Newest first. Filter by `conversationId` and `status` (comma-separated);
        page with `nextCursor`. Connector tokens list only the runs billed
        through their connection.
      operationId: agent_run_list
      parameters:
        - name: canvasId
          required: false
          in: query
          schema:
            type: string
        - name: pageId
          required: false
          in: query
          schema:
            type: string
        - name: conversationId
          required: false
          in: query
          schema:
            format: uuid
            type: string
        - name: status
          required: false
          in: query
          description: Comma-separated statuses, e.g. `running,waiting`.
          schema:
            type: string
        - name: cursor
          required: false
          in: query
          description: '`nextCursor` of the previous page.'
          schema:
            type: string
        - name: limit
          required: false
          in: query
          schema:
            minimum: 1
            maximum: 100
            default: 20
            type: number
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AgentRunListDto'
      security:
        - bearer: []
      summary: List your agent runs
      tags:
        - agent-runs
  /agent-runs/{id}:
    get:
      operationId: agent_run_get
      parameters:
        - name: id
          required: true
          in: path
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AgentRunEnvelopeDto'
        '404':
          description: >-
            Not found, not yours, or (connector tokens) billed through another
            connection.
      security:
        - bearer: []
      summary: Get an agent run
      tags:
        - agent-runs
  /agent-runs/{id}/client-tools:
    get:
      operationId: ReadController.clientTools
      parameters:
        - name: id
          required: true
          in: path
          schema:
            type: string
      responses:
        '200':
          description: ''
      security:
        - bearer: []
      tags:
        - agent-runs
  /agent-runs/{id}/events:
    get:
      description: >-
        Events with `seq > after`, ascending. `nextAfter` is present when there
        may be more.
      operationId: agent_run_events
      parameters:
        - name: id
          required: true
          in: path
          schema:
            type: string
        - name: after
          required: false
          in: query
          description: Return events with seq greater than this.
          schema:
            minimum: 0
            default: 0
            type: number
        - name: limit
          required: false
          in: query
          schema:
            minimum: 1
            maximum: 500
            default: 100
            type: number
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AgentRunEventListDto'
        '404':
          description: >-
            Not found, not yours, or (connector tokens) billed through another
            connection.
      security:
        - bearer: []
      summary: Replay a run’s events
      tags:
        - agent-runs
  /agent-runs/{id}/messages:
    post:
      description: >-
        Queued as the next user turn. A parked run wakes; a busy run sees it at
        its next step. Every open question of the run is answered first with
        `{answeredInChat: true, text}` (a `question.answered` event each): the
        user replied in words instead of on the card.
      operationId: agent_run_message
      parameters:
        - name: id
          required: true
          in: path
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AgentRunMessageRequest'
      responses:
        '202':
          description: Queued.
        '403':
          description: >-
            `organization_membership_required` (no longer in the run’s
            organization); run tokens.
        '404':
          description: >-
            Not found, not yours, or (connector tokens) billed through another
            connection.
        '409':
          description: '`run_finished`.'
      security:
        - bearer: []
      summary: Send the next user message to a run
      tags:
        - agent-runs
  /agent-runs/{id}/answers:
    post:
      description: Resolves the `question` wait; the run continues.
      operationId: agent_run_answer
      parameters:
        - name: id
          required: true
          in: path
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AgentRunAnswerRequest'
      responses:
        '204':
          description: Answered.
        '403':
          description: >-
            `organization_membership_required` (no longer in the run’s
            organization); run tokens.
        '404':
          description: '`run_not_found`, `question_not_found`.'
        '409':
          description: '`run_finished`.'
      security:
        - bearer: []
      summary: Answer a run’s question
      tags:
        - agent-runs
  /agent-runs/{id}/client-tools/{callId}/claim:
    post:
      operationId: UpdateController.claimClientTool
      parameters:
        - name: id
          required: true
          in: path
          schema:
            type: string
        - name: callId
          required: true
          in: path
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AgentRunClientToolClaimRequest'
      responses:
        '200':
          description: ''
      security:
        - bearer: []
      tags:
        - agent-runs
  /agent-runs/{id}/client-tools/{callId}/result:
    post:
      operationId: UpdateController.finishClientTool
      parameters:
        - name: id
          required: true
          in: path
          schema:
            type: string
        - name: callId
          required: true
          in: path
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AgentRunClientToolResultRequest'
      responses:
        '204':
          description: ''
      security:
        - bearer: []
      tags:
        - agent-runs
  /agent-runs/{id}/cancel:
    post:
      description: Idempotent. Ends the run `cancelled` and revokes its run tokens.
      operationId: agent_run_cancel
      parameters:
        - name: id
          required: true
          in: path
          schema:
            type: string
      responses:
        '204':
          description: Cancelled, or already finished.
        '403':
          description: Run tokens.
        '404':
          description: >-
            Not found, not yours, or (connector tokens) billed through another
            connection.
      security:
        - bearer: []
      summary: Cancel a run
      tags:
        - agent-runs
info:
  title: LetzAI API
  description: ''
  version: '1.0'
  contact: {}
tags: []
servers:
  - url: https://api.letz.ai
components:
  securitySchemes:
    Bearer:
      scheme: bearer
      bearerFormat: JWT
      type: http
      description: >-
        Authentication via Bearer token: provide a user integration token or an
        organization integration token.
  schemas:
    BoardCreateRequest:
      type: object
      properties:
        name:
          type: string
          description: Name of the board
        description:
          type: string
          description: Description of the board
        visibility:
          type: string
          enum:
            - public
            - private
            - hidden
          description: Defaults to `public` when omitted
        safety:
          type: string
          enum:
            - nsfw
            - sfw
          description: Defaults to `sfw` when omitted
        challengeDeadline:
          type: string
          format: date-time
          example: '2026-12-31T23:59:59.000Z'
          description: ISO date string for the challenge deadline
      required:
        - name
    PublicUserDto:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        username:
          type: string
        profilePicture:
          type: string
        description:
          type: string
        website:
          type: string
        socialMediaAccounts:
          type: object
        imagesGenerated:
          type: number
        imagesAvailable:
          type: number
        videosGenerated:
          type: number
        videosPublished:
          type: number
        imagesEdited:
          type: number
        editedImagesPublished:
          type: number
        modelsTrained:
          type: number
        modelsAvailable:
          type: number
        followersCount:
          type: number
        followingCount:
          type: number
        isVerified:
          type: boolean
      required:
        - id
        - name
        - username
        - profilePicture
        - description
        - website
        - socialMediaAccounts
        - imagesGenerated
        - imagesAvailable
        - videosGenerated
        - videosPublished
        - imagesEdited
        - editedImagesPublished
        - modelsTrained
        - modelsAvailable
        - followersCount
        - followingCount
        - isVerified
    BoardVisibility:
      type: string
      enum:
        - public
        - private
        - hidden
    BoardSafety:
      type: string
      enum:
        - nsfw
        - sfw
    BoardDto:
      type: object
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
        description:
          type: string
          nullable: true
        challengeDeadline:
          type: string
          nullable: true
          format: date-time
        thumbnail:
          type: object
          nullable: true
          additionalProperties:
            type: string
          description: >-
            Thumbnail image versions keyed by size, e.g. `original`, `640x640`,
            `240x240`, `96x96`. Absent while the board has no thumbnail.
          example:
            original: https://images.letz.ai/path/image.jpg
            96x96: https://images.letz.ai/path/image_96x96.jpg
        members:
          type: number
          description: Number of approved members.
        owner:
          $ref: '#/components/schemas/PublicUserDto'
        isActive:
          type: boolean
        isMember:
          type: boolean
          description: >-
            Whether the authenticated user is a member of the board. Only set
            when the request is authenticated.
        isAdmin:
          type: boolean
          description: >-
            Whether the authenticated user owns or administers the board. Only
            set when the request is authenticated.
        visibility:
          allOf:
            - $ref: '#/components/schemas/BoardVisibility'
        safety:
          allOf:
            - $ref: '#/components/schemas/BoardSafety'
        createdAt:
          format: date-time
          type: string
        updatedAt:
          format: date-time
          type: string
      required:
        - id
        - name
        - members
        - owner
        - isActive
        - visibility
        - safety
        - createdAt
        - updatedAt
    BoardFeedItemType:
      type: string
      enum:
        - image
        - video
      description: Which of `image` and `video` is set on this item.
    ModelVersionDto:
      type: object
      properties:
        id:
          type: string
        version:
          type: number
        storagePath:
          type: string
        systemVersions:
          type: array
          items:
            type: string
        status:
          type: string
        createdAt:
          format: date-time
          type: string
        trainedAt:
          format: date-time
          type: string
      required:
        - id
        - version
        - storagePath
        - systemVersions
        - status
        - createdAt
        - trainedAt
    PublicOrganizationDto:
      type: object
      properties: {}
    ModelOrganizationDto:
      type: object
      properties:
        id:
          type: string
          description: Unique identifier of the model-organization relationship
          example: 123e4567-e89b-12d3-a456-426614174000
        organization:
          description: Organization that has access to the model
          allOf:
            - $ref: '#/components/schemas/PublicOrganizationDto'
        sharedByUser:
          description: User who shared the model with the organization
          allOf:
            - $ref: '#/components/schemas/PublicUserDto'
        createdAt:
          format: date-time
          type: string
          description: Date when the model was shared
          example: '2024-01-15T10:30:00Z'
        updatedAt:
          format: date-time
          type: string
          description: Date when the sharing was last updated
          example: '2024-01-15T10:30:00Z'
      required:
        - id
        - organization
        - createdAt
        - updatedAt
    ModelDto:
      type: object
      properties:
        id:
          type: string
        user:
          $ref: '#/components/schemas/PublicUserDto'
        userId:
          type: string
        name:
          type: string
        username:
          type: string
        class:
          type: string
        type:
          type: string
        description:
          type: string
        website:
          type: string
        status:
          type: string
        statusDetail:
          type: string
        progress:
          type: number
        privacy:
          type: string
        usages:
          type: number
        imagesAvailable:
          type: number
        likes:
          type: number
        version:
          type: number
        thumbnail:
          type: string
        thumbnailOptions:
          type: object
        settings:
          type: object
        images:
          type: object
        isActive:
          type: boolean
        blockedAt:
          format: date-time
          type: string
        createdAt:
          format: date-time
          type: string
        systemVersions:
          type: array
          items:
            type: string
        versions:
          type: array
          items:
            $ref: '#/components/schemas/ModelVersionDto'
      required:
        - id
        - user
        - userId
        - name
        - username
        - class
        - type
        - description
        - website
        - status
        - statusDetail
        - progress
        - privacy
        - usages
        - imagesAvailable
        - likes
        - version
        - thumbnail
        - thumbnailOptions
        - settings
        - images
        - isActive
        - blockedAt
        - createdAt
        - systemVersions
        - versions
    ImageCompletionDto:
      type: object
      properties:
        id:
          type: string
        user:
          $ref: '#/components/schemas/PublicUserDto'
        userId:
          type: string
        organizationId:
          type: string
          description: Organization ID billed for this generation
        regeneratedFromId:
          type: string
        originalImageCompletions:
          description: Original image completions
          type: array
          items:
            $ref: '#/components/schemas/ImageCompletionDto'
        originalImageCompletion:
          description: Original image completion (top level)
          allOf:
            - $ref: '#/components/schemas/ImageCompletionDto'
        originalImageCompletionIds:
          description: Original image completion IDs
          type: array
          items:
            type: string
        imageEdit:
          $ref: '#/components/schemas/ImageEditDto'
        prompt:
          type: string
        baseModel:
          type: string
        promptSystem:
          type: string
        autocaption:
          type: string
          description: Machine generated caption describing the image
          nullable: true
        status:
          type: string
        statusDetail:
          type: string
        progress:
          type: number
        previewImage:
          type: string
        username:
          type: string
        queue:
          type: string
        isUserVerified:
          type: boolean
        isHot:
          type: boolean
        privacy:
          type: string
        likes:
          type: number
        comments:
          type: number
        liked:
          type: boolean
        regenerations:
          type: number
        reports:
          type: number
        storageBucket:
          type: string
        storagePath:
          type: string
        generationSettings:
          type: object
        generationData:
          type: string
        generatedByUnit:
          type: string
        generationSeconds:
          type: number
        imagePaths:
          type: object
        imageVersions:
          type: object
        systemVersion:
          type: number
        hasWatermark:
          type: boolean
        isNsfw:
          type: boolean
        webhookUrl:
          type: string
        isBookmarked:
          type: boolean
        isUnsafe:
          type: boolean
        hidePrompt:
          type: boolean
        blockedAt:
          format: date-time
          type: string
        createdAt:
          format: date-time
          type: string
        deletedAt:
          format: date-time
          type: string
          description: Internal only
        updatedAt:
          format: date-time
          type: string
          description: Internal only
        isActive:
          type: boolean
          description: Internal only
        models:
          type: array
          items:
            $ref: '#/components/schemas/ModelDto'
        modelId:
          type: string
          description: Primary model ID used for generation (first model)
          example: 550e8400-e29b-41d4-a716-446655440000
      required:
        - id
        - user
        - userId
        - regeneratedFromId
        - originalImageCompletions
        - originalImageCompletion
        - originalImageCompletionIds
        - imageEdit
        - prompt
        - baseModel
        - promptSystem
        - status
        - statusDetail
        - progress
        - previewImage
        - username
        - queue
        - isUserVerified
        - isHot
        - privacy
        - likes
        - comments
        - liked
        - regenerations
        - reports
        - storageBucket
        - storagePath
        - generationSettings
        - generationData
        - generatedByUnit
        - generationSeconds
        - imagePaths
        - imageVersions
        - systemVersion
        - hasWatermark
        - isNsfw
        - webhookUrl
        - isBookmarked
        - isUnsafe
        - hidePrompt
        - blockedAt
        - createdAt
        - models
    ImageEditDto:
      type: object
      properties:
        id:
          type: string
          description: Unique identifier for the image edit
        originalImageCompletions:
          description: Original image completions
          type: array
          items:
            $ref: '#/components/schemas/ImageCompletionDto'
        originalImageCompletion:
          description: Original image completion (top level)
          allOf:
            - $ref: '#/components/schemas/ImageCompletionDto'
        originalImageCompletionIds:
          description: Original image completion IDs
          type: array
          items:
            type: string
        originalImageEdit:
          description: Source image completion of the edit
          allOf:
            - $ref: '#/components/schemas/ImageEditDto'
        generatedImageCompletion:
          description: Generated image completion
          allOf:
            - $ref: '#/components/schemas/ImageCompletionDto'
        imageCompletionChoices:
          description: Generated image completion choices
          type: array
          items:
            type: string
        mode:
          type: string
          description: Edit mode (max 32 characters)
          nullable: true
        width:
          type: number
          description: Width of the edited image
        height:
          type: number
          description: Height of the edited image
        imageCompletionsCount:
          type: number
          description: Number of image completions to be generated
        prompt:
          type: string
          description: Prompt
        baseModel:
          type: string
          description: Base model identifier used for generation
        mask:
          type: string
          description: Inpainting mask
        inputImageUrls:
          description: Input image URLs
          type: array
          items:
            type: string
        imageUrl:
          type: string
          description: Input image URL
        webhookUrl:
          type: string
          description: Webhook URL
        settings:
          type: object
        models:
          type: array
          items:
            $ref: '#/components/schemas/ModelDto'
        status:
          type: string
          description: Status of the image edit process
        statusDetail:
          type: string
          description: Detailed worker status/error message
        progress:
          type: number
          description: Progress of the image edit process (0-100)
        generationSeconds:
          type: number
          description: >-
            Generation time in seconds. If provided, overrides the default fixed
            credit cost.
        hidePrompt:
          type: boolean
      required:
        - id
        - originalImageCompletions
        - originalImageCompletion
        - originalImageCompletionIds
        - originalImageEdit
        - generatedImageCompletion
        - imageCompletionChoices
        - mode
        - width
        - height
        - imageCompletionsCount
        - prompt
        - baseModel
        - mask
        - inputImageUrls
        - imageUrl
        - webhookUrl
        - settings
        - models
        - progress
        - hidePrompt
    ImageDto:
      type: object
      properties:
        id:
          type: string
        user:
          $ref: '#/components/schemas/PublicUserDto'
        organizationId:
          type: string
          description: Organization UUID used for credit deduction
        imageEdit:
          $ref: '#/components/schemas/ImageEditDto'
        prompt:
          type: string
        baseModel:
          type: string
        autocaption:
          type: string
          description: Machine generated caption describing the image
          nullable: true
        status:
          type: string
        statusDetail:
          type: string
        progressMessage:
          type: string
        progress:
          type: number
        previewImage:
          type: string
        isHot:
          type: boolean
        privacy:
          type: string
        likes:
          type: number
        regenerations:
          type: number
        imageVersions:
          type: object
        systemVersion:
          type: number
        hasWatermark:
          type: boolean
        generationSettings:
          type: object
        isNsfw:
          type: boolean
        webhookUrl:
          type: string
        hidePrompt:
          type: boolean
        regeneratedFromId:
          type: string
          description: The image this one was regenerated from, if any
        originalImageCompletionIds:
          description: Input images this image was generated from (image-to-image)
          type: array
          items:
            type: string
        createdAt:
          format: date-time
          type: string
        models:
          type: array
          items:
            $ref: '#/components/schemas/ModelDto'
      required:
        - id
        - user
        - imageEdit
        - prompt
        - baseModel
        - status
        - progressMessage
        - progress
        - previewImage
        - isHot
        - privacy
        - likes
        - regenerations
        - imageVersions
        - systemVersion
        - hasWatermark
        - generationSettings
        - isNsfw
        - webhookUrl
        - hidePrompt
        - originalImageCompletionIds
        - createdAt
        - models
    VideoCutDto:
      type: object
      properties:
        index:
          type: number
          description: 0-based cut index
          example: 1
        start:
          type: number
          description: Start time in seconds
          example: 3.7083
        end:
          type: number
          description: End time in seconds
          example: 12.4167
        duration:
          type: number
          description: Denormalized end - start, in seconds
          example: 8.7084
        score:
          type: number
          description: >-
            Detector confidence for the boundary that opens this cut (ffmpeg
            lavfi.scene_score, 0..1). Absent for index 0.
          example: 0.2692
        clipUrl:
          type: string
          description: >-
            CDN URL of the extracted clip for this cut, when one has been
            produced
      required:
        - index
        - start
        - end
    VideoCutsMetaDto:
      type: object
      properties:
        detector:
          type: string
          description: Detector that produced the cut list
          enum:
            - ffmpeg-scene
            - manual
        detectorVersion:
          type: string
          description: Detector version
        threshold:
          type: number
          description: Scene score threshold used
        minSegment:
          type: number
          description: Minimum segment length in seconds
        maxCuts:
          type: number
          description: Maximum number of cuts kept
        detectedAt:
          type: string
          description: ISO-8601 detection timestamp
        status:
          type: string
          description: Detection lifecycle state
          enum:
            - pending
            - ready
            - failed
            - skipped
        error:
          type: string
          description: Failure reason when status is "failed"
    VideoCutClipDto:
      type: object
      properties:
        index:
          type: number
          description: 0-based index of the cut this clip covers
        status:
          type: string
          description: Extraction state
          enum:
            - pending
            - ready
            - failed
        url:
          type: string
          description: CDN URL, once ready
        filename:
          type: string
          description: Suggested download filename
        sizeBytes:
          type: number
          description: Clip size in bytes
        error:
          type: string
          description: Failure reason when status is "failed"
      required:
        - index
        - status
    VideoCutReviewDto:
      type: object
      properties:
        videoId:
          type: string
          description: Video the review belongs to
        cutsRevision:
          type: number
          description: The video.cutsRevision these marks describe
          example: 1
        marks:
          type: array
          description: Marks positionally aligned with cuts[]; null means not yet reviewed
          nullable: true
          example:
            - green
            - null
            - red
          items:
            type: string
            enum:
              - red
              - orange
              - green
        reviewedCount:
          type: number
          description: How many cuts carry a mark
          example: 2
        revision:
          type: number
          description: Optimistic-concurrency counter; 0 means the video was never reviewed
          example: 4
        updatedAt:
          format: date-time
          type: string
          description: When the review was last written
      required:
        - videoId
        - cutsRevision
        - marks
        - reviewedCount
        - revision
    VideoDto:
      type: object
      properties:
        id:
          type: string
          description: Unique identifier for the video animation
        user:
          description: User who created the video
          allOf:
            - $ref: '#/components/schemas/PublicUserDto'
        userId:
          type: string
          description: User ID of the video creator
        organizationId:
          type: string
          description: Organization ID billed for this generation
        regeneratedFromId:
          type: string
          description: ID of the video this was regenerated from
        originalImageCompletion:
          description: Original image completion being animated
          allOf:
            - $ref: '#/components/schemas/ImageCompletionDto'
        originalImageCompletionId:
          type: string
          description: Original image completion ID
        prompt:
          type: string
          description: Video animation prompt
        prompts:
          type: array
          description: Array of prompt objects for multi-scene videos
          items:
            type: object
        promptSystem:
          type: string
          description: System prompt for video generation
        autocaption:
          type: string
          description: Machine generated caption describing the video
          nullable: true
        baseModel:
          type: string
          description: Base model identifier used for video generation
        imageUrls:
          description: Input image URLs
          type: array
          items:
            type: string
        assetUrls:
          description: Input asset URLs
          type: array
          items:
            type: string
        videoUrls:
          description: >-
            Source clip URLs (Omni video edits, reference-to-video); from
            `settings.videoUrls`.
          type: array
          items:
            type: string
        secondFrameUrl:
          type: string
          description: >-
            Last frame of a first+last-frame video; from
            `settings.secondFrameUrl`.
        imageUrl:
          type: string
          description: Input image URL
        width:
          type: number
          description: Video width in pixels
        height:
          type: number
          description: Video height in pixels
        resolution:
          type: number
          description: Video resolution
        settings:
          type: object
          description: Video generation settings
        generationSettings:
          type: object
          description: Generation settings used for the video
        status:
          type: string
          description: Status of the video animation process
        statusDetail:
          type: string
          description: Detailed status information
        progress:
          type: number
          description: Generation progress percentage (0-100)
        previewImage:
          type: string
          description: Preview image URL for the video
        queue:
          type: string
          description: Processing queue type
        systemVersion:
          type: number
          description: System version used for generation
        generationSeconds:
          type: number
          description: Generation time in seconds
        videoVersions:
          type: object
          description: Generated video file versions
        videoPaths:
          type: object
          description: 'Internal only: raw video paths'
        imageCompletionsCount:
          type: number
          description: 'Internal only: image completions count'
        deletedAt:
          format: date-time
          type: string
          description: Internal only
        updatedAt:
          format: date-time
          type: string
          description: Internal only
        imageVersions:
          type: object
          description: Generated image file versions
        storageBucket:
          type: string
          description: Storage bucket for video files
        storagePath:
          type: string
          description: Storage path for video files
        webhookUrl:
          type: string
          description: Webhook URL for completion notification
        hidePrompt:
          type: boolean
          description: Whether to hide the prompt from public view
        hasWatermark:
          type: boolean
          description: Whether the video has a watermark
        likes:
          type: number
          description: Number of likes for this video
        comments:
          type: number
          description: Number of comments for this video
        regenerations:
          type: number
          description: >-
            Number of regenerations/remixes of this video. Always 0 in practice
            — see VideoEntity.regenerations.
          deprecated: true
        reports:
          type: number
          description: Number of reports for inappropriate content
        privacy:
          type: string
          description: Privacy setting for the video
        isNsfw:
          type: boolean
          description: Whether the video contains NSFW content
        isHot:
          type: boolean
          description: Whether the video is flagged as trending/hot
        liked:
          type: boolean
          description: Whether the current user has liked this video
        isUnsafe:
          type: boolean
          description: Whether the video is flagged as unsafe content
        isActive:
          type: boolean
          description: Whether the video is actively available
        hideFromUserProfile:
          type: boolean
          description: Whether to hide the video from user profile
        isBookmarked:
          type: boolean
          description: Whether the current user has bookmarked this video
        username:
          type: string
          description: Username of the video creator
        isUserVerified:
          type: boolean
          description: Whether the creator is a verified user
        publishedAt:
          format: date-time
          type: string
          description: When the video was published/made public
        blockedAt:
          format: date-time
          type: string
          description: When the video was blocked (if applicable)
        createdAt:
          format: date-time
          type: string
          description: Creation timestamp
        models:
          description: Models used for video generation
          type: array
          items:
            $ref: '#/components/schemas/ModelDto'
        thumbnailUrl:
          type: string
          description: CDN URL of the poster frame (grabbed ~1s in)
        durationSeconds:
          type: number
          description: Real measured duration in seconds
          example: 15.093
        fps:
          type: number
          description: Frames per second, required for frame-accurate stepping
          example: 23.976
        cutsStatus:
          type: string
          description: >-
            Detection lifecycle state, mirrored from cutsMeta so clients can
            branch without unpacking it. Absent when the video was never
            analysed.
          enum:
            - pending
            - ready
            - failed
            - skipped
        cutsRevision:
          type: number
          description: Bumps on every (re-)detection. Review marks are keyed to it.
          example: 1
        cuts:
          description: >-
            Detected shot boundaries, contiguous and covering [0,
            durationSeconds]. A single-shot video has exactly one cut; null
            means never analysed.
          type: array
          items:
            $ref: '#/components/schemas/VideoCutDto'
        cutsMeta:
          description: 'Internal only: cut detection provenance'
          allOf:
            - $ref: '#/components/schemas/VideoCutsMetaDto'
        cutClips:
          description: Per-cut clips that have been extracted or are being extracted
          type: array
          items:
            $ref: '#/components/schemas/VideoCutClipDto'
        cutReview:
          description: The requesting user's cut review. Omitted for anonymous callers.
          allOf:
            - $ref: '#/components/schemas/VideoCutReviewDto'
      required:
        - id
        - user
        - userId
        - regeneratedFromId
        - originalImageCompletion
        - originalImageCompletionId
        - prompt
        - prompts
        - promptSystem
        - baseModel
        - imageUrls
        - assetUrls
        - imageUrl
        - width
        - height
        - resolution
        - settings
        - generationSettings
        - statusDetail
        - progress
        - previewImage
        - queue
        - systemVersion
        - generationSeconds
        - videoVersions
        - imageVersions
        - storageBucket
        - storagePath
        - webhookUrl
        - hidePrompt
        - hasWatermark
        - likes
        - comments
        - regenerations
        - reports
        - privacy
        - isNsfw
        - isHot
        - liked
        - isUnsafe
        - isActive
        - hideFromUserProfile
        - isBookmarked
        - username
        - isUserVerified
        - publishedAt
        - blockedAt
        - createdAt
        - models
    BoardFeedItemDto:
      type: object
      properties:
        type:
          description: Which of `image` and `video` is set on this item.
          allOf:
            - $ref: '#/components/schemas/BoardFeedItemType'
        likes:
          type: number
          description: Number of likes.
        comments:
          type: number
          description: Number of comments.
        score:
          type: number
          description: >-
            Ranking score combining engagement and recency. Used by
            `sortBy=score`.
        image:
          description: Set when `type` is `image`.
          allOf:
            - $ref: '#/components/schemas/ImageDto'
        video:
          description: Set when `type` is `video`.
          allOf:
            - $ref: '#/components/schemas/VideoDto'
      required:
        - type
        - likes
        - comments
        - score
    ImageRequest:
      type: object
      properties:
        prompt:
          type: string
        width:
          type: number
        height:
          type: number
        quality:
          type: number
        creativity:
          type: number
        hasWatermark:
          type: boolean
        systemVersion:
          type: number
        hideFromUserProfile:
          type: boolean
        mode:
          type: string
          enum:
            - default
            - sigma
        webhookUrl:
          type: string
        organizationId:
          type: string
          description: >-
            Organization ID to deduct credits from. If provided, credits will be
            deducted from the organization account instead of the user account.
            User must be a member of the organization.
          example: 123e4567-e89b-12d3-a456-426614174000
        baseModel:
          type: string
          description: Base model identifier used for generation
          example: stable-diffusion-v1
      required:
        - prompt
        - width
        - height
        - quality
        - creativity
        - hasWatermark
        - systemVersion
        - hideFromUserProfile
        - mode
        - webhookUrl
    ImagePrivacyRequest:
      type: object
      properties:
        privacy:
          type: string
          enum:
            - public
            - private
            - licensed
      required:
        - privacy
    ImagePromptPrivacyRequest:
      type: object
      properties:
        hidePrompt:
          type: object
          default: false
      required:
        - hidePrompt
    ImageEditRequest:
      type: object
      properties:
        originalImageCompletionIds:
          description: Original image completion IDs
          type: array
          items:
            type: string
        originalImageCompletionId:
          type: string
          description: Original image completion ID
        imageUrl:
          type: string
          description: Input image URL
        mode:
          type: string
          description: Edit mode (max 32 characters)
        width:
          type: number
          description: Width of the edited image
        height:
          type: number
          description: Height of the edited image
        imageCompletionsCount:
          type: number
          description: Number of image completions to generate
        prompt:
          type: string
          description: Prompt
        mask:
          type: string
          description: Inpainting mask
        inputImageUrls:
          description: Input image URLs
          type: array
          items:
            type: string
        settings:
          type: object
          additionalProperties: true
        webhookUrl:
          type: string
        hidePrompt:
          type: object
          default: false
        baseModel:
          type: string
          description: Base model identifier used for generation
          example: stable-diffusion-v1
        organizationId:
          type: string
          description: >-
            Organization ID to deduct credits from. If provided, credits will be
            deducted from the organization account instead of the user account.
            User must be a member of the organization.
          example: 123e4567-e89b-12d3-a456-426614174000
        generationSeconds:
          type: number
          description: >-
            Generation time in seconds used to calculate credit cost. If
            provided, overrides the default fixed cost for the edit mode.
          example: 45
      required:
        - imageUrl
        - mode
        - inputImageUrls
        - webhookUrl
        - hidePrompt
    ImageEditMaskDto:
      type: object
      properties:
        mask:
          type: string
          description: Inpainting mask
      required:
        - mask
    SettingsEnum:
      type: string
      enum:
        - NO_VIOLENCE
        - NO_HATE_SPEECH
        - NO_ILLEGAL_CONTENT
        - NO_COPYRIGHTED_CONTENT
        - NO_ADULT_CONTENT
        - NO_RELIGIOUS_CONTENT
        - NO_POLITICAL_CONTENT
        - NO_BRANDED_CONTENT
        - NO_OTHER
    ModelCreateRequest:
      type: object
      properties:
        name:
          type: string
        privacy:
          type: string
          enum:
            - public
            - private
            - licensed
        type:
          type: string
        class:
          type: string
          enum:
            - person
            - style
            - object
        description:
          type: string
        website:
          type: string
        settings:
          type: array
          example:
            - NO_ADULT_CONTENT
            - NO_VIOLENCE
          items:
            $ref: '#/components/schemas/SettingsEnum'
        trainingDataUrls:
          minItems: 1
          maxItems: 50
          type: array
          items:
            type: string
        webhookUrl:
          type: string
        trainingMode:
          type: string
        organizationId:
          type: string
          description: >-
            Organization ID to deduct credits from. If provided, credits will be
            deducted from the organization account instead of the user account.
            User must be a member of the organization.
          example: 123e4567-e89b-12d3-a456-426614174000
      required:
        - name
        - privacy
        - type
        - class
        - description
        - website
        - webhookUrl
        - trainingMode
    ModelUpdateRequest:
      type: object
      properties:
        privacy:
          type: string
          enum:
            - public
            - private
            - licensed
        type:
          type: string
        description:
          type: string
        website:
          type: string
        settings:
          type: array
          items:
            type: string
            enum:
              - NO_VIOLENCE
              - NO_HATE_SPEECH
              - NO_ILLEGAL_CONTENT
              - NO_COPYRIGHTED_CONTENT
              - NO_ADULT_CONTENT
              - NO_RELIGIOUS_CONTENT
              - NO_POLITICAL_CONTENT
              - NO_BRANDED_CONTENT
              - NO_OTHER
        webhookUrl:
          type: string
      required:
        - privacy
        - type
        - description
        - website
    ModelThumbnailRequest:
      type: object
      properties:
        imageCompletionId:
          type: string
          description: >-
            Image completion that should be used as thumbnail for the given
            model
      required:
        - imageCompletionId
    UpscaleRequest:
      type: object
      properties:
        prompt:
          type: string
        mode:
          type: string
          description: Upscale mode (any string, max 32 characters)
        size:
          type: number
        imageId:
          type: string
        imageUrl:
          type: string
        type:
          type: string
          enum:
            - image
            - video
          default: image
        assetUrl:
          type: string
        assetId:
          type: string
        strength:
          type: object
          default: 1
        generationSettings:
          type: object
          additionalProperties: true
          description: >-
            Model-specific upscale settings. `mode` here takes precedence over
            the top-level `mode` for validation; `strength` is always taken from
            the top-level field.
        webhookUrl:
          type: string
        organizationId:
          type: string
          description: >-
            Organization ID to deduct credits from. If provided, credits will be
            deducted from the organization account instead of the user account.
            User must be a member of the organization.
          example: 123e4567-e89b-12d3-a456-426614174000
      required:
        - prompt
        - size
        - imageId
        - imageUrl
        - strength
        - webhookUrl
    UpscaleDto:
      type: object
      properties:
        id:
          type: string
        user:
          $ref: '#/components/schemas/PublicUserDto'
        userId:
          type: string
        imageCompletionId:
          type: string
        imageUrl:
          type: string
        type:
          type: string
        assetUrl:
          type: string
        assetId:
          type: string
        originalImageThumbnail:
          type: string
        status:
          type: string
        mode:
          type: string
        generationSettings:
          type: object
          additionalProperties: true
        statusDetail:
          type: string
        progress:
          type: number
        username:
          type: string
        createdByUsername:
          type: string
        createdByThumbnail:
          type: string
        isUserVerified:
          type: boolean
        imageVersions:
          type: object
        webhookUrl:
          type: string
        selected:
          type: boolean
        size:
          type: number
        blockedAt:
          format: date-time
          type: string
        createdAt:
          format: date-time
          type: string
      required:
        - id
        - user
        - userId
        - imageCompletionId
        - imageUrl
        - type
        - assetUrl
        - assetId
        - originalImageThumbnail
        - status
        - mode
        - statusDetail
        - progress
        - username
        - createdByUsername
        - createdByThumbnail
        - isUserVerified
        - imageVersions
        - webhookUrl
        - selected
        - size
        - blockedAt
        - createdAt
    UserImageRequest:
      type: object
      properties:
        extension:
          type: string
          description: >-
            File extension of the image or video. This determines the file
            format that will be uploaded.
          enum:
            - jpg
            - jpeg
            - png
            - gif
            - webp
            - mp4
            - webm
            - mov
            - avi
          example: jpg
        numberOfImages:
          type: object
          description: >-
            Number of images to generate upload URLs for. If you need to upload
            multiple images at once, increase this value.
          default: 1
          example: 1
        originalFilename:
          type: string
          description: >-
            Original filename of the image. This is stored for reference but
            does not affect the actual filename used in storage.
          example: my_photo.jpg
        metadata:
          type: object
          description: >-
            Additional metadata for the image. This can be any JSON object with
            custom properties you want to associate with the image.
          additionalProperties: true
          example:
            title: My vacation photo
            tags:
              - vacation
              - beach
      required:
        - extension
    UserImageDto:
      type: object
      properties:
        id:
          type: string
        userId:
          type: string
        imageUrl:
          type: string
          description: >-
            URL to access the uploaded file. This URL will be available after
            uploading the image or video using the uploadUrl.
        uploadUrl:
          type: string
          description: >-
            Pre-signed S3 URL for uploading the file. Make a PUT request to this
            URL with the image or video as the request body and appropriate
            Content-Type header (e.g., image/jpeg, video/mp4).
        originalFilename:
          type: string
        mimeType:
          type: string
        fileSize:
          type: number
        metadata:
          type: object
        createdAt:
          format: date-time
          type: string
        updatedAt:
          format: date-time
          type: string
      required:
        - id
        - userId
        - imageUrl
        - createdAt
        - updatedAt
    UserAssetRequest:
      type: object
      properties:
        extension:
          type: string
          description: >-
            File extension of the asset. This determines the file format that
            will be uploaded.
          enum:
            - jpg
            - jpeg
            - png
            - gif
            - webp
            - mp4
            - webm
            - mov
            - avi
            - mp3
            - wav
            - ogg
            - m4a
            - aac
            - flac
          example: jpg
        numberOfImages:
          type: object
          description: >-
            Number of assets to generate upload URLs for. If you need to upload
            multiple files at once, increase this value.
          default: 1
          example: 1
        originalFilename:
          type: string
          description: >-
            Original filename of the asset. This is stored for reference but
            does not affect the actual filename used in storage.
          example: my_photo.jpg
        mimeType:
          type: string
          description: >-
            Optional MIME type for the asset (e.g., image/jpeg, video/mp4,
            audio/mpeg).
          example: image/jpeg
        fileSize:
          type: number
          description: Optional file size in bytes.
          example: 204800
        metadata:
          type: object
          description: >-
            Additional metadata for the asset. This can be any JSON object with
            custom properties you want to associate with the file.
          additionalProperties: true
          example:
            title: My vacation photo
            tags:
              - vacation
              - beach
        caption:
          type: string
          description: >-
            Optional caption associated with the asset. Works for image, video,
            and audio assets.
          example: Behind the scenes recording from today.
      required:
        - extension
    UserAssetDto:
      type: object
      properties:
        id:
          type: string
        userId:
          type: string
        user:
          $ref: '#/components/schemas/PublicUserDto'
        imageUrl:
          type: string
          description: >-
            URL to access the uploaded file. This URL will be available after
            uploading the image or video using the uploadUrl.
        uploadUrl:
          type: string
          description: >-
            Pre-signed S3 URL for uploading the file. Make a PUT request to this
            URL with the image or video as the request body and appropriate
            Content-Type header (e.g., image/jpeg, video/mp4).
        originalFilename:
          type: string
        mimeType:
          type: string
        fileSize:
          type: number
        metadata:
          type: object
        caption:
          type: string
        autocaption:
          type: string
          description: Machine generated caption describing the asset
          nullable: true
        createdAt:
          format: date-time
          type: string
        updatedAt:
          format: date-time
          type: string
      required:
        - id
        - userId
        - user
        - imageUrl
        - createdAt
        - updatedAt
    UserAssetUpdateRequest:
      type: object
      properties:
        caption:
          type: string
          description: >-
            Optional caption associated with the asset. Works for image, video,
            and audio assets.
          example: Updated caption for this asset.
    PublicVideoRequest:
      type: object
      properties:
        originalImageCompletionId:
          type: string
          description: Original image completion ID to create video from
          example: 123e4567-e89b-12d3-a456-426614174000
        imageUrls:
          description: Input image URLs
          type: array
          items:
            type: string
        secondFrameUrl:
          type: string
          description: >-
            Last frame of a first+last-frame (keyframe) video; `imageUrl` /
            `originalImageCompletionId` is the first. Stored in
            `settings.secondFrameUrl`.
        videoUrls:
          description: >-
            Source clip URLs (Omni video edits, reference-to-video). At most 3.
            Stored in `settings.videoUrls`; `settings.videoUrls` is also
            accepted, with the same checks.
          maxItems: 3
          type: array
          items:
            type: string
        assetUrls:
          description: Input asset URLs (e.g. face images for Seedance)
          type: array
          items:
            type: string
        imageUrl:
          type: string
          description: >-
            Image URL to create video from (alternative to
            originalImageCompletionId)
          example: https://example.com/image.jpg
        organizationId:
          type: string
          description: Organization ID (for organization accounts)
          example: 123e4567-e89b-12d3-a456-426614174000
        width:
          type: number
          description: Width of the video
          example: 1024
        height:
          type: number
          description: Height of the video
          example: 1024
        resolution:
          type: number
          description: Resolution of the video
          example: 1024
        prompt:
          type: string
          description: Prompt for video generation
          example: A beautiful sunset over the ocean
        prompts:
          type: array
          description: Array of prompt objects for multi-scene videos
          items:
            type: object
          example:
            - prompt: Scene 1 description
              duration: 3
        baseModel:
          type: string
          description: Base model identifier for video generation
          example: stable-diffusion-v1
        webhookUrl:
          type: string
          description: Webhook URL to receive notifications about video generation progress
          example: https://your-app.com/webhook/video-complete
        hidePrompt:
          type: object
          description: Whether to hide the prompt in public listings
          default: false
          example: false
        settings:
          type: object
          description: Additional settings for video generation
          example:
            mode: video-kling26
            withSound: false
            highQuality: true
            duration: 4
      required:
        - prompt
    VideoPrivacyRequest:
      type: object
      properties:
        privacy:
          type: string
          enum:
            - public
            - private
            - licensed
      required:
        - privacy
    VideoPromptPrivacyRequest:
      type: object
      properties:
        hidePrompt:
          type: object
          description: Whether to hide the prompt from public view
          default: false
      required:
        - hidePrompt
    AudioSettingsRequest:
      type: object
      properties:
        voice:
          type: string
          description: Voice id (speech)
        language:
          type: string
          description: Language code, e.g. "en" or "lb" (speech)
        durationSeconds:
          type: number
          description: Requested length in seconds (music, sound effects)
        instrumental:
          type: boolean
          description: No vocals (music)
    PublicAudioRequest:
      type: object
      properties:
        kind:
          type: string
          enum:
            - speech
            - music
            - sound_effect
          description: What to make
        prompt:
          type: string
          description: >-
            What the sound should be. Required for music and sound effects; an
            optional direction for speech.
        text:
          type: string
          description: The words to speak. Required for speech.
        baseModel:
          type: string
          description: Model identifier from models.json
        settings:
          $ref: '#/components/schemas/AudioSettingsRequest'
        organizationId:
          type: string
        webhookUrl:
          type: string
        hidePrompt:
          type: boolean
          default: false
      required:
        - kind
        - baseModel
    AudioSpectrumDto:
      type: object
      properties:
        bands:
          type: number
          description: Frequency bands per row, low to high
        frameSeconds:
          type: number
          description: Seconds between rows
        frames:
          type: array
          description: Levels 0–1, one row per frameSeconds
          items:
            type: array
            items:
              type: number
      required:
        - bands
        - frameSeconds
        - frames
    PublicAudioDto:
      type: object
      properties:
        id:
          type: string
        kind:
          type: string
          enum:
            - speech
            - music
            - sound_effect
        status:
          type: string
          enum:
            - new
            - generating
            - ready
            - failed
        statusDetail:
          type: string
        progress:
          type: number
          description: Progress (0-100)
        prompt:
          type: string
        text:
          type: string
        baseModel:
          type: string
        settings:
          type: object
          additionalProperties: true
        organizationId:
          type: string
        username:
          type: string
        audioUrl:
          type: string
          description: The generated file, once ready
        durationSeconds:
          type: number
        spectrum:
          $ref: '#/components/schemas/AudioSpectrumDto'
        credits:
          type: number
          description: What the sound cost, once ready
        byokProvider:
          type: string
        hidePrompt:
          type: boolean
        createdAt:
          format: date-time
          type: string
        updatedAt:
          format: date-time
          type: string
      required:
        - id
        - kind
        - status
        - progress
        - baseModel
        - settings
        - hidePrompt
        - createdAt
        - updatedAt
    PublicVideoEditRequest:
      type: object
      properties:
        originalVideoIds:
          description: Original video IDs (source videos for the edit)
          type: array
          items:
            type: string
        organizationId:
          type: string
        mode:
          type: string
          description: Edit mode (max 32 characters)
        width:
          type: number
          description: Width
        height:
          type: number
          description: Height
        resolution:
          type: number
          description: Resolution
        videoChoicesCount:
          type: number
          description: Number of video choices to generate
        hidePrompt:
          type: object
          default: false
        prompt:
          type: string
          description: Prompt
        prompts:
          type: array
          description: Array of prompt objects for multi-scene videos
          items:
            type: object
          example:
            - prompt: Scene 1 description
              duration: 3
        inputVideoUrls:
          description: Input video URLs (alternative to originalVideoIds)
          type: array
          items:
            type: string
        inputImageUrls:
          description: Input image URLs for the video edit
          type: array
          items:
            type: string
        imageCompletionIds:
          description: Image completion IDs to use as input for the video edit
          type: array
          items:
            type: string
        settings:
          type: object
          additionalProperties: true
        baseModel:
          type: string
          description: Base model identifier
          example: default
        webhookUrl:
          type: string
      required:
        - organizationId
        - hidePrompt
        - webhookUrl
    PublicVideoEditDto:
      type: object
      properties:
        id:
          type: string
          description: Unique identifier for the video edit
        originalVideos:
          description: Original videos used as source
          type: array
          items:
            $ref: '#/components/schemas/VideoDto'
        originalVideoIds:
          description: Original video IDs
          type: array
          items:
            type: string
        savedVideo:
          description: Saved/selected output video
          allOf:
            - $ref: '#/components/schemas/VideoDto'
        savedVideoId:
          type: string
          description: Saved video ID
        videoChoices:
          description: Output video choices
          type: array
          items:
            $ref: '#/components/schemas/VideoDto'
        mode:
          type: string
          description: Edit mode (max 32 characters)
          nullable: true
        width:
          type: number
          description: Width
        height:
          type: number
          description: Height
        resolution:
          type: number
          description: Resolution
        videoChoicesCount:
          type: number
          description: Number of video choices to generate
        prompt:
          type: string
          description: Prompt
        prompts:
          type: array
          description: Array of prompt objects for multi-scene videos
          items:
            type: object
        baseModel:
          type: string
          description: Base model identifier
        inputVideoUrls:
          description: Input video URLs
          type: array
          items:
            type: string
        inputImageUrls:
          description: Input image URLs
          type: array
          items:
            type: string
        imageCompletionIds:
          description: Image completion IDs used as input
          type: array
          items:
            type: string
        settings:
          type: object
        status:
          type: string
          description: Status of the video edit process
        statusDetail:
          type: string
          description: Detailed worker status/error message
        progress:
          type: number
          description: Progress (0-100)
        organizationId:
          type: string
          description: Organization UUID used for credit deduction
        webhookUrl:
          type: string
        hidePrompt:
          type: boolean
      required:
        - id
        - originalVideos
        - originalVideoIds
        - savedVideo
        - savedVideoId
        - videoChoices
        - width
        - height
        - resolution
        - videoChoicesCount
        - prompt
        - prompts
        - baseModel
        - inputVideoUrls
        - inputImageUrls
        - imageCompletionIds
        - settings
        - progress
        - webhookUrl
        - hidePrompt
    PublicSearchItemDto:
      type: object
      properties:
        type:
          type: string
          enum:
            - image
            - video
        image:
          description: Set when type is image; same shape as GET /images/:id
          allOf:
            - $ref: '#/components/schemas/ImageDto'
        video:
          description: Set when type is video; same shape as GET /videos/:id
          allOf:
            - $ref: '#/components/schemas/VideoDto'
      required:
        - type
    PublicSearchPaginationDto:
      type: object
      properties:
        count:
          type: number
          description: Items on this page
        hasMore:
          type: boolean
        nextCursor:
          type: string
          description: Pass as `cursor` to get the next page
      required:
        - count
        - hasMore
    PublicSearchResponseDto:
      type: object
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/PublicSearchItemDto'
        pagination:
          $ref: '#/components/schemas/PublicSearchPaginationDto'
      required:
        - items
        - pagination
    UnifiedFeedItemDto:
      type: object
      properties:
        id:
          type: string
          description: Feed item cursor ID (for pagination)
          example: '12345'
        entityType:
          type: string
          description: >-
            Entity type. `audio` only ever appears in your own feed
            (`/v2/feed/user/me`): sounds are private to their owner.
          enum:
            - image
            - video
            - audio
          example: image
        entityId:
          type: string
          description: Entity UUID
          example: uuid-string
        source:
          type: string
          description: >-
            Where this item is surfaced from. "generation" when it was published
            normally by its creator, "board" when it was published on a board
            the viewer can see. Items published on a board report "board" even
            if they are also public.
          enum:
            - generation
            - board
          example: generation
        sourceBoardId:
          type: string
          description: UUID of the board this item is sourced from (source=board)
          example: board-uuid
        thumbnailUrl:
          type: string
          description: Thumbnail URL for display
          example: https://cdn.example.com/thumb.jpg
        imageVersions:
          type: object
          description: >-
            Image versions map including original and sized variants (images
            only)
          additionalProperties:
            type: string
          example:
            original: https://cdn.example.com/user-id/image-id/image.jpg
            96x96: https://cdn.example.com/user-id/image-id/image_96x96.jpg
            240x240: https://cdn.example.com/user-id/image-id/image_240x240.jpg
            640x640: https://cdn.example.com/user-id/image-id/image_640x640.jpg
        videoUrl:
          type: string
          description: Video URL (only for video entities)
          example: https://cdn.example.com/videos/user-id/video-id/video.mp4
        audioUrl:
          type: string
          description: >-
            The sound file. Audio only, once ready; null on images and videos
            and while a sound is still generating.
          nullable: true
          example: https://images.letz.ai/user-id/audio-id/rain.mp3
        audioKind:
          type: string
          description: What kind of sound this is. Audio only; null otherwise.
          enum:
            - speech
            - music
            - sound_effect
          nullable: true
          example: music
        durationSeconds:
          type: number
          description: >-
            Length of the sound in seconds. Audio only, once the worker reported
            it; null otherwise.
          nullable: true
          example: 31.2
        usedModels:
          type: array
          description: Models used in this content
          items:
            type: object
            properties:
              id:
                type: string
                example: model-uuid
              name:
                type: string
                example: Realistic Vision V6
              thumbnailUrl:
                type: string
                example: https://cdn.example.com/model-thumb.jpg
        userId:
          type: string
          description: User ID of the creator
          example: user-uuid
        username:
          type: string
          description: Username of the creator
          example: john_doe
        userAvatarUrl:
          type: string
          description: Avatar URL of the creator
          example: https://cdn.example.com/avatar.jpg
        likes:
          type: number
          description: Number of likes
          example: 42
        comments:
          type: number
          description: Number of comments
          example: 8
        regenerations:
          type: number
          description: Number of regenerations
          example: 5
        engagementScore:
          type: number
          description: Engagement score
          example: 58.5
        trendingScore:
          type: number
          description: Trending score
          example: 12.3
        isNsfw:
          type: boolean
          description: Whether content is NSFW
          example: false
        isHot:
          type: boolean
          description: Whether content is marked as hot
          example: true
        status:
          type: string
          description: Entity processing status
          example: ready
        progress:
          type: number
          description: Generation progress (0-100). Only set for items that are not ready.
          example: 62
        previewImage:
          type: string
          description: >-
            Low resolution preview of a running generation. Images only, and
            only while the item is not ready.
        statusDetail:
          type: string
          description: Why a generation failed. Only set for items that are not ready.
          example: Generation timed out
        baseModel:
          type: string
          description: Base model used for generation
          example: stable-diffusion-xl
        imageWasEdited:
          type: boolean
          description: >-
            Whether this image was created via image editing (inpainting,
            outpainting, etc.)
          example: false
        imageWasUploaded:
          type: boolean
          description: >-
            Whether this image has uploaded reference images (real photos) as
            source
          example: false
        videoWasEdited:
          type: boolean
          description: Whether this video was created via video editing
          example: false
        contentCreatedAt:
          type: string
          description: Content creation date
          example: '2025-01-15T10:30:00Z'
        hasLiked:
          type: boolean
          description: Whether current user has liked this item
          example: false
        hasBookmarked:
          type: boolean
          description: Whether current user has bookmarked this item
          example: false
        isFollowingCreator:
          type: boolean
          description: Whether current user follows the creator
          example: true
      required:
        - id
        - entityType
        - entityId
        - source
        - userId
        - likes
        - comments
        - regenerations
        - engagementScore
        - trendingScore
        - isNsfw
        - isHot
        - status
        - imageWasEdited
        - imageWasUploaded
        - videoWasEdited
        - contentCreatedAt
    UnifiedFeedPaginationDto:
      type: object
      properties:
        count:
          type: number
          description: Number of items returned
          example: 20
        hasMore:
          type: boolean
          description: Whether more items are available
          example: true
        nextCursor:
          type: string
          description: Cursor for next page (feed item ID)
          example: '12345'
      required:
        - count
        - hasMore
    UnifiedFeedResponseDto:
      type: object
      properties:
        items:
          description: Feed items
          type: array
          items:
            $ref: '#/components/schemas/UnifiedFeedItemDto'
        pagination:
          description: Pagination info
          allOf:
            - $ref: '#/components/schemas/UnifiedFeedPaginationDto'
        feedType:
          type: string
          description: Feed type
          enum:
            - discovery
            - following
            - user
            - hot
            - search
            - board
          example: discovery
        generatedAt:
          type: string
          description: Response generation timestamp
          example: '2025-01-15T10:30:00Z'
      required:
        - items
        - pagination
        - feedType
        - generatedAt
    SkillDto:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
          description: Slug, matching /^[a-z0-9-]{1,64}$/
        description:
          type: string
          description: >-
            The L1 index entry. Injected into the system prompt for every active
            skill.
        surfaces:
          type: array
          description: >-
            Agent surfaces this skill is meaningful on. A capability declaration
            — orthogonal to where it is activated.
          items:
            type: string
            enum:
              - canvas
              - chat
              - worker
        source:
          type: string
          enum:
            - builtin
            - user
            - canvas
            - board
        ownerUserId:
          type: string
          nullable: true
        priority:
          type: number
          description: L1 ordering. Lower sorts earlier.
        alwaysHint:
          type: boolean
          description: Renders the [MANDATORY] marker in the L1 index.
        workerTypes:
          type: array
          items:
            type: string
            enum:
              - design
              - media
              - research
        createdAt:
          format: date-time
          type: string
        updatedAt:
          format: date-time
          type: string
      required:
        - id
        - name
        - description
        - surfaces
        - source
        - priority
        - alwaysHint
        - workerTypes
        - createdAt
        - updatedAt
    SkillListDto:
      type: object
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/SkillDto'
        total:
          type: number
        page:
          type: number
        limit:
          type: number
      required:
        - items
        - total
        - page
        - limit
    SkillBodyDto:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        content:
          type: string
          description: The L2 markdown instructions.
        bundledFiles:
          description: >-
            Relative paths of L3 bundled reference files, e.g.
            references/models/flux2.md. Pass one back as `path` to read it.
          type: array
          items:
            type: string
      required:
        - id
        - name
        - content
    SkillFileDto:
      type: object
      properties:
        id:
          type: string
        skillId:
          type: string
        path:
          type: string
          example: references/models/flux2.md
        content:
          type: string
        createdAt:
          format: date-time
          type: string
        updatedAt:
          format: date-time
          type: string
      required:
        - id
        - skillId
        - path
        - content
        - createdAt
        - updatedAt
    PublicApiOrganizationDto:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        handle:
          type: string
        description:
          type: string
        website:
          type: string
        profilePicture:
          type: string
        isActive:
          type: boolean
        isAdmin:
          type: boolean
          description: Whether you manage this organization
        creditMechanism:
          type: string
          description: How members spend the organization credits (pooled or allocated)
        members:
          type: number
      required:
        - id
        - name
        - handle
        - isActive
        - isAdmin
    OrganizationCreditBalanceDto:
      type: object
      properties:
        organizationId:
          type: string
        creditType:
          type: string
        balance:
          type: number
          description: >-
            What the requesting member can spend: the organization's pool after
            their own credit limit and this period's spend.
        poolBalance:
          type: number
          description: >-
            The organization's whole pool, before any member limit. Returned to
            managers only; it can be negative after a final charge the pool
            couldn't cover.
        updatedAt:
          format: date-time
          type: string
      required:
        - organizationId
        - creditType
        - balance
        - updatedAt
    StudioDesignSizeDto:
      type: object
      properties:
        w:
          type: number
          description: Design width in px.
        h:
          type: number
          description: Design height in px.
      required:
        - w
        - h
    StudioDesignListItemDto:
      type: object
      properties:
        conversationId:
          type: string
        designId:
          type: string
        entryFile:
          type: string
        title:
          type: string
          nullable: true
        size:
          nullable: true
          type: object
          allOf:
            - $ref: '#/components/schemas/StudioDesignSizeDto'
        version:
          type: number
        updatedBy:
          type: string
          nullable: true
        createdAt:
          type: string
        updatedAt:
          type: string
        filesCount:
          type: number
          description: Number of files in the design.
      required:
        - conversationId
        - designId
        - entryFile
        - title
        - size
        - version
        - updatedBy
        - createdAt
        - updatedAt
        - filesCount
    StudioDesignListResponseDto:
      type: object
      properties:
        designs:
          type: array
          items:
            $ref: '#/components/schemas/StudioDesignListItemDto'
      required:
        - designs
    StudioDesignDto:
      type: object
      properties:
        conversationId:
          type: string
        designId:
          type: string
          description: Client-minted, opaque design id.
        entryFile:
          type: string
        files:
          type: object
          additionalProperties:
            type: string
        title:
          type: string
          nullable: true
        size:
          nullable: true
          type: object
          allOf:
            - $ref: '#/components/schemas/StudioDesignSizeDto'
        version:
          type: number
        updatedBy:
          type: string
          nullable: true
        createdAt:
          type: string
        updatedAt:
          type: string
      required:
        - conversationId
        - designId
        - entryFile
        - files
        - title
        - size
        - version
        - updatedBy
        - createdAt
        - updatedAt
    StudioDesignGetResponseDto:
      type: object
      properties:
        design:
          $ref: '#/components/schemas/StudioDesignDto'
        versionsCount:
          type: number
      required:
        - design
        - versionsCount
    StudioDesignSizeRequest:
      type: object
      properties:
        w:
          type: number
          description: Design width in px.
        h:
          type: number
          description: Design height in px.
      required:
        - w
        - h
    StudioDesignPutRequest:
      type: object
      properties:
        designId:
          type: string
          description: Client-minted design id. Must equal the :designId path segment.
        entryFile:
          type: string
          description: Entrypoint file key inside files map.
        files:
          type: object
          additionalProperties:
            type: string
          description: Design source files keyed by path.
        title:
          type: string
          nullable: true
        size:
          $ref: '#/components/schemas/StudioDesignSizeRequest'
        snapshotVersion:
          type: boolean
          default: false
          description: >-
            Push the pre-write state onto the version history. Streaming writes
            leave this false so one generation does not flood the history.
      required:
        - designId
        - entryFile
        - files
    StudioDesignPutResponseDto:
      type: object
      properties:
        design:
          $ref: '#/components/schemas/StudioDesignDto'
      required:
        - design
    StudioDesignDeleteResponseDto:
      type: object
      properties:
        deleted:
          type: boolean
      required:
        - deleted
    StudioDesignVersionDto:
      type: object
      properties:
        id:
          type: string
        snapshotAt:
          type: string
        designVersion:
          type: number
          description: Design row version number captured when the snapshot ran.
        createdBy:
          type: string
          nullable: true
        title:
          type: string
          nullable: true
        filesCount:
          type: number
        size:
          type: number
          description: Serialized size of the snapshot in bytes.
      required:
        - id
        - snapshotAt
        - designVersion
        - createdBy
        - title
        - filesCount
        - size
    StudioDesignVersionsResponseDto:
      type: object
      properties:
        versions:
          type: array
          items:
            $ref: '#/components/schemas/StudioDesignVersionDto'
      required:
        - versions
    StudioDesignVersionDetailDto:
      type: object
      properties:
        id:
          type: string
        snapshotAt:
          type: string
        designVersion:
          type: number
          description: Design row version number captured when the snapshot ran.
        createdBy:
          type: string
          nullable: true
        title:
          type: string
          nullable: true
        filesCount:
          type: number
        size:
          type: number
          description: Serialized size of the snapshot in bytes.
        entryFile:
          type: string
        files:
          type: object
          additionalProperties:
            type: string
        designSize:
          nullable: true
          type: object
          allOf:
            - $ref: '#/components/schemas/StudioDesignSizeDto'
      required:
        - id
        - snapshotAt
        - designVersion
        - createdBy
        - title
        - filesCount
        - size
        - entryFile
        - files
        - designSize
    StudioDesignVersionResponseDto:
      type: object
      properties:
        version:
          $ref: '#/components/schemas/StudioDesignVersionDetailDto'
      required:
        - version
    StudioDesignRestoreRequest:
      type: object
      properties:
        versionId:
          type: string
          description: Version snapshot id to restore from.
      required:
        - versionId
    StudioDesignToCanvasRequest:
      type: object
      properties:
        canvasId:
          type: string
          description: Target canvas id.
        pageId:
          type: string
          description: Target page id inside the canvas.
        nodeId:
          type: string
          description: Target design node id. The node must already exist.
      required:
        - canvasId
        - pageId
        - nodeId
    StudioDesignToCanvasResponseDto:
      type: object
      properties:
        canvasId:
          type: string
        pageId:
          type: string
        nodeId:
          type: string
        version:
          type: number
          description: Version of the canvas design after the copy.
      required:
        - canvasId
        - pageId
        - nodeId
        - version
    DesignPublishDto:
      type: object
      properties:
        publishId:
          type: string
          description: Opaque stable id — never changes for this node.
        slug:
          type: string
          nullable: true
          description: User-facing path segment; null if never set.
        nodeId:
          type: string
          nullable: true
          description: Owning canvas node; null when a studio design owns this.
        conversationId:
          type: string
          nullable: true
          description: Owning conversation; null when a canvas node owns this.
        studioDesignId:
          type: string
          nullable: true
          description: Owning studio design id; null when a canvas node owns this.
        artifactId:
          type: string
        visibility:
          type: string
          enum:
            - private
            - unlisted
            - public
        designVersion:
          type: number
          description: DesignBody.version at last successful publish / re-publish.
        liveVersion:
          type: number
          nullable: true
          description: Currently-live published version number; null for legacy rows.
        url:
          type: string
          description: Primary share link — slug URL when slug set, else fallbackUrl.
        fallbackUrl:
          type: string
          description: Always the /{publishId}/ form.
        publishedAt:
          type: string
        updatedAt:
          type: string
      required:
        - publishId
        - slug
        - nodeId
        - conversationId
        - studioDesignId
        - artifactId
        - visibility
        - designVersion
        - liveVersion
        - url
        - fallbackUrl
        - publishedAt
        - updatedAt
    DesignPublishResponseDto:
      type: object
      properties:
        publish:
          $ref: '#/components/schemas/DesignPublishDto'
      required:
        - publish
    DesignPublishRequest:
      type: object
      properties:
        visibility:
          type: string
          enum:
            - private
            - unlisted
            - public
          description: Requested visibility (capped by canvas visibility). Default private.
        slug:
          type: string
          description: Claim a custom slug for /artifact/{slug}/ URLs.
    DesignPublishPatchRequest:
      type: object
      properties:
        visibility:
          type: string
          enum:
            - private
            - unlisted
            - public
          description: Update effective visibility (still capped by canvas).
        slug:
          type: string
          nullable: true
          description: Claim, change, or pass null to release the slug.
    CanvasOwnerDto:
      type: object
      properties:
        id:
          type: string
        username:
          type: string
        profilePicture:
          type: string
      required:
        - id
    CanvasListItemDto:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        description:
          type: string
        coverThumbs:
          type: array
          items:
            type: string
        thumbnail:
          type: string
        organization:
          nullable: true
          description: Organization attached to the canvas.
          type: object
          allOf:
            - $ref: '#/components/schemas/PublicOrganizationDto'
        updatedAt:
          format: date-time
          type: string
        collaborators:
          type: array
          items:
            $ref: '#/components/schemas/CanvasOwnerDto'
        role:
          type: string
          enum:
            - owner
            - editor
            - viewer
          description: Effective role for the requesting user on this canvas.
      required:
        - id
        - name
        - coverThumbs
        - updatedAt
        - collaborators
    CanvasCollaboratorDto:
      type: object
      properties:
        id:
          type: string
        username:
          type: string
        profilePicture:
          type: string
        userId:
          type: string
        role:
          type: string
          enum:
            - owner
            - editor
            - viewer
          description: Permission tier for this collaborator.
        color:
          type: string
          description: 'Cursor/selection color in #RRGGBB format.'
        addedAt:
          format: date-time
          type: string
          description: When this collaborator was added.
        status:
          type: string
          enum:
            - pending
            - requested
            - accepted
            - rejected
          description: Invitation status for this collaborator.
        invitedBy:
          nullable: true
          type: object
          allOf:
            - $ref: '#/components/schemas/CanvasOwnerDto'
        requestedByCurrentUser:
          type: boolean
      required:
        - id
        - role
        - color
        - addedAt
    CanvasPageSummaryDto:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        systemPrompt:
          type: string
          description: Page-level system prompt that describes what this page is about.
        orderIndex:
          type: number
          description: Page tab order position (0-based).
        thumbUrl:
          type: string
          description: Optional page thumbnail URL.
        nodeCount:
          type: number
          description: Count of active nodes in this page.
        version:
          type: number
          description: Monotonic page version. Increments by 1 for each committed mutation.
        updatedAt:
          format: date-time
          type: string
      required:
        - id
        - name
        - orderIndex
        - nodeCount
        - version
        - updatedAt
    CanvasDto:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        description:
          type: string
        visibility:
          type: string
          enum:
            - private
            - unlisted
            - public
          description: Canvas visibility level.
        owner:
          $ref: '#/components/schemas/CanvasOwnerDto'
        organization:
          nullable: true
          description: Organization attached to the canvas.
          type: object
          allOf:
            - $ref: '#/components/schemas/PublicOrganizationDto'
        collaborators:
          type: array
          items:
            $ref: '#/components/schemas/CanvasCollaboratorDto'
        pages:
          type: array
          items:
            $ref: '#/components/schemas/CanvasPageSummaryDto'
        defaultPageId:
          type: string
          description: Default page id opened by frontend.
        coverThumbs:
          description: Optional up-to-4 thumbnail URLs used on index cards.
          type: array
          items:
            type: string
        thumbnail:
          type: string
          description: Canonical thumbnail URL used on index cards.
        createdAt:
          format: date-time
          type: string
        updatedAt:
          format: date-time
          type: string
        version:
          type: number
          description: Monotonic canvas version.
      required:
        - id
        - name
        - visibility
        - owner
        - collaborators
        - pages
        - defaultPageId
        - createdAt
        - updatedAt
        - version
    PageCameraDto:
      type: object
      properties:
        x:
          type: number
        'y':
          type: number
        zoom:
          type: number
      required:
        - x
        - 'y'
        - zoom
    NodeDto:
      type: object
      properties:
        id:
          type: string
          description: Node UUID.
        canvasId:
          type: string
          description: Canvas UUID this node belongs to.
        pageId:
          type: string
          description: Page UUID this node belongs to.
        clientNodeId:
          type: string
          description: >-
            Idempotency key the node was created with, so a writer can match
            created rows to its request.
        kind:
          type: string
          enum:
            - media
            - text
            - shape
            - line
            - pen
            - section
          description: Discriminator for node payload in data.
        parentId:
          type: string
          nullable: true
          description: Parent section node id on same page, or null.
        position:
          type: object
          description: World-space position.
          example:
            x: 120
            'y': 240
        size:
          type: object
          description: World-space size.
          example:
            w: 400
            h: 240
        rotation:
          type: number
          description: Clockwise rotation in degrees.
        z:
          type: number
          description: Stacking hint; page.order is authoritative.
        locked:
          type: boolean
          description: Whether node is locked for mutations.
        orderIndex:
          type: number
          description: Position index inside page.order.
        version:
          type: number
          description: Monotonic node version.
        createdBy:
          type: string
        updatedBy:
          type: string
        createdAt:
          format: date-time
          type: string
        updatedAt:
          format: date-time
          type: string
        data:
          type: object
          description: Kind-specific payload. Must be interpreted based on node kind.
          example:
            shape: rect
            fill: '#D9D9D9'
            strokeWidth: 6
            opacity: 1
      required:
        - id
        - canvasId
        - pageId
        - kind
        - position
        - size
        - rotation
        - z
        - locked
        - orderIndex
        - version
        - createdBy
        - createdAt
        - updatedAt
        - data
    PageDto:
      type: object
      properties:
        id:
          type: string
        canvasId:
          type: string
        name:
          type: string
        systemPrompt:
          type: string
          description: Page-level system prompt that describes what this page is about.
        orderIndex:
          type: number
        camera:
          description: Shared page camera defaults.
          allOf:
            - $ref: '#/components/schemas/PageCameraDto'
        nodes:
          description: Full node graph for this page.
          type: array
          items:
            $ref: '#/components/schemas/NodeDto'
        order:
          description: Authoritative stacking array. Start = front, end = back in this API.
          type: array
          items:
            type: string
        createdBy:
          type: string
        updatedBy:
          type: string
        createdAt:
          format: date-time
          type: string
        updatedAt:
          format: date-time
          type: string
        version:
          type: number
          description: Monotonic page version.
      required:
        - id
        - canvasId
        - name
        - orderIndex
        - nodes
        - order
        - createdBy
        - createdAt
        - updatedAt
        - version
    Vec2Request:
      type: object
      properties:
        x:
          type: number
        'y':
          type: number
      required:
        - x
        - 'y'
    SizeRequest:
      type: object
      properties:
        w:
          type: number
        h:
          type: number
      required:
        - w
        - h
    NodeRequest:
      type: object
      properties:
        clientNodeId:
          type: string
          description: >-
            Client-generated idempotency key for logical create dedupe (opaque
            string).
          example: tmp_9ea8fd13-1f0d-43d8-b3d1-6b5df0f2630e
        kind:
          type: string
          enum:
            - media
            - text
            - shape
            - line
            - pen
            - section
          description: Node kind discriminator for payload in data.
        position:
          description: World-space position.
          allOf:
            - $ref: '#/components/schemas/Vec2Request'
        size:
          description: World-space size.
          allOf:
            - $ref: '#/components/schemas/SizeRequest'
        rotation:
          type: number
          default: 0
          description: Rotation in degrees.
        z:
          type: number
          default: 0
          description: Stacking hint; page.order remains authoritative.
        parentId:
          type: string
          nullable: true
          description: Parent section node id on same page.
        locked:
          type: boolean
          default: false
        data:
          type: object
          description: Kind-specific payload; shallow merged on patch updates.
          example:
            shape: rect
            fill: '#D9D9D9'
            strokeWidth: 6
            opacity: 1
      required:
        - kind
        - position
        - size
        - data
    NodeResponseDto:
      type: object
      properties:
        node:
          $ref: '#/components/schemas/NodeDto'
        pageVersion:
          type: number
      required:
        - node
        - pageVersion
    NodesBatchCreateRequest:
      type: object
      properties:
        nodes:
          type: array
          items:
            $ref: '#/components/schemas/NodeRequest'
      required:
        - nodes
    NodesResponseDto:
      type: object
      properties:
        nodes:
          type: array
          items:
            $ref: '#/components/schemas/NodeDto'
        pageVersion:
          type: number
      required:
        - nodes
        - pageVersion
    Vec2PatchRequest:
      type: object
      properties:
        x:
          type: number
        'y':
          type: number
      required:
        - x
        - 'y'
    SizePatchRequest:
      type: object
      properties:
        w:
          type: number
        h:
          type: number
      required:
        - w
        - h
    NodePatchRequest:
      type: object
      properties:
        position:
          $ref: '#/components/schemas/Vec2PatchRequest'
        size:
          $ref: '#/components/schemas/SizePatchRequest'
        rotation:
          type: number
        z:
          type: number
        parentId:
          type: string
          nullable: true
        locked:
          type: boolean
        orderIndex:
          type: number
        data:
          type: object
          description: Partial node.data patch. Merged shallowly with existing node.data.
          example:
            fill: '#7C5CFF'
    NodeOpsPatchItemRequest:
      type: object
      properties:
        id:
          type: string
        patch:
          $ref: '#/components/schemas/NodePatchRequest'
        version:
          type: number
      required:
        - id
        - patch
    NodesOpsRequest:
      type: object
      properties:
        clientOpId:
          type: string
        creates:
          type: array
          items:
            $ref: '#/components/schemas/NodeRequest'
        patches:
          type: array
          items:
            $ref: '#/components/schemas/NodeOpsPatchItemRequest'
        deletes:
          type: array
          items:
            type: string
        restores:
          type: array
          items:
            type: string
        order:
          type: array
          items:
            type: string
    NodesRestoreSkippedDto:
      type: object
      properties:
        id:
          type: string
        reason:
          type: string
          enum:
            - not_found
            - not_deleted
      required:
        - id
        - reason
    NodesOpsResponseDto:
      type: object
      properties:
        nodes:
          type: array
          items:
            $ref: '#/components/schemas/NodeDto'
        restored:
          type: array
          items:
            $ref: '#/components/schemas/NodeDto'
        skipped:
          type: array
          items:
            $ref: '#/components/schemas/NodesRestoreSkippedDto'
        deleted:
          type: array
          items:
            type: string
        order:
          type: array
          items:
            type: string
        pageVersion:
          type: number
      required:
        - nodes
        - restored
        - skipped
        - deleted
        - order
        - pageVersion
    NodeUpdateItemRequest:
      type: object
      properties:
        id:
          type: string
        patch:
          $ref: '#/components/schemas/NodePatchRequest'
      required:
        - id
        - patch
    NodesBatchUpdateRequest:
      type: object
      properties:
        updates:
          type: array
          items:
            $ref: '#/components/schemas/NodeUpdateItemRequest'
      required:
        - updates
    NodesDeleteResponseDto:
      type: object
      properties:
        deleted:
          type: array
          items:
            type: string
        pageVersion:
          type: number
      required:
        - deleted
        - pageVersion
    NodesBulkDeleteRequest:
      type: object
      properties:
        ids:
          type: array
          items:
            type: string
      required:
        - ids
    DesignDto:
      type: object
      properties:
        nodeId:
          type: string
        artifactId:
          type: string
        entryFile:
          type: string
        files:
          type: object
          additionalProperties:
            type: string
        version:
          type: number
        updatedBy:
          type: string
          nullable: true
        createdAt:
          type: string
        updatedAt:
          type: string
      required:
        - nodeId
        - artifactId
        - entryFile
        - files
        - version
        - createdAt
        - updatedAt
    DesignGetResponseDto:
      type: object
      properties:
        design:
          $ref: '#/components/schemas/DesignDto'
        versionsCount:
          type: number
      required:
        - design
        - versionsCount
    DesignPutRequest:
      type: object
      properties:
        artifactId:
          type: string
          description: Design artifact id from parent node body.
        entryFile:
          type: string
          description: Entrypoint file key inside files map.
        files:
          type: object
          additionalProperties:
            type: string
          description: Design source files keyed by path.
        snapshotVersion:
          type: boolean
          deprecated: true
          description: >-
            Deprecated and ignored. The server now snapshots the prior state on
            every edit, so all changes are restorable regardless of this flag.
            Retained so existing clients that still send it are not rejected.
          default: false
      required:
        - artifactId
        - entryFile
        - files
    DesignPutResponseDto:
      type: object
      properties:
        design:
          $ref: '#/components/schemas/DesignDto'
      required:
        - design
    GenerationQuoteRequest:
      type: object
      properties:
        type:
          type: string
          enum:
            - image
            - image-edit
            - video
            - video-edit
            - upscale
            - audio
        baseModel:
          type: string
          description: >-
            The model: `baseModel` for images and edits, the video model key for
            videos, the editing model for video edits, the upscale mode for
            upscales, the audio model key.
          maxLength: 255
        mode:
          type: string
          description: >-
            Images: `generationSettings.mode` (the resolution mode). Videos:
            `settings.mode` (wins over baseModel). Upscales:
            `generationSettings.mode` (wins over baseModel).
        width:
          type: number
          description: 'Pixels. Images: picks the tier when `mode` does not.'
        height:
          type: number
        duration:
          type: number
          description: >-
            Seconds. Videos: requested length. Video edits and video upscales:
            the source clip. Music and sound effects: requested length.
        withSound:
          type: boolean
          description: 'Videos: `settings.withSound`.'
        quantity:
          type: number
          description: >-
            Images: how many images (one job each). Image edits:
            `imageCompletionsCount`. Default 1.
          minimum: 1
          maximum: 100
        size:
          description: >-
            Upscales: the numeric `size` code sent to `/upscales` (4/8/12, Pruna
            4–18, video 8–16), or a tier name (`2k`, `4mp`, `2x`).
          oneOf:
            - type: integer
            - type: string
        characters:
          type: number
          description: 'Speech: characters of script.'
        resolution:
          type: string
          description: >-
            Videos and video upscales: output tier (`settings.resolution`, e.g.
            `720p`). Images: a UI tier (`1k`, `hd`, `4k`) when no `mode` is
            sent.
        highQuality:
          type: boolean
          description: 'Videos: `settings.highQuality`.'
        fps:
          type: number
          description: 'Video upscales: `generationSettings.fps`.'
        organizationId:
          type: string
          format: uuid
          description: >-
            The paying organization (you must belong to it). Decides whose
            provider keys and plan apply.
      required:
        - type
        - baseModel
    GenerationQuoteMultipliersDto:
      type: object
      properties:
        audio:
          type: number
        highQuality:
          type: number
        fps:
          type: number
      required:
        - audio
        - highQuality
        - fps
    GenerationQuoteBreakdownDto:
      type: object
      properties:
        model:
          type: string
          description: Catalogue key of the priced model.
        capability:
          type: string
          enum:
            - generation
            - editing
            - video
            - video_editing
            - upscaling
            - audio
        active:
          type: boolean
        enterpriseOnly:
          type: boolean
        unit:
          type: string
          enum:
            - image
            - job
            - second
            - 1k_characters
        tier:
          type: string
          nullable: true
          description: Pricing tier (`1k`, `720p`, `4mp` …).
        unitPrice:
          type: number
        units:
          type: number
          description: Seconds, characters, or 1.
        multipliers:
          $ref: '#/components/schemas/GenerationQuoteMultipliersDto'
        perJob:
          type: number
          description: Credits for one job at list price.
        quantity:
          type: number
        jobs:
          type: number
        listCredits:
          type: number
          description: List price of the request, ignoring BYOK.
        byok:
          type: boolean
          description: >-
            True when the job would run on the paying account's own provider
            key: 1 credit per job.
        notes:
          description: >-
            Assumptions made where the request left something open
            (`duration_assumed:5`, `tier_clamped:4k->2k` …).
          type: array
          items:
            type: string
      required:
        - model
        - capability
        - active
        - enterpriseOnly
        - unit
        - tier
        - unitPrice
        - units
        - multipliers
        - perJob
        - quantity
        - jobs
        - listCredits
        - byok
        - notes
    GenerationQuoteDto:
      type: object
      properties:
        credits:
          type: number
          description: Estimated credits for the request.
        estimate:
          type: boolean
          enum:
            - true
          description: >-
            Always true: the charge is the price the worker reports when the job
            is ready.
        breakdown:
          $ref: '#/components/schemas/GenerationQuoteBreakdownDto'
      required:
        - credits
        - estimate
        - breakdown
    AgentRunPrefsRequest:
      type: object
      properties:
        prefs:
          type: object
          additionalProperties: true
          description: >-
            Session preferences of the agent (opaque to the API; at most 64 KB
            of JSON). Replaces what was stored.
      required:
        - prefs
    AgentRunCanvasRequest:
      type: object
      properties:
        canvasId:
          type: string
          format: uuid
        pageId:
          type: string
          format: uuid
      required:
        - canvasId
        - pageId
    AgentRunFrameImageRequest:
      type: object
      properties: {}
    AgentRunAttachmentRequest:
      type: object
      properties:
        type:
          type: string
          enum:
            - image
            - video
            - audio
            - file
        id:
          type: string
          description: Id of the image, video, sound or user document.
        url:
          type: string
          description: >-
            Where it can be fetched; passed to the agent as an upload of this
            turn. Required for `audio`: a sound is only usable through its URL.
        name:
          type: string
          description: File name, for user documents.
      required:
        - type
        - id
    AgentRunSelectionRequest:
      type: object
      properties:
        model:
          type: string
        thinkingLevel:
          type: string
        mediaModels:
          type: object
          additionalProperties: true
          description: >-
            Generation-mode picks (image / video / … model per mode). At most 4
            KB of JSON.
    AgentRunMessageRequest:
      type: object
      properties:
        frameImages:
          type: array
          items:
            $ref: '#/components/schemas/AgentRunFrameImageRequest'
        text:
          type: string
          maxLength: 32000
        attachments:
          type: array
          items:
            $ref: '#/components/schemas/AgentRunAttachmentRequest'
        selection:
          $ref: '#/components/schemas/AgentRunSelectionRequest'
        selectedNodeIds:
          description: >-
            Canvas runs: node ids selected on the board when this message was
            sent.
          type: array
          items:
            type: string
        clientContext:
          type: object
          additionalProperties: true
          description: >-
            What the client knows about this turn that the API does not (opaque
            to the API; at most 32 KB of JSON): `chat` (Studio: user, image /
            video / audio history, image search results, browser-held documents)
            or `canvas` (viewport, organization, uploaded files, frame contents,
            timeline focus). Stored with the message; the agent gets the one of
            the latest real user message as `context.clientContext`.
      required:
        - text
    AgentRunRequest:
      type: object
      properties:
        surface:
          type: string
          enum:
            - studio
            - canvas
            - api
        conversationId:
          type: string
          format: uuid
          description: >-
            A chat conversation of yours. The run sees its earlier runs, and its
            messages are added to it.
        canvas:
          description: Required for surface `canvas`.
          allOf:
            - $ref: '#/components/schemas/AgentRunCanvasRequest'
        message:
          $ref: '#/components/schemas/AgentRunMessageRequest'
        model:
          type: string
          description: >-
            Text model id. Default: the catalogue default. Unknown ids are 400
            unknown_model.
        thinkingLevel:
          type: string
          maxLength: 32
        organizationId:
          type: string
          format: uuid
          description: >-
            Bill an organization you belong to. Connector tokens: filled in from
            the connection.
      required:
        - surface
        - message
    AgentRunLimitsDto:
      type: object
      properties:
        maxSteps:
          type: number
        maxWallSeconds:
          type: number
      required:
        - maxSteps
        - maxWallSeconds
    AgentRunUsageDto:
      type: object
      properties:
        inputTokens:
          type: number
        cacheReadTokens:
          type: number
        cacheWriteTokens:
          type: number
        outputTokens:
          type: number
        sandboxSeconds:
          type: number
        credits:
          type: number
          description: Image credits charged so far.
      required:
        - inputTokens
        - cacheReadTokens
        - cacheWriteTokens
        - outputTokens
        - sandboxSeconds
        - credits
    AgentRunErrorDto:
      type: object
      properties:
        code:
          type: string
          example: insufficient_credits
          description: >-
            `insufficient_credits`, `limit_exceeded`, `agent_error`,
            `step_attempts_exceeded`, `grant_revoked`.
        message:
          type: string
      required:
        - code
    AgentRunDto:
      type: object
      properties:
        id:
          type: string
        userId:
          type: string
        organizationId:
          type: string
          nullable: true
        conversationId:
          type: string
          nullable: true
        surface:
          type: string
          enum:
            - studio
            - canvas
            - api
        canvasId:
          type: string
          nullable: true
        pageId:
          type: string
          nullable: true
        model:
          type: string
        thinkingLevel:
          type: string
          nullable: true
        status:
          type: string
          enum:
            - queued
            - running
            - waiting
            - done
            - failed
            - cancelled
        limits:
          $ref: '#/components/schemas/AgentRunLimitsDto'
        usage:
          $ref: '#/components/schemas/AgentRunUsageDto'
        stepCount:
          type: number
        lastEventSeq:
          type: number
          description: 'Seq of the latest event: replay from here.'
        error:
          nullable: true
          type: object
          allOf:
            - $ref: '#/components/schemas/AgentRunErrorDto'
        createdAt:
          type: string
        startedAt:
          type: string
          nullable: true
        endedAt:
          type: string
          nullable: true
        waits:
          type: array
          example:
            - jobs
          description: >-
            Only while `status` is `waiting`: the distinct kinds of the run’s
            open waits. Exactly `["jobs"]` means it only waits for media jobs to
            finish.
          items:
            type: string
            enum:
              - jobs
              - question
              - client_tool
              - child_run
      required:
        - id
        - userId
        - organizationId
        - conversationId
        - surface
        - canvasId
        - pageId
        - model
        - thinkingLevel
        - status
        - limits
        - usage
        - stepCount
        - lastEventSeq
        - error
        - createdAt
        - startedAt
        - endedAt
    AgentRunEnvelopeDto:
      type: object
      properties:
        run:
          $ref: '#/components/schemas/AgentRunDto'
      required:
        - run
    AgentRunListDto:
      type: object
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/AgentRunDto'
        nextCursor:
          type: string
      required:
        - items
    AgentRunEventDto:
      type: object
      properties:
        seq:
          type: number
        type:
          type: string
        data:
          type: object
          additionalProperties: true
        createdAt:
          type: string
      required:
        - seq
        - type
        - data
        - createdAt
    AgentRunEventListDto:
      type: object
      properties:
        events:
          type: array
          items:
            $ref: '#/components/schemas/AgentRunEventDto'
        nextAfter:
          type: number
          description: 'Present when there may be more: pass it as `after`.'
      required:
        - events
    AgentRunAnswerRequest:
      type: object
      properties:
        questionId:
          type: string
          format: uuid
        answer:
          type: object
          description: 'The answer: an option id, a boolean, or text. At most 16 KB of JSON.'
      required:
        - questionId
        - answer
    AgentRunClientToolClaimRequest:
      type: object
      properties: {}
    AgentRunClientToolResultRequest:
      type: object
      properties: {}
