> ## Documentation Index
> Fetch the complete documentation index at: https://dev.moonpay.com/llms.txt
> Use this file to discover all available pages before exploring further.

# client.setupAuth()

> Render the Auth frame to authenticate a customer with email and OTP.

Render the Auth frame into your UI to authenticate the customer with email and
a one-time passcode. The Auth frame is the lighter-weight counterpart to
[`client.connect()`](/platform/sdk-reference/web/connect) for headless and
Identity API integrations — it handles authentication only, with no
payment-method setup or KYC steps. When the customer finishes, the SDK
decrypts the returned credentials and primes the client so that subsequent SDK
calls are authenticated automatically.

<Callout icon="circle-info" iconType="regular">
  Call [`client.getConnection()`](/platform/sdk-reference/web/get-connection)
  first. The connection check primes the client with the token the Auth frame
  needs. If you call `setupAuth()` without a prior connection check that
  resolved with `status: "connectionRequired"`, it returns a
  `configurationError`.
</Callout>

```ts Setup auth focus={5-30} theme={null}
import { createClient, type AuthEvent } from "@moonpay/platform-sdk-web";

const client = createClient({ sessionToken: "c3N0XzAwMQ==" });

const connectionResult = await client.getConnection({ skipKyc: true });

if (!connectionResult.ok) {
  // Handle error
  return;
}

if (connectionResult.value.status === "connectionRequired") {
  const authResult = await client.setupAuth({
    container: document.querySelector("#authContainer"),
    onEvent: (event: AuthEvent) => {
      switch (event.kind) {
        case "ready":
          // The auth UI is rendered. Reveal the container if you hide it while loading.
          break;
        case "complete":
          if (event.payload.status === "active") {
            // Customer authenticated — SDK calls are now authenticated.
            console.log(event.payload.customer.id);
          }
          break;
        case "error":
          console.error(event.payload);
          break;
      }
    },
  });

  if (!authResult.ok) {
    // Handle error
    console.error(authResult.error.kind, authResult.error.message);
    return;
  }

  // Remove the frame from the DOM now that the flow has completed:
  authResult.value.dispose();
}
```

<Callout icon="circle-info" iconType="regular">
  The promise returned by `client.setupAuth()` resolves after the customer
  completes the auth flow (or an error ends it). Track flow progress — including
  the moment the UI is ready to show — through `onEvent`, not by awaiting the
  promise.
</Callout>

***

## Parameters

| Field       | Type                         | Required | Description                                                           |
| ----------- | ---------------------------- | -------- | --------------------------------------------------------------------- |
| `container` | `HTMLElement`                | ✅        | A DOM element to render the Auth frame into.                          |
| `onEvent`   | `(event: AuthEvent) => void` |          | Callback invoked for auth flow events. See [`AuthEvent`](#authevent). |

### `AuthEvent`

`onEvent` receives events as the auth flow progresses. Use `event.kind` to
decide how to handle each event.

| kind         | Payload                                                               | When you receive it                                                                                                                      |
| ------------ | --------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `"ready"`    | —                                                                     | The auth UI is rendered and ready to be shown.                                                                                           |
| `"complete"` | [`Connection`](/platform/sdk-reference/web/get-connection#connection) | The customer authenticated. `status` is `"active"`, or `"termsAcceptanceRequired"` when a Terms of Use attestation is still outstanding. |
| `"error"`    | [`AuthEventError`](#autheventerror)                                   | The flow encountered an error.                                                                                                           |

#### `AuthEventError`

The error event payload comes from the underlying auth frame. It is
discriminated by `code`.

| Field     | Type                                  | Required | Description                                                            |
| --------- | ------------------------------------- | -------- | ---------------------------------------------------------------------- |
| `code`    | `"validationError"` \| `"generic"`    | ✅        | The error category.                                                    |
| `errors`  | `{ code: string; message: string }[]` |          | Field-level errors. Present when `code` is `"validationError"`.        |
| `message` | `string`                              |          | Developer-friendly details. May be present when `code` is `"generic"`. |

## Result

`client.setupAuth()` returns a `Result<AuthFrame, SetupAuthError>`.

### Result envelope

`Result<AuthFrame, SetupAuthError>`

| Field   | Type                                | Required | Description                      |
| ------- | ----------------------------------- | -------- | -------------------------------- |
| `ok`    | `boolean`                           | ✅        | Whether the operation succeeded. |
| `value` | [`AuthFrame`](#authframe)           |          | Present when `ok` is `true`.     |
| `error` | [`SetupAuthError`](#setupautherror) |          | Present when `ok` is `false`.    |

### `AuthFrame`

| Field     | Type         | Required | Description                                                                                           |
| --------- | ------------ | -------- | ----------------------------------------------------------------------------------------------------- |
| `dispose` | `() => void` | ✅        | Unmounts the frame. After you call this, no further events are dispatched to your `onEvent` callback. |

### `SetupAuthError`

| Field     | Type                                       | Required | Description                                                                                             |
| --------- | ------------------------------------------ | -------- | ------------------------------------------------------------------------------------------------------- |
| `kind`    | `"configurationError"` \| `"genericError"` | ✅        | The error category. `"configurationError"` means the client has no token from a prior connection check. |
| `message` | `string`                                   | ✅        | Developer-friendly details.                                                                             |

<Accordion title="TS Definitions">
  ```ts types.ts theme={null}
  type AuthFrame = {
    dispose: () => void;
  };

  type AuthEvent =
    | { kind: "ready" }
    | {
        kind: "complete";
        /** status is "active" or "termsAcceptanceRequired" */
        payload: Connection;
      }
    | { kind: "error"; payload: AuthEventError };

  type AuthEventError =
    | {
        code: "validationError";
        errors: { code: string; message: string }[];
      }
    | {
        code: "generic";
        message?: string;
      };

  type SetupAuthError = {
    kind: "configurationError" | "genericError";
    message: string;
  };
  ```
</Accordion>
