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

# Sweep to Omnibus

Fireblocks supports two vault structures suited to different market segments: **segregated account** and **omnibus account**. In an omnibus setup, three vault types work together:

* **Intermediate vault accounts**: Assigned per end-client for deposits. Use the Fireblocks API to generate as many as needed.
* **Omnibus deposits**: The central vault where end-client funds are swept and stored.
* **Withdrawal pool**: Vault accounts containing funds allocated for end-client withdrawals. More than one may be required due to blockchain limitations.

[Learn more about best practices for structuring your Fireblocks Vault.](https://support.fireblocks.io/hc/en-us/articles/5253421857564)

## Sweeping

Sweeping moves funds from intermediate vault accounts into your omnibus account via an on-chain transfer. Because it is an on-chain transfer, fees apply.

Set the trigger for when sweeping runs based on your business needs — for example:

* When the balance in an intermediate vault account reaches a threshold
* On a fixed schedule (daily, weekly)
* When network fees are favorable

See also: [Reconciliation & crediting](https://support.fireblocks.io/hc/en-us/articles/5431957627548-Best-practices-for-transaction-reconciliation-and-crediting) and [Deposit control & Confirmation policy](https://support.fireblocks.io/hc/en-us/articles/360013034359-Deposit-Control-Confirmation-Policy).

## Fueling

When sweeping non-base assets such as ERC-20 tokens, the transaction fee must be paid in the base asset — for example, sweeping USDC on Ethereum requires ETH.

Fireblocks offers two automated approaches for managing gas fees across your intermediate vault accounts:

**Gas Station** pushes ETH directly into each intermediate vault account before a sweep, so the vault itself holds and spends the gas. This is the right fit if you're comfortable holding ETH in your source vaults and want automated per-vault fueling. See the [Gas Station setup and usage](/docs/enabling-the-gas-station-1) guide.

**Universal Gasless** takes a different approach: a designated relay sponsors gas fees on behalf of your intermediate vault accounts during the transaction, so those vaults never need to hold ETH. It supports sweeping all Ethereum-based tokens (ERC-20, ERC-721, and ERC-1155), but does not relay native ETH transfers — Gas Station remains the right choice for sweeping ETH itself. Three relay options are available:

* **This workspace**: a single dedicated vault in your workspace holds ETH and covers gas fees for all other vault accounts — you still hold ETH, but only in one place.
* **External workspace**: a separate Fireblocks workspace acts as the relay, suited for multi-workspace setups or compliance requirements that prohibit holding ETH in the sweeping workspace.
* **Fireblocks relay**: Fireblocks sponsors the gas directly, with no ETH holding required anywhere in your workspace.

To configure Universal Gasless, see the [Universal Gasless](https://support.fireblocks.io/hc/en-us/articles/19948199000092-Universal-Gasless) setup guide.

## Example

### Step 1: Create the vault accounts in batch

This guide assumes you use a backend "internal ledger" that correlates your internal customer ref IDs with Fireblocks vault account IDs.

The following example:

1. Creates vault accounts for your end-users using a naming convention you define.
2. Creates an ETH deposit address under each vault account.
3. Creates your omnibus vault account to serve as the treasury.

It calls `createVaultAccounts` (TypeScript/JavaScript) or `create_vault_accounts` (Python), passing the number of accounts to create, the asset ID, the name prefix, and the treasury account.

<CodeGroup>
  ```typescript TypeScript theme={"system"}
  const createVaultAccounts = async (
    amountOfVaultAccounts: number,
    assetId: string,
    vaultAccountNamePrefix: string
  ): Promise<Array<{}> | undefined> => {
    const result: Array<{}> = [];
    try {
      for (let i = 1; i <= amountOfVaultAccounts; i++) {
        const vaultAccountResponse = await fireblocks.vaults.createVaultAccount(
          {
            createVaultAccountRequest:
            {
              name: vaultAccountNamePrefix.toString() + i.toString()
            }
          }
        );
        let vaultWalletAddress = await fireblocks.vaults.createVaultAccountAsset(
          {
            vaultAccountId: vaultAccountResponse.data.id as string,
            assetId
          }
        );
        result.push({
          "Vault Account Name": vaultAccountResponse.data.name,
          "Vault Account ID": vaultAccountResponse.data.id,
          "Asset ID": assetId,
          "Address": vaultWalletAddress.data.address
        })
        console.log("Vault Account Details: ", result);
      }

      return result;
    }
    catch (error) {
      console.error(error);
    }
  }

  createVaultAccounts(2, "ETH_TEST6", "END-USER#22223");
  ```

  ```javascript JavaScript theme={"system"}
  async function createVaultAccounts(amountOfVaultAccounts, assetId, vaultAccountNamePrefix){
      let vaultRes;
      let vault;
      let vaultWallet;

      for (let i = 1; i <= amountOfVaultAccounts; i++){
              vaultRes = await fireblocks.createVaultAccount(vaultAccountNamePrefix.toString()+i.toString());
              vault = {
                  vaultName: vaultRes.name,
                  vaultID: vaultRes.id
              }
              vaultWallet = await fireblocks.createVaultAsset(Number(vault.vaultID), assetId);
              console.log("Created vault account", vault.vaultName,":", "with wallet address:", vaultWallet.address);
      };
   }
   createVaultAccounts(2, "ETH","END-USER-#","treasuryVaultName");
  ```

  ```python Python theme={"system"}
  ASSET = "ETH_TEST"
  def create_vault_accounts(amount: int) -> dict:
     """
     :param amount: Amount of vault accounts to create (one, per end user).
     :return: A dictionary where keys are the vault names and IDs are the co-responding values.
     """
     vault_dict = {}
     counter = 1

     while counter <= amount:
         vault_name = f"End-User {counter} Vault"
         vault_id = fireblocks.create_vault_account(name=vault_name, hiddenOnUI=True)['id']
         fireblocks.create_vault_asset(vault_id, ASSET)
         vault_dict[vault_name] = vault_id
         counter += 1
     else:
         vault_name = "Treasury"
         vault_id = SDK.create_vault_account(name=vault_name)['id']
         fireblocks.create_vault_asset(vault_id, ASSET)
         vault_dict[vault_name] = vault_id

     return vault_dict
  ```
</CodeGroup>

### Step 2: Create the sweeping logic

This guide assumes your internal ledger can produce a list of vault accounts ready for sweeping. For a basic internal ledger description, see the section at the bottom of this article.

Define which vault accounts to sweep and the minimum balance threshold. The example below sweeps any intermediate vault account that meets the threshold into the treasury.

* Filter intermediate vault accounts by name prefix and minimum balance.
* Initiate a create transaction loop for each qualifying account.

### Testing

Add this code to the vault creation code from Step 1.

<CodeGroup>
  ```typescript TypeScript theme={"system"}
  const createTagWithdrawalVaultAccounts = async (
    assetId: string,
    name: string,
  ): Promise<Array<{}> | undefined> => {
    const result: Array<{}> = [];

    try {
      const vaultAccount = await fireblocks.vaults.createVaultAccount({
        createVaultAccountRequest: {
          name,
        },
      });

      if (vaultAccount.data) {
        const vaultWallet = await fireblocks.vaults.createVaultAccountAsset({
          vaultAccountId: vaultAccount.data.id as string,
          assetId,
        });

        result.push({
          "Vault Account Name": vaultAccount.data.name,
          "Vault Account ID": vaultAccount.data.id,
          "Asset ID": assetId,
          Address: vaultWallet.data.address,
        });

        console.log(JSON.stringify(result, null, 2));
      }

      return result;
    } catch (error) {
      console.error(error);
    }
  };

  const sweepToOmnibus = async (
    vaNamePrefix: string,
    minAmount: number,
    assetId: string,
    omnibusVaId: string,
  ): Promise<
    Array<{
      fromVaName: string;
      fromVaId: string;
      txId: string;
      grossAmount: string;
    }>
  > => {
    let sweepingInfo: any[] = [];

    const vaultsToSweepFrom = await fireblocks.vaults.getPagedVaultAccounts({
      namePrefix: vaNamePrefix,
      assetId,
      minAmountThreshold: minAmount,
    });

    if (vaultsToSweepFrom.data.accounts) {
      await Promise.all(
        vaultsToSweepFrom.data.accounts.map(
          async (vaultAccount: VaultAccount) => {
            if (vaultAccount.assets && vaultAccount.assets.length > 0) {
              const createTxResponse =
                await fireblocks.transactions.createTransaction({
                  transactionRequest: {
                    assetId,
                    source: {
                      type: TransferPeerPathType.VaultAccount,
                      id: vaultAccount.id,
                    },
                    destination: {
                      type: TransferPeerPathType.VaultAccount,
                      id: omnibusVaId,
                    },
                    amount: vaultAccount.assets[0].available,
                  },
                });

              sweepingInfo.push({
                fromVaName: vaultAccount.name,
                fromVaId: vaultAccount.id,
                txId: createTxResponse.data.id,
                grossAmount: vaultAccount.assets[0].available,
              });
            }
          },
        ),
      );
    }

    console.log(
      "Initiated sweeping transactions:\n" +
        JSON.stringify(sweepingInfo, null, 2),
    );
    return sweepingInfo;
  };

  sweepToOmnibus("END-USER-#", 0.1, "ETH_TEST5", "0");
  ```

  ```javascript JavaScript theme={"system"}
  async function sweep(vaultAccountNamePrefixtoSweep, sweepAmount, assetId, treasuryVaultAccountId){
      vaultListToSweep = await fireblocks.getVaultAccountsWithPageInfo({namePrefix: vaultAccountNamePrefixtoSweep, assetId: assetId, minAmountThreshold:sweepAmount});
      for (let i = 0; i < Object.keys(vaultListToSweep.accounts).length; i++) {
          await fireblocks.createTransaction({
              "assetId" : assetId,
              "source" : {
                  "type" : PeerType.VAULT_ACCOUNT,
                  "id" : vaultListToSweep.accounts[i].id
              },
              "destination" : {
                  "type" : PeerType.VAULT_ACCOUNT,
                  "id" : String(treasuryVaultAccountId)
              },
              "amount" : vaultListToSweep.accounts[i].assets[0].total,
          })
      };
      vaultListToSweep.accounts.forEach(element => {
          console.log("Swept", "Vault id:", element.id,", Vault name:", element.name);
      })
   }
  sweep("END-USER-#",1,"ETH","0");
  ```

  ```python Python theme={"system"}
  ASSET = "ETH_TEST"
  def sweep_accounts(treasury_vault_id: str) -> dict:
     """
     :param treasury_vault_id: The vault that will receive all the funds.
     :return: A dictionary of accounts swept with the values being the amount transferred.
     """
     vault_dict = {}
     vault_accounts = fireblocks.get_vault_accounts(name_prefix="End-User")
     for vault in vault_accounts['accounts']:
         for asset in vault['assets']:
             if asset['id'] == ASSET and int(asset['amount']) >= 1:
                 fireblocks.create_transaction(
                     asset_id=ASSET,
                     amount=asset['amount'],
                     source=TransferPeerPath(
                         peer_type=VAULT_ACCOUNT,
                         peer_id=vault['id']
                     ),
                     destination=DestinationTransferPeerPath(
                         peer_type=VAULT_ACCOUNT,
                         peer_id=treasury_vault_id
                     )
                 )
                 vault_dict[vault['name']] = asset['amount']

     return vault_accounts
  ```
</CodeGroup>
