Skip to content

Preview links

A preview is a version of your app at an address of its own. The live version keeps serving everyone as it was. When the preview looks right, promote it and it goes live as it is.

Previews are on every plan. They work for Worker apps and static sites that already have a version live. Container apps can’t have one yet, and neither can an upload from the dashboard.

Terminal window
forculus deploy acme/hello --preview
Version 5 (3f2a9c1d0b7e) is up as a preview. The live version is as it was.
https://p-4c1f9a2e--hello--acme.forculuslabs-apps.tech/
Only people acme/hello is shared with can open it, until 2026-10-09 or the app's next preview. To make it live, run `forculus promote acme/hello 5`.

With --json, url is the preview’s address and live_url the live app’s.

The address starts with p- and eight random characters, so it can’t be guessed from the app’s name. It answers like the app’s own address: people sign in, and only the people the app is shared with get in. A preview is never more open than its app. Taking someone’s access to the app away takes their access to its previews away too, within 60 seconds.

A preview uses the app’s current environment variables, secrets and database. Code in a preview that writes to the database writes to the live app’s data.

A preview answers for 7 days. Each app has one preview of its own at a time, so the app’s next preview replaces it, whoever puts it up. Pull requests’ previews are kept apart: each pull request has its own, and none of them replaces another or the app’s. A preview also stops answering when whoever put it up can no longer edit the app, and it ends for good: giving them edit access again doesn’t bring it back. After that, its address answers 404 as an address with no app, and we delete what it ran. In a browser it says previews end and that the app’s Versions tab lists the ones still open, the same page anyone gets on a preview address they can’t open.

The version stays in the list either way, and you can still promote it while its build is kept.

To stop a preview answering before then, end it by its version:

Terminal window
forculus preview end acme/hello 5
Ended version 5's preview. Its address no longer answers, and the live version is as it was.

Its address answers 404 from then on, and we delete what it ran. Like a preview that ran out, it stays in the list and can still be promoted. Ending one that had stopped answering already changes nothing and says so. The Versions tab has an End preview button beside each preview that’s still open.

Each preview you put up is a version of the app, and counts toward the newest 20 versions we keep. Twenty previews in a row push older versions out, versions that were live before included, and those can’t be rolled back to or promoted any more. The version live now is always kept.

Terminal window
forculus versions acme/hello
5 deployed 2026-10-02 you@example.com (preview until 2026-10-09: https://p-4c1f9a2e--hello--acme.forculuslabs-apps.tech/)
4 deployed 2026-10-01 you@example.com (live)
3 deployed 2026-09-30 you@example.com (preview, ended)

The app’s Versions tab in the dashboard shows the same, with the preview’s link beside its version and a Promote button.

forculus curl and forculus open take --preview with the preview’s version:

Terminal window
forculus curl acme/hello /api/items --preview 5
forculus open acme/hello --preview 5

forculus open prints the preview’s address. forculus curl sends the request as you, through the apps domain, to https://forculuslabs-apps.tech/acme/p-4c1f9a2e--hello/api/items, the preview’s own address laid out as a path. It lets in exactly the people the app is shared with, as the preview’s address does in a browser. Only someone who can deploy the app can look a preview up by its version. Anyone else the app is shared with gives forculus curl the address instead, and forculus open takes one too:

Terminal window
forculus curl acme/hello /api/items --preview https://p-4c1f9a2e--hello--acme.forculuslabs-apps.tech/

A preview never takes a bypass token or an agent’s credential, even one the live app takes. A preview is code nobody has made live yet, so only a person reaches it. A preview that ended answers 404, as an app that isn’t there does. If it ends while forculus curl is reading from it, forculus curl says the preview ended and exits with code 1.

Terminal window
forculus promote acme/hello 5
Version 5 is live.
https://hello--acme.forculuslabs-apps.tech

Promoting is a rollback to the preview’s version: it goes live as it is, for everyone using the app, within a minute or two. Its preview address keeps working until it runs out, and forculus versions shows both, like (live, preview until 2026-10-09: https://p-4c1f9a2e--hello--acme.forculuslabs-apps.tech/). forculus promote only takes a preview. For any other version, run forculus rollback.

With deploys from GitHub Actions set up, an owner of the app can turn on previews of pull requests, naming the GitHub environment their runs deploy in. Each pull request in the repository then gets a preview of its own, commented on the pull request, which ends when the pull request closes. A fork’s pull request never gets one. Your plan sets how many pull requests in the workspace have one at a time: 3 on Free, 10 on Team and 25 on Business. They don’t count toward the newest 20 versions.

In forculus versions they read as (preview of pull request #7 until 2026-10-09: https://p-...), and the Versions tab names the pull request beside the link. To end one before its pull request closes, by the pull request or by its version:

Terminal window
forculus preview end acme/hello --pull-request 7
forculus preview end acme/hello 6

Ended, a pull request’s preview loses its build, as it does when the pull request closes, so it can’t be promoted after.

The deploy_app tool takes preview: true. The agent gets the preview’s address back, and calls rollback with the version’s number to make it live. call_app takes preview, the version’s number or the preview’s address, to read the preview as you before anyone looks. end_preview ends a preview by its version, or a pull request’s by its pull_request.

Putting up, promoting and ending a preview take an editor or owner of the app, or a workspace admin or owner. Each is recorded in the audit log, and so is every request to a preview’s address.