> ## Documentation Index
> Fetch the complete documentation index at: https://docs.judt.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Previews and access

> Share a running sandbox with a preview link, and control who can open an App.

Judt separates access to your development **sandbox** from access to your published **production** App:

* **Sandbox previews** let you and your agents test uncommitted code on the sandbox dev server through a short-lived signed URL.
* **Production visibility** (`public`, `password`, or `private`) controls who can open your published App at `https://<slug>.judt.dev` or its custom domain.
* **Visitor tokens** let scripts, webhooks, and agents call a `password` or `private` production App without an interactive browser sign-in.

## Sandbox preview links

A sandbox is always private to your organization. To open or test the sandbox's live dev server (`celld dev`), call `POST /api/apps/{id}/preview`:

```bash theme={null}
curl -X POST https://api.judt.ai/api/apps/$APP_ID/preview \
  -H "Authorization: Bearer $JUDT_API_KEY"
```

When you call `POST /api/apps/{id}/preview`, Judt does the following:

1. Starts the sandbox if it is stopped.
2. Starts `celld dev` on port `3000` (if not already running) and waits for the bundler to build your entry module.
3. Returns a signed preview URL that is valid for 5 minutes. The `expires_at` field says when the URL stops working:

```json theme={null}
{
  "url": "https://PREVIEW_HOST/__judt/access#token=eyJhbGci...",
  "expires_at": "2026-10-15T20:35:00.000Z"
}
```

When you open `url` in a browser, the preview gateway reads the `#token=` fragment, sets a 5-minute session cookie on the preview subdomain, and serves your App from the sandbox dev server.

> [!NOTE]
>
> If your code has a syntax or bundler error, `POST /api/apps/{id}/preview` returns `422 preview_failed` with the compiler error output in `error.detail`. See [Test on the dev server](https://docs.judt.ai/build/dev-server.md).

## Production visibility

You control who can open the published production App through the `production` object on `POST /api/apps` or `PATCH /api/apps/{id}`. Only organization `owner` and `admin` roles can change production visibility.

| `visibility` | Who can open the published App |
| - | - |
| `public` (default) | Anyone on the internet with the App's URL. |
| `password` | Visitors who enter the App's password (`8` to `128` characters), or members of the App's organization who sign in with Judt. |
| `private` | Only members of the App's organization who sign in with Judt. |

Both `password` and `private` sign-ins grant a **60-minute** browser session on the App.

### Set password protection

To require a password on a published App, send `visibility: "password"` and a `password` (`8` to `128` characters) to `PATCH /api/apps/{id}`:

```bash theme={null}
curl -X PATCH https://api.judt.ai/api/apps/$APP_ID \
  -H "Authorization: Bearer $JUDT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "production": {
      "visibility": "password",
      "password": "correct-horse-battery-staple"
    }
  }'
```

The API never returns the password in responses; instead, `production.password_updated_at` records when the password was last set. Setting a new password immediately invalidates existing browser sessions that signed in with the old password.

To change the password, pass a new `password`. If the App moves to another visibility, Judt deletes the password. To go back to `password` visibility, send a new password. If you do not, the API returns `400 password_required`. If you send a password with another visibility, the API returns `400 password_not_applicable`.

### Restrict to organization members

To restrict the published App to members of your organization, set `visibility` to `"private"`:

```bash theme={null}
curl -X PATCH https://api.judt.ai/api/apps/$APP_ID \
  -H "Authorization: Bearer $JUDT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "production": {
      "visibility": "private"
    }
  }'
```

When a visitor opens the App URL in a browser, Judt redirects them to sign in and verifies that they belong to the App's organization.

## Short-lived visitor tokens

When a published App uses `password` or `private` visibility, automated callers—such as agents, curl scripts, or webhook tests—cannot complete an interactive browser sign-in. Any organization member (including `member` roles) can create a 5-minute visitor token for a published App by calling `POST /api/apps/{id}/visitor-tokens`:

```bash theme={null}
curl -X POST https://api.judt.ai/api/apps/$APP_ID/visitor-tokens \
  -H "Authorization: Bearer $JUDT_API_KEY"
```

The API returns a short-lived token (`expires_at` is 5 minutes in the future):

```json theme={null}
{
  "token": "eyJhbGciOiJFUzI1NiIs...",
  "expires_at": "2026-10-15T20:35:00.000Z"
}
```

If the App is not currently published, `POST /api/apps/{id}/visitor-tokens` returns `409 app_unpublished`. A public App ignores the token.

### Use a visitor token

You can send the visitor token to the published App in two ways:

1. **`X-Judt-Access-Token` request header (recommended for scripts and agents)**:
   ```bash theme={null}
   curl https://customer-portal.judt.dev/api/items \
     -H "X-Judt-Access-Token: $VISITOR_TOKEN"
   ```
   Using `X-Judt-Access-Token` authorizes the request at the Judt edge while leaving the `Authorization` header free for your App's own authentication logic.
2. **`?access_token=` URL query parameter (for browsers)**:
   ```text theme={null}
   https://customer-portal.judt.dev/?access_token=TOKEN
   ```
   On a `GET` or `HEAD` request, the edge verifies the query parameter, sets a session cookie for the App, and redirects (`303 See Other`) to the clean URL without `access_token` in the address bar.

## Next steps

* Learn how to test your code in the sandbox in [Test on the dev server](https://docs.judt.ai/build/dev-server.md).
* Publish or unpublish an App in [Publish and unpublish an App](https://docs.judt.ai/manage/guides/publish.md).


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