{
  "openapi": "3.0.0",
  "info": {
    "title": "AI Fitzpatrick Skin Type Analysis",
    "description": "# Overview\n\n![](https://plugins-media.makeupar.com/smb/blog/post/2026-01-28/webp_a00e88ca-e20a-4082-89c2-9d486b03b8e8.webp)\n\n**AI Fitzpatrick Skin Type Analysis**\n\nIntegrate AI driven Fitzpatrick skin type detection into your applications to classify skin types accurately using camera input. This API enables developers to build personalized skincare, sunscreen, and product recommendation workflows for eCommerce and digital health platforms.\n\n**Skin Type Detection**\n\nThe API uses computer vision and machine learning models to analyze skin characteristics and return a Fitzpatrick classification in a single request. It provides structured, objective data that can be directly consumed by frontend applications, recommendation engines, or clinical systems.\n\nThe Fitzpatrick Scale, introduced by Dr. Thomas B. Fitzpatrick, defines six skin types based on melanin levels and response to UV exposure, allowing systems to predict tendencies to burn or tan.\n\n**Classification Output**\n\nThe API returns one of six standardized skin types from Type I to Type VI based on UV response modeling.\n\nThis output enables developers to deliver tailored product recommendations, automate skincare workflows, and enhance personalization logic across user experiences while maintaining consistency and scalability.\n\n| Fitzpatrick Scale | Skin Type | Skin Reaction to Sun |\n|  ----  | ----  | ---- |\n| Type I | White | Almost always burns, never tans |\n| Type II |  Beige | Usually burns, tans minimally |\n| Type III | Light Brown | Sometimes burns, gradually tans |\n| Type V | Medium Brown | Rarely burns, tans easily |\n| Type V | Dark Brown | Very rarely burns |\n| Type VI | Very Dark Brown | Almost never burns |\n\n![](https://bcw-media.s3.ap-northeast-1.amazonaws.com/fitapatrick_skin_type_S_02_enu_5e4343e801.jpg)\n\n![](https://plugins-media.makeupar.com/smb/blog/post/2026-03-10/webp_b9ca4198-1a9e-44df-9551-ac3ad8b65d17.webp)\n\n---\n\n## Integration Guide\n\n**1. Capture Image**\nCapture a front facing image with adequate lighting. Ensure the face is clearly visible and occupies a sufficient portion of the frame.\n\n\n**2. Upload Image**\nRequest upload URLs and file IDs via:\n\n```\nPOST /s2s/v2.0/file\n```\n\nUpload the image using the returned URL.\nAlternatively, provide a publicly accessible image URL hosted on your own storage.\n\n\n**3. Optional Preprocessing**\n\n```\nPOST /s2s/v2.0/task/fitzpatrick-scale-analyzer/pre-process\n```\n\nUse this step when the image contains multiple faces or when explicit target selection is required. For single face images, this step can be skipped if default indexing is sufficient.\n\n\n**4. Retrieve Preprocess Result**\n\n```\nGET /s2s/v2.0/task/fitzpatrick-scale-analyzer/pre-process\n```\n\nConfigure a [webhook](/develop/webhook.md) or implement polling to retrieve task results. With webhooks, your application receives automatic notifications when the task is completed. With polling, your system repeatedly calls the task endpoint until the status changes from running to success or error.\n\n**5. Execute Analysis Task**\n\n```\nPOST /s2s/v2.0/task/fitzpatrick-scale-analyzer\n```\n\nSubmit the task using file IDs or image URLs as input. The response returns a task_id for tracking and retrieving the result.\n\n\n**6. Retrieve Task Result**\n\n```\nGET /s2s/v2.0/task/fitzpatrick-scale-analyzer/{task_id}\n```\n\nUse the task ID to track status and obtain results.\n\n[Webhooks](/develop/webhook.md) can be configured to receive asynchronous notifications on task completion with a success or error status. Polling is also supported by repeatedly calling the task endpoint until the status is updated from running to success or error.\n\nUsage is only charged when the task completes successfully.\n\n---\n\n## File Specs & Errors\n\n* Supported Formats & Dimensions\n\n|AI Feature|Supported Dimensions|Supported File Size|Supported Formats|\n|  ----  | ----  | ----  | ----  |\n| AI Fitzpatrick Skin Type Analysis | The length of the longer side shall not exceed 4096 pixels, and the length of the shorter side shall be no less than 320 pixels. | < 10MB | jpg/jpeg |\n\n* Error Codes\n\n|Error Code|Description|\n|  ----  | ----  |\n| error_below_min_image_size | Source image dimensions must be at least 320 pixels. |\n|error_face_position_invalid|Your face needs to be fully visible in the image, without any parts cut off|\n|error_face_position_too_small|The face in your photo is too small to analyze properly|\n|error_face_position_out_of_boundary|Your face is either too large or partially outside the edges of the photo|\n|error_insufficient_lighting|The lighting is too dim, which makes analysis difficult|\n|error_face_angle_invalid|Your face angle isn't quite right. For front-facing shots, keep your head within 10 degrees of straight. For side-facing shots, the angle should be more than 15 degrees|\n\n* Environment & Dependency\n\n| Sample Code Language / Tool | Recommended Runtime Versions |\n|---|---|\n| cURL | - bash >= 3.2</br>   - curl >= 7.58 (modern TLS/HTTP support)</br>   - jq >= 1.6 (robust JSON parsing) |\n| Node.js (JavaScript) | Node >= 18 (for global fetch) |\n| JavaScript | - Chrome / Edge >= 80</br>   - Firefox >= 74</br>   - Safari >= 13.1 |\n| PHP | PHP >= 7.4 (for modern TLS/compat), ext-curl (recommended) or allow_url_fopen=On + ext-openssl, ext-json |\n| Python | Python >= 3.10 (for f-strings), requests >= 2.20.0 |\n| Java | Java 11+ (for HttpClient), Jackson Databind >= 2.12.0 |\n\n---\n\n## Unit Consumption\n\n| AI Feature | Unit Consumed |\n|---|---|\n| AI Fitzpatrick Skin Type Analysis V1.0 | 10 |\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 Fitzpatrick Skin Type Analysis precisely categorizes skin tones into six types, from Type I: White, Type II: Beige, Type III: Light Brown, Type V: Medium Brown, Type V: Dark Brown, to Type VI: Very Dark Brown, based on melanin levels and sensitivity to UV exposure. This system predicts how likely your skin is to burn or tan. "
    }
  ],
  "paths": {
    "/s2s/v2.0/task/fitzpatrick-scale-analyzer/pre-process": {
      "post": {
        "summary": "Run an AI Fitzpatrick Scale Analyzer 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/fitzpatrick-scale-analyzer/pre-process/{task_id}": {
      "get": {
        "summary": "Check the status of a AI Fitzpatrick Scale Analyzer detection task.",
        "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/TaskStatusResponsePreProcessSingleIndexWithTimed"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidTaskId"
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "500": {
            "$ref": "#/components/responses/TaskTimeout"
          }
        }
      }
    },
    "/s2s/v2.0/task/fitzpatrick-scale-analyzer": {
      "post": {
        "summary": "Run an AI Fitzpatrick Scale Analyzer 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/BasicRunTaskV2"
                  },
                  {
                    "type": "object",
                    "required": [
                      "version"
                    ],
                    "properties": {
                      "version": {
                        "type": "string",
                        "description": "Version of the features specification. Defaults to `\"1.0\"` unless otherwise specified.\n",
                        "example": "1.0",
                        "enum": [
                          "1.0"
                        ]
                      },
                      "index": {
                        "type": "integer",
                        "description": "Zero-based index of the target object to apply the effect to. For multi-objects images, run the pre-process task first, inspect the object coordinates in `data.results.result`, and pass the index of the selected object here.\n\nThe pre-processing step analyzes the input image to identify all detectable objects before any effect is applied. It runs a detection task that returns structured data for each object, including a list of bounding box coordinates. The position of each entry in this list serves as its zero-based index, which is then used to specify the target object for the effect.\n\nThis information is returned in a structured format, commonly under `data.results.result`.\nBy running this step first, you can:\n    * Understand how many objects are present in the image\n    * Inspect their positions and sizes\n    * Select the correct target object by its index\n\nAlways run the pre-processing step for images with multiple objects.\nReview `data.results.result` to identify objects and their indices.\nUse the corresponding zero-based index to select the correct target.",
                        "default": 0,
                        "example": 0
                      }
                    }
                  }
                ]
              }
            }
          }
        },
        "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/fitzpatrick-scale-analyzer/{task_id}": {
      "get": {
        "summary": "Check the status of a AI Fitzpatrick Scale Analyzer task.",
        "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/TaskStatusResponsePreProcessNoUrlBase"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "object",
                          "properties": {
                            "results": {
                              "type": "object",
                              "properties": {
                                "fitzpatrick_scale": {
                                  "type": "string",
                                  "enum": [
                                    "I",
                                    "II",
                                    "III",
                                    "IV",
                                    "V",
                                    "VI"
                                  ],
                                  "description": "Detected Fitzpatrick skin type classification (I to VI).",
                                  "example": "I"
                                },
                                "timed": {
                                  "type": "number",
                                  "description": "Engine processing time, in seconds."
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "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"
      },
      "TaskStatusResponsePreProcessNoUrlBase": {
        "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"
              }
            }
          }
        }
      },
      "TaskStatusResponsePreProcessSingleIndexWithTimed": {
        "allOf": [
          {
            "$ref": "#/components/schemas/TaskStatusResponsePreProcessNoUrlBase"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "object",
                "properties": {
                  "results": {
                    "type": "object",
                    "properties": {
                      "timed": {
                        "type": "number"
                      },
                      "result": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "left": {
                              "type": "number"
                            },
                            "top": {
                              "type": "number"
                            },
                            "width": {
                              "type": "number"
                            },
                            "height": {
                              "type": "number"
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        ]
      }
    },
    "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"
                }
              }
            }
          }
        }
      }
    }
  }
}