> ## 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, 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. The merchant must open the emailed sign-in link and create an API token before authenticated calls are possible.
> 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 where a spec documents it — in practice the unversioned company-v0 admin surface; every versioned surface uses cursor pagination.
> Navigation menu management is documented in themes/navigation-menus. These unversioned admin endpoints (/api/menus and nested menu_items) are verified against the implementation but are not yet in the synced OpenAPI specs. Use that reference for menu payloads and its flat page/per_page pagination; missing spec coverage does not make these endpoints unavailable.
> 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 — 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.

# Open a country

> Start selling in a new country, set up from Fluid's Country Atlas: currency, tax, legal and checkout defaults, prices in the local currency, languages, agreements, and storefront translations.

Opening a country adds it to your company so you can sell there. Fluid's Country Atlas holds a certified setup profile for each market: its currency, how tax is named and shown, consumer-protection rules, the checkout address layout, recommended payment methods, the languages people shop in, and the agreements a storefront there needs. This guide opens the country from that profile, converts your prices into its currency, and translates what its shoppers see, then lists what the atlas can't do for you.

## Before you start

* Your token needs company admin access with permission to update countries, languages, agreements, and products. Translating also needs the permissions listed in [Add a language](/setup/add-a-language#before-you-start). Your own sign-in with `fluid login` works if you are a company admin.
* Decide how you will operate in the country. The atlas describes three modes, and a company uses exactly one per country:

  | Mode | What it means |
  | - | - |
  | `nfr` | Not For Resale. You ship cross-border from a warehouse outside the country. |
  | `otg` | On The Ground. You have a local entity, register for local tax, and fulfill locally. |
  | `usd` | You sell cross-border and charge in US dollars, usually for digital goods. |

  `fluid countries atlas <iso>` shows each mode's overview for the market, with its typical setup time and cost, and its launch checklist.
* For NFR or OTG, know which warehouse fulfills the country's orders. For OTG, have your local tax or business registration number if you already have one.
* Install and sign in to the CLI:

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

Every `fluid countries` and `fluid translations` command prints JSON. Failures print a JSON `error` on stderr and exit with a non-zero code. Countries are given by their two-letter ISO code, such as `DE` or `JP`; `UK` is accepted for the United Kingdom.

<Tip>
  Prefer to answer questions? Run `fluid countries walk` in a terminal. It asks for the country, shows its atlas, and asks the mode, languages, agreements, and whether to keep each atlas default. It opens the country only after you confirm a summary, then offers the price conversion and hands each language to the translations walk. Type `<` to go back, `>` to skip, and `?` for the menu.
</Tip>

## Steps

<Steps>
  <Step title="Preview the setup">
    ```bash theme={null}
    fluid countries plan DE --mode otg
    ```

    This changes nothing. It prints the settings `open` will save, each of the market's major languages and whether your company has it on, each atlas agreement and whether you already have one with that title, your warehouses, and the mode's launch checklist. If `alreadyOpen` names a country, the country is open already: skip to step 3.

    If Fluid has no atlas for the market, the command says so and stops. Open the country by hand in **Settings > Countries** instead, and don't assume tax, legal, or agreement defaults for it.
  </Step>

  <Step title="Open the country">
    This changes live configuration: it adds the country to your company.

    ```bash theme={null}
    fluid countries open DE --mode otg --warehouse-id 12 --business-id DE123456789 --entity-registered --yes
    ```

    The country is seeded from the atlas: its currency, the operating mode, the tax name, whether prices include tax, whether tax invoices are required, whether card payments need 3-D Secure, the legal settings (cooling-off period, warranty period, cookie consent, subscription disclosure), the checkout address layout with local labels, and the order checkout ranks payment methods in.

    Add what the atlas can't know with flags: `--warehouse-id` for the fulfilling warehouse, `--business-id` and `--entity-registered` for an OTG entity, and `--settlement-currency` if you settle in a different currency from the one you charge in. Override any seeded value with `--set`, for example `--set tax_inclusive_pricing=false` or `--set legal_settings.cooling_off_period_days=30`.

    The atlas's agreements replace Fluid's generic country agreements and forms, which this step skips. Pass `--legacy-defaults` to add those as well.

    If your company uses per-country test mode, the new country starts in it and takes no live payments until you turn test mode off. If the country is already open, `open` changes nothing; `--reseed` writes the atlas values over its current settings, replacing changes an admin made.
  </Step>

  <Step title="Convert your prices">
    Preview first. This changes nothing:

    ```bash theme={null}
    fluid countries prices DE
    ```

    For every variant of your active products, the preview takes its price in the United States, multiplies it by an exchange rate, and rounds it to the country's currency: to the cent for euros, to whole units for currencies such as yen. It shows the rate, the rounding, how many variants it would convert, how many it would skip and why, and a sample of prices before and after. Without `--rate`, it uses the European Central Bank's reference rate for the day.

    Then save the prices, with the rate you reviewed. This changes live prices:

    ```bash theme={null}
    fluid countries prices DE --rate 0.92 --write --yes
    ```

    It converts the retail price, the subscription price, and the compare-at price. Add the wholesale prices with `--fields price,subscription_price,compare_price,wholesale,wholesale_subscription_price`. Convert from another of your countries with `--from-country`, and include draft products with `--status draft`.

    It's safe to run again. A variant that already has a price in the country is skipped, so a price is never converted twice; `--overwrite` replaces existing prices. Each variant is saved on its own, and any the API refuses are listed under `failed` with the reason, while the rest are saved. Converted prices don't put a product on sale in the country; pass `--activate` to do that as well.

    If your prices are managed in the price editor, `priceEditor` is `true`. The prices are saved into the price editor, and any it can't take are listed with `refusedByPriceEditor`. `--overwrite` isn't available then, so prices set in the price editor are never replaced. Change those in the price editor.
  </Step>

  <Step title="Enable the market's languages">
    See which of the market's major languages your company doesn't have on yet:

    ```bash theme={null}
    fluid countries languages DE
    ```

    Then turn them on. This changes live configuration: it turns languages on for your whole company, not just this country.

    ```bash theme={null}
    fluid translations enable de --yes
    ```

    `next` in the first command's output is the `enable` command with every language that's off. Enable the languages before you create the agreements, because each agreement translation is saved in its own language.
  </Step>

  <Step title="Create the agreements">
    This changes live configuration: it creates agreements and puts them on the country.

    ```bash theme={null}
    fluid countries agreements DE --create --yes
    ```

    Each atlas agreement you don't already have is created from the atlas's legal text, with its checkout settings (required, shown at checkout, checked by default), in every language the atlas has it in. An agreement whose title matches one you already have is skipped, never duplicated. Run it without `--create` to see each agreement's status first, or pass `--only agreement_2` to create one at a time.

    Have someone qualified review the agreements before you launch. The atlas text is a starting point, not legal advice for your business.
  </Step>

  <Step title="Translate the storefront">
    Shoppers need the storefront in their language, even when your company already had that language on. For each of the market's languages, see what isn't translated yet, then machine-translate it:

    ```bash theme={null}
    fluid translations missing de
    fluid translations auto de --limit 25 --write --yes
    ```

    This changes live content. It covers products and the rest of your storefront, navigation, your theme's strings, agreements, and product labels. Run `auto` again until `remaining` is `0` for every type. [Add a language](/setup/add-a-language) explains the report, how to review and correct translations, and what still has to be translated by hand.
  </Step>

  <Step title="Check the setup">
    ```bash theme={null}
    fluid countries status DE
    ```

    This compares the country with the atlas and lists each check with `ok` and a `detail`. It also checks that every variant of your active products has a price in the country, counting a bundle by the price checkout charges for it (`prices`), and that something is on sale there (`on_sale`). `done` is `true` when every check passes. `prices` and `translations` give the commands for steps 3 and 6. `byHand` lists the work no command does for you, and `launchChecklist` is the atlas's checklist for your mode: the registrations, licences, and filings to complete before you launch. Work through both.
  </Step>
</Steps>

## What the status means

| Field | Meaning | What to do |
| - | - | - |
| `covered: false` (`atlas`) | Fluid publishes no atlas for the market. | Open the country by hand and verify its rules locally. |
| `alreadyOpen` (`plan`, `open`) | The country is already on your company. | Continue from step 3, or pass `--reseed` to `open` to rewrite its settings. |
| `toConvert` (`prices`) | Variants that would get a price in the country. | Save them with `--write`. Done when it's `0`. |
| `skipped.alreadyPriced` (`prices`) | Variants that already have a price in the country. | Nothing, or `--overwrite` to replace them. |
| `skipped.pricedInOtherCurrency` (`prices`) | Variants with a price saved in a different currency, from before the country's currency changed. | Review them. `--overwrite` replaces them. |
| `skipped.noSourcePrice` (`prices`) | Variants with no price in the source country. | Price them by hand, or convert from another country with `--from-country`. |
| `skipped.roundsToZero` (`prices`) | Variants whose converted price would round to zero, so they aren't priced at all rather than made free. | Price them by hand, or check the rate. |
| `failed` (`prices`) | Variants the API refused to save, each with the reason. | Fix what the reason names and run the step again. Saved variants are skipped. |
| `changedSincePreview` (`prices`) | Variants someone priced in the country after the preview, left as they are. | Nothing. Check them if the new price looks wrong. |
| `priceEditor: null` (`prices`) | Your token can't read the company profile, so the CLI can't tell whether the price editor manages your prices. | Fine without `--overwrite`. To overwrite, use a token that can view the company. |
| `enabled: false` (`languages`) | Your company doesn't have this language on. | Run step 4. A `languageId` of `null` means Fluid's language catalog lacks it. |
| `status: missing` (`agreements`) | You have no agreement with this title. | Run step 5. |
| `status: inactive` (`agreements`) | The agreement is on the country but switched off, so checkout doesn't show it. | Activate it in **Settings > Agreements**. |
| `status: exists` (`agreements`) | You have an agreement with this title, but it isn't on this country. | Add the country to it in **Settings > Agreements**. |
| `remaining` (`translations auto`) | Items still untranslated in that language. | Run step 6 again. |
| `ok: false` (`status`) | The country differs from the atlas. | Change it back, or leave it if the difference is deliberate. |
| `testMode: true` (`status`) | The country takes no live payments yet. | Turn test mode off once payments are set up. |

### What stays with you

The commands don't do these; `status` lists them under `byHand`:

* **Payment methods.** The atlas recommends methods for the market in order. Connect each provider in **Settings > Payments**; that needs your account details with the provider.
* **Enrollment form fields.** The atlas lists the fields to collect when members enroll in the country. Add them to the country's enrollment form.
* **Putting products on sale.** Converted prices don't put a product on sale in the country unless you passed `--activate`. Turn on the products you will sell there.
* **Content no API translates.** Promotions, enrollment form fields, and theme settings written as plain text. See [Add a language](/setup/add-a-language#what-isnt-covered).
* **The mode's own work.** OTG means registering for local tax and setting up local invoicing; USD means checking whether the country taxes cross-border digital sales. `fluid countries compliance <iso>` lists the market's disclosure pages, cookie rule, and how prices must be shown.

## Troubleshooting

**`open` fails with a 422.** The country couldn't be saved. The error's `details` name the setting the API refused. Fix it with `--set` and run the step again; nothing was saved.

**`open --reseed` fails with a 409.** Someone changed the country while you were working. Run it again to start from the current settings.

**A price is listed under `failed`.** The API refused that variant, for example because the price editor couldn't place it in a price list for the country. The reason is in `error` and `details`. Fix it, or set that price in the admin, then run step 3 again; variants already saved are skipped.

**`--write needs the rate you reviewed`.** Saving prices needs `--rate`. Run the preview, check the rate, and pass it.

**An agreement's `failedTranslations` says the locale is unsupported.** That language isn't on for your company. The agreement itself was created. Run step 4, then `fluid countries agreements DE --translate --yes` to write the atlas translations onto the agreements already on the country.

**`isn't open for this company yet`.** `agreements` needs the country. Run step 2 first.

**A 403 from any command.** Your token lacks permission for that step. See **Before you start**.

## Use the API directly

The CLI reads the public Country Atlas at `/api/v202604/country/atlas/{iso}`, which needs no token, and calls company operations authenticated with a Bearer token:

1. [List company countries](/api-reference/countries/list-company-countries) — `GET /api/settings/company_countries`, to see whether the country is already open.
2. [Create a company country](/api-reference/countries/create-a-company-country) — `POST /api/settings/company_countries`, with the atlas values as the country's own. Send `seed_legacy_defaults` as `false` to skip Fluid's generic agreements and forms.
3. [Update a company country](/api-reference/countries/update-a-company-country) — `PUT /api/settings/company_countries/{id}`. Send the `revision` you read as `expected_revision`, and a concurrent change answers `409` instead of being overwritten.
4. [List company languages](/api-reference/languages/list-company-languages) and [Configure company language](/api-reference/languages/configure-company-language) — `GET` and `POST /api/settings/languages`.
5. [Creates an agreement](/api-reference/company-v0/agreements/creates-an-agreement), then [Updates an agreement](/api-reference/company-v0/agreements/updates-an-agreement) with the language's ISO code as the `language_iso` query parameter for each translation.
6. [List warehouses](/api-reference/warehouses/list-warehouses) — `GET /api/settings/warehouses`, to choose the warehouse.
7. Prices are saved one variant at a time through the variants API, in the variant's price row for the country. The CLI reads the products with their variants and prices first, and checks the company profile for whether the price editor manages your prices.

The country's ID in Fluid's catalog comes from [List countries](/api-reference/company-v0/countries/list-countries).

```bash theme={null}
curl -X POST "https://api.fluid.app/api/settings/company_countries" \
  -H "Authorization: Bearer <your_token>" \
  -H "Content-Type: application/json" \
  -d '{"seed_legacy_defaults": false, "company_country": {"country_id": 81, "currency": "EUR", "tax_name": "VAT", "tax_inclusive_pricing": true, "requires_3ds": true}}'
```

The Country Atlas isn't in the API reference yet, so read it through `fluid countries atlas` where you can.


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