Capxul Docs
HooksSub-accounts

useCapxulSubAccountDelete

Mutation hook that deletes an empty sub-account (envelope).

Deletes a sub-account. The envelope must be empty: a delete with money still assigned is rejected, so move the balance back to main (or to another envelope) with useCapxulTransfer first. Deleting an envelope never destroys money — an empty envelope is just a name.

Import

import { useCapxulSubAccountDelete } from "@capxul/sdk-react";

Usage

"use client";

import { useCapxulSubAccountDelete, useCapxulTransfer } from "@capxul/sdk-react";
import type { SubAccount } from "@capxul/sdk";

function DeleteEnvelopeButton({ subAccount }: { subAccount: SubAccount }) {
  const transfer = useCapxulTransfer();
  const deleteSubAccount = useCapxulSubAccountDelete();

  return (
    <button
      type="button"
      disabled={transfer.isPending || deleteSubAccount.isPending}
      onClick={async () => {
        // Delete requires zero balance — empty the envelope back to main first.
        if (Number(subAccount.balance.value) > 0) {
          await transfer.mutateAsync({
            accountId: subAccount.accountId,
            from: subAccount.id,
            to: "main",
            amount: subAccount.balance,
          });
        }
        await deleteSubAccount.mutateAsync({
          accountId: subAccount.accountId,
          subAccountId: subAccount.id,
        });
      }}
    >
      Delete envelope
    </button>
  );
}

Parameters

The hook itself takes no parameters. The mutation input is an object with two fields:

FieldTypeDescription
accountIdAccountIdThe parent Account. Carried only so the hook can invalidate the right sub-account list — the delete itself is addressed by subAccountId.
subAccountIdSubAccountIdThe sub-account to delete. Must have a zero balance.

Return type

import { type UseCapxulSubAccountDeleteReturn } from "@capxul/sdk-react";
// UseMutationResult<void, CapxulError, { accountId: AccountId; subAccountId: SubAccountId }>

On success, data is undefined — a successful delete returns nothing.

The hook returns TanStack Query's UseMutationResult. The most-used fields:

FieldDescription
mutateFire the mutation (fire-and-forget; pair with onSuccess/onError callbacks).
mutateAsyncFire the mutation and get a Promise of the result. Rejects with a CapxulError on failure.
dataThe mutation result (typed per hook, shown above). undefined until the first success.
errorA CapxulError when the last attempt failed, otherwise null.
isPendingtrue while the mutation is in flight. Use it to disable submit buttons.
resetClear the mutation state (data, error) back to idle.

Mutations do not retry by default. The full field list is in the TanStack Query useMutation reference; see also the TanStack Query integration guide.

Cache behavior

On success this mutation invalidates the Account's sub-account list (["capxul", "subAccounts", accountId]) and the personal balance (["capxul", "accountBalance"]), so the deleted envelope drops out of lists and the available balance refetches.

Errors

Failures surface as a CapxulError on error / thrown from mutateAsync — most notably when the sub-account still holds money (delete requires zero balance), when the sub-account does not exist, or when the mutation fires while <CapxulProvider> is still bootstrapping.

Client method

This hook wraps client.subAccounts.delete(subAccountId) on the core SDK.

On this page