# Preview URLs

> Every sandbox has its own HTTPS address on nanite.page, open to anyone or only to your workspace, that wakes it and can start its server.

Each sandbox gets one address on nanite.page. Requests to it go to port 8080 inside the sandbox, so a web app an agent builds can be opened in a browser and shared.

```text
https://agent-1-wb7xkq2l.nanite.page
```

The address is in the `url` field of the sandbox. A request to it wakes the sandbox when it is asleep. A sandbox with a name longer than 54 characters has no address, and its `url` is `null`.

## Who can open it

`url_settings.auth` decides:

| Value     | Who                                                                              |
| --------- | -------------------------------------------------------------------------------- |
| `sandbox` | The default. Members of your workspace, signed in, or a request with an API key. |
| `public`  | Anyone with the address.                                                         |

Set it when you create the sandbox:

```json
{ "name": "agent-1", "url_settings": { "auth": "public" } }
```

Or change it later:

```bash
curl -X PUT $API/agent-1 -H "$AUTH" -d '{"url_settings": {"auth": "sandbox"}}'
```

A browser that opens a `sandbox` address is sent through the SuperHQ console to sign in, then back. A program sends `Authorization: Bearer` with an API key of the workspace; the key is not passed on to the sandbox.

## Start command

Processes do not survive a stop, so a server that ran before the sandbox went to sleep is gone when a request wakes it. Give the sandbox a start command and the URL brings the server back on its own:

```json
{ "url_settings": { "start": ["/srv/app/start"] } }
```

`url_settings.start` is a command as [exec](https://nanite.run/docs/exec.md) takes it: 1 to 64 strings, the first not empty, at most 16 KiB in all. The URL runs it:

- before the request, when the sandbox is not running,
- when nothing answers on port 8080, and then sends the request again.

The command should start the server in the background and return, and do nothing when the server is up already. It has 30 seconds. A request body is kept for the second try up to 16 MiB; a larger one answers `413`. Set `start` to `null` to remove it.

## Hold

A held sandbox stays stopped. Its URL answers `503` with a page saying it is stopped by its owner, and nothing wakes it until you release it. See [Hold a sandbox](https://nanite.run/docs/sandboxes.md#hold-a-sandbox).

## Limits

| What                    | Limit             | Answer                   |
| ----------------------- | ----------------- | ------------------------ |
| Requests to one address | 300 in 10 seconds | `429` with `Retry-After` |
| Request body on a retry | 16 MiB            | `413`                    |
| Start command           | 30 seconds        |                          |

## Things to know

- A request that wakes a sleeping sandbox spends the credits of its workspace, whoever sent it. Use `sandbox` auth, or [hold](#hold) the sandbox, to keep strangers from waking it.
- Only port 8080 is served. Have your app listen on `0.0.0.0:8080`.
- Treat a public sandbox as a public website: anyone can reach what it serves.
