{"templateId":"openapi_docs","sharedDataIds":{"openAPIDocsStore":"oas-reference/ai_look_vto.yaml","sidebar":"sidebar-reference/sidebars.yaml"},"props":{"definitionId":"reference/ai_look_vto.yaml","dynamicMarkdocComponents":[],"baseSlug":"/reference/ai_look_vto","seo":{"title":"AI Look Virtual Try-On","llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"itemId":"","disableAutoScroll":true,"metadata":{"type":"openapi","title":"AI Look Virtual Try-On","description":"# Overview\nThe AI Look Virtual Try-On API provides a complete workflow for applying professionally designed facial looks to user photos. Each look is crafted by beauty experts and can be applied instantly via API.\n\n## Integration Guide\nThis guide walks you through:\n\n*   **Endpoint:** `/s2s/v2.0/task/look-vto`\n*   **Authentication:** All requests require an `Authorization: Bearer <TOKEN>`\n*   **Workflow:**\n    1.  **Prepare a selfie:** Uploading an image or provide a valid image URL\n    1.  **List look templates:** Listing available AI look templates\n    1.  **Start Task (`POST`):** Submit your image id/URL and a look ``template_id``.\n    1.  **Retrieve Task ID:** Capture the `task_id` from the response.\n    1.  **Poll Status (`GET`):** Use the `task_id` to check the status of the task. Continue polling until `task_status` is `\"success\"` or `\"error\"`.\n\n---\n\n* API Playground\n\nInteractively explore and test the API using our official playground:\n\n**API Playground:**\n[http://yce.makeupar.com/api-console/en/api-playground/ai-look-virtual-try-on/](http://yce.makeupar.com/api-console/en/api-playground/ai-look-virtual-try-on/)\n\n---\n\n* Authentication\n- Include your API key in the request header using **Bearer Token**:\n    ```\n    Authorization: Bearer <API Key>\n    ```\nYou can find your API Key at https://yce.makeupar.com/api-console/en/api-keys/.\n\n\n* 1. Upload an Image\n\nYou may upload a file directly to the server or provide a valid image URL in the VTO task payload.\n\n   * Upload Endpoint\n\n```\nPOST /s2s/v2.0/file/look-vto\n```\n\nAlternatively, skip this step if you already have a public image URL.\n\n---\n\n* 2. List Available Look Styles\n\nRetrieve all AI makeup look templates available for virtual try-on.\n\n   * Endpoint\n\n```\nGET /s2s/v2.0/task/template/look-vto\n```\n\n   * Query Parameters\n\n| Parameter        | Description                     |\n| ---------------- | ------------------------------- |\n| `page_size`      | Number of items per page        |\n| `starting_token` | Token for pagination (optional) |\n\n   * Sample Javascript Request\n\n```javascript\nconst data = null;\n\nconst xhr = new XMLHttpRequest();\nxhr.withCredentials = true;\n\nxhr.addEventListener('readystatechange', function () {\n    if (this.readyState === this.DONE) {\n        console.log(this.responseText);\n    }\n});\n\nxhr.open('GET', 'https://yce-api-01.makeupar.com/s2s/v2.0/task/template/look-vto?page_size=20&starting_token=13045969587275114');\nxhr.setRequestHeader('Authorization', 'Bearer <access_token for v1, API Key for v2>');\n\nxhr.send(data);\n```\n\n   * Sample Successful Response\n\n```json\n{\n  \"status\": 200,\n  \"data\": {\n    \"templates\": [\n      {\n        \"id\": \"good_template_001\",\n        \"thumb\": \"thumbnail preview image URL\",\n        \"title\": \"Berry Smooth\",\n        \"category_name\": \"Daily\"\n      }\n    ],\n    \"next_token\": 13045969587275114\n  }\n}\n```\n\n> **Note:** Use the `id` value (`template_id`) when creating the Look VTO task.\n\n---\n\n* 3. Create a Look VTO Task and Poll for Results\n\nOnce you have an image and a template ID, create a task. The API processes the request asynchronously. You must poll the task status until it reaches `success` or `error`.\n\n   * Create Task Endpoint\n\n```\nPOST /s2s/v2.0/task/look-vto\n```\n\n   * Polling Endpoint\n\n```\nGET /s2s/v2.0/task/look-vto/{task_id}\n```\n\n---\n\n   * Sample JavaScript Implementation\n\n```javascript\nconst BASE_URL = 'https://yce-api-01.makeupar.com/s2s/v2.0/task/look-vto';\nconst START_METHOD = 'POST';\nconst HEADERS = {\n  \"Content-Type\": \"application/json\",\n  \"Authorization\": \"Bearer FT6Xa7xuU1SBU2ZW6pdAAUh9D093kuX3\"\n};\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nasync function startTask() {\n  const init = {\n    method: START_METHOD,\n    headers: HEADERS,\n    body: JSON.stringify({\n      \"src_file_url\": \"https://plugins-media.makeupar.com/strapi/assets/sample_Image_7_fa28b2618a.jpg\",\n      \"template_id\": \"all_rosy_chic\"\n    })\n  };\n\n  const res = await fetch(BASE_URL, init);\n  if (!res.ok) throw new Error(`Start request failed: ${res.status} ${res.statusText}`);\n\n  const payload = await res.json().catch(() => ({}));\n  const taskId = payload?.data?.task_id;\n  if (!taskId) throw new Error('task_id missing: ' + JSON.stringify(payload));\n\n  console.log('[startTask] Task started, id =', taskId);\n  return taskId;\n}\n\nasync function pollTask(taskId, { intervalMs = 2000, maxAttempts = 300 } = {}) {\n  for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n    const pollUrl = `${BASE_URL}/${taskId}`;\n    const res = await fetch(pollUrl, { method: 'GET', headers: HEADERS });\n\n    if (!res.ok) throw new Error(`Polling failed: ${res.status} ${res.statusText}`);\n\n    const payload = await res.json().catch(() => ({}));\n    const status = payload?.data?.task_status;\n    console.log(`[pollTask] Attempt ${attempt} status = ${status}`);\n\n    if (status === 'success') {\n      console.log('[pollTask] Success results:', payload?.data?.results);\n      return payload;\n    }\n\n    if (status === 'error') {\n      throw new Error('Task failed: ' + JSON.stringify(payload));\n    }\n\n    await sleep(intervalMs);\n  }\n\n  throw new Error('Polling timeout: Max attempts exceeded');\n}\n\n(async () => {\n  try {\n    const taskId = await startTask();\n    const final = await pollTask(taskId);\n    console.log('[main] Final response:', final);\n  } catch (e) {\n    console.error('[main] Flow error:', e);\n  }\n})();\n```\n\n---\n\n   * Sample Success Response\n\n```json\n{\n  \"status\": 200,\n  \"data\": {\n    \"results\": {\n      \"url\": \"https://yce-us.s3-accelerate.amazonaws.com/demo/.../result.jpg?...\"\n    },\n    \"task_status\": \"success\"\n  }\n}\n```\n\nThe `results.url` field contains the final rendered virtual makeup image.\n\n---\n\n* Summary\n\n| Step                       | Description                              |\n| -------------------------- | ---------------------------------------- |\n| **1. Upload Image**        | Upload directly or provide an image URL. |\n| **2. List Look Templates** | Retrieve available look styles with IDs. |\n| **3. Create VTO Task**     | Submit image URL + template ID.          |\n| **4. Poll for Completion** | Retrieve the final result image URL.     |\n\nThis workflow ensures a reliable, developer-friendly integration for real-time virtual makeup try-on experiences.\n\n---\n\n## File Specs & Errors\n* Supported Formats & Dimensions\n\n|AI Feature|Supported Dimensions|Supported File Size|Supported Formats|\n|  ----  | ----  | ----  | ----  |\n|AI Look Virtual Try-On|long side < 1920, face width >= 100|< 10MB|jpg/jpeg/png|\n\n* Error Codes\n\n|Error Code|Description|\n|  ----  | ----  |\n|error_below_min_image_size|the size of the source image is smaller than minimum (expect: width >= 100px, height >= 100px)\n|error_exceed_max_image_size|the size of the source image is larger than maximum (expect: width < 1920px, height < 1080px)\n|error_face_position_invalid |Please ensure your entire face is fully visible within the image|\n|error_face_position_too_small|The detected face is too small. Move closer to the camera|\n|error_face_position_out_of_boundary|The face is too large or partially outside the image frame. Adjust your position|\n|error_face_angle_invalid|The face angle is incorrect. For front-facing photos, keep your head within 10°. For side-facing photos, ensure more than 15°.|\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"},"compilationErrors":[],"markdown":{"partials":{},"variables":{"rbac":{"teams":["anonymous"]},"user":{},"remoteAddr":{"hostname":"docs.perfectcorp.com","port":4000,"ipAddress":"216.73.217.15"},"lang":"default_locale","env":{"PUBLIC_REDOCLY_BRANCH_NAME":"master"}}},"pagePropGetterError":{"message":"","name":""}},"slug":"/reference/ai_look_vto","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}