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

# Try-On Status

> Check the status of a virtual try-on job

Poll this endpoint until status is `COMPLETED` or `FAILED`. Recommended interval: every 2 seconds, max 60 attempts.

<Note>
  On JavaScript, the [`@genlook/storefront` SDK](/docs/virtual-tryon/sdk) is the recommended integration: it calls this endpoint for you, along with the rest of the try-on flow.
</Note>

With the SDK there is nothing to poll: `generate()` resolves when the try-on completes, and the `tryon:generation_succeeded` / `tryon:generation_failed` [events](/docs/virtual-tryon/sdk#state-and-events) fire along the way.

## Path Parameters

<ParamField path="id" type="string" required>
  The `jobId` from the create try-on response.
</ParamField>

<RequestExample>
  ```bash cURL theme={null}
  curl "https://api.genlook.app/storefront/v1/try-ons/gen_xyz789abc" \
    -H "Authorization: Bearer pk_your_key_here" \
    -H "X-Genlook-Anonymous-Id: anon_..."
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(`https://api.genlook.app/storefront/v1/try-ons/${jobId}`, {
    headers: {
      'Authorization': `Bearer ${PUBLISHABLE_KEY}`,
      'X-Genlook-Anonymous-Id': anonymousId,
    },
  });
  const status = await response.json();
  ```
</RequestExample>

## Response

<ResponseField name="generationId" type="string" required>
  The try-on job ID.
</ResponseField>

<ResponseField name="status" type="string" required>
  `PENDING` | `PROCESSING` | `COMPLETED` | `FAILED`
</ResponseField>

<ResponseField name="resultImageKey" type="string">
  Storage key of the generated image. Present when `COMPLETED`.
</ResponseField>

<ResponseField name="resultImageUrl" type="string">
  Temporary signed URL of the generated image. Present when `COMPLETED`.
</ResponseField>

<ResponseField name="errorMessage" type="string">
  Error description. Present when `FAILED`.
</ResponseField>

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

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

<ResponseExample>
  ```json Completed theme={null}
  {
    "generationId": "gen_xyz789abc",
    "status": "COMPLETED",
    "resultImageKey": "generations/gen_xyz789abc.jpg",
    "resultImageUrl": "https://storage.googleapis.com/bucket-name/generations/gen_xyz789abc.jpg?X-Goog-Signature=...",
    "createdAt": "2024-01-15T10:30:00Z",
    "updatedAt": "2024-01-15T10:32:15Z"
  }
  ```

  ```json Failed theme={null}
  {
    "generationId": "gen_xyz789abc",
    "status": "FAILED",
    "errorMessage": "Failed to process image: Invalid image format",
    "createdAt": "2024-01-15T10:30:00Z",
    "updatedAt": "2024-01-15T10:30:45Z"
  }
  ```

  ```json Pending theme={null}
  {
    "generationId": "gen_xyz789abc",
    "status": "PENDING",
    "createdAt": "2024-01-15T10:30:00Z",
    "updatedAt": "2024-01-15T10:30:00Z"
  }
  ```
</ResponseExample>

## Polling Example

```javascript theme={null}
async function pollTryOn(jobId) {
  for (let i = 0; i < 60; i++) {
    const res = await fetch(`https://api.genlook.app/storefront/v1/try-ons/${jobId}`, {
      headers: {
        'Authorization': `Bearer ${PUBLISHABLE_KEY}`,
        'X-Genlook-Anonymous-Id': anonymousId,
      },
    });
    const data = await res.json();

    if (data.status === 'COMPLETED') return data;
    if (data.status === 'FAILED') throw new Error(data.errorMessage);

    await new Promise(r => setTimeout(r, 2000));
  }
  throw new Error('Try-on timeout');
}
```

<Note>
  Most try-ons finish in 10 to 20 seconds. Allow up to 60 seconds before treating a try-on as unusually slow.
</Note>
