openapi: 3.0.0
info:
  title: AI Body Reshape
  description: >
    # Overview

    AI Body Reshape API for Body Reshape & Slimming

    Feel confident in photos with an AI body editor! Slim, reshape, and enhance
    your body for natural, stunning proportions. Effortlessly reshape any area —
    waist, arms, thighs, chest, and more. Get natural, stunning results in just
    a tap!



    ## Integration Guide

    This guide walks you through:


    Workflow for AI Body Reshape API:


    **Endpoint:** `/s2s/v2.0/task/body-reshape`


    **Authentication Required:** `Authorization: Bearer YOUR_API_KEY`


    **Workflow Steps:**


    1. **Image Upload Preparation:**
        - Prepare a selfie image for upload.
        - Call the File API `/s2s/v2.0/file` to obtain the upload URL and associated `file_id`.
        - Upload the selfie image using the provided upload URL.

    2. **Optional Preprocessing For Group Photos:**
        - Preprocess the selfie image if there are more than one person in the image.

    3. **Body Reshape Effect Setup:**
        - Begin by selecting suitable body reshape parameters.

    4. **Initiate AI Task and Obtain Task ID:**
        - Send the `file_id` along with the chosen effect configuration via an HTTP POST request to `/s2s/v2.0/task/body-reshape`.
        - Await a unique task ID in the response, which identifies this interaction.

    5. **Poll Task Status (Continuous Check):**
        - Use the obtained `task_id` to periodically poll the task status using an HTTP GET request (e.g., `GET /s2s/v2.0/task/body-reshape/${task_id}`).
        - Continuously monitor for:
        - `Task_status = "success"` (process completed).
        - `Task_status = "error"` (resolve or retry if applicable).
        - Update the workflow accordingly once the status transitions to success.

    This structured workflow ensures efficient integration with user inputs,
    automated monitoring of tasks, and seamless retrieval of results.


    ---


    * API Playground


    Interactively explore and test the API using our official playground:


    **API Playground:**

    [http://yce.makeupar.com/api-console/en/api-playground/ai-body-reshape/](http://yce.makeupar.com/api-console/en/api-playground/ai-body-reshape/)


    ---


    * Authentication

    - Include your API key in the request header using **Bearer Token**:

    ```

    Authorization: Bearer YOUR_API_KEY

    ```

    You can find your API Key at
    https://yce.makeupar.com/api-console/en/api-keys/.



    * 1. Upload an Image


    You may upload a file directly to the server or provide a valid image URL in
    the AI task payload.


    * Upload Endpoint


    ```

    POST /s2s/v2.0/file

    ```


    Alternatively, skip this step if you already have a public image URL.


    ---


    * 2. Prepare an effect template


    * Preprocessing

    Output detected bounding boxes in pixel coordinate. Use the index of result
    to create a Body Reshape AI task later.

    ```

    {

    "timed": number,

    "result": [

    {
     "left": number,
     "top": number,
     "width": number,
     "height": number
    }

    ]

    }

    ```


    * Effect Template JSON Schemas

    ```

    {

    "version": "1.0",

    "index": 0,

    "features": {

    "arm": 0, // -100~100

    "breast_left": 0, // -100~100

    "breast_right": 0, // -100~100

    "hip": 0, // -100~100

    "hip_lift": 0, // -100~100

    "leg": 0, // -100~100

    "neck_left": 0, // 0~100

    "neck_right": 0, // 0~100

    "shoulder_left": 0, // -100~100

    "shoulder_right": 0, // -100~100

    "squared_shoulder_left": 0, // -100~100

    "squared_shoulder_right": 0, // -100~100

    "slim": 0, // -100~100

    "taller": 0, // 0~100

    "waist": 0, // -100~100

    "belly": 0 // -100~100

    }

    }

    ```

    index: index of detected body from preprocessing. optional, default 0.

    features: required at least 1, non-zero body reshape parameter, cannot be
    all zero.



    * Example Payload (ready to send)

    ```

    {
     "src_file_url": "https://plugins-media.makeupar.com/strapi/assets/body_reshape_02_7777218379.jpg",
     "version": "1.0",
     "index": 0,
     "features": {
    "arm": 0,

    "waist": -20,

    "taller": 80,

    "squared_shoulder_left": 10,

    "squared_shoulder_right": 10,

    "neck_left": 0,

    "neck_right": 0,

    "hip": 10,

    "breast_left": 30,

    "breast_right": 30,

    "slim": -70,

    "shoulder_left": 30,

    "shoulder_right": 30,

    "leg": -30,

    "hip_lift": 0,

    "belly": -50
     }
    }

    ```



    * 3. Create a Body Reshape AI Task and Poll for Results


    Once you have an image and a complete effect payload, create a task. The API
    processes the request asynchronously. You must poll the task status until it
    reaches `success` or `error`.


    * Create Task Endpoint


    ```

    POST /s2s/v2.0/task/body-reshape

    ```


    * Polling Endpoint


    ```

    GET /s2s/v2.0/task/body-reshape/{task_id}

    ```


    ---


    ## File Specs & Errors


    * AI Body Reshape Specification


    **Supported Selfie View**

    Full body shot with clear facial expression and body posture visible.


    ![](https://plugins-media.makeupar.com/strapi/assets/thumbnail_body_reshape_02_7777218379.jpg)


    **Visibility & Pose Requirements**


    | **Region** | **What must be true in the source image** |

    |------------|---------------------------------------------------|

    | **Neck** | The neck must be visible in the source image. |

    | **Arm** | Both arms – upper arm, forearm and hand – have to be fully
    shown. |

    | **Leg** | The whole leg must appear in the picture. |

    | **Hip** | Hips need to be in view. |

    | **Hip‑Lift** | Hips need to be in view. |

    | **Shoulder** | • Shoulders are required to be seen.<br>• Raising a hand is
    not allowed.<br>• A 90° side pose is not allowed. |

    | **Belly** | The belly is required to be visible. |

    | **Waist** | Waist must be visible. |

    | **Breast** | • Breast area must appear in the picture.<br>• The shot
    should include the hips (i.e., not a “half‑body without hips”).<br>• The
    middle of the breast must be shown. |

    | **Slim** | Shoulders need to be in the frame. |

    | **Taller** | • Hips must appear.<br>• A half‑body view should include the
    legs (i.e., legs are visible). |




    **Body Reshape Customization Parameters Guide**


    | Category | Parameter | Function | Min Value (-100 / 0) | Max Value (100) |

    | -------- | --------- | -------- | -------------------- | --------------- |

    | Arms| Intensity | Adjusts the thickness of the arms | Thin | Thick |

    | Belly| Intensity | Adjusts abdominal projection | Flat | Protruding |

    | Chest| Intensity (Left / Right) | Adjusts chest volume on each side | Flat
    | Full |

    | Hip Lift | Intensity | Adjusts the curvature and lift of the hips (adds a
    butt‑lifting effect) | Sculpted (lifted and tightened) | Rounded (lifted
    with fuller volume) |

    | Hip Size | Intensity | Adjusts the overall width of the hips | Narrow |
    Wide |

    | Legs| Intensity | Adjusts the thickness of the legs | Thin | Thick|

    | Neck| Intensity (Left / Right) | Adjusts neck contour and slimming per
    side| Original (0)| Tucked in |

    | Shoulder Width | Intensity (Left / Right) | Adjusts the span of each
    shoulder | Narrow | Broad |

    | Shoulder Shape | Intensity (Left / Right) | Adjusts the angle and slope of
    each shoulder | Sloped | Squared |

    | Slim| Intensity | Adjusts overall body curvature | Slim | Curvy |

    | Tall| Intensity | Adjusts the overall character height | Original (0) |
    Taller |

    | Waist| Intensity | Adjusts the width of the waistline | Narrow | Wide |


    **Note:** *“Left” and “Right” refer to the character's perspective, not the
    viewer's side of the screen.*



    ---


    * Supported Formats & Dimensions


    |AI Feature|Supported Dimensions|Supported File Size|Supported Formats|

    | ---- | ---- | ---- | ---- |

    |AI Body Reshape|long side <= 2048, short side >= 320|< 10MB|jpg/jpeg/png|


    * Error Codes


    | Error Code | Description |

    | ---- | ---- |

    | RUNTIME_ERROR | An unexpected error occurred dubody reshape runtime |

    | PHOTO_DETECTION_FAIL | The user photo could not be processed correctly,
    for example no hand detected |

    | PHOTO_CHECK_INVALID | The pose or size of the user photo is invalid |

    | INPUT_ERROR | The input file format is incorrect |

    | INPUT_MAIN_IMAGE_EMPTY | A user image is required |



    * Environment & Dependency


    | Sample Code Language / Tool | Recommended Runtime Versions |

    |---|---|

    | cURL | - bash >= 3.2</br>- curl >= 7.58 (modern TLS/HTTP support)</br>- jq
    >= 1.6 (robust JSON parsing) |

    | Node.js (JavaScript) | Node >= 18 (for global fetch) |

    | JavaScript | - Chrome / Edge >= 80</br>- Firefox >= 74</br>- Safari >=
    13.1 |

    | PHP | PHP >= 7.4 (for modern TLS/compat), ext-curl (recommended) or
    allow_url_fopen=On + ext-openssl, ext-json |

    | Python | Python >= 3.10 (for f-strings), requests >= 2.20.0 |

    | Java | Java 11+ (for HttpClient), Jackson Databind >= 2.12.0 |


    ---


    ## Unit Consumption


    | AI Feature | Unit Consumed |

    |---|---|

    | AI Body Reshape V1.0 | 1 |


    ---
  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
paths:
  /s2s/v2.0/task/body-reshape/pre-process:
    post:
      summary: Run an AI Body Reshape 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.


        The 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.


        For 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.


        This 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`.
      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/body-reshape/pre-process/{task_id}:
    get:
      summary: Check the status of a AI Body Reshape 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:
                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
        '400':
          $ref: '#/components/responses/InvalidTaskId'
        '401':
          $ref: '#/components/responses/InvalidApiKey'
        '500':
          $ref: '#/components/responses/TaskTimeout'
  /s2s/v2.0/task/body-reshape:
    post:
      summary: Run an AI Body Reshape 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.


        If webhooks are not supported for the feature, or if your integration
        cannot use webhooks, implement polling. After starting an AI task, keep
        polling the task status endpoint at the given `polling_interval` until
        the task status is either `success` or `error`.


        Do not stop polling a running task for longer than the allowed polling
        window. If the task is not polled in time, the task may expire; a later
        status check can return `InvalidTaskId` even if processing finished, and
        the consumed units may still be charged.
      tags:
        - V1.0
      security:
        - BearerAuthenticationV2: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              allOf:
                - $ref: '#/components/schemas/BasicRunTaskV2'
                - type: object
                  required:
                    - version
                    - features
                  properties:
                    version:
                      type: string
                      description: >
                        Version of the features specification. Defaults to
                        `"1.0"` unless otherwise specified.
                      default: '1.0'
                      example: '1.0'
                    index:
                      type: integer
                      example: 0
                      description: The index of the person from detection task result.
                    features:
                      type: object
                      description: Cannot be all zero
                      minProperties: 1
                      properties:
                        arm:
                          type: number
                          minimum: -100
                          maximum: 100
                          example: 0
                        breast:
                          type: number
                          minimum: -100
                          maximum: 100
                          example: 0
                          description: >-
                            Applies to both sides. A per-side key (`breast_left`
                            / `breast_right`) overrides this value for that
                            side; a per-side `0` means that side is left
                            unchanged.
                        breast_left:
                          type: number
                          minimum: -100
                          maximum: 100
                          example: 0
                        breast_right:
                          type: number
                          minimum: -100
                          maximum: 100
                          example: 0
                        hip:
                          type: number
                          minimum: -100
                          maximum: 100
                          example: 0
                        hip_lift:
                          type: number
                          minimum: -100
                          maximum: 100
                          example: 0
                        leg:
                          type: number
                          minimum: -100
                          maximum: 100
                          example: 0
                        neck:
                          type: number
                          minimum: 0
                          maximum: 100
                          example: 0
                          description: >-
                            Applies to both sides. A per-side key (`neck_left` /
                            `neck_right`) overrides this value for that side; a
                            per-side `0` means that side is left unchanged.
                        neck_left:
                          type: number
                          minimum: 0
                          maximum: 100
                          example: 0
                        neck_right:
                          type: number
                          minimum: 0
                          maximum: 100
                          example: 0
                        shoulder:
                          type: number
                          minimum: -100
                          maximum: 100
                          example: 0
                          description: >-
                            Applies to both sides. A per-side key
                            (`shoulder_left` / `shoulder_right`) overrides this
                            value for that side; a per-side `0` means that side
                            is left unchanged.
                        shoulder_left:
                          type: number
                          minimum: -100
                          maximum: 100
                          example: 0
                        shoulder_right:
                          type: number
                          minimum: -100
                          maximum: 100
                          example: 0
                        squared_shoulder:
                          type: number
                          minimum: -100
                          maximum: 100
                          example: 0
                          description: >-
                            Applies to both sides. A per-side key
                            (`squared_shoulder_left` / `squared_shoulder_right`)
                            overrides this value for that side; a per-side `0`
                            means that side is left unchanged.
                        squared_shoulder_left:
                          type: number
                          minimum: -100
                          maximum: 100
                          example: 0
                        squared_shoulder_right:
                          type: number
                          minimum: -100
                          maximum: 100
                          example: 0
                        slim:
                          type: number
                          minimum: -100
                          maximum: 100
                          example: 0
                        taller:
                          type: number
                          minimum: 0
                          maximum: 100
                          example: 0
                        waist:
                          type: number
                          minimum: -100
                          maximum: 100
                          example: 0
                        belly:
                          type: number
                          minimum: -100
                          maximum: 100
                          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/body-reshape/{task_id}:
    get:
      summary: Check the status of a AI Body Reshape 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/TaskStatusResponseV2'
                  - type: object
                    properties:
                      data:
                        type: object
                        properties:
                          results:
                            type: object
                            properties:
                              timed:
                                type: number
                              timed_apply:
                                type: number
                              arm:
                                type: boolean
                              breast_left:
                                type: boolean
                              breast_right:
                                type: boolean
                              hip:
                                type: boolean
                              hip_lift:
                                type: boolean
                              leg:
                                type: boolean
                              neck_left:
                                type: boolean
                              neck_right:
                                type: boolean
                              shoulder_left:
                                type: boolean
                              shoulder_right:
                                type: boolean
                              squared_shoulder_left:
                                type: boolean
                              squared_shoulder_right:
                                type: boolean
                              slim:
                                type: boolean
                              taller:
                                type: boolean
                              waist:
                                type: boolean
                              belly:
                                type: boolean
        '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:
              * InvalidParameters - Invalid request parameters
              * CreditInsufficiency - Insufficient unit to run
              * BadRequest - Unexpected request parameter
              * InvalidStyleGroup - Invalid style group id
              * InvalidStyle - Invalid style id
    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:

        - \`error_exceed_max_image_size\`  - Input image size exceeds the
        maximum limit

        - \`exceed_max_filesize\` - Input file size exceeds the maximum limit

        - \`invalid_parameter\` - Invalid parameter value

        - \`error_download_image\` - Download source image error

        - \`error_download_mask\` - Download mask image error

        - \`error_decode_image\` - Decode source image error

        - \`error_decode_mask\` - Decode mask image error

        - \`error_nsfw_content_detected\` - NSFW content detected in source
        image

        - \`error_no_face\` - No face detected on source image

        - \`error_pose\` - Failed to detect pose on source image

        - \`error_face_parsing\` - Failed to do face segmentation on source
        image

        - \`error_inference\` - Inference pipeline error

        - \`exceed_nsfw_retry_limits\` - Exceed the retry limits to avoid
        generated NSFW image

        - \`error_upload\` - Upload result image error

        - \`unknown_internal_error\` - Others
    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
    TaskStatusResponseBodySingleUrlResultsV2:
      type: object
      properties:
        url:
          type: string
          description: URL to download this result. Valid for 2 hours
          example: https://example.com/sample-result-url
    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
