{
  "openapi": "3.0.0",
  "info": {
    "title": "AI Image Extender",
    "description": "# Overview\nExperience vibrant AI Outpainting with our cutting-edge AI Image Extender. Seamlessly expand images in any ratio, bringing out your creativity with our advanced AI technology. Preserve the highest quality while expanding your photos without compromising on style or aesthetics. Instantly transform your photos with one-click automatic background enlargement thanks to our user-friendly AI tool. Thanks to our advanced context-aware technology, we ensure a seamless and captivating experience for every viewer.\n\n![AI Image Extender](https://bcw-media.s3.ap-northeast-1.amazonaws.com/yce_web_outpainting_S1_img_03_cf19a018d9.jpg \"AI Image Extender\")\n\nWhether you're aiming for Instagram glory or framing a digital masterpiece, select from a variety of sizes and ratios for that perfect fit. As you tweak and transform, our AI seamlessly weaves its magic, ensuring the expanded areas blend flawlessly with your original photo.\n\n![AI Image Extender](https://bcw-media.s3.ap-northeast-1.amazonaws.com/yce_web_outpainting_S1_img_01_1876fb85a5.jpg \"AI Image Extender\")\n\n\n## File Specs & Errors\n* Supported Formats & Dimensions\n\n| AI Feature | Supported Dimensions | Supported File Size | Supported Formats |\n| ---- | ---- | ----  | ---- |\n| AI Image Extender | long side <= 4096 | < 10MB | jpg/jpeg |\n\n* Error Codes\n\n|Error Code|Description|\n|  ----  | ----  |\n| exceed_max_filesize |\tInput file size exceeds the maximum limit |\n| invalid_parameter |\tInvalid parameter value |\n| error_download_image\t| Download source image error |\n| error_decode_image\t| Decode source image error |\n| error_nsfw_content_detected\t| NSFW content detected in source image |\n\n---\n\n## Unit Consumption\n\n| AI Feature | Unit Consumed |\n|---|---|\n| AI Image Extender V2.0 | 2 |\n\n---\n",
    "version": "",
    "termsOfService": "https://www.makeupar.com/perfectbeauty/youcam/terms-of-service-api",
    "contact": {
      "email": "YouCamOnlineEditor_API@perfectcorp.com"
    },
    "license": {
      "name": "Privacy policy",
      "url": "https://www.makeupar.com/perfectbeauty/youcam/privacy-policy-api"
    }
  },
  "servers": [
    {
      "url": "https://yce-api-01.makeupar.com"
    }
  ],
  "tags": [
    {
      "name": "V2.0",
      "description": "AI Image Extender API allows you to extend the dimensions of an image by generating new content around it (Outpainting)."
    }
  ],
  "paths": {
    "/s2s/v2.0/task/out-paint": {
      "post": {
        "summary": "Run an AI Image Extender task.",
        "description": "Please refer to the polling guide for checking task status. The API takes 3 key parameters: input image, pivot point, and output image.",
        "tags": [
          "V2.0"
        ],
        "security": [
          {
            "BearerAuthenticationV2": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RunOutPaintTaskRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful execution of the task",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BasicRunTaskResponseV2"
                }
              }
            }
          },
          "400": {
            "description": "Failed execution of task",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/responses/RunError"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "429": {
            "description": "Too many requests within a given amount of time",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/s2s/v2.0/task/out-paint/{task_id}": {
      "get": {
        "summary": "Check an AI Image Extender task status.",
        "tags": [
          "V2.0"
        ],
        "security": [
          {
            "BearerAuthenticationV2": []
          }
        ],
        "parameters": [
          {
            "name": "task_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "example": "grH0CvsgXuAIHLUzD0V1Ol34hoet3R1tvdbtiVHrDb6_UqCLKIejAIajwxrhOAfe"
            },
            "description": "ID of task to check"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful check of the task status",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskStatusResponseV2"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidTaskId"
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "500": {
            "$ref": "#/components/responses/TaskTimeout"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "FileV1.1": {
        "title": "File V1.1",
        "description": "This object represents a file.",
        "type": "object",
        "required": [
          "files"
        ],
        "properties": {
          "files": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "content_type",
                "file_name",
                "file_size"
              ],
              "properties": {
                "content_type": {
                  "type": "string",
                  "example": "image/jpg",
                  "description": "Content MIME type for this file. Currently available values are listed in the enum."
                },
                "file_name": {
                  "type": "string",
                  "example": "my-selfie.jpg",
                  "description": "Name of this file"
                },
                "file_size": {
                  "type": "integer",
                  "example": 50000,
                  "description": "Content length for this file in bytes. Should not be larger than 10MB."
                }
              }
            }
          }
        }
      },
      "BasicFileResponse": {
        "type": "object",
        "properties": {
          "files": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "content_type": {
                  "type": "string",
                  "example": "image/jpg",
                  "description": "Content MIME type for this file."
                },
                "file_name": {
                  "type": "string",
                  "example": "my-selfie.jpg",
                  "description": "Name of this file"
                },
                "file_id": {
                  "type": "string",
                  "example": "U8aqJbsXGT537jtGnEDFHqxdDXqh8+oTF/cSkLimzuvVwMP+Jb1XbjPsf7ZgUgLY",
                  "description": "ID of this file. Other run task API will need this `file_id`."
                },
                "requests": {
                  "type": "array",
                  "description": "Using upload `url`, `headers`, `method` below to upload file. After completion, the `file_id` is used to proceed with calling run task API.",
                  "items": {
                    "type": "object",
                    "properties": {
                      "headers": {
                        "type": "object",
                        "example": {
                          "Content-Type": "image/jpg",
                          "Content-Length": 50000
                        },
                        "description": "Headers to include when uploading the file"
                      },
                      "url": {
                        "type": "string",
                        "example": "https://example.com/presigned-upload-url",
                        "description": "URL to upload this file"
                      },
                      "method": {
                        "type": "string",
                        "example": "PUT",
                        "description": "HTTP method to upload this file"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "FileResponseV2": {
        "type": "object",
        "properties": {
          "status": {
            "type": "integer",
            "example": 200,
            "description": "Response status"
          },
          "data": {
            "$ref": "#/components/schemas/BasicFileResponse"
          }
        }
      },
      "BasicRunTaskV2SrcFileUrl": {
        "title": "Run task with src file url",
        "type": "object",
        "required": [
          "src_file_url"
        ],
        "properties": {
          "src_file_url": {
            "type": "string",
            "description": "Url of the file to run task. The url should be publicly accessible.",
            "example": "https://example.com/selfie.jpg"
          }
        }
      },
      "BasicRunTaskV2SrcFileId": {
        "title": "Run task with src file ID",
        "type": "object",
        "required": [
          "src_file_id"
        ],
        "properties": {
          "src_file_id": {
            "type": "string",
            "description": "ID of file to run task. File ID from upload file API.",
            "example": "pfNK5PuRe0MrwLHcGA3DOmB1ahwfXTbYHjv+KoBIxbE="
          }
        }
      },
      "BasicRunTaskV2": {
        "title": "BasicRunTaskV2",
        "anyOf": [
          {
            "$ref": "#/components/schemas/BasicRunTaskV2SrcFileUrl"
          },
          {
            "$ref": "#/components/schemas/BasicRunTaskV2SrcFileId"
          }
        ]
      },
      "OutPaintTaskParams": {
        "type": "object",
        "required": [
          "output_width",
          "output_height",
          "input_x",
          "input_y",
          "input_width",
          "input_height",
          "crop_input_x",
          "crop_input_y",
          "crop_input_width",
          "crop_input_height"
        ],
        "properties": {
          "output_width": {
            "type": "integer",
            "description": "Output image width. value range: [1 - 4096]",
            "example": 960,
            "minimum": 1,
            "maximum": 4096
          },
          "output_height": {
            "type": "integer",
            "description": "Output image height. value range: [1 - 4096]",
            "example": 1280,
            "minimum": 1,
            "maximum": 4096
          },
          "input_x": {
            "type": "integer",
            "description": "Source image left position in output image, where The indices are ordered from top to bottom, and from left to right. value range: [0 - 4096]",
            "example": 240,
            "minimum": 0,
            "maximum": 4096
          },
          "input_y": {
            "type": "integer",
            "description": "Source image top position in output image, where The indices are ordered from top to bottom, and from left to right. value range: [0 - 4096]",
            "example": 320,
            "minimum": 0,
            "maximum": 4096
          },
          "input_width": {
            "type": "integer",
            "description": "Source image width, input_x + input_width must <= output_width. value range: [1 - 4096]",
            "example": 480,
            "minimum": 1,
            "maximum": 4096
          },
          "input_height": {
            "type": "integer",
            "description": "Source image height, input_y + input_height must <= output_height. value range: [1 - 4096]",
            "example": 640,
            "minimum": 1,
            "maximum": 4096
          },
          "crop_input_x": {
            "type": "integer",
            "description": "Crop source image from x, where The indices are ordered from top to bottom, and from left to right. value range: [0 - 4096]",
            "example": 0,
            "minimum": 0,
            "maximum": 4096
          },
          "crop_input_y": {
            "type": "integer",
            "description": "Crop source image from y, where The indices are ordered from top to bottom, and from left to right. value range: [0 - 4096]",
            "example": 0,
            "minimum": 0,
            "maximum": 4096
          },
          "crop_input_width": {
            "type": "integer",
            "description": "Crop source image with width crop_input_width. value range: [1 - 4096]",
            "example": 480,
            "minimum": 1,
            "maximum": 4096
          },
          "crop_input_height": {
            "type": "integer",
            "description": "Crop source image with height crop_input_height. value range: [1 - 4096]",
            "example": 640,
            "minimum": 1,
            "maximum": 4096
          }
        }
      },
      "RunOutPaintTaskRequest": {
        "title": "RunOutPaintTaskRequest",
        "description": "The AI Image Extender API takes 3 key parameters to work, an input image, a pivot point and an output image. The size of output image should always be larger than the size of input image.",
        "allOf": [
          {
            "$ref": "#/components/schemas/BasicRunTaskV2"
          },
          {
            "$ref": "#/components/schemas/OutPaintTaskParams"
          }
        ]
      },
      "BasicRunTaskResponseV2": {
        "type": "object",
        "properties": {
          "status": {
            "type": "integer",
            "description": "Response status",
            "example": 200
          },
          "data": {
            "type": "object",
            "properties": {
              "task_id": {
                "type": "string",
                "description": "ID of this task. Task result is valid to query by this ID for 24 hours.",
                "example": "grH0CvsgXuAIHLUzD0V1Ol34hoet3R1tvdbtiVHrDb6_UqCLKIejAIajwxrhOAfe"
              }
            }
          }
        }
      },
      "TaskStatusResponseV2": {
        "type": "object",
        "properties": {
          "status": {
            "type": "integer",
            "description": "Response status",
            "example": 200
          },
          "data": {
            "type": "object",
            "properties": {
              "task_status": {
                "type": "string",
                "enum": [
                  "running",
                  "success",
                  "error"
                ],
                "description": "Status of this task"
              },
              "error": {
                "$ref": "#/components/schemas/EngineErrorCode"
              },
              "error_message": {
                "type": "string",
                "description": "Detailed description of error"
              },
              "results": {
                "$ref": "#/components/schemas/TaskStatusResponseBodySingleUrlResultsV2"
              }
            }
          }
        }
      },
      "TaskStatusResponseBodySingleUrlResultsV2": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "description": "URL to download this result. Valid for 2 hours",
            "example": "https://example.com/sample-result-url"
          }
        }
      },
      "EngineErrorCode": {
        "type": "string",
        "nullable": true,
        "enum": [
          "exceed_max_filesize",
          "invalid_parameter",
          "error_download_image",
          "error_download_mask",
          "error_decode_image",
          "error_decode_mask",
          "error_nsfw_content_detected",
          "error_no_face",
          "error_pose",
          "error_face_parsing",
          "error_inference",
          "exceed_nsfw_retry_limits",
          "error_upload",
          "unknown_internal_error"
        ],
        "description": "Errors:\n- `exceed_max_filesize` - Input file size exceeds the maximum limit\n- `invalid_parameter` - Invalid parameter value\n- `error_download_image` - Download source image error\n- `error_download_mask` - Download mask image error\n- `error_decode_image` - Decode source image error\n- `error_decode_mask` - Decode mask image error\n- `error_nsfw_content_detected` - NSFW content detected in source image\n- `error_no_face` - No face detected on source image\n- `error_pose` - Failed to detect pose on source image\n- `error_face_parsing` - Failed to do face segmentation on source image\n- `error_inference` - Inference pipeline error\n- `exceed_nsfw_retry_limits` - Exceed the retry limits to avoid generated NSFW image\n- `error_upload` - Upload result image error\n- `unknown_internal_error` - Others\n"
      },
      "InvalidParametersSchema": {
        "type": "object",
        "properties": {
          "status": {
            "type": "integer",
            "example": 400,
            "description": "Response status"
          },
          "error": {
            "type": "string",
            "description": "Error message",
            "example": "The operation could not be completed"
          },
          "error_code": {
            "type": "string",
            "enum": [
              "InvalidParameters"
            ],
            "description": "Error code:\n  * InvalidParameters - Invalid request parameters or body\n"
          }
        }
      },
      "InvalidApiKeySchema": {
        "type": "object",
        "properties": {
          "status": {
            "type": "integer",
            "example": 401,
            "description": "Response status"
          },
          "error_code": {
            "type": "string",
            "enum": [
              "InvalidApiKey",
              "InactiveApiKey",
              "ExpiredApiKey"
            ],
            "description": "Error code:\n  * InvalidApiKey - API Key is not given or not valid\n  * InactiveApiKey - API Key is inactivated\n  * ExpiredApiKey - API Key is expired\n"
          }
        }
      },
      "RunErrorSchema": {
        "type": "object",
        "properties": {
          "status": {
            "type": "integer",
            "description": "Response status",
            "example": 400
          },
          "error": {
            "type": "string",
            "description": "Error message",
            "example": "The operation could not be completed"
          },
          "error_code": {
            "type": "string",
            "enum": [
              "CreditInsufficiency",
              "InvalidStyleGroup",
              "InvalidStyle",
              "BadRequest",
              "InvalidParameters"
            ],
            "description": "Error code:\n  * CreditInsufficiency - Insufficient unit to run\n  * BadRequest - Unexpected request parameter\n  * InvalidStyleGroup - Invalid style group id\n  * InvalidStyle - Invalid style id\n  * InvalidParameters - Invalid request parameters\n"
          }
        }
      },
      "InvalidTaskIdSchema": {
        "type": "object",
        "properties": {
          "status": {
            "type": "integer",
            "description": "Response status",
            "example": 400
          },
          "error_code": {
            "type": "string",
            "enum": [
              "InvalidTaskId"
            ],
            "description": "Error code:\n  * InvalidTaskId - Invalid task id\n"
          }
        }
      },
      "TaskTimeoutSchema": {
        "type": "object",
        "properties": {
          "status": {
            "type": "integer",
            "description": "Response status",
            "example": 500
          },
          "error_code": {
            "type": "string",
            "enum": [
              "TaskTimeout"
            ],
            "description": "Error code:\n  * TaskTimeout - The task has no response in the expected time\n"
          }
        }
      }
    },
    "responses": {
      "InvalidParameters": {
        "description": "Invalid request parameters",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/InvalidParametersSchema"
            }
          }
        }
      },
      "InvalidApiKey": {
        "description": "Invalid API Key or Inactive API Key or Expired API Key",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/InvalidApiKeySchema"
            }
          }
        }
      },
      "RunError": {
        "description": "Failed execution of task",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/RunErrorSchema"
            }
          }
        }
      },
      "InvalidTaskId": {
        "description": "Invalid task id",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/InvalidTaskIdSchema"
            }
          }
        }
      },
      "TooManyRequests": {
        "description": "Too many requests within a given amount of time"
      },
      "TaskTimeout": {
        "description": "The task has no response in the expected time",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/TaskTimeoutSchema"
            }
          }
        }
      }
    },
    "securitySchemes": {
      "BearerAuthenticationV2": {
        "type": "http",
        "scheme": "bearer",
        "description": "Use the standard 'Bearer authentication'. Put your 'API Key' in header: `Authorization:Bearer YOUR_API_KEY`. Notice that there is ' ' a space between 'Bearer' and the 'YOUR_API_KEY'."
      }
    }
  }
}