What it is. Your product catalog, matched against a precise skin analysis. Upload the skincare products you sell with their descriptions, pass the catalog's id, and the endpoint returns the best-matching products for each detected concern in llm_results.json.
The difference from a general LLM recommendation is the input. A general LLM recommends from probability and priors. Perfect AI Skin Analysis first produces scientific, quantified skin metrics and real detection masks, so the model matches products against measured skin conditions — reliable, fast, and explainable, not a statistical guess.
Parameters
| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
catalog_id | string | Yes | — | From Upload a product catalog. Must be ready and belong to your account. |
top_n | integer | No | 3 | Products recommended per concern. Min 1; must not exceed the catalog's sku_count. |
- Prerequisite — Upload Your Product Catalog
A product catalog is the list of products Skin Analysis recommends from. Upload it once, keep its catalog_id, and pass that id on every analysis call. Catalogs belong to your account, not to one API key — every key of the account, project keys included, sees the same catalogs, and rotating or deleting a key does not affect them. Uploading and storing catalogs is free.
Catalog file requirements
| Item | Value |
|---|---|
| Format | CSV with a header row |
| Encoding | UTF-8, with or without BOM (Excel's "CSV UTF-8" adds one) |
| Maximum file size | 5 MB |
| Maximum SKU count | No limit other than file size |
| Required columns | product_id, product_name, product_description |
Extra columns are ignored but still count toward the 5 MB limit. Quote values containing commas or line breaks. Each non-empty data row counts as one SKU.
product_id,product_name,product_description
SKU-001,Hydrating Serum,"A lightweight serum for dry skin."
SKU-002,Brightening Cream,"Evens out skin tone, for daily use."
SKU-003,Barrier Repair Cream,"Rich cream for dry, redness-prone skin."# Upload a catalog — validated in the same request
curl -sS -X POST "$BASE_URL/s2s/v2.1/product-catalog" \
-H "Authorization: Bearer $API_KEY" \
-F "file=@catalog.csv" \
-F "name=Summer skincare"A valid file answers status: ready with its catalog_id and sku_count — keep that id:
{
"status": 200,
"data": {
"catalog_id": "1662043585118399001",
"name": "Summer skincare",
"status": "ready",
"created_time": 1760256000000,
"sku_count": 3
}
}# List every catalog of your account, newest first (ready and failed alike)
curl -sS -H "Authorization: Bearer $API_KEY" "$BASE_URL/s2s/v2.1/product-catalog"
# Delete a catalog — immediate and permanent
curl -sS -X DELETE -H "Authorization: Bearer $API_KEY" \
"$BASE_URL/s2s/v2.1/product-catalog/1662043585118399001"Catalog states and limits
| Status | Meaning | Usable in Skin Analysis |
|---|---|---|
ready | Uploaded and validated | Yes |
failed | Uploaded, file failed validation | No |
An upload that fails validation answers an error and is still recorded as a failed catalog, visible in List catalogs; the error body never carries its catalog_id. Each account keeps up to 10 catalogs, ready and failed together — delete one before uploading another. To update a catalog, upload a new file: every upload creates a new catalog_id, and the old catalog stays usable until you delete it, so you can verify the new one before switching.
- Create an AI Task
# Skin Analysis with Product Recommendation
curl -sS -X POST "$BASE_URL/s2s/v2.1/task/skin-analysis-recommendation" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"src_file_url": "https://your-cdn.example.com/customer-001.jpg",
"dst_actions": [
"hd_skin_type", "hd_wrinkle", "hd_pore", "hd_texture",
"hd_acne", "hd_redness", "hd_oiliness", "hd_moisture",
"hd_age_spot", "hd_radiance", "hd_dark_circle"
],
"format": "zip",
"pf_camera_kit": true,
"product_recommendation": {
"catalog_id": "1662043585118399001",
"top_n": 3
}
}'Validation. Every case below answers 400 with error_code: InvalidParameters and is not charged:
| Cause | error message |
|---|---|
product_recommendation without catalog_id | catalog_id is required when product_recommendation is provided. |
| Catalog missing, deleted, or owned by another account | No catalog was found with this catalog_id. |
Catalog failed validation at upload (status: failed) | This catalog failed validation when it was uploaded and can't be used. Upload the catalog again. |
top_n not an integer ≥ 1 | (common InvalidParameters case) |
top_n above the catalog's product count | product_recommendation.top_n can't be more than the 3 products in this catalog. |
The last message is dynamic — it reports the catalog's real sku_count. Read sku_count from List catalogs and clamp top_n to it client-side.
- Polling for the Report and Recommendations
Every run answers a BasicRunTaskResponseV2 immediately. Poll the task with the returned id; the report and the recommendations are delivered in llm_results.json.
# 1. Run the task and capture the task id
TASK_ID=$(curl -sS -X POST "$BASE_URL/s2s/v2.1/task/skin-analysis-recommendation" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{ ... }' | jq -r '.data.task_id')
# 2. Poll until task_status is "success"
curl -sS -H "Authorization: Bearer $API_KEY" \
"$BASE_URL/s2s/v2.1/task/skin-analysis-recommendation$TASK_ID"task_status moves running → success | error. With format: zip, results.url is a download link valid for 2 hours, and the ZIP contains a skinanalysisResult folder with score_info.json and every detection image. With format: json, results.output returns the scores directly in the body.
- Request-Field Quick Reference
| Field | Required | Notes |
|---|---|---|
src_file_id / src_file_url | Yes (one of) | Input image, per BasicRunTaskV2 |
dst_actions | Yes | HD features or SD features — never mixed |
format | No | zip (default) | json — response schema differs |
pf_camera_kit | No | V2.1 addition; face outline and feature localization |
miniserver_args | No | Mask overlay and HD pore/wrinkle background controls |
advanced_report | No | Present → report; {} → all defaults; omitted → none |
product_recommendation | No | Present → recommendations; needs catalog_id |
Resolution. All output images are capped at a 2560 px long side, with automatic input resizing. If enable_mask_overlay is false, you receive the raw mask as .png and must composite it yourself — verify the input resolution and use 2560 px to size your display when the long side exceeds it.