Perpetuals are restricted in some jurisdictions and may require identity verification. If a call
returns
403, see Eligibility & geo restrictions.Two IDs: proposalId vs assignmentId
This is the one thing to get straight before you start. Perp routes are keyed by one of two IDs, and they are not interchangeable.CREATE, JOIN, and CLOSE-proposal are keyed by
proposalId. REDUCE and CLAIM act on a single
position and are keyed by assignmentId. A PerpPosition.id and its assignment id are the same
value — use it wherever a route says {assignmentId}.Setup
Same base URL, key, and money rules as everywhere else in the API.Every monetary value on the wire is a full-precision decimal string in USD.
collateralUsd and
leverage are sent as numeric strings ("25.00", "5") — never numbers, never raw base units.
Base-lot quantities are strings too. See Money & precision.Lifecycle
1
Pick a market
List the tradable perp markets and read a live price to size your entry.
GET /api/v1/perps/markets (or /markets/{symbol} for one).2
Open a position
POST /api/v1/perps/proposals creates a proposal and opens your position in one call — pick
side, collateralUsd, leverage, and optional stopLossPct / takeProfitPct brackets.
To back an idea someone else posted, POST /perps/proposals/{id}/increase instead.3
Monitor PnL
GET /api/v1/perps/positions?filter=active returns your open positions with live
markPrice-derived value, unrealizedPnlUsd, funding, and liquidationPriceUsd. For
low-latency price ticks, subscribe to market data over WebSocket.4
Reduce or close
POST /api/v1/perps/positions/{assignmentId}/reduce trims or fully closes your position
(reduceFraction in (0, 1], isFullClose). The proposal creator can close the whole proposal
with POST /perps/proposals/{id}/close.5
Claim a take-profit close
If a
takeProfitPct bracket fired, the position closes automatically and becomes claimable.
POST /api/v1/perps/positions/{assignmentId}/claim acknowledges it and drains the proceeds to
your wallet.Browse markets
GET /api/v1/perps/markets returns every tradable perp market; GET /api/v1/perps/markets/{symbol}
returns one (and data: null if the symbol is unknown).
Response
PerpAsset (selected fields):
See proposals in a group
A proposal is a shared LONG/SHORT idea. Reads are members only — you’ll get403 NOT_GROUP_MEMBER
for a group you don’t belong to.
GET /api/v1/perps/proposals?groupId=... lists a group’s perp proposals;
GET /api/v1/perps/proposals/{id} returns one (data: null if not found).
Response
PerpProposal (selected fields):
Open a position (new proposal)
POST /api/v1/perps/proposals creates the proposal and opens your position atomically. The wallet is
resolved for you — you never pass one.
Response
PerpPositionResult. On an open (or increase) the close-side fields are null; they’re
populated only when a reduce fully closes the position.
Stop-loss and take-profit brackets
stopLossPct and takeProfitPct are optional and expressed as % collateral ROI (account P&L),
not as a price move in the underlying.
takeProfitPct: "100" means “close when the position is up 100% of collateral” — i.e. you’d
roughly double your stake. stopLossPct: "50" means “close when down 50% of collateral.” Because
ROI is on collateral, these scale with leverage: at higher leverage a smaller price move hits the
same ROI bracket. The corresponding trigger prices come back on the position as stopLossPriceUsd
and takeProfitPriceUsd.Join a proposal (increase)
To back an idea that already exists,POST /api/v1/perps/proposals/{id}/increase opens a new
position under that proposal. The side is inherited from the proposal — you only send your own
collateralUsd and leverage. You must be a member of the proposal’s group.
PerpPositionResult with your new assignmentId (same shape as opening above).
Monitor your positions
GET /api/v1/perps/positions?filter=active returns your positions, with live mark/PnL/funding fields
plus realized fields once closed. filter is active (default), past, or all.
Response
PerpPosition (selected fields):
When closed, the realized fields populate:
priceRealizedPnlUsd, fundingRealizedUsd,
totalFeesUsd, liquidationPenaltyUsd, netRealizedPnlUsd, and finalCollateralReturned — all
MoneyString. Use filter=past or filter=all to see them.
Reduce or close your position
POST /api/v1/perps/positions/{assignmentId}/reduce trims or fully closes your position. It’s
keyed by assignmentId (the position’s id).
Response (full close)
PerpPositionResult (table above). On a full close, closePnlUsd, closePnlPct,
closeProceedsUsd, and closedBaseUnits are populated.
Close the whole proposal (creator only)
POST /api/v1/perps/proposals/{id}/close closes the proposal, keyed by proposalId. Only the
creator can do this (enforced); it closes the creator’s own open position(s) and locks
out new joiners. Other members’ positions are left untouched — they manage their own exits via
/reduce.
Response
If you’re not the creator, this returns
403. To exit a position you joined, use
/positions/{assignmentId}/reduce instead.Claim a take-profit close
When atakeProfitPct bracket fires, the position closes automatically and becomes claimable
(isClaimable: true). POST /api/v1/perps/positions/{assignmentId}/claim acknowledges that close
and drains the proceeds to your wallet. It’s keyed by assignmentId.
Response
PerpClaimResult:
Errors you’ll hit
See Errors for the full status-code and
code reference and a retry pattern.
Next
Perps bot
Open, monitor, and close a position in one script.
Money & precision
Why
collateralUsd is "25.00" and not 25.Groups & proposals
The social model: groups, proposals, positions.
Market data (WebSocket)
Live per-symbol perp ticks for low-latency monitoring.
API Reference
Every Perpetuals endpoint, field by field.