Skip to main content
GET
/
tryon
/
v1
/
products
curl "https://api.genlook.app/tryon/v1/products?limit=10" \
  -H "x-api-key: gk_your_api_key"
{
  "items": [
    {
      "externalId": "shirt-42",
      "title": "Red tee",
      "description": "Soft cotton regular fit",
      "images": [
        { "sourceUrl": "https://cdn.example/front.jpg", "order": 0 },
        { "sourceUrl": "https://cdn.example/back.jpg", "order": 1 }
      ],
      "metadata": null,
      "autoDetectImageRoles": false,
      "validForDays": null,
      "lastUsedAt": "2026-05-12T14:32:00.000Z",
      "expiresAt": null,
      "createdAt": "2026-04-30T08:11:00.000Z",
      "updatedAt": "2026-04-30T08:11:00.000Z"
    }
  ],
  "nextCursor": null,
  "hasMore": false,
  "count": 1
}

Documentation Index

Fetch the complete documentation index at: https://docs.genlook.app/docs/llms.txt

Use this file to discover all available pages before exploring further.

These endpoints are for introspection and cleanup, not part of the core try-on flow. If you’re using the inline POST /try-on pattern you can skip them entirely — products self-manage via TTL.
GET /tryon/v1/products paginates through products you’ve registered with a stable externalId. One-shot products (created by /try-on without an externalId) are not part of your catalog and don’t appear here. GET /tryon/v1/products/:externalId fetches a single product by ID. This works for any ID you have, including server-generated one-shot IDs returned from /try-on. DELETE /tryon/v1/products/:externalId removes a product. Past generations keep their snapshot of the product details — deleting only removes the product itself, not the history.

List

limit
number
1–200, default 50.
cursor
string
nextCursor from the previous page.
curl "https://api.genlook.app/tryon/v1/products?limit=10" \
  -H "x-api-key: gk_your_api_key"

Response shape

Each product has:
externalId
string
required
Your product ID.
title
string
required
description
string
required
images
array
required
One entry per image: { sourceUrl, order }.
  • sourceUrl — the URL you supplied on upsert. For images shipped as multipart bytes this is an opaque internal reference (e.g. upload://…); treat it as a stable identifier, not as something you can fetch.
  • order — 0-indexed position in the original list.
metadata
object | null
Whatever JSON you sent on upsert.
autoDetectImageRoles
boolean
validForDays
integer | null
How long the product lives between uses, in days. null means kept forever.
lastUsedAt
string | null
ISO timestamp of the last generation that referenced this product. null until the first use.
expiresAt
string | null
ISO timestamp at which the product will be removed if it’s not used again. null when validForDays is null (kept forever). Refreshed on every generation.
createdAt
string
required
ISO 8601 timestamp.
updatedAt
string
required
ISO 8601 timestamp of the last edit.
The list endpoint wraps items in { items, nextCursor, hasMore, count }. nextCursor is null (or omitted) on the last page.
{
  "items": [
    {
      "externalId": "shirt-42",
      "title": "Red tee",
      "description": "Soft cotton regular fit",
      "images": [
        { "sourceUrl": "https://cdn.example/front.jpg", "order": 0 },
        { "sourceUrl": "https://cdn.example/back.jpg", "order": 1 }
      ],
      "metadata": null,
      "autoDetectImageRoles": false,
      "validForDays": null,
      "lastUsedAt": "2026-05-12T14:32:00.000Z",
      "expiresAt": null,
      "createdAt": "2026-04-30T08:11:00.000Z",
      "updatedAt": "2026-04-30T08:11:00.000Z"
    }
  ],
  "nextCursor": null,
  "hasMore": false,
  "count": 1
}