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

# Wallets

> Custodial stablecoin balances managed by OMS. For user-controlled wallets, see OMS non-custodial wallets.

Wallets are custodial stablecoin accounts. OMS manages the private keys, with no user signing, no wallet SDKs, and no blockchain interactions required from your application. All operations are server-to-server API calls. Each wallet holds a single asset on one chain (USDC on Polygon by default).

A wallet is the source or destination for every transaction. To hold more than one asset, create a wallet per asset and chain under the same customer.

<Note>
  This page covers the custodial `wallet` resource of the Payments API. If your product needs users to control their own keys on-chain (consumer apps, agentic flows), use [OMS non-custodial wallets](/wallets/non-custodial-wallets). The two models can be combined in a single product.
</Note>

## Object

```json theme={null}
{
  "id": "wlt_...",
  "object": "wallet",
  "customerId": "cst_...",
  "type": "internal",
  "status": "active",
  "address": "0x7B3a9F2c4D1eA8bF6390cE5d2B7fA104C8e3D9b1",
  "asset": "usdc",
  "chain": "polygon",
  "blockchainAsset": {
    "protocol": "evm",
    "chainId": "137",
    "tokenId": "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359"
  },
  "createdAt": "2026-01-15T10:31:00Z",
  "updatedAt": "2026-01-15T10:31:00Z"
}
```

The `address` field is the wallet's on-chain address. It is read-only and assigned at creation. `type` is `internal` for OMS-managed wallets or `external` for wallets held outside OMS. `chain` is the canonical chain name (for example, `polygon`), and `blockchainAsset` carries the resolved on-chain identity: `protocol`, `chainId`, and `tokenId`.

| Wallet status | Meaning                        |
| ------------- | ------------------------------ |
| `active`      | Usable for sends and receipts. |
| `suspended`   | Temporarily blocked.           |
| `closed`      | Terminated.                    |

<Note>
  At launch, wallets are custodial only: a single asset on one chain. Provisioning is scoped per asset and chain, so hold multiple assets by creating one wallet each under the same customer.
</Note>

## Create a wallet

`POST /customers/{id}/wallets` provisions a wallet for a customer for the requested asset and chain, and returns the created wallet.

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

Pass an `Idempotency-Key` header to safely retry without provisioning duplicates.

<Warning>
  `POST /customers/{id}/wallets` and `GET /customers/{id}/wallets` are deprecated. Responses carry `Deprecation: true` and a `Sunset` header. Migrate to `POST /wallets` for creation and `GET /wallets?customerId=...` for listing. The flat list carries only the common wallet fields; asset, chain, and address require a follow-up `GET /wallets/{id}` per row. The flat list also does not sync live with the custody provider on every request.
</Warning>

## Associate an embedded wallet

`POST /customers/{customerId}/wallets/associate` links an existing embedded (WaaS) wallet to a customer so subsequent operations reference it like any other wallet. The wallet is identified by a WaaS ID token in the request body: the token's subject is the wallet ID, so the wallet ID is never passed directly, and the token's audience must be the authenticated project. The response returns the associated wallet.

## Balance

Read a wallet's current balance with `GET /wallets/{id}/balance`. The response includes the display balance and its estimated value; pass `estimatedBalanceCurrencyCode` to value the balance in a currency other than USD (the default).

```json theme={null}
{
  "data": {
    "id": "wlt_...",
    "customerId": "cst_...",
    "address": "0x7B3a...D9b1",
    "asset": "usdc",
    "chain": "polygon",
    "currencyName": "USD Coin",
    "balance": "1234.56",
    "estimatedBalanceValue": "1234.56",
    "blockchainAsset": {
      "protocol": "evm",
      "chainId": "137",
      "tokenId": "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359"
    },
    "updatedAt": "2026-01-15T10:31:00Z"
  }
}
```

For the customer's total balance across every wallet and asset, use `GET /customers/{id}/balance`. See [Customers](/payments/customers#balance).

### Fiat wallet balance

A fiat wallet's `balance` renders as a fixed-point USD decimal string with exactly two decimal places: `"0.00"` for a never-funded wallet, `"500.00"` when funded, `"-25.00"` when overdrawn. The key is present on every `200`, never omitted, never `null`. Crypto wallets keep per-asset decimal scaling, so a USDC balance still renders trimmed (for example, `"1234.56"`).

When the wallet provider returns a successful balance response but omits an entry for a given wallet, `estimatedBalanceValue` defaults to `"0.00"` so a zero-balance fiat wallet keeps a stable response shape.

## Funding a wallet

A wallet can receive funds in three ways:

| Method                 | How it works                                                                           |
| ---------------------- | -------------------------------------------------------------------------------------- |
| Direct crypto transfer | Send crypto to the wallet's `address`.                                                 |
| Virtual account        | Fiat deposited to the customer's assigned bank account number auto-converts to crypto. |
| Deposit address        | Crypto sent to a monitored address auto-routes to the configured destination.          |

A direct transfer to the `address` credits the wallet balance. Virtual accounts and deposit addresses are the flows where OMS auto-creates a transaction in response to incoming funds.

## Transaction history

`GET /wallets/{id}/transactions` returns a wallet's transaction history, most recent first, with cursor-based pagination and optional `transactionType`, `since`, and `until` filters. The `id` path parameter accepts a wallet ID (`wlt_` prefix).

<Warning>
  `GET /wallets/{id}/transactions` is deprecated. Responses carry `Deprecation: true` and a `Sunset` header. Migrate to `GET /transactions?walletId={id}`, which returns business transactions (source, destination, pricing, status). Note that the deprecated endpoint returns raw ledger entries (credit, debit, hold, release with `balanceAfter`) and includes reconciliation-only entries that have no counterpart on the transactions endpoint; if you rely on those raw entries, plan the migration accordingly.
</Warning>

## Key operations

| Operation                 | Endpoint                                                |
| ------------------------- | ------------------------------------------------------- |
| Create a wallet           | `POST /customers/{id}/wallets` (body: `asset`, `chain`) |
| List a customer's wallets | `GET /customers/{id}/wallets`                           |
| Get a wallet balance      | `GET /wallets/{id}/balance`                             |
| List wallet transactions  | `GET /wallets/{id}/transactions`                        |

<Note>
  Programmatic wallet creation via `POST /wallets` with an explicit `custodyType` (custodial or embedded) is coming in an upcoming release. Today, provision wallets under a customer with `POST /customers/{id}/wallets`.
</Note>

## Related

* [Virtual accounts](/payments/virtual-accounts): assign a bank account number that auto-funds a destination
* [Deposit addresses](/payments/deposit-addresses): set up a monitored crypto address that routes to a destination
* [Transactions](/payments/transactions): move funds out of a wallet via crypto, bank transfer, or cash
