> ## 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.
> 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. /api/company/v1 and /api/v1/... paths are documented in no spec here and must never be used (/api/v1.1/... is distinct and documented in company-v0). Use page/per_page offset pagination only where a spec documents it — in practice the unversioned company-v0 admin surface; every versioned surface uses cursor pagination.
> 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/auth-v0.yaml covers the unversioned auth surface (/api/... paths — authentication, MFA, social auth, and token exchange); 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 — 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.

# Give members their own pages with member sites

> Group member pages into sites, decide which countries and member types each site serves, and give every site its own layout and navigation inside the active theme.

<Warning>
  Coming soon: member storefront is in a limited pilot and is not yet generally available. This page describes the pilot release for companies that have it enabled, and details can change before general availability. Contact [Fluid support](mailto:support@fluid.app) to ask about enabling it for your company.
</Warning>

A member site is an access rule and the set of pages it governs. Your theme holds an ordered list of sites. A signed-in member resolves to exactly one of them, is served that site's pages, and receives a not-found response for every other site's pages. The rule is a permission, not a display choice, and Fluid enforces it on every request.

Use member sites when reps and customers need different pages, when a country needs its own set, or when one group of members should not see another group's content.

<Note>
  Member sites require member storefront enablement for your company. The member layout and page templates a site frames are theme content that you author. See [Member page templates](/themes/member-storefront/member-page-templates).
</Note>

## Understand the building blocks

| Building block | Responsibility                                                                                            |
| -------------- | --------------------------------------------------------------------------------------------------------- |
| Member site    | An access rule, a layout choice, a navigation menu, and the pages it governs                              |
| Rule           | The countries and member types a site serves. An empty rule serves everyone                               |
| Default site   | A fallback that is tried only after every explicit site fails to match                                    |
| Member page    | A page you add to one site. It has its own template and its own slug                                      |
| System page    | The dashboard at the site root and the sign-in landing. Template types your theme provides                |
| System screen  | Messaging, Contacts, and My Site. Fluid renders them, and every site has all of them                      |
| Layout         | The `layouts` template that frames every page in the site                                                 |
| Menu           | The site's navigation. Edited in the theme editor's menu editor and read by the layout as `settings.menu` |

Sites belong to the theme, not to the company. Switching the active theme switches the sites, duplicating a theme copies them, and exporting a theme writes them to disk.

## Know where member pages live

Member pages are served on your company's account subdomain, not on the storefront domain. Replace `acme` with your company's Fluid subdomain:

| Page            | Path on `https://acme.account.fluid.app` |
| --------------- | ---------------------------------------- |
| Dashboard       | `/`                                      |
| Sign-in landing | `/login`                                 |
| Member page     | `/pages/rewards`                         |
| Messaging       | `/messaging`                             |
| Contacts        | `/contacts`                              |
| My Site         | `/my-site`                               |

A storefront on a custom domain still uses its Fluid subdomain for member pages. On the storefront domain, the `/accounts` prefix is reserved and serves no pages, so do not link to it.

Every member page is rendered for the signed-in member on each request. It is never cached, never served by the CDN, and never indexed by search engines.

## Create a site

1. Open your theme in the **Page Editor**.
2. In the templates panel, open **Member Sites** and add a site.
3. Give the site a name that describes its audience, such as `Reps` or `US customers`. Names are unique within a theme.
4. Set the rule: the countries and member types the site serves. Leave both empty for a site that serves everyone.
5. Choose whether the site is a default site.
6. Pick the layout that frames the site's pages.
7. Save. The site is appended after the theme's existing sites and receives a menu named after it.

A new theme has no sites, and a member who matches no site receives a not-found response for every member page. Add a site before you invite members to the account subdomain.

## Decide who a site serves

A rule has two axes: countries and member types. Each axis is a list.

* An empty axis is unconstrained. A site with both axes empty matches every member.
* A constrained axis matches when the member's value is in the list. A member whose country is unknown takes the company's default country.
* Clearing an axis **widens** the site. Removing the last country from a rule does not turn the site off. It serves every country.

Fluid resolves a member to a site in two passes:

1. **Explicit sites first.** Every active site that is not a default site is tried in position order. The first match wins.
2. **Default sites next.** Only when no explicit site matches, active default sites are tried in position order.

A default site therefore never shadows an explicit one, wherever it sits in the list. An inactive site resolves for nobody. A member who matches nothing is refused: every member page, including the dashboard and the system screens, returns a not-found response for them.

A common arrangement is one explicit site per audience plus one default site with no rule:

| Site          | Default | Rule                   | Serves                                         |
| ------------- | ------- | ---------------------- | ---------------------------------------------- |
| Reps          | No      | Member type: Rep       | Every rep, in any country                      |
| US customers  | No      | Country: United States | Customers in the United States                 |
| Everyone else | Yes     | None                   | Every member the two sites above did not match |

Two explicit sites can overlap. A US rep matches both `Reps` and `US customers`, and the higher site wins. Reorder the list to change which one that is.

You can rename, reorder, narrow, or deactivate any site. You cannot delete a theme's last site. Deactivate it instead, which is visible in the editor and reversible.

## Add pages to a site

Each site holds its own pages. In **Member Sites**, open a site and choose **Add page**.

* A page has a title, a slug, and a published flag. The slug is derived from the title unless you set one. It uses lowercase letters, numbers, and hyphens, and is at most 64 characters.
* Slugs are unique within a site, not within the theme. Two sites can both have a `rewards` page, and each member gets the one in their site.
* Every page gets its own `members_page` template, created with the page. Compose it with sections the way you compose any other template.
* An unpublished page returns a not-found response and is absent from derived navigation. Publish it when it is ready.
* A page can move to another site. It keeps its template and its slug.

Deleting a site deletes its pages, and deletes each page's template when no other page uses it.

The dashboard at the site root and the system screens are not pages you add. Every site has them as soon as the theme provides the dashboard template.

## Arrange the navigation

Every site has its own menu. When you create a site, Fluid creates a menu named after it, such as `Reps navigation`, and links the site to it by slug.

Edit the menu in the theme editor's menu editor. Its items can point at:

* A member page in the site.
* A system screen: Messaging, Contacts, or My Site.
* Any other destination, such as the storefront shop or an external URL.

Nesting, order, and labels are whatever you save. Your layout reads the result as `settings.menu`, in the same shape as any `link_list` setting. See [Member page templates](/themes/member-storefront/member-page-templates) for the Liquid.

Until a site has a menu with items, Fluid derives one: the Dashboard first, then the site's published pages by title. A menu whose items all resolve to nothing falls back the same way, so a member always has a way out of the page they landed on.

Two things the menu does not do. It does not mark the current page: compare an item's `url` with `request.path` in Liquid, as the storefront navigation does. And it does not hide links that leave the member area: a link back to the shop is a normal thing to want.

## Frame the site in a layout

A site names the layout that frames its pages. The page's own `{% layout %}` tag is ignored for member pages, because a page can move between sites and the site owns the frame.

| Layout value                    | Result                                                        |
| ------------------------------- | ------------------------------------------------------------- |
| A layout name, such as `member` | That `layouts` template, resolved inside the site's own theme |
| `theme`                         | The theme's storefront layout                                 |
| `none`                          | No layout. The page template must supply its own document     |

A new site is framed in the theme's `member` layout when the theme has one, and in `theme` otherwise. When a site names a layout the theme no longer has, Fluid falls back to `member`, then to `theme`, so a renamed layout degrades rather than leaving the page bare. `none` is a deliberate choice and does not fall back.

The editor's layout picker offers only layouts the theme has. Write the member layout before you expect to pick it. See [Member page templates](/themes/member-storefront/member-page-templates#create-the-member-layout).

## Sign in and sign out

A guest who opens any member page is redirected to Fluid's hosted sign-in for your company, with the requested path carried along. After signing in, the member returns to the account subdomain, receives a session, and lands on the page they asked for.

The session is a signed, HTTP-only cookie that lasts 30 days. Fluid re-checks the member's standing in your company on every request, so a member whose access ends is signed out immediately, whatever the cookie says.

The sign-in landing at `/login` is a themed page you control. Nothing redirects a guest through it, but you can link to it from the storefront, and it receives the sign-in URL to put behind its button. Sign-out is a form in your layout that posts to the member's sign-out route. Both are shown in [Member page templates](/themes/member-storefront/member-page-templates#build-the-sign-in-landing).

## Use the system screens

Fluid ships three screens that every site has:

| Screen    | Path         |
| --------- | ------------ |
| Messaging | `/messaging` |
| Contacts  | `/contacts`  |
| My Site   | `/my-site`   |

A system screen is not a page you compose. Fluid renders it inside the site's layout, and the member's identity comes from their session. You control whether a screen appears in a site's menu and where. You do not control its content or its address.

<Note>
  System screens require the account screens runtime to be enabled for your company. Fluid loads it once, on every member page, through a global embed. Your layout needs only `{{ content_for_header }}` for the runtime and its security token to reach the page.
</Note>

## Export and import sites

Exporting a theme writes `members_sites.json` at the theme root, next to `variables.json`. It lists every site in resolution order with its rule, layout name, menu slug, and pages. Every reference is a name: a site names its layout, and a page names its template, which the export writes as `members_page/{name}/index.liquid`.

Importing a theme recreates the sites and pages from the manifest and relinks each page to its template by name:

* The importing company must have member storefront enabled. Otherwise the layouts and page templates import as ordinary templates and no sites are created.
* A theme that already has sites keeps them. The manifest is skipped rather than merged.
* A page whose template did not import arrives unbound. Bind it in the editor.
* A malformed manifest costs the sites, not the import.

Review each imported site's rule. Country and member type identifiers belong to the exporting company, so a constrained rule may match nobody after import until you reselect its values.

## Test a member site

1. Sign in as a member who matches the site's rule. Confirm the dashboard, each published page, and each system screen open.
2. Sign in as a member who matches a different site. Confirm the first site's pages return a not-found response, including by direct URL.
3. Sign in as a member who matches no site. Confirm every member page returns a not-found response.
4. Open a member page as a guest. Confirm you are sent to sign in and return to the same page afterwards.
5. Reorder two overlapping explicit sites and confirm a member who matches both moves with the order.
6. Confirm the menu lists what the same member can open, and nothing they cannot.

## Troubleshoot a member site

| Symptom                                             | What to check                                                                                                                                                                          |
| --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Every member page returns not found                 | Confirm member storefront is enabled for the company, the theme has a `members_dashboard` template, at least one active site matches the member, and you are on the account subdomain. |
| One member gets pages another does not              | Expected when they resolve to different sites. Compare their country and member type with each site's rule and position.                                                               |
| A default site swallows every member                | Another site is inactive or has a rule that matches nobody. A default site is tried only after every explicit site fails.                                                              |
| Clearing a rule field locked nobody out             | Expected. An empty axis matches everyone. Deactivate the site to turn it off.                                                                                                          |
| A page is missing from the menu                     | Confirm it is published and that the site's menu links to it, or that the site has no menu and derives one.                                                                            |
| A menu link points at the storefront copy of a page | Edit the menu item to point at the member page rather than a storefront page. Fluid renders the link you saved.                                                                        |
| A member page wears the storefront header           | The site is framed in `theme`. Pick the member layout in the site's settings, and create it if the theme has none.                                                                     |
| A system screen renders empty                       | Confirm the account screens runtime is enabled for the company and that the layout renders `{{ content_for_header }}`.                                                                 |
| Imported sites match nobody                         | The rule's identifiers came from another company. Reselect countries and member types in the site's settings.                                                                          |
| Cannot delete a site                                | A theme keeps at least one site. Deactivate it, or delete a different one first.                                                                                                       |

## Implementation checklist for coding agents

Treat this page as the member site contract. Read the target theme before editing it, and preserve its existing conventions and content.

* Confirm member storefront is enabled for the target company. Do not infer it from the presence of this guide.
* Create sites through the theme editor or its API. Do not edit `members_sites.json` to change a live theme.
* Give every site a name unique within the theme and a rule made only of countries and member types.
* Treat an empty axis as unconstrained. Never clear an axis to disable a site; deactivate it.
* Keep one default site with no rule when every member should reach some page set. Place explicit sites above it.
* Use lowercase, hyphenated slugs of at most 64 characters, unique within the site.
* Point a site at a layout the theme has. Create `layouts/member.liquid` before selecting it.
* Link the site's menu to member pages and system screens rather than to storefront copies.
* Never link to `/accounts` paths on the storefront domain.
* Verify matching, non-matching, and no-match members, guest redirect and return, and menu contents.
* Report which files changed and which checks ran. Editing a theme, publishing it, and enabling the feature are separate actions; confirm the target and authorization before each remote change.

### Copyable task brief

```text theme={null}
Set up member sites for this Fluid theme using the Member sites guide.

First inspect the theme's layouts, its existing member sites, and the company's member types
and countries. Confirm that member storefront is enabled for the target company.

Create a Reps site constrained to the Rep member type, and an Everyone else site marked default
with no rule, in that order. Frame both in the theme's member layout. Add a published Rewards
page to the Reps site and link it, the Dashboard, and the Contacts screen from the Reps menu.

Do not clear a rule axis to disable a site; use active instead.
Do not link menu items to /accounts paths on the storefront domain.

Verify a rep reaches the Rewards page, a customer receives not found for it and reaches the
Everyone else site, and a guest is redirected to sign in and returns to the requested page.
Do not publish or overwrite an existing theme without explicit authorization.
Report completed checks and any environment-dependent checks still needed.
```

For the Liquid that frames and fills these pages, see [Member page templates](/themes/member-storefront/member-page-templates). For member values on cached storefront pages, see [Member-aware sections](/themes/member-storefront/member-aware-sections).
