/positions/{positionId}/marginMoves quote balance in or out of the margin of an open position, which moves its leverage and liquidation price with it.
- The position must still be open, and its account must belong to the caller and be
active— an account locked by the managed capital limit is refused here. - The market must be open and not in close-only mode.
marginChange: "0"is accepted and returns the position untouched.- Adding more than the free balance covers fails with
insufficient_balance; leaving zero or negative nominal margin fails withnon_positive_margin. - The resulting leverage must stay within the allowed range, otherwise the request fails with
invalid_leverage. - Removing margin must leave the position outside liquidation at the current market price. Reaching or crossing the recalculated liquidation price fails with
margin_withdrawal_liquidation(HTTP 400); no margin or balance changes are applied.
https://api.upscale.tradeParameters
positionIdstring · uuidrequiredPosition identifier. Its account must belong to the caller.
00000000-0000-4000-8000-000000000000Request body · required
marginChangestring · fp9requiredSigned quote amount to move in or out of the position margin, fp9 raw. Positive adds margin and requires that much free balance, negative withdraws it and must keep the remaining margin positive. 0 is accepted and changes nothing.
- pattern
- ^(?:-?[1-9][0-9]*|0)$
1000000000{
"marginChange": "1000000000"
}Examples
curl --request PATCH 'https://api.upscale.trade/positions/{positionId}/margin' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data-raw '{
"marginChange": "1000000000"
}'const response = await fetch("https://api.upscale.trade/positions/{positionId}/margin", {
method: "PATCH",
headers: {
"Accept": "application/json",
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
},
body: "{\n \"marginChange\": \"1000000000\"\n}",
});
console.log(response.status, await response.text());import requests
response = requests.request(
"PATCH",
"https://api.upscale.trade/positions/{positionId}/margin",
headers={"Accept":"application/json","Authorization":"Bearer YOUR_API_KEY","Content-Type":"application/json"},
data="{\n \"marginChange\": \"1000000000\"\n}",
timeout=30,
)
print(response.status_code, response.text)Responses
Unauthorized
The account belongs to another user (account_access_denied), or the request is authenticated with an API key while api_trading is disabled on the account (api_trading_not_enabled). The account is not in an active status. The market is paused (market_paused) or accepts closing orders only (market_close_only).
No position with this identifier.
Rate limit of the API key exceeded (api_key_rate_limit_exceeded). Retry-After says when to come back; the body carries the bucket (read / write), the window that tripped, its limit and retryAt.
defaultResponseapplication/json
idxstring · nullablerequiredPosition identifier.
stringversionnumberrequiredRevision of the position: incremented by every event applied to it.
0openedAtstring · date-timerequiredWhen the position was opened.
2026-05-01T12:30:00.000ZlastUpdatedAtstring · date-timerequiredWhen the last event was applied to the position.
2026-05-01T12:30:00.000ZclosedAtstring · date-time · nullablerequiredWhen the position was closed; null while it is still open.
2026-05-01T12:30:00.000Zstatusstring · enumrequiredWhether the position is still open, closed by the trader, or liquidated.
"opened" "closed" "liquidated"openedmarketstring · uuidrequiredMarket the position is held on.
- pattern
- ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$
00000000-0000-4000-8000-000000000000traderstring · uuidrequiredTrader account the position belongs to.
- pattern
- ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$
00000000-0000-4000-8000-000000000000sizestring · fp9requiredPosition size in base asset units, fp9 raw.
- pattern
- ^(?:-?[1-9][0-9]*|0)$
1000000000notionalstring · fp9requiredOpen notional of the position in quote currency, fp9 raw — size at entry price.
- pattern
- ^(?:-?[1-9][0-9]*|0)$
1000000000marginstring · fp9requiredMargin currently backing the position, fp9 raw. Moves with pnl, funding and manual margin changes.
- pattern
- ^(?:-?[1-9][0-9]*|0)$
1000000000pnlstring · fp9 · nullablerequiredRealised pnl accumulated over every event of the position, fp9 raw.
- pattern
- ^(?:-?[1-9][0-9]*|0)$
1000000000fundingstring · fp9 · nullablerequiredFunding paid (negative) or received (positive) over the life of the position, fp9 raw.
- pattern
- ^(?:-?[1-9][0-9]*|0)$
1000000000feestring · fp9requiredTrading fees charged over the life of the position, fp9 raw.
- pattern
- ^(?:-?[1-9][0-9]*|0)$
1000000000feeRatestring · fp9requiredFee rate applied to the position, fp9 raw fraction (1000000 = 0.1%).
- pattern
- ^(?:-?[1-9][0-9]*|0)$
1000000000exchangedQuotestring · fp9requiredQuote amount exchanged by the most recent event, fp9 raw.
- pattern
- ^(?:-?[1-9][0-9]*|0)$
1000000000exchangedBasestring · fp9requiredBase amount exchanged by the most recent event, fp9 raw.
- pattern
- ^(?:-?[1-9][0-9]*|0)$
1000000000directionstring · enumrequiredDirection of the position.
"long" "short"longeventNamestring · enumrequiredType of the most recent event applied to the position.
"addMargin" "removeMargin" "closePosition" "increasePosition" "liquidate" "forceClose" "payFunding"addMarginpnlInEventstring · fp9requiredRealised pnl of the most recent event, fp9 raw.
- pattern
- ^(?:-?[1-9][0-9]*|0)$
1000000000rawPnlInEventstring · fp9requiredRealised pnl of the most recent event before the 60-second adjustment, fp9 raw. Differs from pnlInEvent only when the adjustment fired.
- pattern
- ^(?:-?[1-9][0-9]*|0)$
1000000000profitAdjustmentAppliedbooleanrequiredWhether the 60-second adjustment capped the profit of the most recent event — inside a minute of an open or increase the position pnl cannot grow above what it was at that moment.
trueholdingTimeMsstring · nullablerequiredHow long the position was held before the most recent close, in milliseconds, counted from the open or the last increase. Null on events that are not closes.
stringfeeInEventstring · fp9requiredFee charged by the most recent event, fp9 raw.
- pattern
- ^(?:-?[1-9][0-9]*|0)$
1000000000fundingInEventstring · fp9requiredFunding settled by the most recent event, fp9 raw.
- pattern
- ^(?:-?[1-9][0-9]*|0)$
1000000000roestring · fp9requiredReturn on equity of the position — realised pnl over the margin put up, fp9 raw fraction.
- pattern
- ^(?:-?[1-9][0-9]*|0)$
1000000000scalpingCoefficientstring · fp9requiredDynamic spread multiplier the position was charged, fp9 raw (1000000000 = 1.0). Above 1 when the trade fell inside the market scalping window.
- pattern
- ^(?:-?[1-9][0-9]*|0)$
1000000000closeReasonstring · nullablerequiredWhy the platform closed the position (for example weekly_session_risk_close). Null for positions closed by the trader and for open ones.
string{
"idx": "string",
"version": 0,
"openedAt": "2026-05-01T12:30:00.000Z",
"lastUpdatedAt": "2026-05-01T12:30:00.000Z",
"closedAt": "2026-05-01T12:30:00.000Z",
"status": "opened",
"market": "00000000-0000-4000-8000-000000000000",
"trader": "00000000-0000-4000-8000-000000000000",
"size": "1000000000",
"notional": "1000000000",
"margin": "1000000000",
"pnl": "1000000000",
"funding": "1000000000",
"fee": "1000000000",
"feeRate": "1000000000",
"exchangedQuote": "1000000000",
"exchangedBase": "1000000000",
"direction": "long",
"eventName": "addMargin",
"pnlInEvent": "1000000000",
"rawPnlInEvent": "1000000000",
"profitAdjustmentApplied": true,
"holdingTimeMs": "string",
"feeInEvent": "1000000000",
"fundingInEvent": "1000000000",
"roe": "1000000000",
"scalpingCoefficient": "1000000000",
"closeReason": "string"
}