/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.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.
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.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.trades — the 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 executedSpotTrade.
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.{ 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).{ 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.{ data: { trade } } (a SpotTradeEnvelope).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.{ 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.
{ 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 buy — groupId, 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.
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.