Skip to content

Competitions & Teams ​

Base URL: https://service.leverup.xyz

Endpoints for trading competitions and the Genesis Airdrop team program. Useful if you are building a community dashboard or surfacing LeverUp campaigns in your own product.

List competitions ​

http
GET /v1/trading-competition
ParameterDefaultNotes
statusallUPCOMING, ONGOING, ENDED
isReadyToDisplaytrue
userAddress—When supplied, populates hasJoined

Response ​

json
[
  {
    "id": 7,
    "title": "Summer Trading Cup",
    "description": "…",
    "banner": "https://…",
    "ruleLink": "https://…",
    "ruleId": "…",
    "leaderboardType": "PNL_BASED",
    "collateralToken": null,
    "rewardAmount": "50000",
    "rewardTokenAddress": "0x…",
    "rewardType": "TOKEN",
    "rewardDescription": "…",
    "startTime": 1785225600,
    "endTime": 1787817600,
    "currentParticipants": 1240,
    "tradingVolume": 18500000.0,
    "isReadyToDisplay": true,
    "status": "ONGOING",
    "hasJoined": false,
    "requiresInviteCode": false
  }
]

Returns a plain array, not a paginated envelope. startTime and endTime are Unix seconds.

COLLATERAL_PNL_VOLUME_BASED competitions set collateralToken to the deposited ERC-20 address whose trades count. Their leaderboard exposes both PnL and Total Volume as sortable columns. Other collateral deposits by the same participant are excluded.

Competition leaderboard ​

http
GET /v1/trading-competition/{id}/leaderboard
ParameterDefaultNotes
page0
limit10Note: limit, not size
orderBy—A key from headers
orderDirectiondesc
userAddress—Returns this user's global row and rank when present

Response ​

json
{
  "headers": [
    { "key": "1", "label": "PnL" },
    { "key": "2", "label": "Total Volume" }
  ],
  "data": {
    "content": [
      { "rank": 1, "trader": "0x111…", "stats": { "1": 12500.0, "2": 890000.0 } }
    ],
    "pageNumber": 0,
    "pageSize": 10,
    "totalPages": 124,
    "totalElements": 500
  },
  "currentUser": {
    "rank": 487,
    "trader": "0xabc…",
    "stats": { "1": -20.0, "2": 420.0 }
  }
}

Columns are dynamic. headers describes what each competition ranks on, and stats is keyed by those same keys — render generically rather than assuming a fixed set. Clients displaying configured reward ranks should paginate to the greater of data.totalElements and the applicable reward schedule length, using vacant rows for rewarded ranks without participants. currentUser is supplemental and does not increase the page size or page count.

ts
const res = await fetch(`${API}/v1/trading-competition/${id}/leaderboard?limit=25`)
const { headers, data } = await res.json()

for (const row of data.content) {
  console.log(row.trader, headers.map((h) => `${h.label}: ${row.stats[h.key] ?? '-'}`).join(' | '))
}

Join ​

http
POST /v1/trading-competition/join
Content-Type: application/json

For a public competition (requiresInviteCode: false):

json
{ "trader": "0x…", "competitionId": 7 }

For a private competition, include its invite code:

json
{ "trader": "0x…", "competitionId": 7, "inviteCode": "ABC123" }

Returns 200 with an empty body on success. trader is required. A null or blank database invite code makes the competition public. Existing clients may omit competitionId and send only trader plus inviteCode.

No signature required

This endpoint takes an address as a parameter and does not verify wallet ownership. It registers participation only — it cannot move funds or place trades. Do not treat it as an authentication mechanism.

Genesis Airdrop ​

Team-based points program.

Team info for a user ​

http
GET /v1/genesis-airdrop/{user_address}/team-info
json
{
  "leaderTeam": {
    "teamName": "Alpha",
    "code": "ALPHA1",
    "totalGeneralPoints": "125000",
    "totalDegenPoints": "42000",
    "teamMemberCount": 38,
    "latestEpochTrading": { "epoch": 6, "volumeUSD": "980000" }
  },
  "memberTeam": null
}

leaderTeam is the team the address leads; memberTeam is the one it belongs to. Either can be null.

Team by invite code ​

http
GET /v1/genesis-airdrop/team-info-by-code/{code}

Returns a single TeamInfo, or null if the code is unknown.

Team members ​

http
GET /v1/genesis-airdrop/{user_address}/team-members?page=0&size=10

The path address is the team leader. Paginated.

json
{
  "content": [
    {
      "member": "0x…",
      "joinDate": "2026-06-01T00:00:00Z",
      "cumulativeVolumeUSD": "125000",
      "cumulativeGeneralPointsToLeader": "3400",
      "cumulativeDegenPointsToLeader": "1200"
    }
  ]
}

Boost history ​

http
GET /v1/genesis-airdrop/{user_address}/team-boost-history?page=0&size=10
json
{
  "content": [
    { "epoch": 6, "generalTeamBoostPoints": "3400", "degenTeamBoostPoints": "1200" }
  ]
}

Team leaderboard ​

http
GET /v1/genesis-airdrop/team-leaderboard?epoch=0&page=0&size=10

epoch defaults to 0, meaning the current epoch.

json
{
  "content": [
    {
      "teamName": "Alpha",
      "currentEpochVolume": "980000",
      "currentGeneralPoints": "125000",
      "currentDegenPoints": "42000"
    }
  ]
}

Trading perpetuals involves risk. Nothing here is financial advice.