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

# Set up an omnibus account

> Use an omnibus account as a partner wallet: give each user a named custodial wallet, sweep their deposits into one wallet you control, and move funds between users.

An omnibus account pools your users' funds into one custodial wallet that your company controls. Each user keeps a named custodial wallet of their own, which acts as their sub-ledger: it has its own deposit address, so every deposit is attributed to a named user. You then sweep funds from those wallets into the omnibus account, either by triggering each transfer or automatically as deposits land.

| Concept | In OMS |
| - | - |
| Omnibus account | A custodial wallet owned by a business customer that represents your company |
| Named user sub-ledger | A custodial wallet owned by the user's own customer record |
| Sweep | A transfer from a user's wallet to the omnibus account |
| Internal P2P | A transfer from one user's wallet to another's |

Transfers between custodial wallets in your project settle as internal ledger movements. Nothing moves onchain, and there is no network fee.

## Step 1: Create the business customer

Create one customer with `type: business` to represent your company. A business requires `companyLegalName` and `email`, and follows your project's KYB policy. Request the `cryptoCustody` endorsement so the customer can hold custodial wallets.

```text theme={null}
POST /v0.13/customers
Authorization: Bearer {accessToken}
Idempotency-Key: cst-omnibus-001
Content-Type: application/json
```

```json theme={null}
{
  "type": "business",
  "companyLegalName": "Your Company Inc.",
  "email": "treasury@yourcompany.example",
  "externalId": "omnibus",
  "signedAgreement": true,
  "endorsements": ["cryptoCustody"]
}
```

Store the returned `cst_` ID, and wait for the `cryptoCustody` endorsement to become active before you create wallets. See [Customer onboarding](/payments/guides/customer-onboarding) for endorsements and verification.

## Step 2: Create the omnibus wallets

Create a custodial wallet for the business customer for each asset and network you accept. Each wallet holds one asset on one chain and has its own onchain `address`.

```text theme={null}
POST /v0.13/customers/cst_omnibus.../wallets
Authorization: Bearer {accessToken}
Idempotency-Key: wlt-omnibus-usdc-polygon
Content-Type: application/json
```

```json theme={null}
{
  "asset": "usdc",
  "chain": "polygon"
}
```

Store each wallet's `wlt_` ID and `address`; you need the address in Step 4.

> [!TIP]
>
> Create one omnibus wallet per asset, for example one for USDC and one for USDT. Each sweep then lands in a wallet of the same asset, and no swap is needed.

## Step 3: Create a wallet for each user

Onboard each user as their own customer, then create their custodial wallets the same way as Step 2. See [Customer onboarding](/payments/guides/customer-onboarding) for the full flow.

Give each user their wallet's `address` to deposit to. Every deposit is recorded against that user's wallet before it is swept.

## Step 4: Register the omnibus account for each user

The omnibus wallets belong to a different customer, so a user's wallet cannot send to them by `wlt_` ID. Register each omnibus wallet as an external account under the user instead. Repeat this step once for each user.

**1. Register your company as a counterparty**

Create a counterparty under the user's customer record that represents your company:

```json theme={null}
POST /v0.13/counterparties

{
  "customerId": "cst_alice...",
  "entityType": "business",
  "businessName": "Your Company Inc."
}
```

**2. Register the omnibus wallet as an external account**

Register the omnibus wallet's `address` as a `walletExternal` external account owned by that counterparty:

```json theme={null}
POST /v0.13/external-accounts

{
  "owner": { "kind": "counterparty", "counterpartyId": "ctp_..." },
  "type": "walletExternal",
  "walletExternal": {
    "blockchainAddress": "0xOmnibusWalletAddress...",
    "networkFamily": "evm",
    "custodian": "OTHER",
    "otherCustodian": "OMS"
  },
  "label": "Omnibus account"
}
```

Store the returned `ext_` ID and wait for the account to become `active`. An EVM address registered once is valid across every EVM chain.

OMS still settles transfers to this external account as internal ledger movements, because both wallets are custodial wallets in your project.

## Step 5: Sweep deposits into the omnibus account

Choose how sweeps run. OMS does not sweep on a schedule: you either trigger each sweep or route deposits through a deposit address that forwards them.

### Trigger sweeps yourself

Create a quote with the user's wallet as the `source` and the omnibus external account as the `destination`:

```text theme={null}
POST /v0.13/quotes
Authorization: Bearer {accessToken}
Idempotency-Key: qt-sweep-alice-001
Content-Type: application/json
```

```json theme={null}
{
  "customerId": "cst_alice...",
  "source": {
    "type": "walletCrypto",
    "details": { "id": "wlt_alice...", "asset": "usdc", "network": "polygon" },
    "amount": "250.00"
  },
  "destination": {
    "type": "walletExternal",
    "details": { "id": "ext_...", "asset": "usdc", "network": "polygon" }
  }
}
```

Confirm it with `POST /transactions`:

```json theme={null}
{ "quoteId": "qt_..." }
```

To automate this, listen for `transaction.statusChanged` and create a sweep when a deposit to a user's wallet reaches `completed`.

### Sweep automatically with deposit addresses

Create a deposit address for each user whose `destination` is the omnibus external account, and give users the deposit address instead of their wallet address. Every deposit is then forwarded to the omnibus account as it lands, with no quote step.

```json theme={null}
POST /v0.13/deposit-addresses

{
  "customerId": "cst_alice...",
  "expectedSourceAsset": "usdc",
  "expectedSourceNetwork": "polygon",
  "destination": {
    "type": "walletExternal",
    "details": { "id": "ext_...", "asset": "usdc", "network": "polygon" }
  }
}
```

A deposit address accepts one asset on one network. If you hold USDC and USDT omnibus wallets, create one deposit address per asset for each user, each pointing at the omnibus wallet of the matching asset. See [Forward deposits to a wallet](/payments/guides/deposit-addresses#forward-deposits-to-a-wallet).

## Send funds between users

A transfer from one user's wallet to another's follows the same pattern as a sweep. Register the recipient's wallet `address` as a `walletExternal` external account under the sender, owned by a counterparty that represents the recipient, then quote from the sender's wallet to that `ext_` ID. The transfer settles as an internal ledger movement.

Transfers between wallets owned by the same customer, such as moving funds between two omnibus wallets, skip registration: reference the destination directly as `walletCrypto` with its `wlt_` ID.

## Reconcile balances

* **Track movements with transaction events.** Subscribe to `transaction.statusChanged` and match events where the `source` or `destination` is the `wlt_` ID of the wallet you are reconciling. OMS does not emit separate balance events.
* **Treat reported balances as spendable.** Balances returned by `GET /wallets/{walletId}/balance` and the customer wallet endpoints never include pending funds.
* **Wait for `completed`.** A transaction changes a wallet's balance only when it reaches `completed`.

## Related

* [Customer onboarding](/payments/guides/customer-onboarding): create customers and custodial wallets
* [External accounts](/payments/external-accounts): register external wallets and counterparty-owned accounts
* [Deposit addresses guide](/payments/guides/deposit-addresses): forward inbound deposits automatically
* [Receiving webhooks](/payments/guides/receiving-webhooks): verify and apply `transaction.statusChanged` deliveries
