Busabase

Publish an AirApp as a Website

Use the Website engine to put an AirApp at a public address that stays online, connect your own domain, and let the site read and write the workspace through the Busabase API.

The other three AirApp engines (In browser, This machine, Cloud sandbox) run only while someone has the app open. The Website engine is different: once it is live, the app stays online at a fixed address, and anyone can open it without signing in. Use it for anything people outside your workspace should see: a shop, a landing page, an enquiry form.

A website can have pages and its own backend endpoints. It runs on Cloudflare Workers.

Before you start

  • Plan: on Busabase Cloud, Plus or higher. On the Free plan, Website shows an upgrade prompt in the engine picker.
  • Self-hosted: an administrator has to configure the Website engine first. Until then, Website is greyed out in the picker with the reason. Self-hosted has no plan limit, but needs a valid licence.
  • The app itself: its airapp.json has to ask for the Website engine. Ask your agent to follow the busabase-app-creator skill; it knows how.

Preview and go live

  1. Run: open the app. With the Website engine, running it makes a preview that only members of the workspace can open.
  2. Go live: when the preview looks right, click Go live in the toolbar. What goes live is the version you just previewed, and the status changes to Live.
  3. After changing files: run the app again and check the new preview before you go live. Otherwise you will see "The files changed after this preview. Run it again, then go live." and the live site keeps the old version.

If the toolbar shows Unpublished changes, the preview is newer than what is live.

Let your agent publish

Your agent can do the same steps without you clicking, through the Busabase CLI, the API or MCP, with your own permission (write access to the app):

busabase-cli airapps site-state --node-id <app id>            # what is live, and whether the files changed
busabase-cli airapps site-deploy-preview --node-id <app id>   # Run: a new members-only preview
busabase-cli airapps site-go-live --node-id <app id>          # Go live: publish that preview

site-unpublish and site-republish turn the Public switch off and on; site-domains, site-bind-domain and site-unbind-domain manage custom domains. The same actions are /api/v1/airapps/{nodeId}/site… in the API and airapps_site_* tools in MCP.

Going live is still your decision: an agent publishes only when you ask, and tells you the address first. It cannot publish files you have not previewed: if the files changed after the preview, Go live answers preview-stale and nothing changes.

Address and the Public switch

The app's Settings show the site's Address and a Public switch:

  • Public on: anyone with the address can open it.
  • Public off: the site goes offline at once and the address shows a not-found page. Turn it back on to restore it; no need to go live again.
  • Moved to Trash: the site goes offline. After restoring the app from Trash, turn Public back on.
  • Deleted permanently: the site and its address are deleted with the app.

Custom domains

Once the site is live, it can also open at a domain you own, such as shop.company.com. The Custom domains section is in the app's Settings, under the address and the Public switch.

Before you start

  • The site is live. Until it is, the domain box is greyed out with "Go live first, then add your domain." Open How to set up DNS in the panel to see the record you will need, so you can prepare your DNS early.
  • You can change the domain's DNS. That is usually where you bought the domain, or wherever its DNS is hosted: Cloudflare, GoDaddy, Namecheap, Route 53 and so on.
  • A subdomain is easiest. shop.company.com or www.company.com takes a plain CNAME. For company.com itself, see Root domains.

Connect a domain

  1. Add the domain: type it into Domain name, without https:// or a path, and click Add domain. It shows as Setup pending, with the exact records to create.

  2. Create the CNAME record at your DNS provider:

    FieldWhat to enter
    TypeCNAME
    Name (some providers say Host)The part before your root domain: shop for shop.company.com. The panel shows the full name; some providers want that instead.
    Value / targetThe target shown in the panel. Use its copy button: it is specific to this deployment.

    If the same name already has an A, AAAA or CNAME record, delete it first. A name can only point one way.

  3. Add any other record listed: if the panel also lists a TXT record or an HTTP verification, create it exactly as shown. Keep the other records your domain needs, such as MX for email.

  4. Check again: come back and click Check again. DNS changes can take a few minutes to a few hours. Once the domain resolves, HTTPS is set up automatically and the status changes to Connected. The toolbar's open button then uses your domain, and the default address keeps working.

If your DNS is on Cloudflare, you can turn on proxying (the orange cloud) once the status is Connected.

Root domains

A root domain such as company.com can only take a CNAME if your DNS provider supports one at the root, under a name such as CNAME flattening, ALIAS or ANAME. Cloudflare does this automatically. If your provider does not, connect www.company.com instead and, if your provider offers URL forwarding, forward company.com to it.

What the status means

StatusMeaning
Setup pendingThe domain is added, but its DNS does not reach the site yet, or HTTPS is still being prepared. Compare your records with the panel, then check again later.
ConnectedDNS and HTTPS are ready.
Needs attentionSomething failed. Read the details under the domain, fix it, then check again.

Turning Public off takes the site offline at every address, custom domains included. If the space's plan no longer includes Website, you cannot add domains, but you can still see and remove the ones you have.

Remove a domain

Click Remove next to the domain, then Remove domain. The domain stops opening the site and the default address keeps working. You can then delete the DNS record.

Let the site read and write Bases

The site's backend (its Worker) reads and writes the workspace through the Busabase API, the same API and permissions that agents, the CLI and the SDK use.

The key the site gets

Every run and every Go live gives the site an API key:

  • Whose it is: the live site's key belongs to the person who clicked Go live, and the preview's to the member who ran it. The site can never do more than that person can in the workspace.
  • What it can do: the level the app's airapp.json asks for: read only (the default), propose changes, or write. Going live is the consent; there is no other approval.
  • Where it works: in this workspace only. It is refused in that person's other workspaces, and it cannot read their personal Vault values.
  • Where to see it: in that person's API key list, named Site: <app name> (Site preview: <app name> for the preview). Deleting it there cuts the site off until the next Go live.

The preview gets its own key at the same level and works on the workspace's real data, as the other engines do.

When it stops

  • Public turned off, or the app moved to Trash: the live key is disabled at once. Turning Public back on restores it.
  • App deleted permanently: its keys are deleted too.
  • The person who went live leaves the workspace: the key stops working. Someone with access runs the app and goes live again.
  • Every Go live: a new key replaces the old one.

The site's changes go through change requests like any API write, and the history names the key.

The site's code decides what a stranger can reach

The key can read and write everything its level allows its owner in this workspace, not just the Bases the site uses. A stranger never sees the key; they can only use it through whatever the site exposes. So have your agent follow the busabase-app-creator skill: expose specific endpoints, and never pass a visitor's request through to the API. If the site does not need to write, leave it read only. There is no CAPTCHA yet, so a public form can be spammed.

On this page