---
title: "Get preview URL"
method: GET
path: "/api/apps/{app_id}/sandbox/preview-url"
---

# Get preview URL

`GET /api/apps/{app_id}/sandbox/preview-url`

<Info>This API is in beta. Endpoints, fields, and behavior may still change, so avoid depending on it in production.</Info>

Returns a URL that serves the app as it currently stands in the app editor, including changes that haven't been published yet. Use it to look at your work in progress. Use [Deploy an app](/api-reference/deploy-an-app) to put it in front of your users.

The preview is served by a sandbox that shuts down when it goes unused. If none is running, this starts one, so the first call after a quiet period takes noticeably longer than later ones. The `sandbox_info.cold_start` field tells you which happened.

A `409` usually means the app's code doesn't currently build. The response body says what failed, so send that to the AI with [Send chat message](/api-reference/send-chat-message) and ask for the preview again.

## Path parameters

- `app_id` string, required

## Response `200`

Successful Response

- PreviewUrlResponse — A preview URL for an app, and the sandbox serving it.
  - `preview_url` string, required — URL that serves the app as it currently stands in the app editor, including changes that haven't been published. Open it in a browser or an iframe.
  - `preview_token` string, nullable — Short-lived token the preview URL needs to authenticate against the preview proxy. Treat it as a credential and don't share it, because anyone holding it can load the app before it is published.
  - `sandbox_info` SandboxInfo, required — Metadata about the sandbox serving this preview URL.
    - `cold_start` boolean, required — Whether a new sandbox was started for this request. A value of `false` means an already running one was reused, which is why a repeat call is much faster.
    - `restored_from_snapshot` boolean, required — Whether the new sandbox was restored from a snapshot rather than built from scratch. Always `false` when `cold_start` is `false`.
    - `timeout_timestamp` string, nullable — When the sandbox shuts down if nothing touches it, as an ISO 8601 timestamp, or `null` when the sandbox already existed, because reusing it does not change its timeout.
  - `proxy_pooled` boolean, nullable — Telemetry only: the preview proxy's connection-pooling rollout arm this app is in, so client-side preview metrics can be split by arm. None when the preview does not go through the platform proxy at all (imported apps).
  - `bridge_injected` boolean — Whether the preview host injects the builder bridge. False when the platform proxy is disabled and the preview falls back to the sandbox's own host, so the editor knows the bridge's mount/paint signals will never arrive and must not wait for them.

## Other responses

- `401` — Missing or invalid credentials.
- `403` — You don't have access to this app.
- `404` — App not found.
- `409` — The app's development server couldn't start, usually because its code doesn't build.
- `500` — The preview couldn't be produced.

## Changes

- **2026-08-30** `394136a6cdd4` — 1 info
  - removed the non-success response with the status `422`
- **2026-08-27** `31ef75eb64ab` — 2 info
  - added the optional property `bridge_injected` to the response with the `200` status
  - added the optional property `proxy_pooled` to the response with the `200` status
- **2026-08-24** `a58b38664ce9` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/idealspot/apis/base44-app-management-api/changes/api/apps/:app_id/sandbox/preview-url/get.md)

---

[API](https://skmtc.dev/idealspot/apis/base44-app-management-api.md) · [All operations](https://skmtc.dev/idealspot/apis/base44-app-management-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/idealspot/base44-app-management-api/revisions/394136a6cdd4/schema)
