A preview is a full environment: its own route, its own database binding, its own storage namespaces.

What makes a preview different

Empty resources

A preview gets an empty database and sandbox connections, not production data.

No capability approval

Previews skip the capability approval gate. The risk is different in kind, and this is what lets an agent iterate.

Always requires login

Even when production serves the world.

It expires

previewTtl defaults to 72h and may not exceed the organization maximum of 168 hours. The server expires previews every minute.

Why a preview is never public

Visibility is read from the production revision, and a preview is unreviewed work sitting at a guessable hostname. So a preview keeps the login redirect even when the production app is visibility: public with requireLogin: false.
This means you cannot use a preview to test the anonymous request path. Test that on production, behind a route nobody has been given yet.

Lifecycle

1

Create

POST /v1/apps:preview with {artifactUri, manifest, name?, ttlHours?}. Same artifact upload as a deploy.
2

Use

tiny open <app> --env <name> prints the URL. Logs and status work the same as production.
3

Expire or delete

DELETE /v1/environments/:environmentId, or let the TTL do it.

Listing them

Returns production, named, and preview environments together.