# Sites & access A **site** is a named container served at `https://.interfold.site`. It attaches to an account-owned bucket and interprets its web files, functions, cron sources, and runtime data. Buckets also work without a Site. This page covers creating sites, subdomains, and the access model that decides who can see what. ## Creating and selecting sites ```sh interfold sites create --name "My Site" --access PUBLIC interfold sites list --status ACTIVE interfold sites get ``` Site creation creates a bucket automatically. To attach existing storage: ```sh interfold buckets create --name "My files" interfold sites create --name "My Site" --bucket interfold files put ./notes.md /notes.md --bucket ``` Each bucket supports at most one Site. Directory locations are fixed: `/web`, `/api`, `/cron`, and `/data`. Other files remain private storage. Pass `--site ` as a convenience for file commands, or select storage with `--bucket `. ### Site creation limits Site creation is limited per account: - **Free:** 10 sites. - **Builder:** 10K sites. - **Platform admins:** no site cap. The site cap applies when creating a new site. Existing sites remain available when an account's subscription status changes. ### Subdomains Each site gets a subdomain, returned by `sites create` and `sites get`. Always read it from the API — never infer it from the display name. Build hosted URLs as `https://.interfold.site/`. Only files under the workspace `/web/` directory are browser-hosted. The `/web/` prefix is omitted from hosted URLs: `/web/index.html` serves at `/`, and `/web/pricing.html` serves at `/pricing.html`. Web files are served verbatim. ## The access model Buckets are account-owned storage. Reading or writing through the Files API always requires account authentication. Attaching a Site does not make the bucket, its object API, or arbitrary stored objects public. The Site's `access` setting controls only browser-hosted `/web/` files: | Site access | Anonymous `/web/` access | `/api/` runtime | | ----------- | ------------------------- | --------------------- | | `PUBLIC` | Anyone | Anyone can invoke it | | `PRIVATE` | Signed-in account members | Anyone can invoke it | ```sh interfold sites update --access PUBLIC interfold sites update --access PRIVATE ``` There are no per-file access overrides. New uploads, replacements, and renames under `/web/` follow the Site's access setting. Private Sites show a sign-in gate for web files. Functions own their authorization. A deployed `/api/` runtime is anonymous for both Site settings, so a handler that protects content must check its own cookie, token, signature, or other credential and return its own `401` or `403`. Do not use `PRIVATE` Site access as function authorization. ## What is never public These resources are always account-private, regardless of Site access: - **Function source** at `/api/*.ts` — the code is not served as a static file. Its separate runtime endpoint (`/api/`) is callable, but source remains available only through authenticated account tooling. - **Cron source** at `/cron/*.ts` — scheduled handler code has no public runtime URL. See [Cron Jobs](/cron-jobs). - **Data files** under `/data/*` — written through `ctx.data`, never served on the web. - **Database and migration assets** — database state and project migration files are never hosted as site objects. - **Other bucket objects** — use the authenticated Files or Bucket API; attaching a Site does not create a public-object feature. Inspect these with authenticated tooling: ```sh interfold files ls /data --site interfold files cat /data/state.json --site ``` ## Verifying a publish Don't trust a publish until you've checked the live URL: ```sh interfold files stat /web/index.html --site interfold sites get curl -I https://.interfold.site/index.html curl -I https://.interfold.site/ # for the homepage, check root too ``` --- Next: [Functions](/functions) · [Cron Jobs](/cron-jobs) · [Databases](/databases) · [Data files](/data-storage) · [Secrets](/secrets)