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

# StackApp

> Reference documentation for HexclaveClientApp and HexclaveServerApp objects.

export const MethodReturns = ({type, children}) => <ContentSection title="Returns">
    <code className="inline-flex rounded-md border border-zinc-950/10 bg-zinc-950/[0.04] px-2 py-0.5 text-[13px] font-medium text-zinc-950 dark:border-white/10 dark:bg-white/[0.08] dark:text-white">
      {type}
    </code>
    {children ? <div className="text-sm leading-6 text-zinc-700 dark:text-zinc-300">{children}</div> : null}
  </ContentSection>;

export const MethodLayout = ({children}) => <div className="grid gap-4 md:grid-cols-2 md:items-start xl:gap-6">
    {children}
  </div>;

export const MethodContent = ({children}) => <div className="min-w-0 space-y-4">{children}</div>;

export const MethodAside = ({title, children}) => <div className="min-w-0 self-start space-y-4 rounded-2xl border border-zinc-950/10 bg-zinc-950/[0.02] p-4 dark:border-white/10 dark:bg-white/[0.03]">
    {title ? <p className="m-0 text-sm font-medium text-zinc-950 dark:text-white">{title}</p> : null}
    <div className="space-y-4">{children}</div>
  </div>;

export const ContentSection = ({title, children}) => <div className="space-y-3">
    {title ? <p className="m-0 text-sm font-medium text-zinc-950 dark:text-white">{title}</p> : null}
    <div className="space-y-3">{children}</div>
  </div>;

export const AsideSection = ({title, children}) => <div className="space-y-3">
    {title ? <p className="m-0 text-sm font-medium text-zinc-950 dark:text-white">{title}</p> : null}
    <div className="space-y-3">{children}</div>
  </div>;

This is a detailed reference for the `StackApp` object. For setup instructions, see [Setup](/guides/getting-started/setup).

## Overview

* [HexclaveClientApp](#stackclientapp) - Client-level permissions for frontend code
* [HexclaveServerApp](#stackserverapp) - Server-level permissions with full access

***

# HexclaveClientApp

A `StackApp` with client-level permissions. It contains most of the useful methods and hooks for your client-side code.

Most commonly you get an instance of `HexclaveClientApp` by calling [`useHexclaveApp()`](/sdk/hooks/use-hexclave-app) in a Client Component.

## Table of Contents

```typescript theme={null}
type HexclaveClientApp = {
  new(options): HexclaveClientApp;

  getUser([options]): Promise<User>;
  useUser([options]): User;
  getProject(): Promise<Project>;
  useProject(): Project;

  signInWithOAuth(provider): void;
  signInWithCredential([options]): Promise<...>;
  signUpWithCredential([options]): Promise<...>;
  sendForgotPasswordEmail(email): Promise<...>;
  sendMagicLinkEmail(email): Promise<...>;
};
```

## Constructor

Creates a new `HexclaveClientApp` instance.

Because each app creates a new connection to Hexclave's backend, you should re-use existing instances wherever possible.

<Info>
  This object is not usually constructed directly. More commonly, you would construct a [`HexclaveServerApp`](#stackserverapp) instead, pass it into your app setup (see the [setup guide](/guides/getting-started/setup)), and then use the `useHexclaveApp()` hook to obtain a `HexclaveClientApp`.

  The [setup wizard](/guides/getting-started/setup) does these steps for you, so you don't need to worry about it unless you are manually setting up Hexclave.

  If you're building a client-only app and don't have a `HEXCLAVE_SECRET_SERVER_KEY`, you can construct a `HexclaveClientApp` directly.
</Info>

<MethodLayout>
  <MethodContent>
    <ContentSection title="Parameters">
      <ParamField body="tokenStore" type="&#x22;nextjs-cookie&#x22; | &#x22;cookie&#x22; | { accessToken, refreshToken } | Request" required>
        Token storage configuration.
      </ParamField>

      <ParamField body="baseUrl" type="string">
        Base URL for the Hexclave API.
      </ParamField>

      <ParamField body="projectId" type="string">
        Project ID. Defaults to the `NEXT_PUBLIC_HEXCLAVE_PROJECT_ID` environment variable.
      </ParamField>

      <ParamField body="publishableClientKey" type="string">
        Publishable client key. Defaults to the `NEXT_PUBLIC_HEXCLAVE_PUBLISHABLE_CLIENT_KEY` environment variable.
      </ParamField>

      <ParamField body="urls" type="object">
        Redirect URL configuration.
      </ParamField>

      <ParamField body="analytics" type="object">
        Analytics capture configuration. SDK-managed capture is enabled by default; pass `{ enabled: false }` to disable it entirely, or `{ replays: { enabled: true } }` to record session replays.
      </ParamField>

      <ParamField body="noAutomaticPrefetch" type="boolean">
        Disable automatic prefetching.
      </ParamField>
    </ContentSection>
  </MethodContent>

  <MethodAside>
    <AsideSection title="Signature">
      ```typescript theme={null}
      declare class HexclaveClientApp {
        constructor(options: {
          tokenStore: "nextjs-cookie" | "cookie" | {
            accessToken: string;
            refreshToken: string;
          } | Request;
          baseUrl?: string;
          projectId?: string;
          publishableClientKey?: string;
          urls?: object;
          analytics?: object;
          noAutomaticPrefetch?: boolean;
        });
      }
      ```
    </AsideSection>

    <AsideSection title="Examples">
      ```typescript theme={null}
      const hexclaveClientApp = new HexclaveClientApp({
        tokenStore: "nextjs-cookie",
        baseUrl: "https://api.hexclave.com",
        projectId: "123",
        publishableClientKey: "123",
        urls: {
          home: "/",
        },
      });
      ```

      ```typescript theme={null}
      "use client";

      function MyReactComponent() {
        const hexclaveClientApp = useHexclaveApp();
      }
      ```
    </AsideSection>
  </MethodAside>
</MethodLayout>

## User Management

### `hexclaveClientApp.getUser([options])`

<MethodLayout>
  <MethodContent>
    Gets the current user.

    <ContentSection title="Parameters">
      <ParamField body="options.or" type="&#x22;return-null&#x22; | &#x22;redirect&#x22; | &#x22;throw&#x22;">
        What to do if the user is not found.
      </ParamField>
    </ContentSection>

    <MethodReturns type="Promise<CurrentUser | null>" />
  </MethodContent>

  <MethodAside>
    <AsideSection title="Signature">
      ```typescript theme={null}
      declare function getUser(options?: {
        or?: "return-null" | "redirect" | "throw";
      }): Promise<CurrentUser | null>;
      ```
    </AsideSection>

    <AsideSection title="Examples">
      ```typescript theme={null}
      const userOrNull = await hexclaveClientApp.getUser();
      console.log(userOrNull);

      const user = await hexclaveClientApp.getUser({ or: "redirect" });
      console.log(user);
      ```
    </AsideSection>
  </MethodAside>
</MethodLayout>

### `hexclaveClientApp.useUser([options])`

<MethodLayout>
  <MethodContent>
    React hook version of `getUser()`. Equivalent to the [`useUser()`](/sdk/hooks/use-user) standalone hook, which is an alias for `useHexclaveApp().useUser()`.

    <ContentSection title="Parameters">
      <ParamField body="options.or" type="&#x22;return-null&#x22; | &#x22;redirect&#x22; | &#x22;throw&#x22;">
        What to do if the user is not found.
      </ParamField>
    </ContentSection>

    <MethodReturns type="CurrentUser | null" />
  </MethodContent>

  <MethodAside>
    <AsideSection title="Signature">
      ```typescript theme={null}
      declare function useUser(options?: {
        or?: "return-null" | "redirect" | "throw";
      }): CurrentUser | null;
      ```
    </AsideSection>

    <AsideSection title="Examples">
      ```jsx theme={null}
      "use client";

      function MyReactComponent() {
        const user = useUser();
        return user ? <div>Hello, {user.name}</div> : <div>Not signed in</div>;
      }
      ```

      ```tsx theme={null}
      "use client";

      function MyProtectedComponent() {
        useUser({ or: "redirect" });
        return <div>You can only see this if you are authenticated</div>;
      }
      ```
    </AsideSection>
  </MethodAside>
</MethodLayout>

### `hexclaveClientApp.getProject()`

<MethodLayout>
  <MethodContent>
    Gets the current project.

    <MethodReturns type="Promise<Project>" />
  </MethodContent>

  <MethodAside>
    <AsideSection title="Signature">
      ```typescript theme={null}
      declare function getProject(): Promise<Project>;
      ```
    </AsideSection>

    <AsideSection title="Examples">
      ```typescript theme={null}
      const project = await hexclaveClientApp.getProject();
      ```
    </AsideSection>
  </MethodAside>
</MethodLayout>

### `hexclaveClientApp.useProject()`

<MethodLayout>
  <MethodContent>
    React hook version of `getProject()`.

    <MethodReturns type="Project" />
  </MethodContent>

  <MethodAside>
    <AsideSection title="Signature">
      ```typescript theme={null}
      declare function useProject(): Project;
      ```
    </AsideSection>

    <AsideSection title="Examples">
      ```typescript theme={null}
      function MyReactComponent() {
        const project = useProject();
      }
      ```
    </AsideSection>
  </MethodAside>
</MethodLayout>

## Authentication

### `hexclaveClientApp.signInWithOAuth(provider)`

<MethodLayout>
  <MethodContent>
    Initiates the OAuth sign-in process with the specified provider.

    <ContentSection title="Parameters">
      <ParamField body="provider" type="string">
        The OAuth provider type.
      </ParamField>
    </ContentSection>

    <MethodReturns type="Promise<void>" />
  </MethodContent>

  <MethodAside>
    <AsideSection title="Signature">
      ```typescript theme={null}
      declare function signInWithOAuth(provider: string): Promise<void>;
      ```
    </AsideSection>

    <AsideSection title="Examples">
      ```typescript theme={null}
      await hexclaveClientApp.signInWithOAuth("google");
      ```
    </AsideSection>
  </MethodAside>
</MethodLayout>

### `hexclaveClientApp.signInWithCredential([options])`

<MethodLayout>
  <MethodContent>
    Sign in using email and password credentials.

    <ContentSection title="Parameters">
      <ParamField body="options.email" type="string">
        User's email.
      </ParamField>

      <ParamField body="options.password" type="string">
        User's password.
      </ParamField>

      <ParamField body="options.noRedirect" type="boolean">
        Whether to skip redirect after sign-in.
      </ParamField>
    </ContentSection>

    <MethodReturns type="Promise<Result<undefined, KnownErrors[&#x22;EmailPasswordMismatch&#x22;]>>" />
  </MethodContent>

  <MethodAside>
    <AsideSection title="Signature">
      ```typescript theme={null}
      declare function signInWithCredential(options?: {
        email?: string;
        password?: string;
        noRedirect?: boolean;
      }): Promise<Result<undefined, KnownErrors["EmailPasswordMismatch"]>>;
      ```
    </AsideSection>

    <AsideSection title="Examples">
      ```typescript theme={null}
      const result = await hexclaveClientApp.signInWithCredential({
        email: "test@example.com",
        password: "password",
      });

      if (result.status === "error") {
        console.error("Sign in failed", result.error.message);
      }
      ```
    </AsideSection>
  </MethodAside>
</MethodLayout>

### `hexclaveClientApp.signUpWithCredential([options])`

<MethodLayout>
  <MethodContent>
    Sign up using email and password credentials.

    <ContentSection title="Parameters">
      <ParamField body="options.email" type="string">
        User's email.
      </ParamField>

      <ParamField body="options.password" type="string">
        User's password.
      </ParamField>

      <ParamField body="options.noRedirect" type="boolean">
        Whether to skip redirect after sign-up.
      </ParamField>
    </ContentSection>

    <MethodReturns type="Promise<Result<undefined, KnownErrors[&#x22;UserWithEmailAlreadyExists&#x22;] | KnownErrors[&#x22;PasswordRequirementsNotMet&#x22;]>>" />
  </MethodContent>

  <MethodAside>
    <AsideSection title="Signature">
      ```typescript theme={null}
      declare function signUpWithCredential(options?: {
        email?: string;
        password?: string;
        noRedirect?: boolean;
      }): Promise<Result<
        undefined,
        KnownErrors["UserWithEmailAlreadyExists"] | KnownErrors["PasswordRequirementsNotMet"]
      >>;
      ```
    </AsideSection>

    <AsideSection title="Examples">
      ```typescript theme={null}
      const result = await hexclaveClientApp.signUpWithCredential({
        email: "test@example.com",
        password: "password",
      });

      if (result.status === "error") {
        console.error("Sign up failed", result.error.message);
      }
      ```
    </AsideSection>
  </MethodAside>
</MethodLayout>

### `hexclaveClientApp.sendForgotPasswordEmail(email)`

<MethodLayout>
  <MethodContent>
    Send a forgot-password email to an email address.

    <ContentSection title="Parameters">
      <ParamField body="email" type="string">
        The email to send the forgot-password email to.
      </ParamField>
    </ContentSection>

    <MethodReturns type="Promise<Result<undefined, KnownErrors[&#x22;UserNotFound&#x22;]>>" />
  </MethodContent>

  <MethodAside>
    <AsideSection title="Signature">
      ```typescript theme={null}
      declare function sendForgotPasswordEmail(
        email: string,
      ): Promise<Result<undefined, KnownErrors["UserNotFound"]>>;
      ```
    </AsideSection>

    <AsideSection title="Examples">
      ```typescript theme={null}
      const result = await hexclaveClientApp.sendForgotPasswordEmail("test@example.com");

      if (result.status === "success") {
        console.log("Forgot password email sent");
      } else {
        console.error("Failed to send forgot password email", result.error.message);
      }
      ```
    </AsideSection>
  </MethodAside>
</MethodLayout>

### `hexclaveClientApp.sendMagicLinkEmail(email)`

<MethodLayout>
  <MethodContent>
    Send a magic-link or OTP sign-in email to an email address.

    <ContentSection title="Parameters">
      <ParamField body="email" type="string">
        The email to send the magic link to.
      </ParamField>
    </ContentSection>

    <MethodReturns type="Promise<Result<{ nonce: string }, KnownErrors[&#x22;RedirectUrlNotWhitelisted&#x22;]>>" />
  </MethodContent>

  <MethodAside>
    <AsideSection title="Signature">
      ```typescript theme={null}
      declare function sendMagicLinkEmail(
        email: string,
      ): Promise<Result<{ nonce: string }, KnownErrors["RedirectUrlNotWhitelisted"]>>;
      ```
    </AsideSection>

    <AsideSection title="Examples">
      ```typescript theme={null}
      const result = await hexclaveClientApp.sendMagicLinkEmail("test@example.com");
      ```
    </AsideSection>
  </MethodAside>
</MethodLayout>

***

# HexclaveServerApp

Like `HexclaveClientApp`, but with server permissions. Has full read and write access to all users.

<Warning>
  Since this functionality should only be available in environments you trust
  (ie. your own server), it requires a `HEXCLAVE_SECRET_SERVER_KEY`. In some cases, you
  may want to use a `HexclaveServerApp` on the client; an example for this is an
  internal dashboard that only your own employees have access to. We generally
  recommend against doing this unless you are aware of and protected against the
  (potentially severe) security implications of exposing `HEXCLAVE_SECRET_SERVER_KEY` on
  the client.
</Warning>

## Table of Contents

```typescript theme={null}
type HexclaveServerApp =
  // Inherits all functionality from HexclaveClientApp
  & HexclaveClientApp
  & {
    new(options): HexclaveServerApp;

    getUser([id][, options]): Promise<ServerUser | null>;
    useUser([id][, options]): ServerUser;
    listUsers([options]): Promise<ServerUser[]>;
    useUsers([options]): ServerUser[];
    createUser([options]): Promise<ServerUser>;
    sendEmail(options): Promise<Result<void, KnownErrors>>;

    getTeam(id): Promise<ServerTeam | null>;
    useTeam(id): ServerTeam;
    listTeams([options]): Promise<ServerTeam[]>;
    useTeams([options]): ServerTeam[];
    listTeamsPaginated([options]): Promise<{ items: ServerTeam[]; nextCursor: string | null }>;
    useTeamsPaginated([options]): { items: ServerTeam[]; nextCursor: string | null };
    createTeam([options]): Promise<ServerTeam>;
  }
```

## Constructor

Creates a new `HexclaveServerApp` instance.

<MethodLayout>
  <MethodContent>
    <ContentSection title="Parameters">
      <ParamField body="tokenStore" type="&#x22;nextjs-cookie&#x22; | &#x22;cookie&#x22; | { accessToken, refreshToken } | Request" required>
        Token storage configuration.
      </ParamField>

      <ParamField body="baseUrl" type="string">
        Base URL for the Hexclave API.
      </ParamField>

      <ParamField body="projectId" type="string">
        Project ID.
      </ParamField>

      <ParamField body="publishableClientKey" type="string">
        Publishable client key.
      </ParamField>

      <ParamField body="secretServerKey" type="string">
        Secret server key. Defaults to the `HEXCLAVE_SECRET_SERVER_KEY` environment variable.
      </ParamField>

      <ParamField body="urls" type="object">
        Redirect URL configuration.
      </ParamField>

      <ParamField body="noAutomaticPrefetch" type="boolean">
        Disable automatic prefetching.
      </ParamField>
    </ContentSection>
  </MethodContent>

  <MethodAside>
    <AsideSection title="Signature">
      ```typescript theme={null}
      declare class HexclaveServerApp {
        constructor(options: {
          tokenStore: "nextjs-cookie" | "cookie" | {
            accessToken: string;
            refreshToken: string;
          } | Request;
          baseUrl?: string;
          projectId?: string;
          publishableClientKey?: string;
          secretServerKey?: string;
          urls?: object;
          noAutomaticPrefetch?: boolean;
        });
      }
      ```
    </AsideSection>

    <AsideSection title="Examples">
      ```typescript theme={null}
      const hexclaveServerApp = new HexclaveServerApp({
        tokenStore: "nextjs-cookie",
        urls: {
          signIn: "/my-custom-sign-in-page",
        },
      });
      ```
    </AsideSection>
  </MethodAside>
</MethodLayout>

## User Operations

### `hexclaveServerApp.getUser([id], [options])`

<MethodLayout>
  <MethodContent>
    Enhanced version of `HexclaveClientApp.getUser()` with server permissions.

    **Overloads:**

    1. `getUser(id: string): Promise<ServerUser | null>` to get a user by ID.
    2. `getUser(options?: { or?: "return-null" | "redirect" | "throw" }): Promise<CurrentServerUser | null>` to get the current user.
  </MethodContent>

  <MethodAside>
    <AsideSection title="Signature">
      ```typescript theme={null}
      declare function getUser(id: string): Promise<ServerUser | null>;
      declare function getUser(options?: {
        or?: "return-null" | "redirect" | "throw";
      }): Promise<CurrentServerUser | null>;
      ```
    </AsideSection>

    <AsideSection title="Examples">
      ```typescript theme={null}
      const currentUser = await hexclaveServerApp.getUser();
      console.log(currentUser);

      const serverUser = await hexclaveServerApp.getUser(
        "12345678-1234-1234-1234-123456789abc",
      );
      console.log(serverUser);
      ```
    </AsideSection>
  </MethodAside>
</MethodLayout>

### `hexclaveServerApp.useUser([id], [options])`

<MethodLayout>
  <MethodContent>
    Functionally equivalent to [`getUser()`](#stackserverappgetuserid-options), but as a React hook.

    <Info>
      This should be used on the server-side only.
    </Info>
  </MethodContent>

  <MethodAside>
    <AsideSection title="Signature">
      ```typescript theme={null}
      declare function useUser(
        idOrOptions?: string | { or?: "return-null" | "redirect" | "throw" },
        options?: { or?: "return-null" | "redirect" | "throw" },
      ): ServerUser | CurrentServerUser | null;
      ```
    </AsideSection>
  </MethodAside>
</MethodLayout>

### `hexclaveServerApp.listUsers([options])`

<MethodLayout>
  <MethodContent>
    Lists all users on the project.

    <ContentSection title="Parameters">
      <ParamField body="options.cursor" type="string">
        The cursor to start the result set from.
      </ParamField>

      <ParamField body="options.limit" type="number">
        Maximum number of items to return. If omitted, all users are returned.
      </ParamField>

      <ParamField body="options.orderBy" type="&#x22;signedUpAt&#x22;">
        The field to sort results by.
      </ParamField>

      <ParamField body="options.desc" type="boolean">
        Whether to sort in descending order. Defaults to `false`.
      </ParamField>

      <ParamField body="options.query" type="string">
        Free-text search on the user's display name and emails.
      </ParamField>
    </ContentSection>

    <MethodReturns type="Promise<ServerUser[] & { nextCursor: string | null }>" />
  </MethodContent>

  <MethodAside>
    <AsideSection title="Signature">
      ```typescript theme={null}
      declare function listUsers(options?: {
        cursor?: string;
        limit?: number;
        orderBy?: "signedUpAt";
        desc?: boolean;
        query?: string;
      }): Promise<ServerUser[] & { nextCursor: string | null }>;
      ```
    </AsideSection>

    <AsideSection title="Examples">
      ```typescript theme={null}
      const users = await hexclaveServerApp.listUsers({ limit: 20 });
      console.log(users);

      if (users.nextCursor) {
        const nextPageUsers = await hexclaveServerApp.listUsers({
          cursor: users.nextCursor,
          limit: 20,
        });
        console.log(nextPageUsers);
      }
      ```
    </AsideSection>
  </MethodAside>
</MethodLayout>

### `hexclaveServerApp.useUsers([options])`

<MethodLayout>
  <MethodContent>
    Functionally equivalent to [`listUsers()`](#stackserverapplistusersoptions), but as a React hook.

    <Info>This should be used on the server-side only.</Info>
  </MethodContent>

  <MethodAside>
    <AsideSection title="Signature">
      ```typescript theme={null}
      declare function useUsers(options?: {
        cursor?: string;
        limit?: number;
        orderBy?: "signedUpAt";
        desc?: boolean;
        query?: string;
      }): ServerUser[];
      ```
    </AsideSection>
  </MethodAside>
</MethodLayout>

### `hexclaveServerApp.createUser([options])`

<MethodLayout>
  <MethodContent>
    Creates a new user from the server.

    <ContentSection title="Parameters">
      <ParamField body="options.primaryEmail" type="string">
        User's primary email.
      </ParamField>

      <ParamField body="options.primaryEmailVerified" type="boolean">
        Whether the email is verified.
      </ParamField>

      <ParamField body="options.primaryEmailAuthEnabled" type="boolean">
        Whether email auth is enabled.
      </ParamField>

      <ParamField body="options.password" type="string">
        User's password.
      </ParamField>

      <ParamField body="options.otpAuthEnabled" type="boolean">
        Enable OTP or magic-link auth.
      </ParamField>

      <ParamField body="options.displayName" type="string">
        User's display name.
      </ParamField>
    </ContentSection>

    <MethodReturns type="Promise<ServerUser>" />
  </MethodContent>

  <MethodAside>
    <AsideSection title="Signature">
      ```typescript theme={null}
      declare function createUser(options?: {
        primaryEmail?: string;
        primaryEmailVerified?: boolean;
        primaryEmailAuthEnabled?: boolean;
        password?: string;
        otpAuthEnabled?: boolean;
        displayName?: string;
      }): Promise<ServerUser>;
      ```
    </AsideSection>

    <AsideSection title="Examples">
      ```typescript theme={null}
      const passwordUser = await hexclaveServerApp.createUser({
        primaryEmail: "test@example.com",
        primaryEmailAuthEnabled: true,
        password: "password123",
      });

      const magicLinkUser = await hexclaveServerApp.createUser({
        primaryEmail: "test@example.com",
        primaryEmailVerified: true,
        primaryEmailAuthEnabled: true,
        otpAuthEnabled: true,
      });
      ```
    </AsideSection>
  </MethodAside>
</MethodLayout>

### `hexclaveServerApp.sendEmail(options)`

<MethodLayout>
  <MethodContent>
    Send custom emails to users. You can send either custom HTML emails or use predefined templates with variables.

    <ContentSection title="Parameters">
      <ParamField body="options" type="SendEmailOptions">
        Email configuration and content.
      </ParamField>
    </ContentSection>

    <MethodReturns type="Promise<Result<void, KnownErrors>>">
      The method returns a `Result` that can include `RequiresCustomEmailServer`, `SchemaError`, and `UserIdDoesNotExist`.
    </MethodReturns>
  </MethodContent>

  <MethodAside>
    <AsideSection title="Signature">
      ```typescript theme={null}
      declare function sendEmail(
        options: SendEmailOptions,
      ): Promise<Result<void, KnownErrors>>;
      ```
    </AsideSection>

    <AsideSection title="Examples">
      ```typescript theme={null}
      const htmlResult = await hexclaveServerApp.sendEmail({
        userIds: ["user-1", "user-2"],
        subject: "Welcome to our platform!",
        html: "<h1>Welcome!</h1><p>Thanks for joining us.</p>",
      });

      if (htmlResult.status === "error") {
        console.error("Failed to send email:", htmlResult.error);
      }
      ```

      ```typescript theme={null}
      const templateResult = await hexclaveServerApp.sendEmail({
        userIds: ["user-1"],
        templateId: "welcome-template",
        variables: {
          userName: "John Doe",
          activationUrl: "https://app.com/activate/token123",
        },
      });
      ```
    </AsideSection>
  </MethodAside>
</MethodLayout>

## Team Management

### `hexclaveServerApp.getTeam(id)`

<MethodLayout>
  <MethodContent>
    Get a team by its ID.

    <ContentSection title="Parameters">
      <ParamField body="id" type="string">
        Team ID.
      </ParamField>
    </ContentSection>

    <MethodReturns type="Promise<ServerTeam | null>" />
  </MethodContent>

  <MethodAside>
    <AsideSection title="Signature">
      ```typescript theme={null}
      declare function getTeam(id: string): Promise<ServerTeam | null>;
      ```
    </AsideSection>

    <AsideSection title="Examples">
      ```typescript theme={null}
      const team = await hexclaveServerApp.getTeam("team_id_123");
      ```
    </AsideSection>
  </MethodAside>
</MethodLayout>

### `hexclaveServerApp.useTeam(id)`

<MethodLayout>
  <MethodContent>
    Functionally equivalent to [`getTeam(id)`](#stackserverappgetteamid), but as a React hook.

    <Info>This should be used on the server-side only.</Info>
  </MethodContent>

  <MethodAside>
    <AsideSection title="Signature">
      ```typescript theme={null}
      declare function useTeam(id: string): ServerTeam;
      ```
    </AsideSection>
  </MethodAside>
</MethodLayout>

### `hexclaveServerApp.listTeams([options])`

<MethodLayout>
  <MethodContent>
    Lists all teams on the current project.

    For cursor-based pagination over teams, see [`listTeamsPaginated`](#stackserverapplistteamspaginatedoptions).

    <ContentSection title="Parameters">
      <ParamField body="options.orderBy" type="&#x22;createdAt&#x22;">
        The field to sort results by.
      </ParamField>

      <ParamField body="options.desc" type="boolean">
        Whether to sort in descending order. Defaults to `false`.
      </ParamField>
    </ContentSection>

    <MethodReturns type="Promise<ServerTeam[]>" />
  </MethodContent>

  <MethodAside>
    <AsideSection title="Signature">
      ```typescript theme={null}
      declare function listTeams(options?: {
        orderBy?: "createdAt";
        desc?: boolean;
      }): Promise<ServerTeam[]>;
      ```
    </AsideSection>

    <AsideSection title="Examples">
      ```typescript theme={null}
      const teams = await hexclaveServerApp.listTeams();
      console.log(teams);
      ```
    </AsideSection>
  </MethodAside>
</MethodLayout>

### `hexclaveServerApp.useTeams([options])`

<MethodLayout>
  <MethodContent>
    Functionally equivalent to [`listTeams()`](#stackserverapplistteamsoptions), but as a React hook.

    <Info>This should be used on the server-side only.</Info>
  </MethodContent>

  <MethodAside>
    <AsideSection title="Signature">
      ```typescript theme={null}
      declare function useTeams(options?: {
        orderBy?: "createdAt";
        desc?: boolean;
      }): ServerTeam[];
      ```
    </AsideSection>
  </MethodAside>
</MethodLayout>

### `hexclaveServerApp.listTeamsPaginated([options])`

<MethodLayout>
  <MethodContent>
    Lists teams on the current project with cursor-based pagination, optional filtering, and ordering. The returned array carries an extra `nextCursor` property; pass it back as `cursor` to load the next page.

    <ContentSection title="Parameters">
      <ParamField body="options.cursor" type="string">
        Cursor returned as `nextCursor` from a previous response.
      </ParamField>

      <ParamField body="options.limit" type="number">
        Maximum number of items to return. If omitted, all matching teams are returned.
      </ParamField>

      <ParamField body="options.orderBy" type="&#x22;createdAt&#x22;">
        The field to sort results by.
      </ParamField>

      <ParamField body="options.desc" type="boolean">
        Whether to sort in descending order. Defaults to `false`.
      </ParamField>

      <ParamField body="options.query" type="string">
        Free-text search on the team's display name (and team ID if the query is a UUID).
      </ParamField>
    </ContentSection>

    <MethodReturns type="Promise<{ items: ServerTeam[]; nextCursor: string | null }>" />
  </MethodContent>

  <MethodAside>
    <AsideSection title="Signature">
      ```typescript theme={null}
      declare function listTeamsPaginated(options?: {
        cursor?: string;
        limit?: number;
        orderBy?: "createdAt";
        desc?: boolean;
        query?: string;
      }): Promise<{ items: ServerTeam[]; nextCursor: string | null }>;
      ```
    </AsideSection>

    <AsideSection title="Examples">
      ```typescript theme={null}
      const teams = await hexclaveServerApp.listTeamsPaginated({ limit: 20 });
      console.log(teams);

      if (teams.nextCursor) {
        const nextPageTeams = await hexclaveServerApp.listTeamsPaginated({
          cursor: teams.nextCursor,
          limit: 20,
        });
        console.log(nextPageTeams);
      }
      ```
    </AsideSection>
  </MethodAside>
</MethodLayout>

### `hexclaveServerApp.useTeamsPaginated([options])`

<MethodLayout>
  <MethodContent>
    Functionally equivalent to [`listTeamsPaginated()`](#stackserverapplistteamspaginatedoptions), but as a React hook.

    <Info>This should be used on the server-side only.</Info>
  </MethodContent>

  <MethodAside>
    <AsideSection title="Signature">
      ```typescript theme={null}
      declare function useTeamsPaginated(options?: {
        cursor?: string;
        limit?: number;
        orderBy?: "createdAt";
        desc?: boolean;
        query?: string;
      }): { items: ServerTeam[]; nextCursor: string | null };
      ```
    </AsideSection>
  </MethodAside>
</MethodLayout>

### `hexclaveServerApp.createTeam([options])`

<MethodLayout>
  <MethodContent>
    Creates a team without adding a user to it.

    <ContentSection title="Parameters">
      <ParamField body="options.displayName" type="string">
        Team display name.
      </ParamField>

      <ParamField body="options.profileImageUrl" type="string | null">
        Team profile image URL.
      </ParamField>
    </ContentSection>

    <MethodReturns type="Promise<ServerTeam>" />
  </MethodContent>

  <MethodAside>
    <AsideSection title="Signature">
      ```typescript theme={null}
      declare function createTeam(options?: {
        displayName?: string;
        profileImageUrl?: string | null;
      }): Promise<ServerTeam>;
      ```
    </AsideSection>

    <AsideSection title="Examples">
      ```typescript theme={null}
      const team = await hexclaveServerApp.createTeam({
        displayName: "New Team",
        profileImageUrl: "https://example.com/profile.jpg",
      });
      ```
    </AsideSection>
  </MethodAside>
</MethodLayout>
