Skip to main content
POST
You probably don’t need this endpoint. The recommended path is the inline product field on POST /try-on: same upsert semantics, one less call. Use this endpoint only when you want:
  • a lifetime TTL by default (inline upserts default to 15 days),
  • the product listed in GET /products and visible in the dashboard,
  • to pre-register a catalog without immediately running a generation.
Creates or updates a product, matched on (account, externalId). The same endpoint handles both: pass full fields the first time, then partial fields to edit later. Products created via this endpoint default to lifetime (no expiry); pass validForDays to opt into a TTL.

Content types

  • application/json: when all images are URLs.
  • multipart/form-data: when you ship image bytes inline. The JSON payload arrives in a data form field; each images[].fileKey references a file field by name.

Request

string
required
Your product ID. Reused on subsequent calls to update the same product. Don’t start it with _anon_; that prefix is reserved for IDs we generate.
string
Optional. Helps the AI classify the product category more accurately. Preserved on updates if omitted.
string
Optional. Helps the AI classify the product category more accurately. Preserved on updates if omitted.
array
Replaces the full image list on update. Each entry has a source object holding exactly one of:
  • url: remote URL.
  • fileKey: name of a multipart file field in the same request.
An optional classifications object can sit alongside source.
The old flat shape ({ url } / { fileKey, classifications } with the fields at the top level) is still accepted but deprecated. Prefer { source: { url | fileKey }, classifications? }.
integer | null
How long the product lives between uses, in days. Defaults to null (kept forever) when created via this endpoint. Pass a number (1–365) to set a custom lifetime, null to opt back into “kept forever” on an existing product, or omit to preserve the existing value.
object
Free-form JSON returned on GET /products/:externalId.
The legacy imageUrls alias from the alpha has been removed. Use images: [{ source: { url } }] instead.

Response

Returns the full product state after the upsert. See List Products for the field-by-field reference.