API Reference
Base URLs
- Testnet:
https://api-testnet.leverup.xyz/ - Mainnet:
https://service.leverup.xyz
Get Oracle Updates by Position
Fetches the encoded oracle update data and fees required by openMarketTradeV2 and openLimitOrderV2.
Clients should call this backend endpoint instead of calling Pyth Hermes directly.
Endpoint
POST /v1/oracle/price/updates/by-position
Request Body
| Name | Type | Description |
|---|---|---|
pairBase | string | Pair base address for the trading pair. |
collateral | string | Collateral token address. Use the wrapped native token address when the user pays with native MON. |
blockChain | string | Blockchain identifier. Currently MONAD. |
options.includeEncodingData | boolean | Set to true to receive encoded update data. |
options.includeEncodingDataByOracleId | boolean | Set to false for the standard trade flow. |
options.includeFee | boolean | Set to true to receive oracle fees. |
options.includePrice | boolean | Set to false unless price snapshots are needed. |
options.includePublishTime | boolean | Set to false unless publish times are needed. |
{
"pairBase": "0xcf5a6076cfa32686c0df13abada2b40dec133f1d",
"collateral": "0x754704Bc059F8C67012fEd69BC8A327a5aafb603",
"blockChain": "MONAD",
"options": {
"includeEncodingData": true,
"includeEncodingDataByOracleId": false,
"includeFee": true,
"includePrice": false,
"includePublishTime": false
}
}Response
Use pythPriceUpdateData and pythProPriceUpdateData as the OracleUpdateData tuple passed to the V2 contract methods. Send updateFee + verifition_fee as transaction value for ERC20 collateral. For native MON, add the native collateral amount as well.
{
"pythPriceUpdateData": ["0x..."],
"pythProPriceUpdateData": ["0x..."],
"updateFee": "123456789",
"verifition_fee": "0",
"pythCoreSingleUpdateFeeWei": "123456789",
"pythCoreTransactionFeeWei": "123456789",
"pythProVerificationFeeWei": "0"
}Note: The response field is currently spelled
verifition_feeby the backend API.
Get Latest Pair Prices
Fetches latest backend oracle prices for multiple pair base addresses.
Endpoint
POST /v1/oracle/price/pairs/latest
Request Body
{
"pairBases": [
"0xcf5a6076cfa32686c0df13abada2b40dec133f1d",
"0xb5a30b0fdc5ea94a52fdc42e3e9760cb8449fb37"
],
"blockChain": "MONAD"
}Response
prices is keyed by pair base address. Price values are integer strings using 18 decimals.
{
"prices": {
"0xcf5a6076cfa32686c0df13abada2b40dec133f1d": "100000000000000000000000",
"0xb5a30b0fdc5ea94a52fdc42e3e9760cb8449fb37": "3000000000000000000000"
}
}Get Pair Historical Price
Fetches a backend oracle price point for a pair from 24 hours ago, or a custom number of hours ago.
Endpoints
GET /v1/oracle/price/pair-24h-agoGET /v1/oracle/price/pair-hours-ago
Parameters
| Name | In | Type | Description |
|---|---|---|---|
pair_base | Query | string | Pair base address. |
block_chain | Query | string | Blockchain identifier. Currently MONAD. |
hours_ago | Query | integer | Number of hours ago. Only used by /pair-hours-ago. |
Response
{
"pairBase": "0xcf5a6076cfa32686c0df13abada2b40dec133f1d",
"hoursAgo": 24,
"blockChain": "MONAD",
"oracleId": {
"kind": "PYTH_CORE",
"id": "0xe62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43"
},
"pricePoint": {
"price": "100000000000000000000000",
"publishTime": 1769586529,
"capturedAt": 1769586530
}
}Get Trading Competitions
Fetches trading competitions, optionally filtered by status, display readiness, and user address.
Endpoint
GET /v1/trading-competition
Parameters
| Name | In | Type | Description |
|---|---|---|---|
status | Query | string | Optional competition status: UPCOMING, ONGOING, or ENDED. |
isReadyToDisplay | Query | boolean | Optional filter for competitions ready to be shown in the UI. |
userAddress | Query | string | Optional user wallet address. When provided, each item includes whether that user has joined. |
Response
[
{
"id": 1,
"title": "Trading Competition",
"description": "Compete by trading volume or PnL.",
"banner": "https://...",
"ruleLink": "https://...",
"ruleId": "DEFAULT",
"leaderboardType": "TOTAL_VOLUME_BASED",
"rewardAmount": "10000",
"rewardTokenAddress": "0x...",
"rewardType": "TOKEN",
"rewardDescription": "10,000 USDC rewards",
"startTime": 1769586529,
"endTime": 1770186529,
"currentParticipants": 128,
"tradingVolume": 2500000,
"isReadyToDisplay": true,
"status": "ONGOING",
"hasJoined": true
}
]Enums
leaderboardType:DEFAULT,PNL_BASED,TOTAL_VOLUME_BASED,LOW_LEVERAGE_VOLUME_BASED,HIGH_LEVERAGE_VOLUME_BASEDrewardType:TOKENstatus:UPCOMING,ONGOING,ENDED
Get Trading Competition Leaderboard
Fetches a paginated leaderboard for a specific trading competition. The leaderboard columns are dynamic; use headers to render and sort columns.
Endpoint
GET /v1/trading-competition/{id}/leaderboard
Parameters
| Name | In | Type | Description |
|---|---|---|---|
id | Path | integer | Trading competition ID. |
page | Query | integer | Page number, 0-indexed. |
limit | Query | integer | Number of rows per page. |
orderBy | Query | string | Optional sort key. Use a headers[].key value returned by this endpoint. |
orderDirection | Query | string | Optional sort direction: ASC or DESC. |
Response
headers describes the dynamic metric columns. Each leaderboard row stores metric values in stats by header key.
{
"headers": [
{
"key": "totalVolume",
"label": "Total Volume"
},
{
"key": "pnl",
"label": "PnL"
}
],
"data": {
"content": [
{
"trader": "0x...",
"stats": {
"totalVolume": 125000,
"pnl": 3200.5
}
}
],
"pageNumber": 0,
"pageSize": 10,
"totalPages": 5,
"totalElements": 42
}
}Join Trading Competition
Joins a trading competition using an invite code.
Endpoint
POST /v1/trading-competition/join
Request Body
| Name | Type | Description |
|---|---|---|
trader | string | Trader wallet address. |
inviteCode | string | Competition invite code. |
{
"trader": "0x...",
"inviteCode": "ABC123"
}Response
Returns 204 No Content on success.
Get User Positions
Fetches a paginated list of positions for a specific user.
Endpoint
GET /v1/user/{userAddress}/positions
Parameters
| Name | In | Type | Description |
|---|---|---|---|
userAddress | Path | string | The user's wallet address (0x...) |
size | Query | integer | Number of items per page (e.g. 50) |
page | Query | integer | Page number (0-indexed) |
Response
The response contains a list of positions and pagination metadata.
Note: The
closeInfoobject is only present if the positionstatusisCLOSED.
{
"content": [
{
"positionHash": "0x...",
"pair": "USD/JPY",
"pairBase": "0x...",
"tokenIn": "0x...",
"marginToken": "0x...",
"isLong": true,
"margin": "198610087343796248914",
"qty": "130027570225",
"entryPrice": "152705269000000000000",
"stopLoss": "0",
"takeProfit": "229073300000000000000",
"openFee": "1389912656203751086",
"executionFee": "0",
"longAccFundingFeePerShare": "0",
"holdingFeeRate": "317",
"timestamp": 1769586529,
"status": "OPEN"
},
{
"positionHash": "0x...",
"pair": "MON/USD",
"pairBase": "0x...",
"tokenIn": "0x...",
"marginToken": "0x...",
"isLong": true,
"margin": "19861095665546146061470",
"qty": "1981375571697510",
"entryPrice": "28048519765000000",
"stopLoss": "0",
"takeProfit": "42140000000000000",
"openFee": "138904334453853938530",
"executionFee": "0",
"longAccFundingFeePerShare": "0",
"holdingFeeRate": "3166",
"timestamp": 1767681382,
"status": "CLOSED",
"closeInfo": {
"closePrice": "27952767860000000",
"fundingFee": "-1463189752048306575",
"closeFee": "138488245583797461449",
"pnl": "-677699989249776266201",
"holdingFee": "113131466803151515"
}
}
],
"pageNumber": 0,
"pageSize": 50,
"totalPages": 1,
"totalElements": 2
}