> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fluid.app/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> For new direct REST integrations, use the v2026-04 surfaces. The @fluid-app FairShare SDK continues to use its own published public-v2025-06 contract.
> Authenticate with the header Authorization: Bearer <token>; public storefront read endpoints require no auth.
> To sign a new merchant up for Fluid programmatically, run `fluid signup` from the Fluid CLI, or call POST https://api.fluid.app/api/company with no credentials, as described in /api/agent-signup. Do not automate the signup form or book a demo. Before authenticated calls are possible, the merchant must sign the agent in to the Fluid CLI with the emailed code and --shop set to the company's fluid_shop (which also confirms the signup), or open the emailed confirmation link and give the agent an API token.
> After signup, to launch a merchant's store (back-office sync, payments onboarding, store setup, a theme copied from their current site, and a preview link before billing), follow /api/agent-launch.
> Lists use cursor pagination via the page[cursor] and page[limit] query params; follow meta.pagination.next_cursor until it is null.
> When the same operation exists on more than one surface, use the newest: dated API versions are newer than unversioned ones, and later dates win (v2026-04 > v2025-06 > unversioned v0/v1.1). Fall back to a legacy or unversioned operation only when no newer versioned equivalent exists — the company-v0 notes below list the known superseded operations. The same applies to /api/company/v1 and /api/v1/... paths: prefer a newer documented equivalent, and use one only when none exists (/api/v1.1/... is distinct and documented in company-v0). Use page/per_page offset pagination only on an operation whose spec documents those params — mostly the unversioned company-v0 admin surface, plus some lists on other surfaces, versioned ones included; page every other list with cursors.
> Fluid has three navigation APIs; don't mix them up. Storefront website menus (navigation bars, footers) are /api/menus and nested menu_items, in api-reference/content-v0.yaml (API Reference: Website > Navigation menus), with a how-to in themes/navigation-menus; their list uses flat page/per_page pagination. The Fluid mobile app's navigation is /api/v2/mobile_navigations, in api-reference/mobile-v2.yaml (API Reference: Mobile app > Navigation); its list also uses page/per_page. Portal navigations belong to a portal definition (Fluid OS), in api-reference/fluid-os-v0.yaml (API Reference: Portal > Portal navigation), and each has a platform of web or mobile.
> The OpenAPI specs under api-reference/ are the authoritative contracts; prefer them over prose when in doubt. api-reference/storefront-v2026-04.yaml covers the v2026-04 storefront surface (/api/v202604/... paths); api-reference/checkout-v2026-04.yaml covers the v2026-04 checkout surface (/api/checkout/v2026-04/... paths — carts, cart auth, discounts, items, subscriptions, orders, enrollments, and store config); api-reference/public-v2025-06.yaml covers the Public SDK surface used by the @fluid-app FairShare SDK, including its parallel cart lifecycle, browser integrations, versioned payment callbacks, unversioned public utilities, and the cart price-override operation; api-reference/payment-v2026-04.yaml covers the v2026-04 payment gateway admin surface (/api/payment/v2026-04/... paths, bearer-authenticated — gateway CRUD, gateway purchase/authorize/$0-verify, transaction list/show and capture/void/credit, and merchant payment configuration); api-reference/payments-v2026-04.yaml covers the v2026-04 cart payment surface (/api/payments/v2026-04/carts/{cart_token}/... paths, authenticated by the cart token in the path with no bearer — payment-method selection, VGS card tokenization, 3D Secure verification, and PayPal/Braintree/Klarna/Apple Pay flows); api-reference/commerce-v2026-04.yaml covers the v2026-04 commerce order-editing surface (/api/v202604/orders/{order_id}/edits paths, bearer-authenticated — post-checkout order edits that atomically insert items and add adjustments/discounts, with an optional dry-run preview); api-reference/webhooks-v0.yaml covers the unversioned webhooks surface (/api/... paths — webhook registration, delivery payloads, callback registrations, company events, and webhook/callback schemas); api-reference/company-v0.yaml covers the legacy unversioned company admin surface (/api/... paths, bearer-authenticated except two operations that take no credential, POST /api/company (create a company) and GET /api/agreements/{id} — company settings and management, customers, users, roles, subscription plans, subscription bundles, subscriptions, media, pages, catch-ups, inventory levels, domains, agreements, and admin order actions). company-v0 caveats: it is the legacy v0 admin contract and its lists use flat page/per_page offset pagination, which is expected there despite the general cursor-pagination rule; where an operation exists in both company-v0 and a versioned spec, prefer the versioned spec — the subscriptions lifecycle (list/create/show/update, cancel, pause, reactivate, resume, retry, skip, failed-cycle-waiver, discounts) and subscription bundles are superseded by checkout-v2026-04, and company pages/media CRUD plus the public pages, categories, products, and media list endpoints are superseded by storefront-v2026-04. Subscription plan management (/api/subscription_plans, resource-wrapped {"subscription_plan": {...}} bodies) exists only in company-v0. api-reference/members-v2025-06.yaml covers the v2025-06 unified Member identity surface (/api/v2025-06/members/... paths, bearer-authenticated — member list/create/show/update, lookup by email/username/external_id/legacy_customer_id, member-type assignment, and the sponsor genealogy read). Prefer it over the customers and reps surfaces when the member type matters: /customers does not serialize member_type. api-reference/analytics-v2026-04.yaml covers the v2026-04 Home dashboard analytics surface (/api/v202604/analytics/dashboard/... paths, bearer-authenticated — read-only endpoints for the Home > Overview, Home > Live, and Home > Field tabs, each accepting an optional country ISO alpha-2 query param that scopes aggregations to a single country).
> api-reference/analytics-v0.yaml covers the unversioned analytics surface that backs the fluid-admin Traffic tab (/api/analytics/... and /api/analytics/traffic/... paths, bearer-authenticated — the legacy shares/views/visitors summary plus traffic overview, ranked campaigns, sources, geographies, flows, and per-rep breakdown, all sharing one reporting-period contract).
> Successful responses wrap the resource payload alongside a top-level integer status and a meta object.
> Portal Definition authoring edits and synchronizes the portal JSON resource graph. Widget Package authoring builds either a company-owned or Droplet-owned Remote DOM package. These are separate contracts; do not imply that one defines the other.
> For Widget Package worker code, use only @fluid-app/portal-sdk/widgets/worker. Use only the Portal Definition and Widget Package workflows and public entry points documented here; do not infer support for undocumented surfaces.
> Every portal function and declarative capability used by a widget must appear in that widget's uses array. Use the same typed function value in uses; do not invent capability-name strings.
> Widget styling must use the portal's semantic theme variables for colors, typography, spacing, radii, borders, focus, and charts whenever a token represents the visual decision. Do not create a separate light or dark palette or duplicate theme controls as widget properties.
> Prefer worker-safe Fluid UI components exported by @fluid-app/portal-sdk/widgets/worker when they fit the interaction. When no exported component fits, use semantic HTML, accessible behavior, and the portal theme variables.
> A Portal Definition push updates the remote working definition. A portal version is an immutable snapshot, and activation is a separate live release operation.
> The Help Center (/help/...) is for merchants, admins and reps using Fluid. Its admin pages mirror the admin's routes: the screen at admin.fluid.app/settings/taxes is documented at /help/admin/settings/taxes. Use the Help Center for how-to questions about the admin, and the Developer Platform and API Reference for building integrations.
> Help Center pages describe what a company admin sees. A reader's role can hide screens and actions; admins manage roles on Settings > Roles (/help/admin/settings/roles). If someone can't find a screen or button, their role's permissions are the first thing to check.
> Send people who need Fluid support to /help/getting-help. Don't invent support email addresses, phone numbers or response times.

# Member site CLI

> Create, pull, edit, preview, lint, push and publish member sites from the terminal with fluid member-site, for a member's own sites or the company's sites.

The `fluid member-site` commands build a [member site](https://docs.fluid.app/member-sites/overview.md) from a folder on your computer. They use the [member API](https://docs.fluid.app/api-reference/sites/add-a-site.md) for a member's own sites and the [company API](https://docs.fluid.app/api-reference/member-sites/create-a-company-site.md) for the company's sites. A site's folder is its files, so you can edit it with any editor or agent, check it with `lint`, and see the draft with `dev` before anyone else can.

`fluid member-site` is not `fluid mysite`, which works on MySite themes, and it is not `fluid theme`, which works on storefront themes. It covers building and publishing. For versions, branches, shares, pins, a home site and featuring, use the APIs: see [Build member sites with the APIs](https://docs.fluid.app/member-sites/apis.md).

## Install and sign in

Install the Fluid CLI and the member site plugin from npm:

```bash theme={null}
npm install -g @fluid-app/fluid-cli @fluid-app/fluid-cli-member-site
```

The plugin needs the core CLI. It keeps no credential of its own and uses the core CLI's login, profiles and `.fluidrc`, so `FLUID_TOKEN`, a project's `.fluidrc` profile and the active profile apply as they do for every other command.

### Choose the login

The login follows the owner of the site.

| Site owner | API | Login |
| - | - | - |
| A member | `/api/member/v2026-10/sites` | The member's own login |
| The company | `/api/company/v2026-10/member-sites` | A signed-in admin who may change themes |

* **Admins and reps** sign in with `fluid login`.
* **A member** signs in to these commands with the member's own token, set in `FLUID_TOKEN`. `fluid login` doesn't sign members in. See [Credentials](https://docs.fluid.app/api/member-apis.md#credentials) for what counts as a member's token.
* **A member who is also an admin** of the same company is refused by the member API, so that login builds company sites only.

The CLI stores a token and doesn't record whose it is, so it can't tell a member's token from an admin's before it sends a request. Say which it is with `--as member` or `--as admin`. A site of the other owner kind is then refused before any request, and the message names the login it needs. Without `--as`, the server decides, and a refusal names the login the site needs.

### Set the API base

The API base follows the login. The CLI uses `FLUID_API_BASE` when it's set, and otherwise the base the stored profile was made for (a `.fluidrc` profile, then the active one). There is no default base. A token from `FLUID_TOKEN`, or a profile with no recorded base, needs `FLUID_API_BASE`:

```bash theme={null}
export FLUID_API_BASE=https://api.fluid.app
export FLUID_TOKEN=<member token>
fluid member-site list --as member
```

With neither a base nor a profile, a command stops with "No API base for this login: run `fluid login` or set FLUID\_API\_BASE" before it makes any request.

## Build a site

This walks one site from creation to publication. It builds a member's own site, so it uses `--as member`. For a company site, add `--company` to `create` and use `--as admin`.

**1. Create the site**

```bash theme={null}
fluid member-site create rileys-shop --name "Riley's Shop" --as member
```

The site starts as a draft.

**2. Pull it into a folder**

```bash theme={null}
fluid member-site pull rileys-shop --as member
cd rileys-shop
```

**3. Edit and lint**

Edit the files, then check the folder. `lint` sends no request.

```bash theme={null}
fluid member-site lint
```

**4. Preview the draft**

```bash theme={null}
fluid member-site dev
```

Open `http://127.0.0.1:9500`. `dev` saves each change as a draft and serves the draft. It refuses to run against the production API unless you pass `--allow-production`: see [dev](#dev).

**5. Push and publish**

```bash theme={null}
fluid member-site push --dry-run
fluid member-site push --publish
```

The dry run prints what a push would send. The second command pushes, then publishes once.

## Commands

Every command except `lint` can take `--as member` or `--as admin`.

### list

```bash theme={null}
fluid member-site list
fluid member-site list --as member
```

With a member login, `list` shows the member's own sites. With an admin login, it shows every site in the company with its owner and status. Without `--as`, the CLI tries the company API first and the member API when the company API refuses the login.

A member's site shows as read-only to an admin, because its owner builds it.

### create

```bash theme={null}
fluid member-site create rileys-shop --name "Riley's Shop"
fluid member-site create fall-launch --company --as admin
```

`create <handle>` makes a site as a draft. The handle is lowercase letters, digits and single hyphens, at most 40 characters. The pages of the site open at `/accounts/<handle>`.

| Flag | What it does |
| - | - |
| `--name <name>` | Sets the site's name. The default is the handle in words |
| `--company` | Makes a company-owned site. It needs an admin login |
| `--as <login>` | Says which kind of login the token is |

### pull

```bash theme={null}
fluid member-site pull rileys-shop --as member
fluid member-site pull fall-launch ./site --as admin
```

`pull <site> [dir]` writes a site into a local folder. `<site>` is the site's handle or id, and `dir` defaults to the handle. Every text file is written at its API path, the pages are written to `config/pages.json`, and a binding file records where the folder came from.

| Flag | What it does |
| - | - |
| `--force` | Writes into a folder that isn't bound to this site, and overwrites local edits |
| `--as <login>` | Says which kind of login the token is |

* **A pull is all or nothing.** It reads every file before it writes any, so a failed read leaves the folder as it was. A file already identical on disk is left alone.
* **It refuses to overwrite your work.** A folder that isn't empty and isn't bound to this site is refused, and so is a pull that would overwrite a file you edited since the last pull. `--force` writes anyway.
* **It never deletes your files.** A file that isn't on the server is kept. The one exception is `config/access.json`: when the site no longer has one and your copy is unchanged since the last pull or push, the pull deletes it, so the next push doesn't bring back a declaration another writer removed. An edited copy is kept unless you pass `--force`.
* **It doesn't write through symbolic links.** A file or folder of the site that is, or is inside, a link is refused before any file is written, with or without `--force`.
* **A member's site can't be pulled with an admin login.** With `--as admin`, or in a folder bound to a member's site, the command stops before any request and names the login the site needs.

### push

```bash theme={null}
fluid member-site push --dry-run
fluid member-site push --as member
fluid member-site push --publish
```

`push [dir]` sends the changes in a pulled folder to its site. Run it in the folder, or pass the folder. The folder's binding names the site and its owner kind, so a member's site goes through the member API and a company site through the company API. A login of the other kind is refused before any request.

| Flag | What it does |
| - | - |
| `--dry-run` | Prints the plan, removals included, and sends nothing |
| `--publish` | Publishes the site once, after every write succeeded |
| `--as <login>` | Says which kind of login the token is |

A push compares the folder with the binding and sends only what changed. A pull followed by a push with no edit sends nothing.

**Versions protect other writers.** Every write and delete carries the version the binding recorded for it, and the server refuses it with `409` if the file or page changed since. A push never overwrites or deletes a copy that moved on the server. A new file is created only if its path is still empty on the server, so a file another writer created since your pull isn't replaced.

**What a push sends, in order:**

1. `config/settings.json`.
2. Each changed or new layout, section, snippet and asset, and `config/access.json`, in path order. On a company site the push leaves `config/access.json` alone and says so, because the server refuses the path.
3. Each new page with its file's content, then each changed page with its changed row fields and content.
4. `config/menus.json`, when it changed. It replaces every menu of the site.
5. Each page's menu assignment.
6. Each removed page, then each removed layout, section, snippet, asset and `config/access.json`. Removals go last, so a failed write never leaves a menu pointing at a page that is gone.

**It refuses before the first request.** A push checks the whole folder first and lists every refusal at once. It refuses:

* A file that isn't a text asset. An asset must be `css`, `js`, `json`, `txt` or `html`, valid UTF-8 and not empty.
* A path outside `layouts`, `sections`, `snippets`, `pages`, `assets` and `config`, a path in a subfolder, a symbolic link, and a name outside lowercase letters, digits, hyphens and underscores. A page's name is lowercase letters and digits separated by single hyphens. Names that start with a dot are ignored.
* A page file with no row in `config/pages.json`, a new row with no file, and a row or file removed without the other. A page goes with its file, so remove both or neither.
* A `config/access.json` that isn't a valid declaration.
* A `config/pages.json` that isn't valid, a page slug of `index`, a menu that `config/menus.json` doesn't define, settings that aren't a JSON object, and menus that don't have the shape the API takes.
* New pages that don't fit in the site's 50-page limit. This check needs the site's current page count, so `--dry-run`, which sends no request, skips it and says so.
* A menu link whose `url` isn't a well-formed `http` or `https` address with a host. A space or non-ASCII character in the address is refused rather than corrected.
* A file the binding holds no version for, which happens after a pull from before the API reported versions. Pull the site again first.

**It stops at the first stale version.** The push names the file or page, tells you to pull, lists what it already wrote, and sends nothing after it. A push isn't atomic, because the API has no batch write, so what it wrote stays written.

**Not everything is sent.** A change to the site's default `layout` in `config/pages.json` isn't sent. The push lists it as not sent.

A page is removed by taking its row out of `config/pages.json` and its file out of the folder. A page renamed in `config/pages.json` is a new page and a removal: the CLI creates the new page first and deletes the old one after it. `config/settings.json` and `config/menus.json` can't be removed. If either is missing, the push says so and leaves the server's copy.

### publish

```bash theme={null}
fluid member-site publish
fluid member-site publish ./rileys-shop --as member
```

`publish [dir]` makes the drafts of the site's layouts, sections, snippets, pages, settings and access declaration the live site. It makes one publish request and sends no file, so a local edit you haven't pushed isn't published. It prints the site's `status` and its new `content_version`.

* **A taken-down site can't be published.** The command prints the API's message, exits with a non-zero code and doesn't retry.
* **A `409` means the site changed while it was being published.** The site wasn't published. Run the command again.
* **A publish moves versions.** It changes the version of every page, layout, section and snippet it publishes, and of the settings. After it succeeds, the CLI records the new versions in the binding only when it can prove the publish published what the folder holds. Anything else keeps its old version, and the next push stops on it and asks for a pull. Push a file you edited before you publish it.

### lint

```bash theme={null}
fluid member-site lint
fluid member-site lint ./rileys-shop
```

`lint [dir]` checks a site folder on disk and makes no request. It needs no login and no binding file, so it works on a folder that was never pulled. A clean folder prints nothing and exits `0`. Any error exits `1`, and each finding names its file. Warnings are printed and don't fail the command.

Lint checks:

* **Liquid** in layouts, sections, snippets and pages, with the same messages as `fluid theme lint`: the `{% schema %}` block and the pairing of block tags such as `{% if %}` and `{% endif %}`. The theme linter's cart, missing-section and routed-template checks are theme rules and don't run.
* **The file rules a push enforces**, with the same messages.
* **`config/pages.json`**, which must be valid and list at most 50 pages. A page with no file still counts.
* **`config/menus.json`**, which must have the shape the API takes. Each link that names a `page` must name a page that `config/pages.json` lists.
* **`config/access.json`**, which must be a file the API accepts. Each problem is an error.
* **Viewer data.** Lint warns on a Liquid file that reads `member.<field>`. When the declaration is valid, it also checks each `fluid.fetch(path, { method })` call in a script against the scope of that path. It warns when the declaration lacks the scope, when no site can ever reach the route, and when it can't read the call, for example because the path or method comes from a variable. See [Declare what a member site uses](https://docs.fluid.app/member-sites/access-declarations.md#check-a-declaration).

### dev

```bash theme={null}
fluid member-site dev
fluid member-site dev ./rileys-shop --as member --port 9600
fluid member-site dev --allow-production
```

`dev [dir]` shows a site's draft while you edit it. It saves each change you make in a pulled folder as a draft and serves the draft on a local port. The server renders the draft with the renderer members get, not a local one.

| Flag | What it does |
| - | - |
| `--port <port>` | Serves on this local port. The default is `9500`. `--port 0` takes a free one |
| `--allow-production` | Lets `dev` save to the production API |
| `--as <login>` | Says which kind of login the token is |

* **It won't write production unless you say so.** A session saves the folder when it starts and again on every change, and some changes are live as soon as they are written. So `dev` stops before it makes any request when the login's API base is production, and names the base and the flag. A local base, a stage base (`*.stage.fluid.app`) and a name under `.test` keep syncing without the flag. Any other base, a custom or unknown host included, is taken for production.
* **It saves drafts and never publishes.** A save is a `push` without `--publish`, with the same plan, refusals and stop at a stale version. Run `fluid member-site publish` when the draft is ready.
* **It starts only when the server can show a draft.** If it can't, `dev` stops with "Draft preview is not available on this server yet" before it saves anything. It never shows the published page in its place.
* **Each change is saved after a short pause.** The command keeps serving when a save is refused, so you can fix the file. Reload the preview to see a save. There is no live reload yet.
* **The preview is at `http://127.0.0.1:<port>`.** `/` is the home page and `/<slug>` is another page. The server listens on `127.0.0.1` only, and your credential stays in the CLI. It never goes into a URL, a page or a header sent to the browser.

## Know the folder

A pull writes this folder:

```text theme={null}
rileys-shop/
  layouts/site.liquid     sections/hero.liquid     snippets/card.liquid
  pages/index.liquid      pages/about.liquid
  assets/site.css         assets/site.js
  config/settings.json    config/menus.json        config/pages.json
  config/access.json      (only when the site declares what it uses)
  .member-site.json
```

The folder is the API: a path here is the path the site's file API uses. The home page is `pages/index.liquid`. The files are described in [Build pages with Liquid](https://docs.fluid.app/member-sites/templates.md#know-the-folder).

### config/settings.json

A JSON object that templates read as `settings`. Don't put a member's data in it. See [Pages and menus](https://docs.fluid.app/member-sites/pages-and-menus.md#write-the-settings-file).

### config/menus.json

The site's menus. It replaces every menu of the site when you push it. See [Pages and menus](https://docs.fluid.app/member-sites/pages-and-menus.md#write-the-menus-file).

```json config/menus.json theme={null}
{
  "menus": [
    {
      "slug": "main",
      "title": "Main menu",
      "items": [
        { "title": "Home", "page": "/" },
        { "title": "About", "page": "about" },
        { "title": "Contact", "url": "https://shop.example.com/contact" }
      ]
    }
  ]
}
```

An item has a `title`. It can nest `items`, and it can carry a `page` (a slug that `config/pages.json` lists) or a `url` (an `http` or `https` address), never both. An item with neither is a heading. Leave out the key you don't use: a `page` or `url` that is present is validated, so a null or empty one is refused.

### config/pages.json

The site's default layout, and what each page holds besides its content. It holds no page content, which is in `pages/<slug>.liquid`. See [Pages and menus](https://docs.fluid.app/member-sites/pages-and-menus.md#write-the-pages-file).

```json config/pages.json theme={null}
{
  "layout": null,
  "pages": [
    { "slug": "/", "title": "Home", "position": 1, "published": true, "layout": null, "menu": null },
    { "slug": "about", "title": "About", "position": 2, "published": true, "layout": null, "menu": "main" }
  ]
}
```

* `layout` at the top is the site's default layout name, or `null`.
* Each row has a `slug`, `title`, `position`, `published`, `layout` and `menu` (a menu's slug). The home page's slug is `/`. A page slug is lowercase letters and digits separated by single hyphens, and never `index`.
* A page with a row and no file is a page whose content is a template the site doesn't own.
* A site holds at most 50 pages. A new page needs a row and a file.

### config/access.json

The scopes a site's scripts use. It exists only once the site has a draft declaration, and a company site never has one. A pull writes it, a push sends it, and a publish makes it live with the settings. See [Declare what a member site uses](https://docs.fluid.app/member-sites/access-declarations.md).

### .member-site.json

The binding file. It records the site's id, handle and owner kind, the API base the folder came from, and the version of every file and page from the last pull or push. It is local state and a push never sends it. Don't edit or delete it.

A site holds text assets only. See [Build pages with Liquid](https://docs.fluid.app/member-sites/templates.md#use-text-assets-only) for what that means for images and fonts.

## Know what is live at once

A push saves most changes as drafts. Some changes have no draft, so they take effect on a published site the moment a push writes them. Before the first write, `push` lists each one.

| Change | When it takes effect |
| - | - |
| A new, changed or removed asset | At once |
| `config/menus.json` | At once |
| A page row: a new page, a changed field, a menu assignment, a removed page | At once |
| A removed layout, section or snippet | At once. The CLI deletes its published copy, so the site stops rendering it |
| Layout, section, snippet and page content, and `config/settings.json` | Saved as a draft until you publish |
| `config/access.json` | Saved as a draft until you publish |

Because assets are live as soon as they are written, a live asset must still work with the published pages. A push without `--publish` never publishes. [Pages and menus](https://docs.fluid.app/member-sites/pages-and-menus.md#know-what-is-live-at-once) explains the same split for page rows and menus.

## Fix common errors

The CLI turns an API answer into one message and a non-zero exit code.

| API answer | What the command says |
| - | - |
| `404` | Member sites aren't enabled for this company, or the site isn't yours |
| `401` | The login wasn't accepted, and which login the site needs |
| `403` | The API's message, and which login the site needs |
| `409` | The site, file or page changed on the server. On a publish, a conflict to run again |
| `422` | The API's message and each field error |
| Other | The API's message and the request id |

A `404` answers the same for a company without member sites, a missing site and another owner's site, so the command names the first and the last. The CLI never retries it. It retries a read that fails with `502`, `503` or `504` twice. It never retries a write.

## Next steps

* [Build pages with Liquid](https://docs.fluid.app/member-sites/templates.md) covers the Liquid objects and the frame's rules.
* [Pages, menus and settings](https://docs.fluid.app/member-sites/pages-and-menus.md) covers the three config files.
* [Read viewer data in site scripts](https://docs.fluid.app/member-sites/site-scripts.md) covers `window.fluid.fetch`.
* [Declare what a member site uses](https://docs.fluid.app/member-sites/access-declarations.md) covers `config/access.json`.
* [Publish, restore, copy and take down a member site](https://docs.fluid.app/member-sites/publishing.md) covers what a publish does and how to go back.
* [Share a member site](https://docs.fluid.app/member-sites/sharing.md) covers visibility and shares.
* [Build member sites with the APIs](https://docs.fluid.app/member-sites/apis.md) covers building without the CLI.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.