{
  "openapi": "3.0.0",
  "info": {
    "title": "AI Face Swap",
    "description": "# Overview\nUsing AI Face Swap for hyper-realistic effect with multiple faces supported.​ Our face swap artificial intelligence supports swapping one or multiple faces. Either for creating funny pictures of faces, or need a professional tool, we've got you covered.\n\n## Integration Guide\n* How to implement AI Face Swap\n\n   * Step 1: Upload source and reference images\n\n      1. Request upload URLs from the API:\n\n        ```\n        POST https://yce-api-01.makeupar.com/s2s/v2.0/file\n        Authorization: Bearer YOUR_API_KEY\n        Content-Type: application/json\n        ```\n\n        Body:\n\n        ```json\n        {\n            \"files\": [\n            {\n                \"file_name\": \"target.jpg\",\n                \"file_size\": 123456,\n                \"content_type\": \"image/jpeg\"\n            }\n            ]\n        }\n        ```\n        1. The response provides a pre-signed **upload URL** and a `file_id`.\n        2. Upload your file with an HTTP PUT request to the given URL.\n        3. Store the `file_id` for later use. Repeat this for both **target** and **reference** images.\n\n      2. Upload the actual file to the **upload URL**.\n\n---\n\n   * Step 2: Pre-process the source and reference images (face detection)\n\n        1. Create a pre-process task:\n\n        ```\n        POST https://yce-api-01.makeupar.com/s2s/v2.0/task/face-swap/pre-process\n        Authorization: Bearer YOUR_API_KEY\n        Content-Type: application/json\n        ```\n\n        Body:\n\n        ```json\n        {\n            \"request_id\": 1,\n            \"payload\": {\n            \"file_sets\": {\n                \"src_ids\": [\"TARGET_FILE_ID\"]\n            },\n            \"actions\": [\n                { \"id\": 0 }\n            ]\n            }\n        }\n        ```\n        1. The API returns a `task_id`.\n        2. Poll task status at:\n\n        ```\n        GET https://yce-api-01.makeupar.com/s2s/v2.0/task/face-swap/pre-process?task_id=TASK_ID\n        ```\n        1. When finished, you receive a list of detected faces with bounding boxes.\n\n---\n\n   * Step 3: Run the face swap task\n        1. Define which reference image will substitute each source image\n        The `face_mapping` array defines how faces in the **Source Image** are replaced by faces from the **Reference Images**. It acts as a link list connecting detected faces in the source to specific reference images.\n\n        * Structure\n\n            Each element in the array is an object containing two properties:\n\n            | Parameter | Type | Description |\n            | :--- | :--- | :--- |\n            | `position` | `integer` | The index of the face detected in the **Source Image** (e.g., 0, 1, 2). |\n            | `index` | `integer` | The index of the face image in the **Reference Image List** to swap with. |\n\n                * Logic Rules\n            1.  **Index Mapping:** The `index` maps directly to the order of images provided in your reference list.\n                *   `0`: First Reference Image.\n                *   `1`: Second Reference Image.\n            2.  **Skipping Swaps:** To skip swapping a specific face detected in the source, set both `index` and `position` to `-1`.\n            3.  **Array Order:** The order of objects in the array should match based on `position`.\n\n                * Example Use Case\n\n            **Scenario:**\n            *   **Reference List:** 2 images provided (Image A, Image B).\n            *   **Source Image:** Contains 3 faces detected (Face 0, Face 1, Face 2).\n\n            **Goal:**\n            *   Swap **Face 0** (Source) with **Image 1** (Reference).\n            *   Skip swapping **Face 1** (Source).\n            *   Swap **Face 2** (Source) with **Image 0** (Reference).\n\n            **Configuration:**\n\n            ```json\n            \"face_mapping\": [\n                {\n                    \"index\": 1,  // Use the second reference image\n                    \"position\": 0 // Apply to the first detected face in source\n                },\n                {\n                    \"index\": -1, // Skip swapping\n                    \"position\": -1 // Skip swapping\n                },\n                {\n                    \"index\": 0,  // Use the first reference image\n                    \"position\": 2 // Apply to the third detected face in source\n                }\n            ]\n            ```\n\n        1. Send the main task request:\n\n        ```\n        POST https://yce-api-01.makeupar.com/s2s/v2.0/task/face-swap\n        Authorization: Bearer YOUR_API_KEY\n        Content-Type: application/json\n        ```\n\n        Body:\n\n        ```json\n        {\n            \"request_id\": 2,\n            \"payload\": {\n            \"file_sets\": {\n                \"src_ids\": [\"TARGET_FILE_ID\"],\n                \"ref_ids\": [\"REFERENCE_FILE_ID\"]\n            },\n            \"actions\": [\n                {\n                \"id\": 0,\n                \"params\": {\n                    \"face_mapping\": [\n                    { \"index\": 0, \"position\": 0 },\n                    { \"index\": -1, \"position\": -1 }\n                    ]\n                }\n                }\n            ]\n            }\n        }\n        ```\n        1. The response returns a `task_id`.\n\n---\n\n   * Step 4: Poll task status and retrieve result\n        It’s necessary to implement a timed loop that queries the task status at regular intervals within the allowed polling window.\n        1. Poll at:\n\n        ```\n        GET https://yce-api-01.makeupar.com/s2s/v2.0/task/face-swap?task_id=TASK_ID\n        ```\n        2. When `status` is `success`, the response contains a URL for the generated image.\n        3. Download or display the image from that URL.\n\n---\n\n   * Step 5: Integrate into your platform\n\n        * On a **web frontend**, you can directly implement this with JavaScript using fetch or Axios.\n        * On a **backend** (Node.js, Python, Java, PHP, etc.), you can use the same endpoints with standard HTTP libraries.\n        * Implement retry and error handling since the tasks run asynchronously.\n\n---\n\n    * Debugging Guide\n        1. **Invalid TaskId Error**\n            </br>**Why:** You’ll receive an InvalidTaskId error if you attempt to check the status of a task that has timed out. Therefore, once an AI task is initiated, you’ll need to poll for its status within the polling_interval until the status changes to either success or error.\n            </br>**Solution:** To avoid the task becoming invalid, it’s necessary to implement a timed loop that queries the task status at regular intervals within the allowed polling window.\n\n        2. **Why are some faces not detected in my source image**\n            </br>**Why:** Reason: The face must be clearly visible, not covered or obstructed, and large enough within the image\n            </br>**Solution:** Try taking a photo where the face appears larger and is clearly visible without any covering or obstruction\n\n---\n\n## Inputs & Outputs\n\n* Real-world examples:\nMultiple faces swap sample:\n![](https://bcw-media.s3.ap-northeast-1.amazonaws.com/dt_yce_face_swap_S2_img_04_d4b747a41d.jpg)\n\nSingle face swap sample:\n![](https://bcw-media.s3.ap-northeast-1.amazonaws.com/dt_yce_face_swap_S2_img_05_8e68faff2c.jpg)\n\n* Suggestions for How to Shoot:\n![](https://bcw-media.s3.ap-northeast-1.amazonaws.com/strapi/assets/webp_AI%20Skin%20Analysis_camera_f93315b088.png)\n\n\n## File Specs & Errors\n* Supported Formats & Dimensions\n\n|AI Feature|Supported Dimensions|Supported File Size|Supported Formats|\n|  ----  | ----  | ----  | ----  |\n|AI Face Swap|Input and output: the long side must be less than or equal to 4096 pixels|< 10MB|jpg/jpeg/png|\n\n\n* Error Codes\n\n| Error Code | Description |\n| ------------------ | ----------- |\n| exceed_max_filesize | The input file size exceeds the maximum limit |\n| invalid_parameter | The parameter value is invalid |\n| error_download_image | There was an error downloading the source image |\n| error_download_mask | There was an error downloading the mask image |\n| error_decode_image | There was an error decoding the source image |\n| error_decode_mask | There was an error decoding the mask image |\n| error_download_video | There was an error downloading the source video |\n| error_decode_video | There was an error decoding the source video |\n| error_nsfw_content_detected | NSFW content was detected in the source image |\n| error_no_face | No face was detected in the source image |\n| error_pose | Failed to detect pose in the source image |\n| error_face_parsing | Failed to perform face parsing on the source image |\n| error_inference | An error occurred in the inference pipeline |\n| exceed_nsfw_retry_limits | Retry limits exceeded to avoid generating NSFW image |\n| error_upload | There was an error uploading the result image |\n| error_multiple_people | People count exceeds the maximum limit |\n| error_no_shoulder | Shoulders are not visible in the source image |\n| error_large_face_angle | The face angle in the uploaded image is too large |\n| error_unsupport_ratio | The aspect ratio of the input image is unsupported |\n| unknown_internal_error | Other internal errors |\n\n---\n\n## Unit Consumption\n\n| AI Feature | Unit Consumed |\n|---|---|\n| AI Face Swap V1.0 | 1 |\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": "V1.0",
      "description": "AI Face Swap API allows you to swap faces between a target image and one or more reference images using predefined templates or manual mapping."
    }
  ],
  "paths": {
    "/s2s/v2.0/task/face-swap/pre-process": {
      "post": {
        "summary": "Run an AI Face Swap face detection task.",
        "description": "Use the pre-process task when the source image may contain more than one valid target, or when your integration needs to explicitly choose which detected target receives the effect. For single-target images, pre-process can be skipped when the feature supports a default `index` value and your application does not need manual target selection.\n\nThe pre-process task detects candidate targets in the source image and returns their coordinates in `data.results.result`. Each item in the result array represents one detected target. Review the returned coordinates, map them to the intended face or region in the source image, and use that item's zero-based array index as the `index` value when creating the effect task.\n\nFor images with multiple detected faces or regions, do not rely on the default `index` value without checking the pre-process result. The effect is applied only to the target selected by `index`, so the integration must confirm the result item that corresponds to the intended target before running the effect task.\n\nThis task is asynchronous. After creating the task, handle completion with webhook if the feature supports it, or poll the corresponding pre-process status endpoint until `data.task_status` is `success` or `error`.\n",
        "tags": [
          "V1.0"
        ],
        "security": [
          {
            "BearerAuthenticationV2": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/BasicRunTaskV2"
                  }
                ]
              }
            }
          }
        },
        "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/schemas/RunError"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/s2s/v2.0/task/face-swap/pre-process/{task_id}": {
      "get": {
        "summary": "Check a AI Face Swap face detection task status.",
        "tags": [
          "V1.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": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/TaskStatusResponsePreProcessBase"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "object",
                          "properties": {
                            "results": {
                              "type": "object",
                              "properties": {
                                "url": {
                                  "type": "string",
                                  "description": "URL to download this result. Valid for 2 hours",
                                  "example": "https://example.com/sample-result-url"
                                },
                                "faces": {
                                  "type": "array",
                                  "items": {
                                    "type": "object",
                                    "properties": {
                                      "bbox": {
                                        "type": "array",
                                        "description": "The location of face. There are 4 numbers, the format is [x1, y1, x2, y2], which (x1, y1) is the top-left point, while (x2, y2) is the bottom-right point.",
                                        "items": {
                                          "type": "integer",
                                          "example": [
                                            0,
                                            0,
                                            100,
                                            100
                                          ]
                                        }
                                      }
                                    }
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidTaskId"
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "500": {
            "$ref": "#/components/responses/TaskTimeout"
          }
        }
      }
    },
    "/s2s/v2.0/task/face-swap": {
      "post": {
        "summary": "Run an AI Face Swap task.",
        "description": "AI tasks are asynchronous. Prefer webhook-based completion handling when the feature supports webhooks. Configure your webhook endpoint, verify webhook signatures, and use the received `task_id` to query the task result after a `success` or `error` notification. See the [webhook integration guide](/develop/webhook.md) for setup and verification details.\n\nIf webhooks are not supported or cannot be used in your integration, implement polling. After submitting an AI task, poll the status endpoint at regular intervals (e.g., every 10 seconds) until the task status is `success` or `error`.\n",
        "tags": [
          "V1.0"
        ],
        "security": [
          {
            "BearerAuthenticationV2": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/BasicRunTaskV2WithMultiRequiredRef"
                  },
                  {
                    "type": "object",
                    "required": [
                      "face_mapping"
                    ],
                    "properties": {
                      "face_mapping": {
                        "type": "array",
                        "description": "The designated ref image id and face position information to be swapped for each detected face on target image.\n\nLogic Rules\n  1.  Index Mapping: The `index` maps directly to the order of images provided in your reference list.\n  2.  Skipping Swaps: To skip swapping a specific face detected in the source, set both `index` and `position` to `-1`.\n  3.  Array Order: The order of objects in the array should match based on `position`.\n\n\nExample Use Case\n\nScenario:\n  Reference List: 2 images provided (Image A, Image B).\n  Source Image: Contains 3 faces detected (Face 0, Face 1, Face 2).\n\n\nGoal:\n  Swap Face 0 (Source) with Image 1 (Reference).\n  Skip swapping Face 1 (Source).\n  Swap Face 2 (Source) with Image 0 (Reference).\n\n\nConfiguration:\n  \"face_mapping\": [\n      {\n          \"index\": 1,  // Use the second reference image\n          \"position\": 0 // Apply to the first detected face in source\n      },\n      {\n          \"index\": -1, // Skip swapping\n          \"position\": -1 // Skip swapping\n      },\n      {\n          \"index\": 0,  // Use the first reference image\n          \"position\": 2 // Apply to the third detected face in source\n      }\n  ]\n",
                        "items": {
                          "type": "object",
                          "properties": {
                            "index": {
                              "type": "integer",
                              "description": "The index of reference image"
                            },
                            "position": {
                              "type": "integer",
                              "description": "The index of face on the target image. The index is from faces of detection result."
                            }
                          }
                        }
                      }
                    }
                  }
                ]
              }
            }
          }
        },
        "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/schemas/RunError"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/s2s/v2.0/task/face-swap/{task_id}": {
      "get": {
        "summary": "Check a AI Face Swap task status.",
        "tags": [
          "V1.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": {
    "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'."
      }
    },
    "schemas": {
      "BasicRunTaskV2SrcFileUrl": {
        "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": {
        "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": [
          {
            "title": "Run task with src file url",
            "allOf": [
              {
                "$ref": "#/components/schemas/BasicRunTaskV2SrcFileUrl"
              }
            ]
          },
          {
            "title": "Run task with src file ID",
            "allOf": [
              {
                "$ref": "#/components/schemas/BasicRunTaskV2SrcFileId"
              }
            ]
          }
        ]
      },
      "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"
              }
            }
          }
        }
      },
      "RunError": {
        "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": [
              "InvalidParameters",
              "CreditInsufficiency",
              "InvalidStyleGroup",
              "InvalidStyle",
              "BadRequest"
            ],
            "description": "Error code:\n  * InvalidParameters - Invalid request parameters\n  * CreditInsufficiency - Insufficient unit to run\n  * BadRequest - Unexpected request parameter\n  * InvalidStyleGroup - Invalid style group id\n  * InvalidStyle - Invalid style id\n"
          }
        }
      },
      "EngineErrorCode": {
        "type": "string",
        "nullable": true,
        "enum": [
          "error_exceed_max_image_size",
          "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- \\`error_exceed_max_image_size\\`  - Input image size exceeds the maximum limit\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"
      },
      "TaskStatusResponseBodySingleUrlResultsV2": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "description": "URL to download this result. Valid for 2 hours",
            "example": "https://example.com/sample-result-url"
          }
        }
      },
      "TaskStatusResponsePreProcessBase": {
        "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": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/TaskStatusResponseBodySingleUrlResultsV2"
                  }
                ]
              }
            }
          }
        }
      },
      "BasicRunTaskV2RefFileUrls": {
        "type": "object",
        "properties": {
          "ref_file_urls": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "string",
              "description": "Urls of the reference file to run task. The url should be publicly accessible.",
              "example": "https://example.com/accessory.jpg"
            }
          }
        }
      },
      "BasicRunTaskV2RefFileIds": {
        "type": "object",
        "properties": {
          "ref_file_ids": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "string",
              "description": "IDs of the reference file to run task. File ID from upload file API.",
              "example": "pfNK5PuRe0MrwLHcGA3DOmB1ahwfXTbYHjv+KoBIxbE="
            }
          }
        }
      },
      "BasicRunTaskV2WithMultiRequiredRef": {
        "title": "BasicRunTaskV2WithRef",
        "anyOf": [
          {
            "allOf": [
              {
                "title": "Run task with src file url & ref file urls",
                "required": [
                  "ref_file_urls"
                ]
              },
              {
                "$ref": "#/components/schemas/BasicRunTaskV2SrcFileUrl"
              },
              {
                "$ref": "#/components/schemas/BasicRunTaskV2RefFileUrls"
              }
            ]
          },
          {
            "allOf": [
              {
                "title": "Run task with src file url & ref file IDs",
                "required": [
                  "ref_file_ids"
                ]
              },
              {
                "$ref": "#/components/schemas/BasicRunTaskV2SrcFileUrl"
              },
              {
                "$ref": "#/components/schemas/BasicRunTaskV2RefFileIds"
              }
            ]
          },
          {
            "allOf": [
              {
                "title": "Run task with src file ID & ref file urls",
                "required": [
                  "ref_file_urls"
                ]
              },
              {
                "$ref": "#/components/schemas/BasicRunTaskV2SrcFileId"
              },
              {
                "$ref": "#/components/schemas/BasicRunTaskV2RefFileUrls"
              }
            ]
          },
          {
            "allOf": [
              {
                "title": "Run task with src file ID & ref file IDs",
                "required": [
                  "ref_file_ids"
                ]
              },
              {
                "$ref": "#/components/schemas/BasicRunTaskV2SrcFileId"
              },
              {
                "$ref": "#/components/schemas/BasicRunTaskV2RefFileIds"
              }
            ]
          }
        ]
      },
      "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": null
            }
          }
        },
        "$ref": "#/components/schemas/TaskStatusResponseBodySingleUrlResultsV2"
      }
    },
    "responses": {
      "InvalidApiKey": {
        "description": "Invalid or missing API key",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "status": {
                  "type": "integer",
                  "example": 401,
                  "description": "Response status"
                },
                "error": {
                  "type": "string",
                  "example": "Invalid API key"
                }
              }
            }
          }
        }
      },
      "TooManyRequests": {
        "description": "Too many requests",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "status": {
                  "type": "integer",
                  "example": 429,
                  "description": "Response status"
                },
                "error": {
                  "type": "string",
                  "example": "Too many requests"
                }
              }
            }
          }
        }
      },
      "InvalidTaskId": {
        "description": "Invalid task ID",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "status": {
                  "type": "integer",
                  "example": 400,
                  "description": "Response status"
                },
                "error": {
                  "type": "string",
                  "example": "Invalid task ID"
                }
              }
            }
          }
        }
      },
      "TaskTimeout": {
        "description": "Task execution timeout",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "status": {
                  "type": "integer",
                  "example": 500,
                  "description": "Response status"
                },
                "error": {
                  "type": "string",
                  "example": "Task execution timed out"
                }
              }
            }
          }
        }
      }
    }
  }
}