# batchPortfolioState - HyperCore Info Endpoint

Batch query perpetual state, spot balances, and account abstraction mode for multiple users in a single request. This is a Dwellir custom endpoint. Standard Hyperliquid nodes do not serve it.

Authenticate by including your Dwellir API key in the URL path: `https://api-hyperliquid-mainnet-info.n.dwellir.com/YOUR_API_KEY/info`.

## When to Use This Endpoint

The `batchPortfolioState` endpoint serves applications that need a full portfolio view for many users at once. It fans out `portfolioState` composition per user and aggregates the results. You do not coordinate clearinghouse, spot, and abstraction calls yourself.

Unified and portfolio-margin accounts return abstraction mode and spot state next to perp state.

- **Portfolio Dashboards**: Load perp state, spot balances, and account mode for every tracked wallet in one call
- **Risk Systems**: Combine derivative exposure with spot collateral and account abstraction mode across a fleet
- **Fund Management**: Aggregate sub-accounts without stitching three responses per wallet
- **Multi-DEX Views**: Use `dex: "ALL_DEXES"` to inspect the native DEX and all operational HIP-3 DEXs together

## Billing

`batchPortfolioState` is billed by the number of upstream responses it aggregates, not as one response per HTTP request.

- `{"type":"batchPortfolioState","users":["0x00f2548cf639e54420e501a35346e8458989e6bd"]}` counts as `3` responses/API credits.
- `{"type":"batchPortfolioState","users":["0x00f2548cf639e54420e501a35346e8458989e6bd","0x010461c14e146ac35fe42271bdc1134ee31c703a"]}` counts as `6` responses/API credits.
- `{"type":"batchPortfolioState","users":["0x00f2548cf639e54420e501a35346e8458989e6bd"],"dex":"ALL_DEXES"}` counts as `1 + users * (N + 2)` responses/API credits, where `N` is the number of keys in each returned `clearinghouseState` map, including `"native"`. For example, one user with `10` returned DEX keys counts as `13` responses/API credits.

Wallets listed in `failed_wallets` still count because an upstream lookup was performed for them. Duplicate and malformed wallet entries are removed before the batch runs and do not count. DEX discovery counts even when served from the gateway cache. Non-success HTTP responses are not charged.

## Request Parameters

- `type` (`string, required`): parameter: Must be `"batchPortfolioState"`
- `users` (`string[], required`): parameter: Non-empty list of wallet addresses
- `dex` (`string, optional`): parameter: HIP-3 market identifier. Query "`perpDexs`" first to discover supported DEX names. Omit to query the main Hyperliquid DEX, or use "`ALL_DEXES`" to aggregate the main DEX plus all operational HIP-3 DEXs.

## Request Example

```bash
curl -X POST "https://api-hyperliquid-mainnet-info.n.dwellir.com/YOUR_API_KEY/info" \
  -H "content-type: application/json" \
  -d '{
  "type": "batchPortfolioState",
  "users": [
    "0x00f2548cf639e54420e501a35346e8458989e6bd",
    "0x010461c14e146ac35fe42271bdc1134ee31c703a"
  ]
}'
```

## Response Fields

- `successful_states` (`[address, payload][], required`): Array of two-element tuples. `payload` is the `portfolioState` object for that user (`clearinghouseState`, `spotClearinghouseState`, `userAbstraction`).
- `failed_wallets` (`string[], required`): Addresses where any composed branch failed.

## Successful Response

```json
{
  "successful_states": [
    [
      "0x00f2548cf639e54420e501a35346e8458989e6bd",
      {
        "clearinghouseState": {
          "marginSummary": {
            "accountValue": "555.13644",
            "totalMarginUsed": "0.0",
            "totalNtlPos": "0.0",
            "totalRawUsd": "555.13644"
          },
          "crossMarginSummary": {
            "accountValue": "555.13644",
            "totalMarginUsed": "0.0",
            "totalNtlPos": "0.0",
            "totalRawUsd": "555.13644"
          },
          "crossMaintenanceMarginUsed": "0.0",
          "withdrawable": "555.13644",
          "assetPositions": [],
          "time": 1776448114752
        },
        "spotClearinghouseState": {
          "balances": [
            {
              "coin": "USDC",
              "token": 0,
              "total": "12.27568764",
              "hold": "0.0",
              "entryNtl": "0.0"
            }
          ]
        },
        "userAbstraction": "default"
      }
    ]
  ],
  "failed_wallets": []
}
```

## Response: Single DEX

Both fields are always present. Order matches input order after malformed and duplicate addresses are dropped.

| Field               | Type                   | Description                                                                                                                                                 |
| ------------------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `successful_states` | `[address, payload][]` | Array of two-element tuples. `payload` is the `portfolioState` object for that user: `clearinghouseState`, `spotClearinghouseState`, and `userAbstraction`. |
| `failed_wallets`    | `string[]`             | Addresses where any composed branch failed. Other users in the same request can still succeed.                                                              |

### Success Response

```json
{
  "successful_states": [
    [
      "0x00f2548cf639e54420e501a35346e8458989e6bd",
      {
        "clearinghouseState": {
          "marginSummary": {
            "accountValue": "555.13644",
            "totalMarginUsed": "0.0",
            "totalNtlPos": "0.0",
            "totalRawUsd": "555.13644"
          },
          "crossMarginSummary": {
            "accountValue": "555.13644",
            "totalMarginUsed": "0.0",
            "totalNtlPos": "0.0",
            "totalRawUsd": "555.13644"
          },
          "crossMaintenanceMarginUsed": "0.0",
          "withdrawable": "555.13644",
          "assetPositions": [],
          "time": 1776448114752
        },
        "spotClearinghouseState": {
          "balances": [
            {
              "coin": "USDC",
              "token": 0,
              "total": "12.27568764",
              "hold": "0.0",
              "entryNtl": "0.0"
            }
          ]
        },
        "userAbstraction": "default"
      }
    ]
  ],
  "failed_wallets": []
}
```

### Partial Failure Response

A user lands in `failed_wallets` when any composed branch fails:

```json
{
  "successful_states": [
    [
      "0x00f2548cf639e54420e501a35346e8458989e6bd",
      {
        "clearinghouseState": {
          "marginSummary": {
            "accountValue": "555.13644",
            "totalMarginUsed": "0.0",
            "totalNtlPos": "0.0",
            "totalRawUsd": "555.13644"
          },
          "crossMarginSummary": {
            "accountValue": "555.13644",
            "totalMarginUsed": "0.0",
            "totalNtlPos": "0.0",
            "totalRawUsd": "555.13644"
          },
          "crossMaintenanceMarginUsed": "0.0",
          "withdrawable": "555.13644",
          "assetPositions": [],
          "time": 1776448114752
        },
        "spotClearinghouseState": {
          "balances": [
            {
              "coin": "USDC",
              "token": 0,
              "total": "12.27568764",
              "hold": "0.0",
              "entryNtl": "0.0"
            }
          ]
        },
        "userAbstraction": "unifiedAccount"
      }
    ]
  ],
  "failed_wallets": ["0x010461c14e146ac35fe42271bdc1134ee31c703a"]
}
```

## The `dex` Parameter

By default, each successful payload returns the main Hyperliquid perpetuals DEX state, spot balances, and account abstraction mode. To target a specific HIP-3 market, pass a DEX name returned by [`perpDexs`](https://www.dwellir.com/docs/hyperliquid/perp-dexs). To aggregate across the native DEX and all operational HIP-3 markets, use `dex: "ALL_DEXES"`.

| `dex` value                                                                      | Returns                                                                                                                                          |
| -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| *(omitted)*                                                                      | Native Hyperliquid perp state plus spot balances and account mode for each user                                                                  |
| Any DEX name returned by [`perpDexs`](https://www.dwellir.com/docs/hyperliquid/perp-dexs) | The named HIP-3 DEX state plus spot balances and account mode for each user                                                                      |
| `"ALL_DEXES"`                                                                    | A DEX map of perp state for the native DEX plus every operational HIP-3 market, alongside top-level spot balances and account mode for each user |

### `ALL_DEXES` Request

```bash
curl -X POST "https://api-hyperliquid-mainnet-info.n.dwellir.com/YOUR_API_KEY/info" \
  -H "content-type: application/json" \
  -d '{
  "type": "batchPortfolioState",
  "users": [
    "0x00f2548cf639e54420e501a35346e8458989e6bd"
  ],
  "dex": "ALL_DEXES"
}'
```

### `ALL_DEXES` Response Shape

When `dex` is `"ALL_DEXES"`, each payload's `clearinghouseState` becomes an object keyed by DEX name. `spotClearinghouseState` and `userAbstraction` remain at the top level of that payload. The native DEX always appears under the `"native"` key. Additional keys are dynamic and correspond to operational HIP-3 DEX names returned by [`perpDexs`](https://www.dwellir.com/docs/hyperliquid/perp-dexs), so discover them instead of hardcoding a single example value.

```json
{
  "successful_states": [
    [
      "0x00f2548cf639e54420e501a35346e8458989e6bd",
      {
        "clearinghouseState": {
          "native": {
            "marginSummary": {
              "accountValue": "555.13644",
              "totalMarginUsed": "0.0",
              "totalNtlPos": "0.0",
              "totalRawUsd": "555.13644"
            },
            "crossMarginSummary": {
              "accountValue": "555.13644",
              "totalMarginUsed": "0.0",
              "totalNtlPos": "0.0",
              "totalRawUsd": "555.13644"
            },
            "crossMaintenanceMarginUsed": "0.0",
            "withdrawable": "555.13644",
            "assetPositions": [],
            "time": 1776448114752
          },
          "<dex_name>": {
            "marginSummary": {
              "accountValue": "0.0",
              "totalMarginUsed": "0.0",
              "totalNtlPos": "0.0",
              "totalRawUsd": "0.0"
            },
            "crossMarginSummary": {
              "accountValue": "0.0",
              "totalMarginUsed": "0.0",
              "totalNtlPos": "0.0",
              "totalRawUsd": "0.0"
            },
            "crossMaintenanceMarginUsed": "0.0",
            "withdrawable": "0.0",
            "assetPositions": [],
            "time": 1776448114649
          }
        },
        "spotClearinghouseState": {
          "balances": [
            {
              "coin": "USDC",
              "token": 0,
              "total": "12.27568764",
              "hold": "0.0",
              "entryNtl": "0.0"
            }
          ]
        },
        "userAbstraction": "default"
      }
    ]
  ],
  "failed_wallets": []
}
```

## What `batchPortfolioState` Composes

Each successful payload is equivalent to one [`portfolioState`](https://www.dwellir.com/docs/hyperliquid/portfolio-state) response:

- [`clearinghouseState`](https://www.dwellir.com/docs/hyperliquid/clearinghouse-state): perp positions and margin data
- [`spotClearinghouseState`](https://www.dwellir.com/docs/hyperliquid/spot-clearinghouse-state): spot balances
- [`userAbstraction`](https://www.dwellir.com/docs/hyperliquid/user-abstraction): account abstraction mode

When `dex` is `"ALL_DEXES"`, the clearinghouse branch reuses the `ALL_DEXES` aggregation and keeps the spot and abstraction data at the top level of each payload.

## Common Use Cases

### 1. Multi-Account Portfolio Overview

```javascript
async function getBatchPortfolioOverview(wallets) {
  const result = await getBatchPortfolioState(wallets, 'ALL_DEXES');

  return result.successful_states.map(([address, portfolio]) => ({
    address,
    abstraction: portfolio.userAbstraction,
    perpDexes: Object.keys(portfolio.clearinghouseState),
    spotBalances: portfolio.spotClearinghouseState.balances.length
  }));
}
```

### 2. Merge Spot and Perp State for Many Wallets

```javascript
async function getDashboardStates(wallets) {
  const result = await getBatchPortfolioState(wallets);

  return result.successful_states.map(([address, portfolio]) => ({
    address,
    accountValue: parseFloat(portfolio.clearinghouseState.marginSummary.accountValue),
    withdrawable: parseFloat(portfolio.clearinghouseState.withdrawable),
    balances: portfolio.spotClearinghouseState.balances,
    accountMode: portfolio.userAbstraction
  }));
}
```

## Related Endpoints

- [**portfolioState**](https://www.dwellir.com/docs/hyperliquid/portfolio-state): Get perp state, spot balances, and account mode for a single user
- [**batchClearinghouseStates**](https://www.dwellir.com/docs/hyperliquid/batch-clearinghouse-states): Batch query perpetual account states
- [**batchSpotClearinghouseState**](https://www.dwellir.com/docs/hyperliquid/batch-spot-clearinghouse-state): Batch query spot balances
- [**clearinghouseState**](https://www.dwellir.com/docs/hyperliquid/clearinghouse-state): Get perpetual account state, including `ALL_DEXES` support
- [**userAbstraction**](https://www.dwellir.com/docs/hyperliquid/user-abstraction): Get account abstraction mode only

***

*Batch query full Hyperliquid portfolio state with Dwellir's HyperCore Info Endpoint. [Get your API key →](https://dashboard.dwellir.com/register)*
