> ## 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.

# Create Try-On (sync)

> Create a try-on and get the result in the same request. Costs 1 credit.

Same body as [Create Try-On](/docs/tryon-api/endpoints/create-try-on), but the request stays open until the result is ready, usually about 10 seconds. No polling. Use it for scripts, serverless functions and any client that prefers one call. Costs 1 credit, refunded if the generation fails.

The request waits up to 90 seconds. Set your HTTP client timeout above that (100 seconds works).

| Outcome | Response |
| - | - |
| Result ready | `200` with the generation, including `resultImageUrl`. |
| Generation failed | The error, same codes as [Generation Status](/docs/tryon-api/endpoints/generation-status) (e.g. `GENERATION_FAILED`, `GENERATION_TIMEOUT`), with the generation in `details.generationId`. The credit is refunded. |
| Still running after 90 s | `202` with the `generationId`. Poll [Generation Status](/docs/tryon-api/endpoints/generation-status) for the result. |

<Tip>
  First try-on of a product is a few seconds slower: the product gets analyzed. Register products ahead of time with
  [Upsert Product](/docs/tryon-api/endpoints/create-product) and the analysis runs right away, before the first try-on.
</Tip>

## Body

Identical to [Create Try-On](/docs/tryon-api/endpoints/create-try-on#body): `products`, `person`, `externalUserId`, `output`.

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST "https://api.genlook.app/tryon/v1/try-on/sync" \
    -H "x-api-key: gk_your_api_key" \
    -H "Content-Type: application/json" \
    --max-time 100 \
    -d '{
      "products": [{
        "externalId": "shirt-42",
        "title": "Red cotton t-shirt",
        "description": "Regular fit crew neck tee, short sleeves, hip length.",
        "images": [{ "source": { "url": "https://cdn.example.com/red-tee.jpg" } }]
      }],
      "person": { "image": { "source": { "url": "https://cdn.example.com/me.jpg" } } }
    }'
  ```

  ```python Python theme={null}
  import requests

  r = requests.post(
      "https://api.genlook.app/tryon/v1/try-on/sync",
      headers={"x-api-key": "gk_your_api_key"},
      json={
          "products": [{"externalId": "shirt-42"}],
          "person": {"image": {"source": {"url": "https://cdn.example.com/me.jpg"}}},
      },
      timeout=100,
  )
  r.raise_for_status()
  data = r.json()
  if r.status_code == 202:
      print("Still running, poll:", data["generationId"])
  else:
      print(data["resultImageUrl"])
  ```

  ```ts Node SDK theme={null}
  import { Genlook } from "@genlook/api";

  const client = new Genlook({ apiKey: process.env.GENLOOK_API_KEY! });

  const result = await client.tryOn.createSync({
    products: [{ externalId: "shirt-42" }],
    person: { image: { source: { url: "https://cdn.example.com/me.jpg" } } },
  });
  // Took longer than 90 s? Wait for it.
  const done =
    result.status === "COMPLETED" ? result : await client.generations.waitFor(result.generationId);
  console.log(done.resultImageUrl);
  ```

  ```javascript JavaScript theme={null}
  const res = await fetch("https://api.genlook.app/tryon/v1/try-on/sync", {
    method: "POST",
    headers: { "x-api-key": API_KEY, "Content-Type": "application/json" },
    body: JSON.stringify({
      products: [{ externalId: "shirt-42" }],
      person: { image: { source: { url: "https://cdn.example.com/me.jpg" } } },
    }),
    signal: AbortSignal.timeout(100_000),
  });
  const data = await res.json();
  if (!res.ok) throw new Error(`${data.code}: ${data.message}`);
  // 202: still running, poll /generations/:id with data.generationId
  console.log(data.resultImageUrl);
  ```
</RequestExample>

## Response

<ResponseField name="generationId" type="string" required>
  The generation ID.
</ResponseField>

<ResponseField name="status" type="string" required>
  `COMPLETED` on `200`. `PENDING` or `PROCESSING` on `202`.
</ResponseField>

<ResponseField name="resultImageUrl" type="string">
  Temporary signed URL of the result. Present on `200`. Display or download it right away, or fetch the generation
  again for a fresh URL.
</ResponseField>

<ResponseField name="productExternalId" type="string">
  Your `externalId`, or the generated ID of a one-shot product.
</ResponseField>

<ResponseField name="createdAt" type="string" required>
  ISO timestamp.
</ResponseField>

<ResponseField name="updatedAt" type="string" required>
  ISO timestamp.
</ResponseField>

<ResponseExample>
  ```json 200 theme={null}
  {
    "generationId": "cm8gen456xyz",
    "status": "COMPLETED",
    "resultImageUrl": "https://storage.googleapis.com/...",
    "productExternalId": "shirt-42",
    "createdAt": "2026-09-30T10:00:00.000Z",
    "updatedAt": "2026-09-30T10:00:09.800Z"
  }
  ```

  ```json 202 theme={null}
  {
    "generationId": "cm8gen456xyz",
    "status": "PROCESSING",
    "productExternalId": "shirt-42",
    "createdAt": "2026-09-30T10:00:00.000Z",
    "updatedAt": "2026-09-30T10:01:30.000Z"
  }
  ```

  ```json 504 theme={null}
  {
    "code": "GENERATION_TIMEOUT",
    "message": "The try-on generation did not finish within 60 seconds and was cancelled. The credit has been refunded; please retry.",
    "status": 504
  }
  ```
</ResponseExample>

## Errors

Everything from [Create Try-On](/docs/tryon-api/endpoints/create-try-on#errors), plus the generation errors from
[Generation Status](/docs/tryon-api/endpoints/generation-status). See [Errors](/docs/tryon-api/errors) for the full list.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.