Skip to main content
These read endpoints answer the three questions a bot asks constantly: who am I, what do I hold, and how am I doing. They cover identity (GET /me), the money side of your wallet (GET /account/*), and a single cross-vertical roll-up of positions and trades across every group (GET /positions, GET /trades). Everything here is a read — the only “write” in the funding story is depositing USDC to an address you read from GET /account.
There is no withdrawal endpoint. Your API key can deploy funds (swaps, 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.
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.
Set up your environment before starting:
export MURMO_API_KEY="murmo_your_key_here"
export MURMO_BASE="https://api.alpha-labs.trade"

Identity — GET /me

The bootstrap call. It echoes the user behind the credential, key metadata (never the secret), and your rate budget. Nothing financial lives here — for balances and the deposit address use GET /account.
curl "$MURMO_BASE/api/v1/me" \
  -H "Authorization: Bearer $MURMO_API_KEY"
Response
{
  "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 }
  }
}
FieldTypeNotes
userIdstringThe user ID behind the credential.
authMethod"apiKey" | "jwt" | nullHow this request authenticated.
apiKeyobject | nullPresent for API-key auth; metadata only, never the secret.
apiKey.idstringKey ID (not the key itself).
apiKey.labelstring | nullHuman label set in the app.
apiKey.prefixstringFirst chars of the key (e.g. murmo_froc) — enough to identify it in logs.
apiKey.lastUsedAtdate-time | nullLast time this key was used.
apiKey.expiresAtdate-time | nullExpiry, or null if non-expiring.
rateLimitobject | null{ limit, windowSeconds } — currently 1,200 requests / 60 s for API keys.
The rate budget here matches what’s documented in Rate limits: 1,200 requests per 60-second window per key. Over the limit you get 429. Use WebSockets for live prices instead of tight REST polling.

Account summary and the deposit address

GET /api/v1/account gives you both your wallet’s headline value and the address to fund it.
curl "$MURMO_BASE/api/v1/account" \
  -H "Authorization: Bearer $MURMO_API_KEY"
Response
{
  "data": {
    "totalValueUsd": "142.86",
    "cashBalanceUsd": "37.50",
    "deposit": {
      "walletAddress": "5xY9q2k...wallet",
      "token": "USDC",
      "tokenMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
      "chain": "solana"
    }
  }
}
FieldTypeNotes
totalValueUsdmoney stringTotal wallet value in USD.
cashBalanceUsdmoney stringUSDC cash balance in USD.
deposit.walletAddressstringSend USDC here on Solana to fund the account.
deposit.tokenstringAlways "USDC".
deposit.tokenMintstringThe USDC mint to send — don’t send other tokens.
deposit.chainstringAlways "solana".
Field-naming nuance. GET /account uses the Usd suffix (totalValueUsd, cashBalanceUsd). The other account/portfolio reads keep upstream names without the suffix: GET /account/portfolio returns totalValue, absoluteChange24h, percentChange24h, and per-balance rows use value and price (not valueUsd/priceUsd). They are all still decimal strings in USD — only the key names differ per endpoint.

Fund and check your account

1

Read the deposit address

GET /api/v1/account and read data.deposit.walletAddress. Check tokenMint to confirm you’re sending the right token — USDC.
2

Send USDC on Solana

Transfer USDC to that address on Solana. This is an on-chain transfer you make from your own wallet or exchange — it is not an API call. There is no API path that pulls funds for you.
3

Poll until the balance lands

Re-GET /api/v1/account (or /account/balances) until cashBalanceUsd reflects the deposit. Settlement follows Solana confirmation, so allow a few seconds.
4

Deploy it

Once funded, the same key can swap, open group proposals, predict, or open perps. To move money out, use the app — there is no withdrawal endpoint.

Balances — GET /account/balances

Cash and token balances held in the main wallet. Each row is a WalletBalance; the response wraps them in a balances array.
curl "$MURMO_BASE/api/v1/account/balances" \
  -H "Authorization: Bearer $MURMO_API_KEY"
Response
{
  "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",
        "balance": "28952000.123456789",
        "value": "105.36",
        "price": "0.0000036389",
        "decimals": 5,
        "currency": "usd",
        "lastUpdated": "2026-06-02T19:01:22.000Z"
      }
    ]
  }
}
WalletBalance fields:
FieldTypeNotes
tokenAddressstringThe token’s mint address.
tokenSymbolstringSymbol, e.g. USDC.
tokenNamestringDisplay name.
balancedecimal stringToken quantity (already humanized, not base units).
valuemoney stringUSD value of the holding. No Usd suffix — upstream name.
pricemoney stringUSD price per token. No Usd suffix.
chainIdstringChain, e.g. solana.
decimalsintegerToken decimals — a plain JSON number, not a string.
currencystringQuote currency, e.g. usd.
lastUpdateddate-timeWhen the balance/valuation was last refreshed.

Spot holdings — GET /account/positions

Token holdings (spot positions) in the main wallet — the same WalletBalance shape as /balances, plus a nextCursor for pagination.
curl "$MURMO_BASE/api/v1/account/positions" \
  -H "Authorization: Bearer $MURMO_API_KEY"
Response
{
  "data": {
    "positions": [
      {
        "tokenAddress": "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263",
        "tokenSymbol": "BONK",
        "balance": "28952000.123456789",
        "value": "105.36",
        "price": "0.0000036389",
        "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.

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

Aggregate portfolio value plus 24-hour change, with the underlying positions inline.
curl "$MURMO_BASE/api/v1/account/portfolio" \
  -H "Authorization: Bearer $MURMO_API_KEY"
Response
{
  "data": {
    "walletAddress": "5xY9q2k...wallet",
    "currency": "usd",
    "totalValue": "142.86",
    "absoluteChange24h": "8.41",
    "percentChange24h": "6.25",
    "positions": [
      {
        "tokenSymbol": "BONK",
        "balance": "28952000.123456789",
        "value": "105.36",
        "price": "0.0000036389",
        "decimals": 5,
        "lastUpdated": "2026-06-02T19:01:22.000Z"
      }
    ],
    "lastUpdated": "2026-06-02T19:01:22.000Z"
  }
}
FieldTypeNotes
walletAddressstringThe main wallet.
totalValuemoney stringTotal value (USD). No Usd suffix — upstream name.
absoluteChange24hmoney stringAbsolute 24h change in USD. No Usd suffix.
percentChange24hdecimal string24h change as a percent, e.g. "6.25" = 6.25%.
positionsWalletBalance[]The holdings behind the total (same shape as /balances).
lastUpdateddate-timeWhen the valuation was last refreshed.

PnL — GET /account/pnl

Just the 24h change numbers, when you don’t need the full portfolio body.
curl "$MURMO_BASE/api/v1/account/pnl" \
  -H "Authorization: Bearer $MURMO_API_KEY"
Response
{
  "data": {
    "absoluteChange24h": "8.41",
    "percentChange24h": "6.25"
  }
}

Cross-vertical positions and trades

Three endpoints give you everything you hold and everything you’ve traded across all groups in one call, without iterating group by group.
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 below before you write your parser.

Open positions — GET /positions

Open positions across perps, spot, and predictions in every group.
curl "$MURMO_BASE/api/v1/positions" \
  -H "Authorization: Bearer $MURMO_API_KEY"
Response
{
  "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",
          "token": { "symbol": "BONK", "contractAddress": "DezXAZ8z7...263" }
        },
        "userPosition": {
          "hasPosition": true,
          "currentTokenAmountRaw": "2895200012345",
          "totalCostUsd": "50.00",
          "unrealizedPnlUsd": "5.36",
          "currentValueUsd": "55.36"
        }
      }
    ],
    "predictions": [
      {
        "proposal": {
          "id": "pp_77de...",
          "eventId": "KXNFLGAME-25SB",
          "marketId": "KXNFLGAME-25SB-KC",
          "isYes": true,
          "status": "OPEN"
        },
        "userPosition": {
          "tokenAmount": "10.5",
          "tokenDecimals": 6,
          "totalCostUsd": "10.00",
          "currentValueUsd": "13.20",
          "unrealizedPnlUsd": "3.20"
        }
      }
    ]
  }
}
Per-vertical item shapes:
  • perps[]PerpPosition (the id is the assignmentId; reduce/claim via the perps endpoints). All ...Usd fields and PnL are decimal strings; base-lot quantities 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 }). tokenAmount/remainingTokenAmount are already humanized.

Past positions — GET /positions/past

Identical { perps, spot, predictions } shape, but for closed/resolved positions across all three verticals.
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.
curl "$MURMO_BASE/api/v1/trades?limit=50" \
  -H "Authorization: Bearer $MURMO_API_KEY"
Response
{
  "data": {
    "spot": [
      {
        "id": "tt_5f2a...",
        "tradingProposalId": "tp_4b1e...",
        "groupId": "1a9d212a-de67-45f4-88f5-6e9f41e78dc0",
        "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...",
        "tradeType": "BUY",
        "tokenAmount": "10.5",
        "tokenDecimals": 6,
        "pricePerTokenUsd": "0.62",
        "totalCostUsd": "10.00",
        "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). tokenAmount is an already-humanized decimal-string quantity; every ...Usd / pnl* field is a USD or percent decimal string (pnl* is null on opening buys).

data envelope cheat-sheet

Every response is wrapped in a top-level { "data": ... }, but the shape inside data varies. Here’s every endpoint on this page:
Endpointdata shapeHow to read it
GET /meobject (Me)data.userId, data.apiKey, data.rateLimit
GET /accountobject (AccountSummary)data.totalValueUsd, data.deposit.walletAddress
GET /account/balancesnamed key → arraydata.balances is WalletBalance[]
GET /account/positionsnamed key → array + cursordata.positions is WalletBalance[]; data.nextCursor
GET /account/portfolioobject (Portfolio)data.totalValue, data.positions[]
GET /account/pnlobjectdata.absoluteChange24h, data.percentChange24h
GET /positionsobject keyed by verticaldata.perps[], data.spot[], data.predictions[]
GET /positions/pastobject keyed by verticaldata.perps[], data.spot[], data.predictions[]
GET /tradesobject keyed by verticaldata.spot[], data.predictions[]
Two gotchas worth pinning: (1) the cross-vertical reads (/positions, /positions/past, /trades) are keyed objects, not arraysdata.spot, data.perps, data.predictions. (2) The account list reads bury their array under a named keydata.balances, data.positions. Blindly calling .map() on either family will produce a runtime error.

Errors

All four standard error statuses apply. 401 means a missing or 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.

Where to next

Money & precision

Why every value is a decimal string, and how to parse it.

Authentication

The Bearer header, what a key can and can’t do, and rate limits.

Groups & proposals

Why positions live as proposals inside groups — the model behind the arrays.

API Reference

Full schemas for Me, AccountSummary, WalletBalance, Portfolio, and cross-vertical positions.