openapi: "3.0.2"
info:
  title: Upscayl Cloud API
  description: |
    API for Upscayl Cloud - An AI-powered image upscaling service.
    Use this API to upscale images, check processing status, and manage uploads.
  version: 1.0.0
  contact:
    name: Upscayl Support
    url: mailto:support@upscayl.org
servers:
  - url: https://api.upscayl.org
    description: Upscayl Server

paths:
  /complete-multipart-upload:
    post:
      summary: Complete Multipart Upload
      description: |
        This endpoint marks a multipart upload as complete.
        It requires the upload ID, a key, and a list of parts with their ETags. This endpoint is used after uploading parts to the multipart URLs generated by the [get-upload-url](/get-upload-url) endpoint.
      operationId: completeMultipartUpload
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  type: object
                  properties:
                    uploadId:
                      type: string
                      description: The ID of the multipart upload.
                    key:
                      type: string
                      description: The S3 key where the file is stored.
                    parts:
                      type: array
                      items:
                        type: object
                        properties:
                          PartNumber:
                            type: integer
                            description: The part number.
                          ETag:
                            type: string
                            description: The ETag of the uploaded part.
                      description: A list of parts with their ETags.
                  required:
                    - uploadId
                    - key
                    - parts
      responses:
        "200":
          description: Multipart upload completed successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      status:
                        type: string
                        example: success
        "400":
          description: Bad Request
          content:
            application/json:
              schema:
                type: object
                example: "Bad Request: Missing required parameters"
        "500":
          description: Internal Server Error
          content:
            application/json:
              schema:
                type: object
                example: "Internal Server Error: Failed to complete upload"
      security:
        - ApiKeyAuth: []

  /get-upload-url:
    post:
      summary: Get Multipart Upload URLs
      description: |
        This endpoint generates a URLs for uploading a file to upscayl servers in multipart format. This is useful for large files or slow connections.
      operationId: getUploadUrl
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  type: object
                  properties:
                    fileSize:
                      type: integer
                      description: The size of the file in bytes.
                    fileType:
                      type: string
                      description: The MIME type of the file.
                    originalFileName:
                      type: string
                      description: The original name of the file.
                  required:
                    - fileSize
                    - fileType
                    - originalFileName
      responses:
        "200":
          description: Presigned URLs generated successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      uploadId:
                        type: string
                        description: The ID of the multipart upload.
                      partUrls:
                        type: array
                        items:
                          type: object
                          properties:
                            partNumber:
                              type: integer
                              description: The part number for the upload.
                            signedUrl:
                              type: string
                              description: The presigned URL for uploading the part.
                      partSize:
                        type: integer
                        description: The size of each part in bytes.
                      fileName:
                        type: string
                        description: The generated file name.
                      fileType:
                        type: string
                        description: The MIME type of the file.
                      fileSize:
                        type: integer
                        description: The size of the file in bytes.
                      originalFileName:
                        type: string
                        description: The original name of the file.
                      path:
                        description: The path of the file to send to [start-task](/start-task).
                      createdAt:
                        type: integer
                        description: Timestamp of URL generation.
                      expiresAt:
                        type: integer
                        description: Timestamp of URL expiration.
        "400":
          description: Bad Request
          content:
            application/json:
              schema:
                type: object
                example: "Bad Request: Missing User ID"
        "402":
          description: Payment Required
          content:
            application/json:
              schema:
                type: object
                example: Insufficient credits
        "500":
          description: Internal Server Error
          content:
            application/json:
              schema:
                type: object
                example: Internal Server Error
      security:
        - ApiKeyAuth: []

  /get-task-status:
    post:
      summary: Get Task Status
      description: |
        This endpoint retrieves the status of a task, including whether it has been processed, credits deducted, and file download links.
        It also handles credit deduction if the task is processed and credits have not been deducted yet.
      operationId: getTaskStatus
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  type: object
                  properties:
                    taskId:
                      type: string
                      description: The ID of the task to retrieve the status for.
      responses:
        "200":
          description: Task status retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      status:
                        $ref: "#/components/schemas/Status"
                      progress:
                        type: string
                        example: "100"
                      files:
                        type: array
                        items:
                          $ref: "#/components/schemas/FileData"
                      deductedCredits:
                        type: integer
                        example: 10
                      creditsDeducted:
                        type: boolean
                        example: true
                      model:
                        $ref: "#/components/schemas/Model"
                      scale:
                        $ref: "#/components/schemas/Scale"
                      saveImageAs:
                        type: string
                        example: "png"
                      compression:
                        type: integer
                        example: 80
                      batchMode:
                        type: boolean
                        example: false
        "400":
          description: Bad Request
          content:
            application/json:
              schema:
                type: object
                example: "Bad Request: Missing User ID"
        "500":
          description: Internal Server Error
          content:
            application/json:
              schema:
                type: object
                example: Error getting data
      security:
        - ApiKeyAuth: []

  /start-task:
    post:
      summary: Start Upscaling Task
      description: |
        This endpoint processes an upscaling task request, including file uploads.
      operationId: startTask
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - enhanceFace
                - model
                - scale
                - saveImageAs
              properties:
                file:
                  type: string
                  format: binary
                  description: "The image file to be processed. Supported formats: JPG, PNG, WEBP."
                files:
                  type: array
                  items:
                    $ref: "#/components/schemas/FileData"
                  description: "The files to be processed. **This is to be only used with 'Get Upload URL' endpoint.**"
                urls:
                  type: array
                  items:
                    type: string
                    format: uri
                  description: "Array of URLs pointing to images to be processed."
                model:
                  $ref: "#/components/schemas/Model"
                scale:
                  $ref: "#/components/schemas/Scale"
                saveImageAs:
                  $ref: "#/components/schemas/SaveImageAs"
                enhanceFace:
                  type: boolean
                  description: Whether to enhance faces in the image.
              oneOf:
                - required: ["file"]
                - required: ["files"]
                - required: ["urls"]
      responses:
        "200":
          description: Task request sent successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  data:
                    type: object
                    properties:
                      message:
                        type: string
                        description: The message returned.
                        example: Task request sent successfully
                      taskId:
                        type: string
                        description: The ID of the task that you can use to check the status.
                        example: "123e4567-e89b-12d3-a456-426614174000"
                      creditsToDeduct:
                        type: integer
                        description: The number of credits to deduct for the task.
                        example: 10
          headers:
            x-task-cost:
              schema:
                type: integer
              description: The number of credits deducted for the task.
        "400":
          description: Bad Request
          content:
            application/json:
              schema:
                type: string
                example: "Bad Request: Missing User"
        "402":
          description: Payment Required
          content:
            application/json:
              schema:
                type: string
                example: Insufficient credits
        "404":
          description: Not Found
          content:
            application/json:
              schema:
                type: object
                example: User not found
        "500":
          description: Internal Server Error
          content:
            application/json:
              schema:
                type: object
                example: Error processing request
      security:
        - ApiKeyAuth: []

components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: |
        API key required to access the API. You can obtain an API key at [https://upscayl.org/account/api-keys](https://upscayl.org/account/api-keys)
  schemas:
    Model:
      type: string
      enum:
        - upscayl-standard-4x
        - upscayl-lite-4x
        - clear-boost-4x
        - crystal-plus-4x
        - digital-art-4x
        - digital-art-plus-4x
        - natural-max-4x
        - natural-plus-4x
        - nature-boost-4x
        - pure-boost-4x
        - quick-clear-4x
        - texture-boost-4x
      description: The available AI models for upscaling

    SaveImageAs:
      type: string
      enum:
        - jpg
        - png
        - webp
      description: The available image formats for saving

    Status:
      type: string
      enum:
        - ENHANCING
        - PROCESSING
        - PROCESSED
        - PROCESSING_FAILED
      description: The status of the task

    Scale:
      type: integer
      enum:
        - 1
        - 2
        - 3
        - 4
        - 5
        - 6
        - 7
        - 8
      description: The scaling factor for the task
      example: 4

    FileData:
      type: object
      properties:
        fileName:
          type: string
          description: The name of the file.
          example: "1k2jj2b3c-cnb1234ij.jpg"
        fileType:
          type: string
          description: The MIME type of the file.
          example: "image/jpeg"
        fileSize:
          type: integer
          description: The size of the file in bytes.
          example: 123456
        originalFileName:
          type: string
          description: The original name of the file.
          example: "image.jpg"
        path:
          type: string
          description: The path where the file is stored.
          example: "users/1412v4124v/1k2jj2b3c-cnb1234ij.jpg"
        createdAt:
          type: integer
          description: Timestamp of file creation.
          example: 1640995200
        expiresAt:
          type: integer
          description: Timestamp of file expiration.
          example: 1640995200
        dimensions:
          type: object
          properties:
            width:
              type: integer
              description: The width of the image.
            height:
              type: integer
              description: The height of the image.

    TaskDocument:
      type: object
      properties:
        userId:
          type: string
          description: The ID of the user submitting the task.
        email:
          type: string
          description: The email of the user.
        files:
          type: array
          items:
            $ref: "#/components/schemas/FileData"
        id:
          type: string
          description: The unique ID of the task.
        enhanceFace:
          type: boolean
          description: Whether to enhance faces in the image.
        model:
          $ref: "#/components/schemas/Model"
        scale:
          $ref: "#/components/schemas/Scale"
        saveImageAs:
          $ref: "#/components/schemas/SaveImageAs"
        compression:
          type: integer
          description: The compression level for the output image.
        createdAt:
          type: integer
          description: Timestamp of task creation.
        # creditsDeducted:
        #   type: boolean
        #   description: Whether credits have been deducted for the task.
        filesCount:
          type: integer
          description: The number of files in the task.
        status:
          $ref: "#/components/schemas/Status"
        batchMode:
          type: boolean
          description: Whether the task is in batch mode.
        progress:
          type: string
          description: The progress of the task.
        creditsToDeduct:
          type: integer
          description: The number of credits to deduct for the task.
          example: 10
        currentCredits:
          type: integer
          description: The current credits of the user.
        currentExtraCredits:
          type: integer
          description: The current extra credits of the user.
