Skip to main content
Spot trading on Murmo happens through group spot proposals: a shared token idea inside a group that a leader opens with a buy and other members can follow. Slippage and the wallet id are always resolved for you (never accepted from the caller). Everything lives under /api/v1/spot. Tokens are addressed by their Solana mint address, or the literal string "USDC".
Every monetary value — in requests and responses — is a full-precision plain decimal string in USD ("12.50", not 12.5, not 12500000, never "1.25e1"). Token quantities in base units are the one exception and are always named with a ...Raw suffix. See Money & precision.
Set up your environment the same way as the Quickstart:

Find a token

GET /api/v1/spot/tokens/search is a Jupiter-backed search over Solana tokens. Both q (a symbol, name, or mint) and limit (default 20) are optional.
data is an array of token objects. The shape passes through from Jupiter/CoinGecko, so treat the keys as opaque — but any price/volume floats are rendered as decimal strings, never JS numbers.
Search is for discovery. Once you have a candidate mint, fetch its canonical price and decimals with the by-mint endpoint below before you trade.

Get price + metadata (and decimals)

GET /api/v1/spot/tokens/{mint} returns price and metadata for one token by its mint address. This is how you get a token’s decimals — the number you need to humanize any ...Raw quantity returned elsewhere.
data is a single token object (opaque, pass-through shape). Price fields are decimal strings; decimals is a plain integer you reuse to convert base units to human amounts.

Group spot proposals

A spot proposal is a token idea inside a group: a leader opens it with a buy, and other members buy in, sell out, and follow along. Each member manages their own position; the creator can close the whole proposal. See Groups & proposals for the social model.
Every proposal endpoint is members-only. Reading or trading a proposal in a group you don’t belong to returns 403 with code: NOT_GROUP_MEMBER. Creating a proposal additionally requires a leader/admin role. See Errors.

List a group’s proposals

GET /api/v1/spot/proposals?groupId=... returns every spot proposal in a group, each paired with your position on it. groupId is required (a missing/blank value is a clean 400).
data is an array of SpotProposalWithPosition:

Proposal detail

GET /api/v1/spot/proposals/{id} returns the same SpotProposalWithPosition shape, and additionally populates proposal.tradesthe caller’s own trades on this proposal. If the proposal doesn’t exist, data is null.

SpotProposal

SpotPositionSummary (userPosition)

currentTokenAmountRaw is the only quantity here in base units (note the ...Raw suffix). Every other field is a human USD or percent string. To get a human token count, divide by 10 ** decimals.

The proposal lifecycle

Open a proposal, scale your position with buys and sells, then close it. Buy, sell, and close all return the executed SpotTrade.
1

Create with an opening buy

POST /api/v1/spot/proposals creates the proposal and places the proposer’s opening buy in a single call. Leader/admin only.
Returns { data: { proposal, trade } } — a SpotProposal and the opening SpotTrade. Keep proposal.id for the calls below.
Response
2

Buy in

POST /api/v1/spot/proposals/{id}/buy adds to your position. Send amountUsd (USDC to spend), or max: true to spend your full USDC balance (then amountUsd is ignored).
Returns { data: { trade } } (a SpotTradeEnvelope).
3

Sell out

POST /api/v1/spot/proposals/{id}/sell trims or exits your position. Here amountUsd is your desired USDC output (how much cash you want back), or max: true to sell the full token position.
Returns { data: { trade } } (a SpotTradeEnvelope).
Buy amountUsd is USDC spent; sell amountUsd is USDC received. Use max: true on either side to skip sizing math — full balance on buy, full position on sell.
4

Close (creator only)

POST /api/v1/spot/proposals/{id}/close is for the proposal’s creator. It sells the creator’s full position and moves the proposal into a closed state.
Returns { data: { proposal, trade } } — the now-closed SpotProposal (with closedAt, exitPriceUsd, exitPnlUsd, exitPnlPct) and the closing SpotTrade. Other members keep their own positions and exit them with /sell.

SpotTrade (buy / sell / close)

Every executed trade — the opening buy on create, each /buy and /sell, and the closing trade — returns a SpotTrade. Unlike position quantities, tokenAmount here is already humanized (it uses tokenDecimals), so you don’t divide it yourself.
Two quantity conventions live side by side: a trade’s tokenAmount is already humanized (uses tokenDecimals), while a position’s currentTokenAmountRaw is raw base units you humanize with decimals. The ...Raw suffix is your signal. See Money & precision → Raw vs. human quantities.

Tokenized stocks (by ticker)

Murmo lists Ondo Global Markets tokenized stocks and ETFs (e.g. NVDA, AAPL). They trade through the exact same group/proposal flow as any other spot token — position tracking and max semantics are identical — but a dedicated /api/v1/spot/stocks surface lets you trade by ticker instead of a mint, and tells you what’s supported and whether the market is open.
The tradeable universe is the Ondo catalog only. A ticker is the clean symbol ("NVDA", case-insensitive); resolution also accepts the raw on-chain symbol ("NVDAON") or the mint. Stocks observe market hours — trades outside them are rejected up front (see below).

List supported stocks

GET /api/v1/spot/stocks returns the full catalog plus the shared market status. There are no parameters.
Returns { data: { marketStatus, nextOpen, stocks } }. marketStatus is OPEN, PAUSED, or CLOSED; nextOpen is the ISO instant trading resumes (null when open). Each stocks[] entry:

Open and trade by ticker

POST /api/v1/spot/stocks/proposals opens a position by ticker (everything else matches Create with an opening buygroupId, optional reason, amountUsd). Follow-on POST /api/v1/spot/stocks/proposals/{id}/buy and /sell take the same { amountUsd | max } body as the mint-based endpoints and return a SpotTradeEnvelope.
Stock-specific errors on these endpoints: 404 TOKEN_NOT_FOUND (ticker not in the catalog — check GET /spot/stocks), 409 MARKET_CLOSED (market paused/closed; details.nextOpenAt carries the next open instant), and 422 ORDER_BELOW_MIN_SIZE (opening buy under the token’s minTradeUsd). Membership/role rules (403 NOT_GROUP_MEMBER) apply exactly as for any proposal.

Errors you’ll hit

See Errors for the full list, status-code semantics, and a ready-made handler. Note that proposal detail returns data: null for an unknown id.

Where to next

Spot momentum bot

The whole flow as one copy-pasteable script.

Money & precision

Decimal strings, and humanizing ...Raw quantities.

Groups & proposals

The social model: groups, proposals, positions.

Errors

Error shapes, status codes, and the codes worth handling.

API Reference

Every Spot endpoint, parameter, and response schema.