Render a look
/v2/agent/looksRenders one outfit as a single styled image of a model wearing every
item, from the product photos alone. Call it once for each look
announced on a looks stream event (or in the non-streaming
response's looks), passing that look's item ids, label and
customInstructions. Fire the calls in parallel — each takes several
seconds and they are independent, so a three-look answer finishes about
as fast as a one-look answer.
The endpoint is not limited to agent output: any two to six active
items from your catalogue can be rendered together. itemIds must be
full item ids (the itemId on a Product), not the 13-character
references the agent uses in its tool calls.
Items are resolved within your organization's datasets only. Every id
must resolve to an active item in scope, or the request fails with
404 naming the ids that did not — a look is never rendered with
pieces missing. When rendering a look from the agent, send the same
datasetIds you sent to the chat endpoint; the agent picked its items
from that scope, and the default (your active datasets) may not
contain them.
The image is generated at a 3:4 aspect ratio by default so nothing
is cropped when displayed in a portrait box; override it with
preferences.aspectRatio. It is returned inline as a data: URI —
there is no hosted URL, so store it yourself if you need to show it
again.
Each request consumes one unit of api.v2.agent.looks, a resource of
its own, separate from the v1 outfit endpoint. A 502 (or any other
5xx) is refunded.
Request body
application/jsonrequiredFull item ids of the garments worn together. Ids that do not resolve to an active item in scope are left out; at least two must resolve.
Name of the look, used in the render prompt. Defaults to Look.
Datasets to resolve the items in. Omit or send [] for every active dataset.
The shopper's own photo, to style the look onto them instead of a stock model. A base64 data: URL of a JPEG, PNG or WebP image, at most 3 MB decoded — never a web URL. Stylor uses it for this request only and stores neither the photo nor the render made from it, so keep both in the shopper's browser if you need them again.
Render preferences. Only aspectRatio is read today; other keys are accepted and ignored.
Output aspect ratio as width:height, for example 3:4, 1:1, 9:16. Match it to the box you display the image in.
Free-text direction for anything the product photos cannot convey. Pass the value from the look unchanged; omit or null when there is none.
Your identifier for the shopper's visit, for analytics only.
Visit metadata for analytics.
Option 1: Session
Where the shopper is talking to the agent. Defaults to widget when omitted.
Which agent version your client is built against. Use v2.
How your client persists the visit id — for example memory, session or local. Defaults to memory.
The shopper's IANA time zone.
The shopper's BCP 47 locale.
A coarse device class, typically mobile or desktop.
Option 2: null
Response
Response headers
X-RateLimit-ResourceThe quota resource this endpoint is metered against: api.v2.agent.chat
for the chat endpoint, api.v2.agent.looks for the looks endpoint and
api.v2.agent.match for the shop-the-look endpoint. These are separate
from the v1 resources, so Agent API usage never draws down a v1
allowance.
X-RateLimit-Quota-LimitRequests allowed in the current billing period, or unlimited.
X-RateLimit-Quota-RemainingRequests left in the current billing period, or unlimited.
X-RateLimit-Quota-ResetUnix epoch seconds at which the billing period resets.
X-RateLimit-RPM-LimitRequests allowed per minute for this resource.
X-RateLimit-RPM-RemainingRequests left in the current one-minute window.
X-RateLimit-RPM-ResetUnix epoch seconds at which the one-minute window resets.
The rendered image as a data:<mime>;base64,… URI, usable directly as an <img src>. Typically image/png.
Errors
29Every error is JSON with a single error string unless noted. Match on the status code; the message is for humans.
Request body must be valid JSON.The body could not be parsed as JSON.
Request body must be a JSON object.The body is empty, or is valid JSON that is not an object (for example an array).
No active datasets found for this organization. Activate one via the dashboard (Dataset → Settings) or through the REST API before proceeding.datasetIds was omitted and the organization has datasets, but none is active.
All requested datasets are archived. Reactivate at least one via the dashboard or REST API.Every dataset in datasetIds is archived.
No datasets found for this organization. Create one via the dashboard or REST API, or pass datasetIds to use draft/archived datasets before proceeding.The organization has no datasets at all.
These items could not be found: <ids>.One or more of itemIds did not match an active item in the resolved datasets. The unmatched ids are listed, comma-separated. Check that you sent full item ids from this organization's catalogue, and the same datasetIds the agent searched.
A look needs at least two itemIds.itemIds is missing, not an array, or has fewer than two distinct entries.
A look can hold at most 6 items.itemIds has more than six entries.
userPhotoUrl must be a base64 data: URL of a JPEG, PNG or WebP image. Shopper photos are never fetched from a URL or stored.userPhotoUrl is a web URL, a storage key, or any other type of image. Send the photo's bytes inline.
userPhotoUrl can be at most 3 MB.The photo in userPhotoUrl is larger than 3 MB once decoded. Downscale it in the browser first; around 1024px on the long edge is plenty.
Invalid datasetIds for this organization: <ids>One or more of datasetIds does not belong to the organization. The offending ids are listed, comma-separated.
Could not generate this look.The image model returned no image or failed, including when none of the product images could be fetched. Retrying usually succeeds.
curl -X POST "https://stylor.ai/api/v2/agent/looks" \
-H "Authorization: Bearer $STYLOR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"label": "Garden wedding",
"itemIds": [
"8f2c1a9e-4b7d-4c1e-9a3f-2d6b7e5c1a90",
"1b7e33c0-9a2d-4f8e-b5c6-7d8e9f0a1b2c",
"c4d5e6f7-0a1b-4c2d-8e9f-0a1b2c3d4e5f"
],
"customInstructions": "Shirt untucked with the top button open; outdoor daylight setting.",
"sessionId": "3b0d4a1e-6f52-4b8a-9d3c-7e2f1a0b9c8d",
"session": {
"surface": "widget",
"agentVersion": "v2"
}
}'{
"visualization": {
"imageData": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAgAAAAKqCAYAAAB..."
}
}