> ## 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.
> Never use /api/company/v1 or /api/v1 paths, page/per_page params, or offset pagination — they are legacy.
> 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).
> Successful responses wrap the resource payload alongside a top-level integer status and a meta object.

# Build a headless checkout

> Drive a custom purchase flow on Fluid's checkout surface — create a cart, add line items, capture the buyer's contact and address, select shipping, collect payment, and complete the order.

Fluid hosts a full checkout, but you can also drive one yourself. The checkout surface exposes every step of a purchase as a cart operation, so you can build a bespoke storefront, embed checkout in your own app, or place orders on behalf of a rep. This guide walks the flow end to end: find a product, create a cart, add items, capture the buyer's details, price shipping, take payment, and turn the cart into an order.

The flow is built for direct-sales commerce — a cart can carry rep attribution, subscription line items, and enrollment context alongside ordinary products.

<Info>
  This guide covers a direct Checkout API integration. If you use the
  `@fluid-app` FairShare SDK, see [Choosing a cart
  surface](/api/choosing-a-cart-surface) for its Public SDK API workflow.
</Info>

## Base URL and authentication

Every request goes to `https://api.fluid.app`. The checkout surface is versioned: paths sit under `/api/checkout/v2026-04/`.

The cart operations in this flow are scoped by the `cart_token` in the path and
need no company Bearer token. Creating a cart, querying a product, and
retrieving a finished order are also public operations.

<Info>
  The create-cart response returns the `cart_token` used in every cart-level
  path. Treat it as a secret and send it only to Fluid.
</Info>

## The checkout flow

<Steps>
  <Step title="Find a product and a variant">
    A cart is built from product variants, so you start by resolving the `variant_id` you want to sell. Query a single product on the checkout surface with `POST /api/checkout/v2026-04/products/{id}`, passing the shop under `metadata.fluid_shop`. The `{id}` segment accepts a product id or slug.

    ```bash theme={null}
    curl -X POST "https://api.fluid.app/api/checkout/v2026-04/products/cordless-blender" \
      -H "Content-Type: application/json" \
      -d '{
        "metadata": {
          "fluid_shop": "acme.fluid.app"
        }
      }'
    ```

    The response lists the product's purchasable variants; see the [Query product endpoint](/api-reference/products/query-product) reference for its full shape. To browse or search the whole catalog instead of fetching one product, use the Storefront products API, documented under the Storefront endpoints reference.
  </Step>

  <Step title="Create a cart">
    Create the cart with `POST /api/checkout/v2026-04/carts`. The body requires `fluid_shop` (the company subdomain) and `country_code` (an ISO country code). You can seed the cart with an `items` array in the same call — each item requires a `variant_id` and a `quantity` — and attach rep attribution under `attribution`.

    ```bash theme={null}
    curl -X POST "https://api.fluid.app/api/checkout/v2026-04/carts" \
      -H "Content-Type: application/json" \
      -d '{
        "fluid_shop": "acme",
        "country_code": "US",
        "attribution": {
          "share_guid": "sh_9f2ac1b7"
        },
        "items": [
          { "variant_id": 88214, "quantity": 2 }
        ]
      }'
    ```

    Creating a cart is a public operation — it needs no Bearer token. A successful call returns the cart, including the `cart_token` you pass to every subsequent step. A body that fails validation — for example a missing `country_code` — returns `422`.

    <Info>
      Store the returned `cart_token` in your application state. It identifies the cart for the rest of the flow.
    </Info>
  </Step>

  <Step title="Add and adjust line items">
    Add more items after creation with `POST /api/checkout/v2026-04/carts/{cart_token}/items`. The body takes an `items` array. For a new line, provide its `variant_id` and `quantity`. Mark an item as a subscription by setting `subscription` to true and naming a `subscription_plan_id`. See the endpoint reference for the alternative batch shapes.

    ```bash theme={null}
    curl -X POST "https://api.fluid.app/api/checkout/v2026-04/carts/ct_7Hq2Kd9Rm4bV1nX/items" \
      -H "Content-Type: application/json" \
      -d '{
        "items": [
          {
            "variant_id": 90731,
            "quantity": 1,
            "subscription": true,
            "subscription_plan_id": 4
          }
        ]
      }'
    ```

    You can inspect the cart at any time with `GET /api/checkout/v2026-04/carts/{cart_token}`, which returns the current items, totals, and available shipping methods.

    ```bash theme={null}
    curl "https://api.fluid.app/api/checkout/v2026-04/carts/ct_7Hq2Kd9Rm4bV1nX"
    ```
  </Step>

  <Step title="Capture the buyer's contact details">
    Attach the buyer's contact information with `PATCH /api/checkout/v2026-04/carts/{cart_token}`. The body accepts `email`, `phone`, and the marketing opt-ins `email_marketing` and `sms_marketing`.

    ```bash theme={null}
    curl -X PATCH "https://api.fluid.app/api/checkout/v2026-04/carts/ct_7Hq2Kd9Rm4bV1nX" \
      -H "Content-Type: application/json" \
      -d '{
        "email": "dana.lee@example.com",
        "phone": "+13105550142",
        "email_marketing": true
      }'
    ```
  </Step>

  <Step title="Set the shipping address">
    Set the address with `POST /api/checkout/v2026-04/carts/{cart_token}/address`. The body requires a `type` — one of `ship_to`, `bill_to`, or `both` — and carries the address fields under an `address` object.

    ```bash theme={null}
    curl -X POST "https://api.fluid.app/api/checkout/v2026-04/carts/ct_7Hq2Kd9Rm4bV1nX/address" \
      -H "Content-Type: application/json" \
      -d '{
        "type": "ship_to",
        "address": {
          "first_name": "Dana",
          "last_name": "Lee",
          "address1": "1200 Market St",
          "city": "San Francisco",
          "state": "CA",
          "postal_code": "94103",
          "country_code": "US"
        }
      }'
    ```

    <Note>
      Setting the address triggers a full recalculation of tax, shipping, and totals, so the cart you get back reflects the destination. Re-read the cart to see the refreshed available shipping methods.
    </Note>
  </Step>

  <Step title="Select a shipping method">
    Once the cart has an address, choose one of its available methods with `PUT /api/checkout/v2026-04/carts/{cart_token}/shipping`, passing the `shipping_method_id`. Selecting a shipping method is idempotent — selecting the same one again is a no-op.

    ```bash theme={null}
    curl -X PUT "https://api.fluid.app/api/checkout/v2026-04/carts/ct_7Hq2Kd9Rm4bV1nX/shipping" \
      -H "Content-Type: application/json" \
      -d '{
        "shipping_method_id": 5123
      }'
    ```
  </Step>

  <Step title="Apply a discount code (optional)">
    Apply a promotion with `POST /api/checkout/v2026-04/carts/{cart_token}/discount`, passing the `discount_code`. Applying a discount is not idempotent — applying the same code twice returns an error.

    ```bash theme={null}
    curl -X POST "https://api.fluid.app/api/checkout/v2026-04/carts/ct_7Hq2Kd9Rm4bV1nX/discount" \
      -H "Content-Type: application/json" \
      -d '{
        "discount_code": "SAVE10"
      }'
    ```
  </Step>

  <Step title="Collect payment">
    Card capture and tokenization happen on Fluid's cart payment surface, which authenticates with the cart token in the path — no Bearer token — and returns a payment reference. See the Cart payment endpoints reference for tokenization, 3D Secure, and the wallet flows (Apple Pay, PayPal, and others). Carry the resulting reference into the next step as the `payment_uuid` query parameter.
  </Step>

  <Step title="Complete the checkout">
    Turn the cart into an order with `POST /api/checkout/v2026-04/carts/{cart_token}/complete`. Pass the payment reference as the `payment_uuid` query parameter, and send an `Idempotency-Key` header so a retried request never places a second order. A successful call returns `200` with the completed order.

    ```bash theme={null}
    curl -X POST "https://api.fluid.app/api/checkout/v2026-04/carts/ct_7Hq2Kd9Rm4bV1nX/complete?payment_uuid=pay_3Fd8Qw" \
      -H "Idempotency-Key: 2f6b1c8a-checkout-01"
    ```

    <Warning>
      Completion is final. Once the cart converts to an order it is locked, and any further mutation returns `410`. Do not reuse the `cart_token` after a successful checkout — start a new cart for the next purchase.
    </Warning>
  </Step>

  <Step title="Retrieve the order">
    Read the order back with `GET /api/checkout/v2026-04/orders/{token}`, using the order token from the completion response. This endpoint is public, so you can show an order-confirmation page without a Bearer token. The response carries the order's `token` and its human-facing `order_number`.

    ```bash theme={null}
    curl "https://api.fluid.app/api/checkout/v2026-04/orders/ord_5Kp1Zt7Yb2"
    ```
  </Step>
</Steps>

## Related surfaces

* **Cart payment** — card tokenization, 3D Secure, and wallet payments live on the cart payment surface; see the Cart payment endpoints reference.
* **Storefront** — browse and search the product catalog on the Storefront endpoints reference.
* **Subscriptions** — the checkout surface also manages the subscriptions a cart creates; see the subscription operations in the reference.

## Next steps

* Browse the [Create a cart endpoint](/api-reference/carts/create-a-cart) reference for full request and response schemas.
* Create a cart, add an item, and read it back to confirm your token handling before wiring up payment.
