> ## 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.
> Successful responses wrap the resource payload alongside a top-level integer status and a meta object.

# List the company's orders

> Cursor-paginated index of the authenticated company's orders,
resolved entirely from Elasticsearch — filtering, sorting and
pagination all happen in the search index rather than in Postgres.

Two deliberate differences from `GET /api/v202506/orders`:

- **No stats block.** The response `meta` carries pagination only.
  Aggregate figures (total and average CV, total and average
  amount, fulfilled count) come from
  `GET /api/v202506/orders/stats`, which is cached and built for
  them. Computing a whole-set aggregation on every page of a list
  endpoint is what made the v2025-06 index expensive.
- **No SQL fallback.** If the search index cannot answer, this
  endpoint returns `503` rather than quietly running the slow
  query it exists to replace. Callers that need availability over
  index freshness should stay on v2025-06.

Cursors are Elasticsearch `search_after` tokens. They are opaque:
echo `meta.pagination.next_cursor` back as `page[cursor]` to walk
forward and `prev_cursor` to walk back. They are **not**
interchangeable with the v2025-06 Rotulus cursors.

Visibility follows the authenticated credential, never a
parameter: a company admin sees the company's orders, and a rep
sees only the orders they hold volume credit on plus their own
purchases.

Unlike `GET /api/v202506/orders`, this surface does **not** accept
customer JWTs — a customer token is rejected with 401. Customers
read their own orders from
`GET /api/checkout/v2026-04/customers/me/orders`.




## OpenAPI

````yaml /api-reference/commerce-v2026-04.yaml get /api/v202604/orders
openapi: 3.1.0
info:
  title: Fluid Commerce v2026-04 API
  version: v2026-04
  description: >-
    Post-checkout order editing — atomically insert items and adjustments into
    existing orders. Powers integrations like droplet-driven free-gift flows.
  contact:
    email: support@fluid.app
  license:
    name: Proprietary
    identifier: LicenseRef-Proprietary
servers:
  - url: https://api.fluid.app
  - url: https://{company}.fluid.app
    description: Production server with company subdomain
    variables:
      company:
        default: myco
        description: Company subdomain
security: []
tags:
  - name: order_edits
    description: >-
      Post-checkout order editing — atomically insert items and add adjustments
      or discounts to existing orders, with an optional dry-run preview of the
      recalculated totals.
  - name: orders
    description: >-
      Company order listing — a cursor-paginated, Elasticsearch-backed index of
      the authenticated company's orders, with free-text search and filtering on
      status, type, country, customer, rep, subscription and effective sale
      date.
paths:
  /api/v202604/orders:
    get:
      tags:
        - orders
      summary: List the company's orders
      description: |
        Cursor-paginated index of the authenticated company's orders,
        resolved entirely from Elasticsearch — filtering, sorting and
        pagination all happen in the search index rather than in Postgres.

        Two deliberate differences from `GET /api/v202506/orders`:

        - **No stats block.** The response `meta` carries pagination only.
          Aggregate figures (total and average CV, total and average
          amount, fulfilled count) come from
          `GET /api/v202506/orders/stats`, which is cached and built for
          them. Computing a whole-set aggregation on every page of a list
          endpoint is what made the v2025-06 index expensive.
        - **No SQL fallback.** If the search index cannot answer, this
          endpoint returns `503` rather than quietly running the slow
          query it exists to replace. Callers that need availability over
          index freshness should stay on v2025-06.

        Cursors are Elasticsearch `search_after` tokens. They are opaque:
        echo `meta.pagination.next_cursor` back as `page[cursor]` to walk
        forward and `prev_cursor` to walk back. They are **not**
        interchangeable with the v2025-06 Rotulus cursors.

        Visibility follows the authenticated credential, never a
        parameter: a company admin sees the company's orders, and a rep
        sees only the orders they hold volume credit on plus their own
        purchases.

        Unlike `GET /api/v202506/orders`, this surface does **not** accept
        customer JWTs — a customer token is rejected with 401. Customers
        read their own orders from
        `GET /api/checkout/v2026-04/customers/me/orders`.
      operationId: commerce_v2026_04_list_orders
      parameters:
        - name: search
          in: query
          required: false
          description: |
            Free-text search. Matches substrings, so a partial value finds the
            row — pasting `4821` finds order number `F148217`.

            Searches, in one pass:

            * the order's `order_number`, `email`, `first_name`, `last_name`,
              `phone` and `external_id`
            * the buyer's full name and the owning member's full name and
              email
            * the order's numeric id, its `number` sequence, and the
              customer's legacy id

            Every term must match, and all of them must match within a single
            one of those fields. Full names are indexed joined for exactly
            this reason, so `jane smith` finds an order whose first and last
            name columns hold one word each.
          schema:
            type: string
          example: jane
        - name: sort
          in: query
          required: false
          description: |
            Sort key. A leading `-` reverses the direction. Defaults to
            `-sale_date` (newest first by effective sale date, which is the
            order's `sale_date` falling back to `created_at`).
          schema:
            type: string
            enum:
              - sale_date
              - '-sale_date'
              - created_at
              - '-created_at'
              - id
              - '-id'
              - order_status
              - '-order_status'
              - status
              - '-status'
              - customer_name
              - '-customer_name'
              - customer
              - '-customer'
              - amount
              - '-amount'
          example: '-sale_date'
        - name: page[cursor]
          in: query
          required: false
          description: |
            Opaque `search_after` cursor from a previous response's
            `meta.pagination.next_cursor` or `prev_cursor`. Omit for the
            first page. A malformed cursor returns 422.
          schema:
            type: string
        - name: page[limit]
          in: query
          required: false
          description: Page size. Defaults to 25, capped at 100.
          schema:
            type: integer
            minimum: 1
            maximum: 100
          example: 25
        - name: filter[status]
          in: query
          required: false
          description: |
            Restrict to one order status. The sentinel `all` imposes no
            constraint and is equivalent to omitting the filter.
          schema:
            type: string
            enum:
              - all
              - draft
              - pending
              - pending_review
              - processing
              - completed
              - cancelled
              - archived
          example: completed
        - name: filter[type]
          in: query
          required: false
          description: Restrict to one order class.
          schema:
            type: string
            enum:
              - sample_order
              - customer_order
              - member_order
              - enrollment_order
              - autoship_order
          example: customer_order
        - name: filter[order_number]
          in: query
          required: false
          description: Exact match on the human-facing order number.
          schema:
            type: string
        - name: filter[cart_source]
          in: query
          required: false
          description: Restrict to orders whose originating cart carried this source value.
          schema:
            type: string
        - name: filter[customer_id]
          in: query
          required: false
          description: >-
            Restrict to one customer's orders, matched on either the owning
            member or a legacy customer id carried on order metadata.
          schema:
            type: integer
        - name: filter[user_company_id]
          in: query
          required: false
          description: >-
            Restrict to orders a given rep holds volume credit on, addressed by
            legacy UserCompany id.
          schema:
            type: integer
        - name: filter[subscription_id]
          in: query
          required: false
          description: Restrict to orders belonging to one subscription.
          schema:
            type: integer
        - name: filter[country_isos]
          in: query
          required: false
          description: >-
            Comma-separated ISO-2 or ISO-3 country codes; matches orders shipped
            to any of them.
          schema:
            type: string
          example: US,CA
        - name: filter[start_date]
          in: query
          required: false
          description: |
            Inclusive lower bound on the effective sale date, as a calendar
            date resolved through `filter[timezone]`.
          schema:
            type: string
            format: date
          example: '2026-08-01'
        - name: filter[end_date]
          in: query
          required: false
          description: |
            Inclusive upper bound on the effective sale date, as a calendar
            date resolved through `filter[timezone]`.
          schema:
            type: string
            format: date
          example: '2026-08-31'
        - name: filter[timezone]
          in: query
          required: false
          description: |
            IANA timezone used to resolve `filter[start_date]` and
            `filter[end_date]` to day boundaries, so a day means the caller's
            day. Defaults to UTC; `Etc/Unknown` is treated as absent. An
            unrecognised zone returns 422.
          schema:
            type: string
          example: America/New_York
      responses:
        '200':
          description: A page of orders, newest first unless `sort` says otherwise.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrderListResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '503':
          $ref: '#/components/responses/SearchUnavailable'
      security:
        - bearer_auth: []
components:
  schemas:
    OrderListResponse:
      type: object
      description: |
        A page of orders. `meta` carries pagination only — this surface
        publishes no stats block; see `GET /api/v202506/orders/stats`.
      required:
        - orders
        - status
        - meta
      properties:
        orders:
          type: array
          description: The orders on this page, in the requested sort order.
          items:
            $ref: '#/components/schemas/OrderListItem'
        status:
          type: integer
          description: HTTP status code, repeated in the body (`200` on success).
        meta:
          type: object
          description: >-
            Response metadata — request correlation fields plus cursor
            pagination.
          properties:
            request_id:
              type:
                - string
                - 'null'
              description: Server-assigned identifier for this request.
            timestamp:
              type: string
              format: date-time
              description: Server time the response was generated.
            pagination:
              $ref: '#/components/schemas/CursorPagination'
              description: Cursor pagination for walking the result set.
    OrderListItem:
      type: object
      description: |
        One order as rendered by the list index. A summary shape tuned for
        table rows — the money and volume figures plus just enough customer,
        first-item and subscription context to render a line without a
        follow-up request. Additional fields may be present; treat this as
        the documented subset rather than an exhaustive contract.
      properties:
        id:
          type: integer
          description: The order's primary-key id.
        order_number:
          type: string
          description: Human-facing order number shown to buyers and staff.
        token:
          type: string
          description: URL-safe public token for the order.
        order_status:
          type: string
          description: Lifecycle status (e.g. `completed`, `cancelled`).
        financial_status:
          type: string
          description: Payment state (e.g. `paid`, `pending`, `refunded`).
        fulfillment_status:
          type: string
          description: Fulfilment state (e.g. `unfulfilled`, `fulfilled`).
        status:
          type: string
          description: >-
            Legacy combined status retained for compatibility with the v2025-06
            payload.
        sale_date:
          type:
            - string
            - 'null'
          format: date-time
          description: >-
            When the sale was recorded. Null for orders that never had one set;
            the index sorts such orders by `created_at`.
        created_at:
          type: string
          format: date-time
          description: When the order row was created.
        updated_at:
          type: string
          format: date-time
          description: When the order was last modified.
        email:
          type:
            - string
            - 'null'
          description: Buyer email captured on the order.
        first_name:
          type:
            - string
            - 'null'
          description: Buyer first name captured on the order.
        last_name:
          type:
            - string
            - 'null'
          description: Buyer last name captured on the order.
        external_id:
          type:
            - string
            - 'null'
          description: Caller-supplied identifier from an external system.
        source:
          type: string
          description: Channel the order originated from (e.g. `web`, `admin`).
        currency_code:
          type: string
          description: ISO 4217 currency code for this order's money amounts.
        currency_symbol:
          type:
            - string
            - 'null'
          description: Display symbol for the order's currency.
        amount:
          type: string
          description: Checkout total, as a decimal string.
        amount_in_base:
          type: string
          description: Checkout total converted to the company's base currency.
        total_display_amount:
          type: string
          description: Pre-formatted total for display, after any points redemption.
        total_cv:
          type: string
          description: Commissionable volume, as a whole-number decimal string.
        total_qv:
          type: string
          description: Qualifying volume, as a whole-number decimal string.
        items_count:
          type: integer
          description: Number of distinct line items on the order.
        quantity_count:
          type: integer
          description: Total quantity summed across all line items.
        customer:
          type:
            - object
            - 'null'
          description: >-
            Lightweight buyer summary; absent when the order has no resolvable
            customer.
          properties:
            id:
              type: integer
              description: Customer primary-key id.
            full_name:
              type:
                - string
                - 'null'
              description: Customer's display name.
            email:
              type:
                - string
                - 'null'
              description: Customer's email address.
        first_item:
          type:
            - object
            - 'null'
          description: >-
            Title and thumbnail of the first line item, for the row preview;
            null when the order has no items.
          properties:
            title:
              type:
                - string
                - 'null'
              description: First item's title.
            image_url:
              type:
                - string
                - 'null'
              description: First item's image URL.
        subscription:
          type:
            - object
            - 'null'
          description: >-
            The subscription this order belongs to, when it came from one; null
            otherwise.
          properties:
            subscription_token:
              type: string
              description: Public token of the owning subscription.
            status:
              type:
                - string
                - 'null'
              description: Current status of the owning subscription.
    CursorPagination:
      type: object
      description: |
        Cursor pagination metadata. Cursors are opaque Elasticsearch
        `search_after` tokens — echo them back verbatim. Unlike the
        v2025-06 index this carries no `total_pages` / `current_page`:
        cursor pagination has no page number to report.
      properties:
        cursor:
          type:
            - string
            - 'null'
          description: The cursor this page was fetched with; null on the first page.
        limit:
          type: integer
          description: Page size used for this request.
        prev_cursor:
          type:
            - string
            - 'null'
          description: Cursor for the previous page; null on the first page.
        next_cursor:
          type:
            - string
            - 'null'
          description: Cursor for the next page; null when this is the last page.
        total_count:
          type: integer
          description: Exact number of orders matching the query across all pages.
    UnauthorizedError:
      type: object
      description: |
        Bare 401 body — a single `message` string, not the wrapped
        `ErrorResponse`.
      required:
        - message
      properties:
        message:
          type: string
          description: >-
            Human-readable reason the credential was rejected (e.g. missing or
            invalid bearer token).
          example: Invalid credentials.
    ForbiddenError:
      description: |
        One of the three 403 bodies:
        - bare `{ message }` when the credential is not company-admin tier
          (e.g. a rep token)
        - bare `{ error }` when the admin-tier credential lacks the
          `orders.update` permission
        - the wrapped `ErrorResponse` when the credential has `orders.update`
          but sends an override-shaped operation without the
          `orders.override` permission
      oneOf:
        - type: object
          required:
            - message
          properties:
            message:
              type: string
              description: |
                Authorization failure message. Present on the bare-`message`
                403 body returned when the credential is not company-admin
                tier (e.g. a rep token).
              example: Not authorized.
        - type: object
          required:
            - error
          properties:
            error:
              type: string
              description: |
                Authorization failure message. Present on the bare-`error`
                403 body returned when an admin-tier credential lacks the
                `orders.update` permission.
              example: Not authorized.
        - $ref: '#/components/schemas/ErrorResponse'
    ErrorResponse:
      type: object
      required:
        - error
        - status
        - meta
      properties:
        error:
          type: object
          description: >-
            Error detail object carrying the human-readable `message` and
            optional field-level `details`.
          required:
            - message
          properties:
            message:
              type: string
              description: Human-readable summary of what went wrong.
            details:
              type: object
              additionalProperties:
                $ref: '#/components/schemas/JsonValue'
              description: Field-level error details (e.g. failed validations).
        status:
          type: integer
          description: >-
            HTTP status code of the error, repeated in the body for convenience
            (e.g. `422`).
        meta:
          $ref: '#/components/schemas/Meta'
          description: Response metadata (`request_id` and `timestamp`).
    JsonValue:
      description: >-
        Any valid JSON value for provider, integration, theme, metadata, or
        other dynamic payloads whose keys are not fixed by the API contract.
      anyOf:
        - type: string
        - type: number
        - type: boolean
        - type: 'null'
        - type: array
          items:
            $ref: '#/components/schemas/JsonValue'
        - type: object
          additionalProperties:
            $ref: '#/components/schemas/JsonValue'
    Meta:
      type: object
      properties:
        request_id:
          type:
            - string
            - 'null'
          description: |
            Server-assigned identifier for this request, echoed for
            correlation with logs and support; `null` when none was assigned.
        timestamp:
          type: string
          format: date-time
          description: >-
            Server time the response was generated, as an ISO-8601 UTC
            timestamp.
  responses:
    Unauthorized:
      description: |
        Missing or invalid bearer token. The body is a bare `{ message }`
        object — not the wrapped `ErrorResponse` envelope used by
        400 / 404 / 422.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/UnauthorizedError'
    Forbidden:
      description: |
        Authenticated but not authorized. Three paths produce 403, each
        with its own body shape:
        - Credential is not company-admin tier (e.g. a rep token) —
          bare `{ message }`.
        - Admin tier but missing the `orders.update` permission —
          bare `{ error }`.
        - Has `orders.update` but sends an override-shaped operation
          (an adjustment op, a line-item op flagged `overridden: true`,
          or a manual-source discount op) without the `orders.override`
          permission — wrapped `ErrorResponse`.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ForbiddenError'
    UnprocessableEntity:
      description: >-
        Business error (e.g. variant not found, editor failure, cross-company
        discount).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    SearchUnavailable:
      description: |
        The search index could not answer the request. Returned by the
        orders index, which resolves entirely from Elasticsearch and has
        no SQL fallback — a slow fallback would hide the outage and
        reintroduce the database load the endpoint exists to avoid. The
        request is safe to retry.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
  securitySchemes:
    bearer_auth:
      type: http
      scheme: bearer
      description: |
        Bearer token authentication. Accepts company tokens, partner tokens,
        public tokens, droplet installation tokens, and user_company tokens.
        The authenticated credential determines `editor_type` and `editor_id`
        on the resulting order-edit audit records — the payload never carries
        either field.

````