# Start or restore a source-backed preview

Start the configured preview, restoring an archived source workspace when needed. Requires product access. Supply the dashboard frameOrigin. Session callers also need X-Hoplite-Action: preview-start. The gateway credential expires after five minutes; idempotent replay returns the original credential, so refresh it with GET preview. While the preview boots, relayed requests answer with X-Preview-State: starting (202 for documents, 425 otherwise). This does not publish or validate the application.

`POST /api/platform/v1/apps/{appId}/threads/{threadId}/preview/start`

Required permission: `thread:update`.

## Parameters

| Name | In | Type | Required | Description |

| --- | --- | --- | --- | --- |

| `appId` | path | `string` | Yes | — |

| `threadId` | path | `string` | Yes | — |

| `Idempotency-Key` | header | `string` | No | Required for service credentials. Retry the same request with the same key. |

## Request body

| Field | Type | Required | Constraints | Description |
| --- | --- | --- | --- | --- |
| `frameOrigin` | `string<uri>` | Yes | max length 2048 | — |

```json
{
  "frameOrigin": "https://dashboard.example.com"
}
```

## Example request

```bash
curl --request POST \
  --url https://api.hoplite.sh/api/platform/v1/apps/appId/threads/threadId/preview/start \
  --header "X-Api-Key: $HOPLITE_API_KEY" \
  --header "Idempotency-Key: $HOPLITE_OPERATION_ID" \
  --header 'Content-Type: application/json' \
  --data '{
  "frameOrigin": "https://dashboard.example.com"
}'
```

## 200 response

Success

Content type: `application/json`. Response type: `object`.

| Field | Type | Required | Constraints | Description |
| --- | --- | --- | --- | --- |
| `ok` | `boolean` | Yes | true | — |
| `preview` | `object` | Yes | — | — |
| `preview.status` | `string` | Yes | ready · unsupported · reconciling · blocked · starting · stopped · crashed · inactive | — |
| `preview.name` | `string` | No | min length 1 | — |
| `preview.port` | `integer` | No | min 1, max 65535 | — |
| `preview.reason` | `string` | No | — | — |
| `preview.url` | `string<uri>` | No | — | — |
| `preview.gateway` | `object` | Yes | — | — |
| `preview.gateway.header` | `string` | Yes | x-hoplite-preview-token | — |
| `preview.gateway.token` | `string` | Yes | — | — |
| `preview.gateway.expiresAt` | `string<date-time>` | Yes | — | — |

```json

```

## Status codes

- `200` — Success

- `400` — Invalid request

- `401` — Authentication required

- `403` — Permission, app scope or entitlement denied

- `404` — App, source or thread not found

- `409` — Idempotency conflict or request in progress

- `413` — Request too large

- `503` — Source storage or execution unavailable