> ## 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.

# Get user information in mobile and Portal widgets

> Use the public_id query parameter and your Droplet installation token to resolve user information for mobile custom widgets and Portal iframe widgets.

Fluid adds a `public_id` query parameter before it opens either of these widgets:

* A custom widget in the Fluid mobile app
* A Droplet iframe widget in Portal

For example, Fluid can open your widget at this URL:

```text theme={null}
https://widgets.example.com/earnings?public_id=0190a1b2-c3d4-7000-8000-000000000001
```

Use `public_id` to resolve the current user's information from your server. Do not use it to authenticate the user or the API request.

<Warning>
  Treat `public_id` as an opaque identifier. It is not a username, slug, user UUID,
  customer UUID, legacy numeric membership ID, or Bearer token.
</Warning>

## What `public_id` identifies

`public_id` is a stable, company-scoped identity identifier. For an ordinary member-backed account, it is the member's stable UUID. An admin-only account can receive an admin identity UUID instead.

Do not parse the value or infer a record type from it. Send it to the resolver and use the returned user data.

## Resolve the user from your server

Keep your Droplet installation token on your server. Never expose it in iframe JavaScript, mobile widget content, a query parameter, or a response to the browser.

<Steps>
  <Step title="Read public_id from the widget URL">
    Read the value as an opaque string. Handle a missing value before you request user information.

    ```javascript theme={null}
    const query = new URLSearchParams(window.location.search);
    const publicId = query.get("public_id");

    if (!publicId) {
      throw new Error("Fluid did not provide public_id");
    }
    ```
  </Step>

  <Step title="Send public_id to your server">
    Send the value to an authenticated route in your widget application. Your server must select the Droplet installation for the current company. Do not accept a company identifier from the browser as proof of that selection.

    ```javascript theme={null}
    const response = await fetch("/api/widget-user", {
      method: "POST",
      credentials: "include",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ public_id: publicId }),
    });
    ```
  </Step>

  <Step title="Call the Fluid resolver">
    From your server, call `GET /api/v2025-06/users/by-public-id/{public_id}`. Authenticate with the installation token for the company that owns the widget.

    ```javascript theme={null}
    const fluidResponse = await fetch(
      `https://api.fluid.app/api/v2025-06/users/by-public-id/${encodeURIComponent(publicId)}`,
      {
        headers: {
          Authorization: `Bearer ${installation.authenticationToken}`,
        },
      },
    );
    ```

    The resolver searches only the company associated with the Bearer token. It does not create a Fluid session or turn `public_id` into a login credential.
  </Step>
</Steps>

## Request the required scope

Request the `users` scope for your Droplet before a company installs it. The resolver returns `403` when the installation does not have this scope.

Use the installation's `authentication_token` as the Bearer token. See [Build and publish a Fluid Droplet](/guides/creating-droplets) for the installation credential flow.

## Handle resolver errors

Handle each response separately:

| Status | Meaning                                                     | Action                                                                                   |
| ------ | ----------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| `401`  | The Bearer token is missing or invalid.                     | Check the stored installation credential. Do not retry with `public_id` as a credential. |
| `403`  | The installation does not have the `users` scope.           | Update the Droplet's requested scopes and reinstall it.                                  |
| `404`  | No matching membership exists in the authenticated company. | Show an unavailable state. Do not search another company.                                |
