{
  "openapi": "3.0.0",
  "info": {
    "title": "AI ファブリックチェンジ",
    "description": "# 概要\nAI ファブリック API では、画像の衣服領域にファブリックスタイルを適用します。\n新しいファブリックスタイルを追加します。\n\n---\n\n## 統合ガイド\n\n* AI ファブリック API 使用ガイド\n\nこのガイドでは、画像のアップロード、事前定義されたファブリックスタイルの取得、および AI ファブリック API を使用したバーチャル試着タスクの作成方法について説明します。\n\n***\n\n   * ステップ 1. ファイル API を使用してファイルをアップロードする\n\n**File API** (`/s2s/v2.0/file`) を使用して、対象ユーザーの画像をアップロードします。\n\n**画像要件:**\n\n*   高解像度の全身写真をアップロードしてください。\n*   写真に全身がはっきりと映っていることを確認してください。\n*   複数の人物や気が散るオブジェクトがある背景は避けてください。\n\n**リクエスト例:**\n\n```bash\ncurl --request POST \\\n  --url https://yce-api-01.makeupar.com/s2s/v2.0/file \\\n  --header 'Authorization: Bearer YOUR_API_KEY' \\\n  --header 'content-type: application/json' \\\n  --data '{\n    \"files\": [\n      {\n        \"content_type\": \"image/jpg\",\n        \"file_name\": \"full_body_photo_01_3dbd1b6683.jpg\",\n        \"file_size\": 547541\n      }\n    ]\n  }'\n```\n\n***\n\n   * ステップ 2. File API のレスポンスを取得する\n\nレスポンスには以下が含まれます:\n\n*   AI タスク作成用の `file_id`。\n*   実際の画像ファイルをアップロードするための `requests.url`。\n\n**レスポンス例:**\n\n```json\n{\n  \"status\": 200,\n  \"data\": {\n    \"files\": [\n      {\n        \"content_type\": \"image/jpg\",\n        \"file_name\": \"full_body_photo_01_3dbd1b6683.jpg\",\n        \"file_id\": \"SaGaqpDgKwFrVBgMpQMA3HY0LeqdT9/13W5TOD8/u/FfjK3xgCQ+hRt9MJXBFaud\",\n        \"requests\": [\n          {\n            \"method\": \"PUT\",\n            \"url\": \"https://yce-us.s3-accelerate.amazonaws.com/demo/ttl30/...signature...\",\n            \"headers\": {\n              \"Content-Length\": \"547541\",\n              \"Content-Type\": \"image/jpg\"\n            }\n          }\n        ]\n      }\n    ]\n  }\n}\n```\n\n***\n\n   * ステップ 3. 指定された URL に画像をアップロードする\n\nFile API レスポンスの `requests.url` を使用して画像をアップロードします:\n\n```bash\ncurl --location --request PUT 'https://yce-us.s3-accelerate.amazonaws.com/demo/ttl30/...signature...' \\\n  --header 'Content-Type: image/jpg' \\\n  --header 'Content-Length: 547541' \\\n  --data-binary @'./full_body_photo_01_3dbd1b6683.jpg'\n```\n\n***\n\n   * ステップ 4. 事前定義されたファブリックテンプレートを取得する\n\n**Template API** (`/s2s/v2.0/task/template/fabric`) を使用して、事前定義されたファブリックテンプレートのリストを取得します:\n\n```bash\ncurl --request GET \\\n    --url 'https://yce-api-01.makeupar.com/s2s/v2.0/task/template/fabric?page_size=20&starting_token=73a3c9e69b89' \\\n    --header 'Authorization: Bearer YOUR_API_KEY'\n```\n\n***\n\n   * ステップ 5. AI タスクを作成する\n\n**AI Task API** (`/s2s/v2.0/task/fabric`) を使用して、バーチャル試着タスクを作成します。\n\n**パラメータ:**\n\n*   ユーザー画像用: `src_file_id` または `src_file_url`。\n*   ファブリックスタイル用: `template_id`。\n\n**リクエスト例:**\n\n```bash\ncurl --request POST \\\n    --url https://yce-api-01.makeupar.com/s2s/v2.0/task/fabric \\\n    --header 'Authorization: Bearer YOUR_API_KEY' \\\n    --header 'content-type: application/json' \\\n    --data '{\n    \"template_id\":\"good_template_001\",\n    \"src_file_url\":\"https://example.com/selfie.jpg\"\n    }'\n```\n\n**レスポンス例:**\n\n```json\n{\n  \"status\": 200,\n  \"data\": {\n    \"task_id\": \"SaGaqpDgKwFrVBgMpQMA3HY0LeqdT9_13W5TOD8_u_GPi6NqQ3dhlmN-6ntFwhzT\"\n  }\n}\n```\n\n***\n\n   * ステップ 6. タスク結果をポーリングする\n\nタスク ID を使用してステータスを確認します:\n\n```bash\ncurl --request GET \\\n  --url https://yce-api-01.makeupar.com/s2s/v2.0/task/fabric/<YOUR_TASK_ID> \\\n  --header 'Authorization: Bearer YOUR_API_KEY' \\\n  --header 'content-type: application/json'\n```\n\n***\n\n   * ステップ 7. 結果を取得する\n\n成功したレスポンスには、結果画像のダウンロード URL が含まれます:\n\n```json\n{\n  \"status\": 200,\n  \"data\": {\n    \"error\": null,\n    \"results\": {\n      \"url\": \"https://yce-us.s3-accelerate.amazonaws.com/demo/ttl30/...signature...\"\n    },\n    \"task_status\": \"success\"\n  }\n}\n```\n\n無効な API キーエラーレスポンス:\n\n```json\n{\n  \"status\": 401,\n  \"error\": \"Unauthorized\",\n  \"error_code\": \"InvalidAccessToken\"\n}\n```\n\n---\n\n\nユースケース:\n![](https://bcw-media.s3.ap-northeast-1.amazonaws.com/strapi/assets/AI%20Fabric.png)\n\n![](https://plugins-media.makeupar.com/smb/blog/post/2024-05-07/b103976d-1b0e-4bed-aab4-9307308b84d7.jpg)\n\n![](https://bcw-media.s3.ap-northeast-1.amazonaws.com/strapi/assets/03%20ai%20clothes%20changer.jpg)\n\n撮影方法の提案:\n![撮影方法の提案](https://bcw-media.s3.ap-northeast-1.amazonaws.com/strapi/assets/AI-Cloth-Guideline.png \"撮影方法の提案\")\n\n---\n\n## ファイル仕様とエラー\n* サポートされる形式と寸法\n\n|AI 機能|サポートされる寸法|サポートされるファイルサイズ|サポートされる形式|\n|  ----  | ----  | ----  | ----  |\n|AI ファブリック|長辺 <= 4096、単一の人物のみ、腹部、顔、肩がすべて見えている必要があります。顔が遮られてはいけません。体は直立し、正面を向いており、座るやしゃがむなどのポーズは避けてください。|< 10MB|jpg/jpeg|\n\n* エラーコード\n\n|エラーコード|説明|\n|  ----  | ----  |\n|error_apply_region_not_detected|入力画像内の衣服領域が小さすぎるか、検出されませんでした\n\n* 環境と依存関係\n\n| サンプルコード言語 / ツール | 推奨ランタイムバージョン |\n|---|---|\n| cURL | - bash >= 3.2</br>   - curl >= 7.58 (モダンな TLS/HTTP サポート)</br>   - jq >= 1.6 (堅牢な JSON パーシング) |\n| Node.js (JavaScript) | Node >= 18 (グローバル fetch 用) |\n| JavaScript | - Chrome / Edge >= 80</br>   - Firefox >= 74</br>   - Safari >= 13.1 |\n| PHP | PHP >= 7.4 (モダンな TLS/互換性用)、ext-curl (推奨) または allow_url_fopen=On + ext-openssl、ext-json |\n| Python | Python >= 3.10 (f-strings 用)、requests >= 2.20.0 |\n| Java | Java 11+ (HttpClient 用)、Jackson Databind >= 2.12.0 |\n\n---\n\n## ユニット消費量\n\n| AI 機能 | 消費ユニット |\n|---|---|\n| ファブリックチェンジ V1.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": "V1.0",
      "description": "AI ファブリック API を使用すると、事前定義されたテンプレートとソース画像を用いて画像にファブリックスタイルを適用できます。"
    }
  ],
  "paths": {
    "/s2s/v2.0/task/template/fabric": {
      "get": {
        "summary": "事前定義されたテンプレートを一覧表示します。",
        "tags": [
          "V1.0"
        ],
        "security": [
          {
            "BearerAuthenticationV2": []
          }
        ],
        "parameters": [
          {
            "name": "page_size",
            "in": "query",
            "schema": {
              "type": "integer",
              "example": 20
            },
            "description": "このページで返す結果の数。有効な値は 1 から 20 です。初期値は 20 です。"
          },
          {
            "name": "starting_token",
            "in": "query",
            "schema": {
              "type": "string",
              "example": "73a3c9e69b89"
            },
            "description": "現在のページのトークン。最初のページでは `null` で開始し、次のページを開始するには前のレスポンスの `next_token` を使用します。"
          }
        ],
        "responses": {
          "200": {
            "description": "スタイルの取得に成功しました",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateResponseSchema"
                }
              }
            }
          },
          "400": {
            "description": "無効なリクエストパラメータ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvalidParametersSchema"
                }
              }
            }
          },
          "401": {
            "description": "無効な API キー、非アクティブな API キー、または期限切れの API キー",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvalidApiKeySchema"
                }
              }
            }
          }
        }
      }
    },
    "/s2s/v2.0/task/fabric": {
      "post": {
        "summary": "ファブリックタスクを実行します。",
        "description": "タスクステータスの確認については、ポーリングガイドを参照してください。",
        "tags": [
          "V1.0"
        ],
        "security": [
          {
            "BearerAuthenticationV2": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RunWithSingleTemplateAndSrcUrl"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "タスクの実行に成功しました",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BasicRunTaskResponseV2"
                }
              }
            }
          },
          "400": {
            "description": "タスクの実行に失敗しました",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/RunErrorSchema"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "無効な API キー、非アクティブな API キー、または期限切れの API キー",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvalidApiKeySchema"
                }
              }
            }
          },
          "429": {
            "description": "一定時間内にリクエストが多すぎます",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/s2s/v2.0/task/fabric/{task_id}": {
      "get": {
        "summary": "ファブリックタスクのステータスを確認します。",
        "tags": [
          "V1.0"
        ],
        "security": [
          {
            "BearerAuthenticationV2": []
          }
        ],
        "parameters": [
          {
            "name": "task_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "example": "grH0CvsgXuAIHLUzD0V1Ol34hoet3R1tvdbtiVHrDb6_UqCLKIejAIajwxrhOAfe"
            },
            "description": "確認するタスクの ID"
          }
        ],
        "responses": {
          "200": {
            "description": "タスクステータスの確認に成功しました",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskStatusResponseV2"
                }
              }
            }
          },
          "400": {
            "description": "無効なタスク ID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvalidTaskIdSchema"
                }
              }
            }
          },
          "401": {
            "description": "無効な API キー、非アクティブな API キー、または期限切れの API キー",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvalidApiKeySchema"
                }
              }
            }
          },
          "500": {
            "description": "タスクが期待される時間内にレスポンスを返していません",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskTimeoutSchema"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Template": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "テンプレートの ID。タスク実行時に `template_id` として使用します。",
            "example": "good_template_001"
          },
          "thumb": {
            "type": "string",
            "description": "スタイルのサムネイル。"
          },
          "title": {
            "type": "string",
            "description": "テンプレートのタイトル。"
          },
          "category_name": {
            "type": "string",
            "description": "テンプレートのカテゴリ名。"
          }
        }
      },
      "TemplateResponseSchema": {
        "type": "object",
        "properties": {
          "status": {
            "type": "integer",
            "description": "レスポンスステータス",
            "example": 200
          },
          "data": {
            "type": "object",
            "properties": {
              "templates": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Template"
                }
              },
              "next_token": {
                "type": "string",
                "example": "73a3c9e69b89",
                "description": "次のページをクエリするためのトークン。"
              }
            }
          }
        }
      },
      "RunWithSingleTemplateAndSrcUrl": {
        "title": "RunWithSingleTemplateAndSrcUrl",
        "allOf": [
          {
            "$ref": "#/components/schemas/RunWithSingleTemplate"
          },
          {
            "$ref": "#/components/schemas/BasicRunTaskV2"
          }
        ]
      },
      "RunWithSingleTemplate": {
        "title": "RunWithSingleTemplate",
        "type": "object",
        "properties": {
          "template_id": {
            "type": "string",
            "description": "テンプレートの ID。まず事前定義されたテンプレートを一覧表示し、テンプレートの ID を使用します。",
            "example": "good_template_001"
          }
        },
        "required": [
          "template_id"
        ]
      },
      "BasicRunTaskV2SrcFileUrl": {
        "title": "ソースファイル URL でタスクを実行",
        "type": "object",
        "required": [
          "src_file_url"
        ],
        "properties": {
          "src_file_url": {
            "type": "string",
            "description": "タスクを実行するファイルの URL。URL は公開アクセス可能である必要があります。",
            "example": "https://example.com/selfie.jpg"
          }
        }
      },
      "BasicRunTaskV2SrcFileId": {
        "title": "ソースファイル ID でタスクを実行",
        "type": "object",
        "required": [
          "src_file_id"
        ],
        "properties": {
          "src_file_id": {
            "type": "string",
            "description": "タスクを実行するファイルの ID。ファイルアップロード API からのファイル ID です。",
            "example": "pfNK5PuRe0MrwLHcGA3DOmB1ahwfXTbYHjv+KoBIxbE="
          }
        }
      },
      "BasicRunTaskV2": {
        "title": "BasicRunTaskV2",
        "anyOf": [
          {
            "$ref": "#/components/schemas/BasicRunTaskV2SrcFileUrl"
          },
          {
            "$ref": "#/components/schemas/BasicRunTaskV2SrcFileId"
          }
        ]
      },
      "BasicRunTaskResponseV2": {
        "type": "object",
        "properties": {
          "status": {
            "type": "integer",
            "description": "レスポンスステータス",
            "example": 200
          },
          "data": {
            "type": "object",
            "properties": {
              "task_id": {
                "type": "string",
                "description": "このタスクの ID。タスク結果はこの ID で 24 時間以内にクエリ可能です。",
                "example": "grH0CvsgXuAIHLUzD0V1Ol34hoet3R1tvdbtiVHrDb6_UqCLKIejAIajwxrhOAfe"
              }
            }
          }
        }
      },
      "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": "エラー:\n- `exceed_max_filesize` - 入力ファイルサイズが最大制限を超えています\n- `invalid_parameter` - 無効なパラメータ値です\n- `error_download_image` - ソース画像のダウンロードエラーです\n- `error_download_mask` - マスク画像のダウンロードエラーです\n- `error_decode_image` - ソース画像のデコードエラーです\n- `error_decode_mask` - マスク画像のデコードエラーです\n- `error_nsfw_content_detected` - ソース画像に NSFW コンテンツが検出されました\n- `error_no_face` - ソース画像に顔が検出されませんでした\n- `error_pose` - ソース画像でのポーズ検出に失敗しました\n- `error_face_parsing` - ソース画像での顔セグメンテーションに失敗しました\n- `error_inference` - 推論パイプラインエラーです\n- `exceed_nsfw_retry_limits` - NSFW 画像生成を避けるための再試行制限を超えました\n- `error_upload` - 結果画像のアップロードエラーです\n- `unknown_internal_error` - その他\n"
      },
      "TaskStatusResponseBodySingleUrlResultsV2": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "description": "この結果をダウンロードするための URL です。有効期間は 2 時間です。",
            "example": "https://example.com/sample-result-url"
          }
        }
      },
      "TaskStatusResponseV2": {
        "type": "object",
        "properties": {
          "status": {
            "type": "integer",
            "description": "レスポンスステータス",
            "example": 200
          },
          "data": {
            "type": "object",
            "properties": {
              "task_status": {
                "type": "string",
                "enum": [
                  "running",
                  "success",
                  "error"
                ],
                "description": "このタスクのステータス"
              },
              "error": {
                "$ref": "#/components/schemas/EngineErrorCode"
              },
              "error_message": {
                "type": "string",
                "description": "エラーの詳細説明"
              },
              "results": {
                "$ref": "#/components/schemas/TaskStatusResponseBodySingleUrlResultsV2"
              }
            }
          }
        }
      },
      "InvalidParametersSchema": {
        "type": "object",
        "properties": {
          "status": {
            "type": "integer",
            "example": 400,
            "description": "レスポンスステータス"
          },
          "error": {
            "type": "string",
            "description": "エラーメッセージ",
            "example": "The operation could not be completed"
          },
          "error_code": {
            "type": "string",
            "enum": [
              "InvalidParameters"
            ],
            "description": "エラーコード:\n  * InvalidParameters - 無効なリクエストパラメータまたはボディです\n"
          }
        }
      },
      "InvalidApiKeySchema": {
        "type": "object",
        "properties": {
          "status": {
            "type": "integer",
            "example": 401,
            "description": "レスポンスステータス"
          },
          "error_code": {
            "type": "string",
            "enum": [
              "InvalidApiKey",
              "InactiveApiKey",
              "ExpiredApiKey"
            ],
            "description": "エラーコード:\n  * InvalidApiKey - API キーが指定されていないか、無効です\n  * InactiveApiKey - API キーが無効化されています\n  * ExpiredApiKey - API キーの有効期限が切れています\n"
          }
        }
      },
      "RunErrorSchema": {
        "type": "object",
        "properties": {
          "status": {
            "type": "integer",
            "description": "レスポンスステータス",
            "example": 400
          },
          "error": {
            "type": "string",
            "description": "エラーメッセージ",
            "example": "The operation could not be completed"
          },
          "error_code": {
            "type": "string",
            "enum": [
              "CreditInsufficiency",
              "InvalidStyleGroup",
              "InvalidStyle",
              "BadRequest",
              "InvalidParameters"
            ],
            "description": "エラーコード:\n  * CreditInsufficiency - 実行に必要なユニットが不足しています\n  * BadRequest - 予期しないリクエストパラメータです\n  * InvalidStyleGroup - 無効なスタイルグループ ID です\n  * InvalidStyle - 無効なスタイル ID です\n  * InvalidParameters - 無効なリクエストパラメータです\n"
          }
        }
      },
      "InvalidTaskIdSchema": {
        "type": "object",
        "properties": {
          "status": {
            "type": "integer",
            "description": "レスポンスステータス",
            "example": 400
          },
          "error_code": {
            "type": "string",
            "enum": [
              "InvalidTaskId"
            ],
            "description": "エラーコード:\n  * InvalidTaskId - 無効なタスク ID です\n"
          }
        }
      },
      "TaskTimeoutSchema": {
        "type": "object",
        "properties": {
          "status": {
            "type": "integer",
            "description": "レスポンスステータス",
            "example": 500
          },
          "error_code": {
            "type": "string",
            "enum": [
              "TaskTimeout"
            ],
            "description": "エラーコード:\n  * TaskTimeout - 期待される時間内にタスクの応答がありませんでした\n"
          }
        }
      }
    },
    "securitySchemes": {
      "BearerAuthenticationV2": {
        "type": "http",
        "scheme": "bearer",
        "description": "標準の 'Bearer authentication' を使用します。ヘッダーに 'API Key' を設定してください: `Authorization:Bearer YOUR_API_KEY`。'Bearer' と 'YOUR_API_KEY' の間にスペース ' ' があることに注意してください。"
      }
    }
  }
}