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

# Portfolio & account

> Identity, your wallet's value and balances, the deposit address for funding in, and a cross-vertical view of every open position and trade.

These read endpoints are how a bot answers the three questions it asks constantly: *who am I*, *what do I hold*, and *how am I doing*. They cover identity ([`/me`](#identity-—-get-/me)), the money side of the wallet ([`/account/*`](#account-summary-and-the-deposit-address)), and a single cross-vertical roll-up of positions and trades across every group ([`/positions`, `/trades`](#cross-vertical-positions-and-trades)).

Everything here is a **read**. The only "write" in the funding story is depositing USDC to an address you read from `GET /account` — and there is no withdrawal endpoint at all (see below).

<Note>
  Every monetary value on the wire is a **full-precision plain decimal string** in USD (`"12.50"`,
  never a number, never raw base units, never scientific notation). Parse with a decimal library;
  round only for display. See [Money & precision](/concepts/money-and-precision).
</Note>

<Warning>
  **There is no withdrawal endpoint.** Your API key can *deploy* funds (group positions,
  predictions, perps) but cannot move money **out** of the wallet to an external address — withdrawals
  require an interactive in-app session and have no REST route. Funding **in** is just a USDC
  transfer to the deposit address from `GET /account`. See [Authentication](/authentication).
</Warning>

## Environment

```bash theme={null}
export MURMO_API_KEY="murmo_your_key_here"
export MURMO_BASE="https://api.alpha-labs.trade"
```

Every request carries `Authorization: Bearer $MURMO_API_KEY`. The examples below use `curl`,
`fetch`, and `requests`; swap in your HTTP client of choice.

## Identity — `GET /me`

The bootstrap call. It echoes the user behind the credential, which key you're using (metadata
only — **never** the secret), and your rate budget. Nothing financial lives here; for balances and
the deposit address use [`GET /account`](#account-summary-and-the-deposit-address).

<CodeGroup>
  ```bash curl theme={null}
  curl "$MURMO_BASE/api/v1/me" \
    -H "Authorization: Bearer $MURMO_API_KEY"
  ```

  ```javascript JavaScript theme={null}
  const res = await fetch(`${process.env.MURMO_BASE}/api/v1/me`, {
    headers: { Authorization: `Bearer ${process.env.MURMO_API_KEY}` },
  });
  const { data } = await res.json();
  console.log(data.userId, data.rateLimit); // who am I, what's my budget
  ```

  ```python Python theme={null}
  import os, requests

  base, key = os.environ["MURMO_BASE"], os.environ["MURMO_API_KEY"]
  res = requests.get(f"{base}/api/v1/me", headers={"Authorization": f"Bearer {key}"})
  data = res.json()["data"]
  print(data["userId"], data["rateLimit"])
  ```
</CodeGroup>

```json Response theme={null}
{
  "data": {
    "userId": "d66bafb2-1f1a-4f7e-9a2c-0b3e9c8f1234",
    "authMethod": "apiKey",
    "apiKey": {
      "id": "ak_7f3c9d20",
      "label": "my-bot",
      "prefix": "murmo_froc",
      "lastUsedAt": "2026-06-02T19:00:00.000Z",
      "expiresAt": null,
      "createdAt": "2026-05-20T12:00:00.000Z"
    },
    "rateLimit": { "limit": 1200, "windowSeconds": 60 }
  }
}
```

For JWT (in-app) auth, `apiKey` and `rateLimit` are `null` and `authMethod` is `"jwt"`. The
`Me` fields:

| Field               | Type                            | Notes                                                                              |
| ------------------- | ------------------------------- | ---------------------------------------------------------------------------------- |
| `userId`            | string                          | The user id behind the credential.                                                 |
| `authMethod`        | `"apiKey"` \| `"jwt"` \| `null` | How this request authenticated.                                                    |
| `apiKey`            | object \| `null`                | Present for API-key auth; metadata only, never the secret.                         |
| `apiKey.id`         | string                          | Key id (not the key itself).                                                       |
| `apiKey.label`      | string \| `null`                | Human label set in the app.                                                        |
| `apiKey.prefix`     | string                          | First chars of the key (e.g. `murmo_froc`) — enough to identify it in logs.        |
| `apiKey.lastUsedAt` | date-time \| `null`             | Last time this key was used.                                                       |
| `apiKey.expiresAt`  | date-time \| `null`             | Expiry, or `null` if non-expiring.                                                 |
| `apiKey.createdAt`  | date-time                       | When the key was created.                                                          |
| `rateLimit`         | object \| `null`                | `{ limit, windowSeconds }` for API-key auth — currently **1,200 requests / 60 s**. |

<Tip>
  The rate budget here matches [Rate limits](/concepts/rate-limits): 1,200 requests per 60-second
  window per key. Over it you get `429`. Prefer [WebSockets](/websockets/overview) for live prices
  instead of tight REST polling.
</Tip>

## Account summary and the deposit address

`GET /account` is the one call that gives you both your wallet's headline value **and** the address
to fund it.

<CodeGroup>
  ```bash curl theme={null}
  curl "$MURMO_BASE/api/v1/account" \
    -H "Authorization: Bearer $MURMO_API_KEY"
  ```

  ```javascript JavaScript theme={null}
  const res = await fetch(`${process.env.MURMO_BASE}/api/v1/account`, {
    headers: { Authorization: `Bearer ${process.env.MURMO_API_KEY}` },
  });
  const { data } = await res.json();
  console.log(data.cashBalanceUsd, data.deposit.walletAddress);
  ```

  ```python Python theme={null}
  res = requests.get(f"{base}/api/v1/account", headers={"Authorization": f"Bearer {key}"})
  data = res.json()["data"]
  print(data["cashBalanceUsd"], data["deposit"]["walletAddress"])
  ```
</CodeGroup>

```json Response theme={null}
{
  "data": {
    "totalValueUsd": "142.86",
    "cashBalanceUsd": "37.50",
    "deposit": {
      "walletAddress": "5xY9q2k...wallet",
      "token": "USDC",
      "tokenMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
      "chain": "solana"
    }
  }
}
```

`AccountSummary` fields:

| Field                   | Type         | Notes                                             |
| ----------------------- | ------------ | ------------------------------------------------- |
| `totalValueUsd`         | money string | Total wallet value in USD.                        |
| `cashBalanceUsd`        | money string | USDC cash balance in USD.                         |
| `deposit.walletAddress` | string       | **Send USDC here** on Solana to fund the account. |
| `deposit.token`         | string       | Always `"USDC"`.                                  |
| `deposit.tokenMint`     | string       | The USDC mint to send (don't send other tokens).  |
| `deposit.chain`         | string       | Always `"solana"`.                                |

<Warning>
  **Field-naming nuance — read this once and save yourself a surprise.** `GET /account` uses the
  `Usd` suffix (`totalValueUsd`, `cashBalanceUsd`). The other account/portfolio reads keep the
  upstream names **without** the suffix: [`/account/portfolio`](#portfolio-value-and-24h-change-—-get-/account/portfolio)
  returns `totalValue`, `absoluteChange24h`, `percentChange24h`, and every per-balance row uses
  `value` and `price` (not `valueUsd`/`priceUsd`). They are **all still decimal strings in USD** —
  only the key names differ per endpoint.
</Warning>

### Balances — `GET /account/balances`

Cash and token balances held in the main wallet. Each row is a `WalletBalance`; the response wraps
them in a named `balances` array.

```bash theme={null}
curl "$MURMO_BASE/api/v1/account/balances" \
  -H "Authorization: Bearer $MURMO_API_KEY"
```

```json Response theme={null}
{
  "data": {
    "balances": [
      {
        "tokenAddress": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
        "tokenSymbol": "USDC",
        "tokenName": "USD Coin",
        "balance": "37.5",
        "value": "37.5",
        "price": "1",
        "chainId": "solana",
        "decimals": 6,
        "currency": "usd",
        "lastUpdated": "2026-06-02T19:01:22.000Z"
      },
      {
        "tokenAddress": "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263",
        "tokenSymbol": "BONK",
        "tokenName": "Bonk",
        "balance": "28952000.123456789",
        "value": "105.36",
        "price": "0.0000036389",
        "chainId": "solana",
        "decimals": 5,
        "currency": "usd",
        "lastUpdated": "2026-06-02T19:01:22.000Z"
      }
    ]
  }
}
```

`WalletBalance` fields:

| Field          | Type           | Notes                                                                  |
| -------------- | -------------- | ---------------------------------------------------------------------- |
| `tokenAddress` | string         | The token's mint address.                                              |
| `tokenSymbol`  | string         | Symbol, e.g. `USDC`.                                                   |
| `tokenName`    | string         | Display name.                                                          |
| `balance`      | decimal string | **Token quantity** (already human, not base units) — a decimal string. |
| `value`        | money string   | USD value of the holding (no `Usd` suffix).                            |
| `price`        | money string   | USD price per token (no `Usd` suffix).                                 |
| `chainId`      | string         | Chain, e.g. `solana`.                                                  |
| `decimals`     | integer        | Structural token decimals — a plain JSON **number**, not a string.     |
| `currency`     | string         | Quote currency, e.g. `usd`.                                            |
| `lastUpdated`  | date-time      | When the balance/valuation was last refreshed.                         |

<Tip>
  `balance` is a decimal-string **quantity** and `decimals` is a structural **integer** — they play
  different roles. `decimals` is informational here (the balance is already humanized); you only need
  it to interpret the `...Raw` base-unit quantities that show up elsewhere (trades). See
  [Money & precision → Raw vs. human quantities](/concepts/money-and-precision).
</Tip>

### Spot holdings — `GET /account/positions`

Token holdings (spot positions) in the main wallet — the same `WalletBalance` shape as `/balances`,
plus a `nextCursor` for pagination when there are more pages.

```bash theme={null}
curl "$MURMO_BASE/api/v1/account/positions" \
  -H "Authorization: Bearer $MURMO_API_KEY"
```

```json Response theme={null}
{
  "data": {
    "positions": [
      {
        "tokenAddress": "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263",
        "tokenSymbol": "BONK",
        "tokenName": "Bonk",
        "balance": "28952000.123456789",
        "value": "105.36",
        "price": "0.0000036389",
        "chainId": "solana",
        "decimals": 5,
        "currency": "usd",
        "lastUpdated": "2026-06-02T19:01:22.000Z"
      }
    ],
    "nextCursor": null
  }
}
```

`nextCursor` is `null` when there are no more pages. When it is a string, pass it back to fetch the
next page (it is `null` in the common single-page case).

### Portfolio value and 24h change — `GET /account/portfolio`

Aggregate portfolio value plus 24-hour change, with the underlying positions inline.

<CodeGroup>
  ```bash curl theme={null}
  curl "$MURMO_BASE/api/v1/account/portfolio" \
    -H "Authorization: Bearer $MURMO_API_KEY"
  ```

  ```javascript JavaScript theme={null}
  const res = await fetch(`${process.env.MURMO_BASE}/api/v1/account/portfolio`, {
    headers: { Authorization: `Bearer ${process.env.MURMO_API_KEY}` },
  });
  const { data } = await res.json();
  // NOTE: no "Usd" suffix here — these are the upstream names, still USD decimal strings.
  console.log(data.totalValue, data.absoluteChange24h, data.percentChange24h);
  ```

  ```python Python theme={null}
  res = requests.get(f"{base}/api/v1/account/portfolio", headers={"Authorization": f"Bearer {key}"})
  data = res.json()["data"]
  print(data["totalValue"], data["absoluteChange24h"], data["percentChange24h"])
  ```
</CodeGroup>

```json Response theme={null}
{
  "data": {
    "walletAddress": "5xY9q2k...wallet",
    "currency": "usd",
    "totalValue": "142.86",
    "absoluteChange24h": "8.41",
    "percentChange24h": "6.25",
    "positions": [
      {
        "tokenAddress": "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263",
        "tokenSymbol": "BONK",
        "tokenName": "Bonk",
        "balance": "28952000.123456789",
        "value": "105.36",
        "price": "0.0000036389",
        "chainId": "solana",
        "decimals": 5,
        "currency": "usd",
        "lastUpdated": "2026-06-02T19:01:22.000Z"
      }
    ],
    "lastUpdated": "2026-06-02T19:01:22.000Z"
  }
}
```

`Portfolio` fields:

| Field               | Type              | Notes                                                      |
| ------------------- | ----------------- | ---------------------------------------------------------- |
| `walletAddress`     | string            | The main wallet.                                           |
| `currency`          | string            | Quote currency, e.g. `usd`.                                |
| `totalValue`        | money string      | Total value (USD). **No `Usd` suffix** — upstream name.    |
| `absoluteChange24h` | money string      | Absolute 24h change in USD. **No `Usd` suffix.**           |
| `percentChange24h`  | decimal string    | 24h change as a percent, e.g. `"6.25"` = **6.25%**.        |
| `positions`         | `WalletBalance[]` | The holdings behind the total (same shape as `/balances`). |
| `lastUpdated`       | date-time         | When the valuation was last refreshed.                     |

### PnL — `GET /account/pnl`

Just the 24h change numbers, when you don't need the full portfolio body.

```bash theme={null}
curl "$MURMO_BASE/api/v1/account/pnl" \
  -H "Authorization: Bearer $MURMO_API_KEY"
```

```json Response theme={null}
{
  "data": {
    "absoluteChange24h": "8.41",
    "percentChange24h": "6.25"
  }
}
```

| Field               | Type           | Notes                                                                |
| ------------------- | -------------- | -------------------------------------------------------------------- |
| `absoluteChange24h` | money string   | Absolute change in USD over the default window. **No `Usd` suffix.** |
| `percentChange24h`  | decimal string | Percent change, e.g. `"6.25"` = **6.25%**.                           |

## Fund and check your account

<Steps>
  <Step title="Read the deposit address">
    `GET /api/v1/account` and read `data.deposit.walletAddress` (plus `tokenMint` to confirm you're
    sending the right token — USDC).
  </Step>

  <Step title="Send USDC on Solana">
    Transfer USDC to that address **on Solana**. This is an on-chain transfer you make from your own
    wallet/exchange — it is not an API call. There is no API path that pulls funds for you.
  </Step>

  <Step title="Poll the balance until it lands">
    Re-`GET /api/v1/account` (or `/account/balances`) until `cashBalanceUsd` reflects the deposit.
    Settlement follows Solana confirmation, so allow a few seconds.
  </Step>

  <Step title="Deploy it">
    Once funded, the same key can open group proposals, predict, or open perps. To move money
    **out**, use the app — there is no withdrawal endpoint.
  </Step>
</Steps>

## Cross-vertical positions and trades

Three endpoints under `/api/v1` give you everything you hold and everything you've traded across
**all** groups in one call, without iterating group by group. Spot, prediction, and perp positions
each have their own per-vertical endpoints elsewhere; these are the aggregated views.

<Warning>
  **The `data` shapes differ — this is the most common cross-endpoint trip hazard.**
  `/positions` and `/positions/past` return `data` as an **object keyed by vertical**
  (`{ perps, spot, predictions }`), **not** a bare array. `/trades` returns `data` as
  `{ spot, predictions }`. The account list reads instead wrap rows in a **named key**
  (`{ balances: [...] }`, `{ positions: [...], nextCursor }`). See the
  [envelope table](#data-envelope-cheat-sheet) below before you write your parser.
</Warning>

### Open positions — `GET /positions`

Open positions across perps + spot + predictions, in every group.

<CodeGroup>
  ```bash curl theme={null}
  curl "$MURMO_BASE/api/v1/positions" \
    -H "Authorization: Bearer $MURMO_API_KEY"
  ```

  ```javascript JavaScript theme={null}
  const res = await fetch(`${process.env.MURMO_BASE}/api/v1/positions`, {
    headers: { Authorization: `Bearer ${process.env.MURMO_API_KEY}` },
  });
  const { data } = await res.json();
  // data is keyed by vertical — not an array.
  console.log(data.perps.length, data.spot.length, data.predictions.length);
  ```

  ```python Python theme={null}
  res = requests.get(f"{base}/api/v1/positions", headers={"Authorization": f"Bearer {key}"})
  data = res.json()["data"]
  print(len(data["perps"]), len(data["spot"]), len(data["predictions"]))
  ```
</CodeGroup>

```json Response theme={null}
{
  "data": {
    "perps": [
      {
        "id": "asg_91ac...",
        "marketSymbol": "BTC",
        "side": "LONG",
        "status": "OPEN",
        "initialCollateralUsdc": "25.00",
        "initialLeverage": "5",
        "positionValueUsd": "128.40",
        "entryPriceUsd": "61840.12",
        "unrealizedPnlUsd": "3.40",
        "liquidationPriceUsd": "51230.00",
        "isClaimable": false
      }
    ],
    "spot": [
      {
        "proposal": {
          "id": "tp_4b1e...",
          "groupId": "1a9d212a-de67-45f4-88f5-6e9f41e78dc0",
          "reason": "Momentum breakout",
          "token": { "symbol": "BONK", "contractAddress": "DezXAZ8z7...263" }
        },
        "userPosition": {
          "hasPosition": true,
          "currentTokenAmountRaw": "2895200012345",
          "totalCostUsd": "50.00",
          "avgEntryPriceUsd": "0.0000034",
          "unrealizedPnlUsd": "5.36",
          "currentValueUsd": "55.36"
        },
        "participantCount": 4,
        "participantAvatars": ["https://..."]
      }
    ],
    "predictions": [
      {
        "proposal": {
          "id": "pp_77de...",
          "eventId": "presidential-election-winner-2028",
          "marketId": "will-jd-vance-win-the-2028-us-presidential-election",
          "isYes": true,
          "status": "ACTIVE"
        },
        "market": { "yesBidDollars": "0.28", "yesAskDollars": "0.29" },
        "userPosition": {
          "tokenAmount": "10.5",
          "tokenDecimals": 6,
          "totalCostUsd": "10.00",
          "currentValueUsd": "13.20",
          "unrealizedPnlUsd": "3.20"
        },
        "remainingTokenAmount": "10.5",
        "createdBy": { "dynamicId": "d66bafb2-...", "username": "satoshi" }
      }
    ]
  }
}
```

The per-vertical item shapes are documented in full in the dedicated guides and the API Reference:

* `perps[]` → `PerpPosition` (the `id` **is** the `assignmentId`; reduce/claim it via the perps
  endpoints). Persisted/realized USD fields and live mark/PnL/price fields are all decimal strings;
  base-lot quantities (`currentSizeBaseLots`) are quantity strings.
* `spot[]` → `SpotProposalWithPosition` (`{ proposal, userPosition, participantCount, participantAvatars }`).
  Note `userPosition.currentTokenAmountRaw` is a **base-unit** quantity (humanize with the token's
  `decimals`).
* `predictions[]` → `PredictionWithPosition` (`{ proposal, market, userPosition, remainingTokenAmount, createdBy }`).
  `market` is venue-native, normalized (`marketTicker` = market slug, `eventTicker` = event slug,
  prices already human dollar strings); `tokenAmount`/`remainingTokenAmount` are already humanized.

### Past positions — `GET /positions/past`

Identical `{ perps, spot, predictions }` shape, but for closed/resolved positions across all three
verticals.

```bash theme={null}
curl "$MURMO_BASE/api/v1/positions/past" \
  -H "Authorization: Bearer $MURMO_API_KEY"
```

### Trade history — `GET /trades`

Executed trade history for **spot + predictions**. (Perp fills are not here — surface those via
`GET /api/v1/perps/positions`.)

<CodeGroup>
  ```bash curl theme={null}
  curl "$MURMO_BASE/api/v1/trades?limit=50" \
    -H "Authorization: Bearer $MURMO_API_KEY"
  ```

  ```javascript JavaScript theme={null}
  const res = await fetch(`${process.env.MURMO_BASE}/api/v1/trades?limit=50`, {
    headers: { Authorization: `Bearer ${process.env.MURMO_API_KEY}` },
  });
  const { data } = await res.json();
  console.log(data.spot.length, data.predictions.length);
  ```

  ```python Python theme={null}
  res = requests.get(
      f"{base}/api/v1/trades",
      headers={"Authorization": f"Bearer {key}"},
      params={"limit": 50},
  )
  data = res.json()["data"]
  print(len(data["spot"]), len(data["predictions"]))
  ```
</CodeGroup>

```json Response theme={null}
{
  "data": {
    "spot": [
      {
        "id": "tt_5f2a...",
        "tradingProposalId": "tp_4b1e...",
        "groupId": "1a9d212a-de67-45f4-88f5-6e9f41e78dc0",
        "walletAddress": "5xY9q2k...wallet",
        "tradeType": "BUY",
        "tokenAmount": "14476000.06",
        "tokenDecimals": 5,
        "pricePerTokenUsd": "0.0000034",
        "totalCostUsd": "50.00",
        "alphaFeeUsd": "0.05",
        "pnlPct": null,
        "pnlUsd": null,
        "txSignature": "4nP...solana_sig",
        "createdAt": "2026-06-02T18:40:00.000Z"
      }
    ],
    "predictions": [
      {
        "id": "pt_8c0b...",
        "proposalId": "pp_77de...",
        "groupId": "1a9d212a-de67-45f4-88f5-6e9f41e78dc0",
        "walletAddress": "5xY9q2k...wallet",
        "tradeType": "BUY",
        "tokenAmount": "16.12",
        "tokenDecimals": 6,
        "pricePerTokenUsd": "0.62",
        "totalCostUsd": "10.00",
        "venueFeeUsd": "0.151876",
        "pnlPct": null,
        "pnlUsd": null,
        "txSignature": "3mK...solana_sig",
        "createdAt": "2026-06-02T18:45:00.000Z"
      }
    ]
  }
}
```

`limit` is optional (default **50**, max **200**; out-of-range values are clamped). Both arrays use
the same money convention: `tokenAmount` is an already-humanized decimal-string quantity (interpret
alongside `tokenDecimals`), and every `...Usd` / `pnl*` field is a USD/percent decimal string
(`pnl*` is `null` on opening buys). On prediction trades, `totalCostUsd` is the gross fill value
(`tokenAmount × pricePerTokenUsd`), `venueFeeUsd` is the venue fee charged on the fill, and
`pnlPct`/`pnlUsd` are net of venue fees.

## `data` envelope cheat-sheet

The thing to internalize: **every** response is wrapped in a top-level `{ "data": ... }`, but the
shape *inside* `data` varies. Here is every endpoint on this page:

| Endpoint                 | `data` shape                   | How to read it                                           |
| ------------------------ | ------------------------------ | -------------------------------------------------------- |
| `GET /me`                | object (`Me`)                  | `data.userId`, `data.apiKey`, `data.rateLimit`           |
| `GET /account`           | object (`AccountSummary`)      | `data.totalValueUsd`, `data.deposit.walletAddress`       |
| `GET /account/balances`  | **named key** → array          | `data.balances` is `WalletBalance[]`                     |
| `GET /account/positions` | **named key** → array + cursor | `data.positions` is `WalletBalance[]`; `data.nextCursor` |
| `GET /account/portfolio` | object (`Portfolio`)           | `data.totalValue`, `data.positions[]`                    |
| `GET /account/pnl`       | object                         | `data.absoluteChange24h`, `data.percentChange24h`        |
| `GET /positions`         | **object keyed by vertical**   | `data.perps[]`, `data.spot[]`, `data.predictions[]`      |
| `GET /positions/past`    | **object keyed by vertical**   | `data.perps[]`, `data.spot[]`, `data.predictions[]`      |
| `GET /trades`            | **object keyed by vertical**   | `data.spot[]`, `data.predictions[]`                      |

<Tip>
  Two gotchas worth pinning: (1) the cross-vertical reads (`/positions`, `/positions/past`,
  `/trades`) are **keyed objects, not arrays** — `data.spot`, `data.perps`, `data.predictions`. (2)
  The account list reads bury their array under a **named key** — `data.balances`, `data.positions`.
  If you blindly `data.map(...)` either family, you'll get a runtime error.
</Tip>

## Errors

All four standard error statuses apply. `401` means a missing/invalid `Authorization` header or key;
`404` on `GET /account` means the wallet couldn't be resolved for the credential. Error bodies come
in two shapes — coded business errors `{ message, code }` and generic framework errors
`{ statusCode, message, error }`. See [Errors](/concepts/errors).

## Where to next

<CardGroup cols={2}>
  <Card title="Money & precision" icon="coins" href="/concepts/money-and-precision">
    Why every value is a decimal string, and how to parse it.
  </Card>

  <Card title="Authentication" icon="key" href="/authentication">
    The Bearer header, what a key can (and can't) do, and rate limits.
  </Card>

  <Card title="Groups & proposals" icon="users" href="/concepts/groups-and-proposals">
    Why positions live as proposals inside groups — the model behind the `spot`/`predictions` arrays.
  </Card>

  <Card title="API Reference" icon="code" href="/api-reference">
    Full schemas for `Me`, `AccountSummary`, `WalletBalance`, `Portfolio`, and `CrossVerticalPositions`.
  </Card>
</CardGroup>
