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

# Item

> Reference for Item and ServerItem types for managing quantifiable resources.

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 CollapsibleTypesSection = ({type, property, signature, defaultOpen = false, deprecated = false, badge, children}) => {
  const id = `${String(type ?? "").toLowerCase().replace(/[^a-z0-9]/g, "")}${String(property ?? "").toLowerCase().replace(/[^a-z0-9]/g, "")}`;
  const [isOpen, setIsOpen] = useState(defaultOpen);
  useEffect(() => {
    if (typeof window === "undefined") {
      return undefined;
    }
    const syncWithHash = () => {
      if (window.location.hash === `#${id}`) {
        setIsOpen(true);
      }
    };
    syncWithHash();
    window.addEventListener("hashchange", syncWithHash);
    return () => window.removeEventListener("hashchange", syncWithHash);
  }, [id]);
  const label = signature ? `${property}(${signature})` : property;
  const fullLabel = type ? `${type}.${label}` : label;
  return <details id={id} open={isOpen} onToggle={event => setIsOpen(event.currentTarget.open)} className={`not-prose my-4 scroll-mt-24 overflow-hidden rounded-2xl border bg-white dark:bg-zinc-950 ${deprecated ? "border-orange-400/40 dark:border-orange-500/30" : "border-zinc-950/10 dark:border-white/10"}`}>
      <summary className="cursor-pointer list-none px-4 py-4 [&::-webkit-details-marker]:hidden">
        <div className="flex items-center gap-3">
          <code className={`text-[15px] font-medium ${deprecated ? "text-zinc-500 line-through decoration-zinc-400/60 dark:text-zinc-400 dark:decoration-zinc-500/60" : "text-zinc-950 dark:text-white"}`}>{fullLabel}</code>
          <span className="ml-auto flex items-center gap-2">
            {deprecated ? <Badge color="orange" size="sm" shape="pill">deprecated</Badge> : null}
            {badge ?? null}
            <span aria-hidden="true" className="text-sm text-zinc-500 transition-transform dark:text-zinc-400">
              {isOpen ? "▾" : "›"}
            </span>
          </span>
        </div>
      </summary>

      <div className="border-t border-zinc-950/10 px-4 py-5 dark:border-white/10">
        {children}
      </div>
    </details>;
};

export const ClickableTableOfContents = ({title, code}) => {
  const lines = String(code ?? "").replace(/\r\n/g, "\n").split("\n");
  return <div className="not-prose my-6 overflow-hidden rounded-2xl border border-zinc-950/10 bg-zinc-950/[0.03] dark:border-white/10 dark:bg-white/[0.03]">
      {title ? <div className="border-b border-zinc-950/10 px-4 py-3 text-sm font-medium text-zinc-950/80 dark:border-white/10 dark:text-white/80">
          {title}
        </div> : null}

      <pre className="overflow-x-auto px-2 py-3 text-[13px] leading-6 text-zinc-900 dark:text-zinc-100">
        <code>
          {lines.map((line, index) => {
    if (line.trim().startsWith("// NEXT_LINE_PLATFORM")) {
      return null;
    }
    const match = line.match(/^(.*?)(?:\s*\/\/\s*\$stack-link-to:(#[a-zA-Z0-9_-]+))\s*$/);
    const href = match?.[2] ?? null;
    const text = match?.[1] ?? line;
    if (text.trim() === "") {
      return <span key={`blank-${index}`} className="block h-6" />;
    }
    const content = <span className="block whitespace-pre rounded-lg px-3 py-0.5">
                {text.replace(/\s+$/, "")}
              </span>;
    if (!href) {
      return <span key={`line-${index}`} className="block text-zinc-700 dark:text-zinc-300">
                  {content}
                </span>;
    }
    return <a key={`line-${index}`} href={href} className="block no-underline transition-colors hover:bg-zinc-950/[0.04] hover:text-zinc-950 dark:hover:bg-white/[0.05] dark:hover:text-white">
                {content}
              </a>;
  })}
        </code>
      </pre>
    </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>;

export const ItemSection = props => <CollapsibleTypesSection badge={<Badge color="green" size="sm" shape="pill">
        item
      </Badge>} {...props} />;

export const ServerItemSection = props => <CollapsibleTypesSection badge={<Badge color="blue" size="sm" shape="pill">
        serverItem
      </Badge>} {...props} />;

Items represent quantifiable resources in your application, such as credits, API calls, storage quotas, or subscription allowances. They can be associated with users, teams, or custom customers and are managed through Hexclave's payment system.

On this page:

* [Item](#item)
* [ServerItem](#serveritem)

***

# `Item`

The `Item` type represents a quantifiable resource that can be consumed or managed within your application. Items are typically obtained through purchases, subscriptions, or manual allocation.

Items can be retrieved through:

* [`user.getItem()`](/sdk/types/user#currentusergetitem)
* [`user.useItem()`](/sdk/types/user#currentuseruseitem) (React hook)
* [`team.getItem()`](/sdk/types/team#teamgetitem)
* [`team.useItem()`](/sdk/types/team#teamuseitem) (React hook)

## Table of Contents

<ClickableTableOfContents
  title="Item Table of Contents"
  code={`type Item = {
displayName: string; //$stack-link-to:#itemdisplayname
quantity: number; //$stack-link-to:#itemquantity
nonNegativeQuantity: number; //$stack-link-to:#itemnonnegativequantity
};`}
/>

## Properties

<ItemSection type="item" property="displayName" defaultOpen={false}>
  <MethodLayout>
    <MethodContent>
      The human-readable name of the item as configured in your Hexclave project settings.
    </MethodContent>

    <MethodAside title="Type Definition">
      `typescript declare const displayName: string; `
    </MethodAside>
  </MethodLayout>
</ItemSection>

<ItemSection type="item" property="quantity" defaultOpen={false}>
  <MethodLayout>
    <MethodContent>
      The current quantity. This value can be negative, which is useful for tracking overdrafts or pending charges.
    </MethodContent>

    <MethodAside title="Type Definition">
      `typescript declare const quantity: number; `
    </MethodAside>
  </MethodLayout>
</ItemSection>

<ItemSection type="item" property="nonNegativeQuantity" defaultOpen={false}>
  <MethodLayout>
    <MethodContent>
      The quantity clamped to a minimum of 0. Equivalent to `Math.max(0, quantity)`. Useful for display purposes when you don't want to show negative values to users.
    </MethodContent>

    <MethodAside title="Type Definition">
      `typescript declare const nonNegativeQuantity: number; `
    </MethodAside>
  </MethodLayout>
</ItemSection>

***

# `ServerItem`

The `ServerItem` type extends `Item` with additional server-side methods for modifying quantities. This type is only available in server-side contexts and provides race-condition-safe operations for managing item quantities.

Server items can be retrieved through:

* [`serverUser.getItem()`](/sdk/types/user#serverusergetitem)
* [`serverUser.useItem()`](/sdk/types/user#serveruseruseitem) (React hook)
* [`serverTeam.getItem()`](/sdk/types/team#serverteamgetitem)
* [`serverTeam.useItem()`](/sdk/types/team#serverteamuseitem) (React hook)

## Table of Contents

<ClickableTableOfContents
  title="ServerItem Table of Contents"
  code={`type ServerItem =
// Inherits all functionality from Item
& Item; //$stack-link-to:#item
& {
increaseQuantity(amount): Promise<void>; //$stack-link-to:#serveritemincreasequantity
decreaseQuantity(amount): Promise<void>; //$stack-link-to:#serveritemdecreasequantity
tryDecreaseQuantity(amount): Promise<boolean>; //$stack-link-to:#serveritemtrydecreasequantity
};`}
/>

## Methods

<ServerItemSection type="serverItem" property="increaseQuantity" signature="amount" defaultOpen={false}>
  <MethodLayout>
    <MethodContent>
      Increases the item quantity by the specified amount. This operation is atomic and safe for concurrent use.

      <ContentSection title="Parameters">
        <ParamField body="amount" type="number">
          The amount to increase the quantity by. Must be a positive number.
        </ParamField>
      </ContentSection>

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

    <MethodAside>
      <AsideSection title="Signature">
        ```typescript theme={null}
        declare function increaseQuantity(amount: number): Promise<void>;
        ```
      </AsideSection>

      <AsideSection title="Examples">
        ```typescript theme={null}
        const user = await hexclaveServerApp.getUser({ userId: "user_123" });
        const credits = await user.getItem("credits");

        await credits.increaseQuantity(100);
        ```
      </AsideSection>
    </MethodAside>
  </MethodLayout>
</ServerItemSection>

<ServerItemSection type="serverItem" property="decreaseQuantity" signature="amount" defaultOpen={false}>
  <MethodLayout>
    <MethodContent>
      Decreases the item quantity by the specified amount. This operation allows the quantity to go negative.

      If you want to prevent the quantity from going below zero, use [`tryDecreaseQuantity()`](#serveritemtrydecreasequantity) instead.

      <ContentSection title="Parameters">
        <ParamField body="amount" type="number">
          The amount to decrease the quantity by. Must be a positive number.
        </ParamField>
      </ContentSection>

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

    <MethodAside>
      <AsideSection title="Signature">
        ```typescript theme={null}
        declare function decreaseQuantity(amount: number): Promise<void>;
        ```
      </AsideSection>

      <AsideSection title="Examples">
        ```typescript theme={null}
        const user = await hexclaveServerApp.getUser({ userId: "user_123" });
        const credits = await user.getItem("credits");

        await credits.decreaseQuantity(50);
        ```
      </AsideSection>
    </MethodAside>
  </MethodLayout>
</ServerItemSection>

<ServerItemSection type="serverItem" property="tryDecreaseQuantity" signature="amount" defaultOpen={false}>
  <MethodLayout>
    <MethodContent>
      Attempts to decrease the item quantity by the specified amount, but only if the result would be non-negative. Returns `true` if the operation succeeded, `false` if it would result in a negative quantity.

      This method is race-condition-safe and is ideal for implementing prepaid credit systems where you need to ensure sufficient balance before allowing an operation.

      <ContentSection title="Parameters">
        <ParamField body="amount" type="number">
          The amount to decrease the quantity by. Must be a positive number.
        </ParamField>
      </ContentSection>

      <MethodReturns type="Promise<boolean>">
        `true` if the quantity was successfully decreased, `false` if the operation would result in a negative quantity.
      </MethodReturns>
    </MethodContent>

    <MethodAside>
      <AsideSection title="Signature">
        ```typescript theme={null}
        declare function tryDecreaseQuantity(amount: number): Promise<boolean>;
        ```
      </AsideSection>

      <AsideSection title="Examples">
        ```typescript theme={null}
        const user = await hexclaveServerApp.getUser({ userId: "user_123" });
        const credits = await user.getItem("credits");

        const success = await credits.tryDecreaseQuantity(50);

        if (success) {
          console.log("Credits consumed successfully");
        } else {
          console.log("Insufficient credits");
          throw new Error("Not enough credits available");
        }
        ```
      </AsideSection>
    </MethodAside>
  </MethodLayout>
</ServerItemSection>

<Tip>
  The `tryDecreaseQuantity()` method is particularly valuable for prepaid credit
  systems where operations require sufficient balance verification before
  proceeding.
</Tip>
