Merchant API v2
Use the current component-based contract for advisory product suggestions and image moderation findings. For an existing integration that expects flat arrays with top-level status and sections, use Merchant API v1. Each endpoint is independent: send the product facts you have, inspect the result, and decide what to apply. Calls do not create, update, or publish catalogue products.
Choose a version
| Version | Use it when | Response shape |
|---|---|---|
| v1 | You maintain an existing integration | Flat arrays with top-level status and sections |
| v2 | You are building a new integration | Component objects with status and items |
Both versions accept the same requests and use the same authentication, catalogue checks, and quotas.
Authenticate and select a catalogue
Send your reusable customer API key in x-client-key and the target catalogue UUID as catalogueId in every JSON request body:
x-client-key: YOUR_CLIENT_KEY
Content-Type: application/json
The API key identifies your client; catalogueId selects one of its enabled, ready catalogues with Merchant API access. Do not create a single-use token or send bearer or x-token authentication. Requests do not accept clientId or a catalogue ID in the URL or query.
categoryId is different from catalogueId: it is an optional product category UUID within the selected catalogue. Use a previously chosen category.id as categoryId on later requests so attribute and description suggestions use the same category. A leaf is used directly. A parent limits selection to its descendants; if none fits, dependent suggestions are skipped. Without categoryId, the service selects from the full catalogue. Do not send a category object in the request.
Choose an endpoint
All paths below use https://platform.youzu.ai/api/v2/merchant-api.
| Endpoint | Result | Minimum input besides catalogueId |
|---|---|---|
POST /identity/suggestions |
name, brand |
Usable name, brand, description, or image |
POST /category/suggestions |
category |
Usable text, image, or categoryId |
POST /attributes/suggestions |
category, attributes |
Usable text, image, or current attribute |
POST /images/moderation |
images |
One to six images |
POST /descriptions/suggestions |
category, descriptions |
Usable text, image, or current attribute |
POST /assets/upload-url |
Upload credentials and asset_id |
File name, media type, and byte size |
All five analysis requests accept the same optional product context: name and description maps keyed by language, brand, attributes, images, and categoryId. You can send the complete current draft on each call. Use attributes for any existing product facts, including keys that are not in the selected category's definitions. These inputs do not change the catalogue's attribute definitions. Image moderation still requires at least one image. Asset upload has its own request shape.
Understand responses
Each analysis response has a top-level errors array. Every returned product component is an object with status and items; category also has selection. There is no top-level analysis status or sections field. The upload-URL response alone has a top-level status.
Component status |
Meaning |
|---|---|
complete |
The component finished, including when items is empty. It is not a pass/fail verdict. |
partial |
Some work finished; inspect errors and decide whether to retry. |
failed |
The component could not be produced. |
skipped |
The component was not attempted, often because a required category was unresolved. |
category.selection is provided, inferred, or unresolved. If category selection fails, category-dependent attributes or descriptions can be skipped; supplied descriptions can still be returned.
Suggestions are ranked, best first. name, brand, and descriptions entries have an ordered value array. Each attribute has a localized label map and an ordered value array of localized maps. Category can return ranked items with a catalogue id, localized label, and root-to-leaf breadcrumb. Use the first candidate if your UI needs one value, or present alternatives. Unknown attribute values are omitted; numeric 0 and boolean false retain their JSON types.
Attribute language keys cover catalogue languages followed by non-empty request name and description languages. String values are translated; numbers and booleans are repeated unchanged. Localization is best-effort: fallback maps stay complete with matching language keys, the affected component becomes partial, and errors includes a retryable localization error.
The errors array contains entries with type (error or warning), code, retryable, and localized messages. An advisory CONTENT_MISMATCH warning also has fieldPaths such as ["/name/en", "/images/0"], pointing into your request. A mismatch does not change component status. Show the warning to the merchant or use it to highlight the implicated fields; do not treat it as an HTTP error or silently discard otherwise usable suggestions.
Customer slugs
Optional customer slugs are configured in the dashboard's category and attribute editors; see Category Attributes. Category items may include category_slug, a language-keyed map. Attribute items may include attribute_slug and attribute_value_slug, an array aligned by index with value. An entry is null when a candidate has no configured slug, and the field is omitted when none has one. Free-text values have no value slug. Slug spelling and case are preserved.
{
"key": "colour",
"label": {"en": "Colour", "fr": "Couleur"},
"value": [{"en": "black", "fr": "noir"}, {"en": "white", "fr": "blanc"}],
"attribute_slug": {"en": "COLOUR"},
"attribute_value_slug": [{"en": "BLACK"}, null]
}
1. Suggest identity
curl -X POST https://platform.youzu.ai/api/v2/merchant-api/identity/suggestions \
-H "x-client-key: YOUR_CLIENT_KEY" -H "Content-Type: application/json" \
-d '{"catalogueId":"550e8400-e29b-41d4-a716-446655440000","name":{"en":"Blak runing shoe"},"brand":"acme"}'
{
"name": {"status": "complete", "items": [{"language": "en", "value": ["Black Running Shoe", "Black Running Trainers"]}]},
"brand": {"status": "complete", "items": [{"value": ["Acme"]}]},
"errors": []
}
2. Suggest a category
Omit categoryId for a new product, then retain the chosen category.items[0].id for later calls. Send categoryId if the merchant has already chosen a category.
curl -X POST https://platform.youzu.ai/api/v2/merchant-api/category/suggestions \
-H "x-client-key: YOUR_CLIENT_KEY" -H "Content-Type: application/json" \
-d '{"catalogueId":"550e8400-e29b-41d4-a716-446655440000","name":{"en":"Black Running Shoe"}}'
{
"category": {
"status": "complete",
"selection": "inferred",
"items": [{
"id": "11111111-1111-4111-8111-111111111111",
"label": {"en": "Running shoes"},
"breadcrumb": [{"en": "Footwear"}, {"en": "Running shoes"}]
}]
},
"errors": []
}
3. Suggest attributes
Pass the merchant's selected categoryId to keep suggestions within that category. Configure allowed keys, types, and choices in Category Attributes. Apply values with the category returned in the same response.
curl -X POST https://platform.youzu.ai/api/v2/merchant-api/attributes/suggestions \
-H "x-client-key: YOUR_CLIENT_KEY" -H "Content-Type: application/json" \
-d '{
"catalogueId": "550e8400-e29b-41d4-a716-446655440000",
"categoryId": "11111111-1111-4111-8111-111111111111",
"name": {"en": "Black Running Shoe"},
"attributes": {"colour": "black", "season": "summer"}
}'
{
"category": {
"status": "complete", "selection": "provided",
"items": [{
"id": "11111111-1111-4111-8111-111111111111",
"label": {"en": "Running shoes"},
"breadcrumb": [{"en": "Footwear"}, {"en": "Running shoes"}]
}]
},
"attributes": {
"status": "complete",
"items": [
{"key": "material", "label": {"en": "Material", "az": "Material"}, "value": [{"en": "mesh", "az": "tor"}]},
{"key": "spike_count", "label": {"en": "Spike count", "az": "Sünbül sayı"}, "value": [{"en": 0, "az": 0}]},
{"key": "waterproof", "label": {"en": "Waterproof", "az": "Su keçirməz"}, "value": [{"en": false, "az": false}]}
]
},
"errors": []
}
An empty attributes.items with status: "complete" means no values were suggested. If no category can be determined, category.status is failed, category.selection is unresolved, and attributes.status is skipped; inspect errors for the cause.
4. Moderate images
Send one to six unique HTTP(S) URLs or Youzu asset IDs. URLs must be publicly accessible; each image may be up to 15 MiB. JPEG, PNG, and WebP files are used as-is, while other supported formats are converted to JPEG before checks run. See Upload a Youzu Asset if you do not have a public URL.
curl -X POST https://platform.youzu.ai/api/v2/merchant-api/images/moderation \
-H "x-client-key: YOUR_CLIENT_KEY" -H "Content-Type: application/json" \
-d '{
"catalogueId": "550e8400-e29b-41d4-a716-446655440000",
"name": {"en": "Leather handbag"},
"images": ["https://images.example.com/products/shoe-front.webp"]
}'
{
"images": {
"status": "complete",
"items": [{
"reference": "https://images.example.com/products/shoe-front.webp",
"code": "IMAGE_LOW_RESOLUTION",
"severity": "warning",
"reasons": {"en": "Use a higher-resolution image.", "en_summary": "The image resolution is too low."},
"evidence": [{"code": "dimensions", "detail": {"width": 640, "height": 640}}],
"policy": null
}]
},
"errors": [{
"type": "warning",
"code": "CONTENT_MISMATCH",
"retryable": false,
"messages": {"en": "The product name may not match the supplied image."},
"fieldPaths": ["/name/en", "/images/0"]
}]
}
Image findings in images.items have severity (info, warning, or error), localized reasons, optional <LANG>_summary text, evidence, and an advisory policy action when a catalogue rule applies. A complete component can still contain error-severity findings: completion means the checks ran, not that the image passed. For a binary flow, treat a partial or failed image component as unable to determine and inspect retryable errors before retrying.
5. Suggest descriptions
Supply an existing description to preserve it while generating missing catalogue languages. Reuse the merchant's selected categoryId for category-dependent generation.
curl -X POST https://platform.youzu.ai/api/v2/merchant-api/descriptions/suggestions \
-H "x-client-key: YOUR_CLIENT_KEY" -H "Content-Type: application/json" \
-d '{
"catalogueId": "550e8400-e29b-41d4-a716-446655440000",
"categoryId": "11111111-1111-4111-8111-111111111111",
"description": {"en": "Lightweight running shoe with a breathable mesh upper."}
}'
{
"category": {
"status": "complete", "selection": "provided",
"items": [{
"id": "11111111-1111-4111-8111-111111111111",
"label": {"en": "Running shoes"},
"breadcrumb": [{"en": "Footwear"}, {"en": "Running shoes"}]
}]
},
"descriptions": {
"status": "complete",
"items": [
{"language": "en", "value": ["Lightweight running shoe with a breathable mesh upper."], "origin": "supplied"},
{"language": "fr", "value": ["Chaussure de course légère à tige en mesh respirant."], "origin": "generated"}
]
},
"errors": []
}
If category selection fails, generated descriptions are skipped; supplied descriptions can still appear in descriptions.items.
6. Upload an image
Use POST /assets/upload-url to get upload credentials, upload the file, and then pass the returned asset_id in an images array for the same catalogue. See Upload a Youzu Asset for the full request and response.
Handle errors
For HTTP 200 analysis responses, inspect component statuses and errors together. Retry a temporary failure only when its retryable field is true. Warnings, including CONTENT_MISMATCH, are advisory and can identify request fields with fieldPaths.
| HTTP status | Meaning |
|---|---|
401 |
Missing or invalid API key |
403 |
Your plan does not include Merchant API |
404 |
Merchant API is unavailable, or the catalogue is missing, deleted, or owned by another client |
409 |
Catalogue is disabled, not ready, or does not support Merchant API |
422 |
Invalid request body, including a missing or invalid catalogueId |
429 |
Monthly endpoint quota exceeded |
502 |
Merchant API returned an invalid, oversized, or unexpected upstream response |
503 |
A required service is temporarily unavailable |
504 |
The request timed out |