# REST API

Read-only HTTP access to prices, markets, positions, trade history, portfolio analytics and
leaderboards. No authentication required.

For placing trades, see [Onchain Integration](/onchain/overview) or
[Gasless Trading](/gasless/overview).

## Base URL

```
https://service.leverup.xyz
```

One-Click Trading is a separate service — see [Gasless Trading](/gasless/overview#endpoints).

## Conventions

**Chain parameter.** Most endpoints take an optional chain selector defaulting to `MONAD`. The
parameter name is inconsistent across endpoints — some use `block_chain`, others `blockchain`, and
request bodies use `blockChain`. Each endpoint below documents the form it accepts. You can omit it
in all cases.

**Numbers are strings.** Amounts, prices and quantities are returned as decimal strings to preserve
precision. Units follow the onchain conventions — see
[Precision & Units](/introduction/precision).

**Addresses.** Accepted in either case; returned lowercase.

**Timestamps.** Either Unix seconds (integer) or ISO-8601 with offset, depending on the field.

## Pagination

Paginated endpoints take `page` (0-based) and `size`, and return:

```json
{
  "content": [],
  "pageNumber": 0,
  "pageSize": 20,
  "totalPages": 5,
  "totalElements": 92
}
```

Position and order endpoints cap `size` at 100.

## Endpoint index

### Oracle & prices

| Method | Path | |
| :--- | :--- | :--- |
| `POST` | `/v1/oracle/price/updates/by-position` | [Oracle payload for a transaction](/api/oracle#price-updates-by-position) |
| `POST` | `/v1/oracle/price/pairs/latest` | [Latest prices](/api/oracle#latest-pair-prices) |
| `GET` | `/v1/oracle/price/pair-24h-ago` | [Price 24h ago](/api/oracle#historical-price) |
| `GET` | `/v1/oracle/price/pair-hours-ago` | [Price N hours ago](/api/oracle#historical-price) |

### Pairs & volume

| Method | Path | |
| :--- | :--- | :--- |
| `GET` | `/v1/pairs` | [List markets](/api/pairs#list-pairs) |
| `GET` | `/v1/pairs/{pairBase}/volume` | [Volume over a window](/api/pairs#pair-volume) |
| `GET` | `/v1/pairs/{pairBase}/cumulative-volume` | [All-time volume](/api/pairs#cumulative-volume) |
| `GET` | `/v1/trading-volumes/users` | [Per-user daily volume](/api/pairs#user-volumes) |
| `GET` | `/v1/trading-volumes/sum-by-date` | [Protocol volume for a range](/api/pairs#protocol-volume) |
| `GET` | `/v1/trading-volumes/sum-all` | [All-time protocol volume](/api/pairs#protocol-volume) |

### Positions

| Method | Path | |
| :--- | :--- | :--- |
| `GET` | `/v1/user/{address}/open-positions` | [Open positions](/api/positions#open-positions) |
| `GET` | `/v1/user/{address}/positions` | [All positions incl. closed](/api/positions#all-positions) |

### History & portfolio

| Method | Path | |
| :--- | :--- | :--- |
| `GET` | `/v1/user/{address}/trade/history` | [Trade history](/api/history#trade-history) |
| `GET` | `/v1/portfolio/{address}/trade_overview` | [PnL summary](/api/history#trade-overview) |
| `GET` | `/v1/portfolio/{address}/pnl_chart_data` | [PnL time series](/api/history#pnl-chart) |
| `GET` | `/v1/portfolio/{address}/portfolio_data` | [Portfolio breakdown](/api/history#portfolio-data) |

### Leaderboard & stats

| Method | Path | |
| :--- | :--- | :--- |
| `GET` | `/v1/leaderboard` | [Global leaderboard](/api/leaderboard#leaderboard) |
| `GET` | `/v1/leaderboard/team/{code}` | [Team leaderboard](/api/leaderboard#team-leaderboard) |
| `GET` | `/v1/leaderboard/my-rank` | [One trader's rank](/api/leaderboard#my-rank) |
| `GET` | `/v1/leaderboard/{address}/trading-stats` | [Stats for a time range](/api/leaderboard#trading-stats) |
| `GET` | `/v1/slvmon/apy` | [sLVMON APY](/api/leaderboard#slvmon) |
| `GET` | `/v1/slvmon/{address}/portfolio` | [sLVMON position](/api/leaderboard#slvmon) |

### Competitions & teams

| Method | Path | |
| :--- | :--- | :--- |
| `GET` | `/v1/trading-competition` | [List competitions](/api/competitions#list-competitions) |
| `GET` | `/v1/trading-competition/{id}/leaderboard` | [Competition leaderboard](/api/competitions#competition-leaderboard) |
| `POST` | `/v1/trading-competition/join` | [Join with an invite code](/api/competitions#join) |
| `GET` | `/v1/genesis-airdrop/…` | [Genesis airdrop teams](/api/competitions#genesis-airdrop) |

## Errors

Standard HTTP status codes. `400` for invalid parameters, `404` for unknown resources, `5xx` for
server errors. Error bodies are Spring-style JSON:

```json
{
  "timestamp": "2026-07-27T10:00:00.000+00:00",
  "status": 400,
  "error": "Bad Request",
  "message": "pair_base should not be empty",
  "path": "/v1/oracle/price/pair-24h-ago"
}
```

## Caching and rate limits

Several endpoints are cached server-side — pair listings for about a minute, volume for five
minutes, portfolio aggregates for 30 seconds. Polling faster than that returns identical data.

There is no published per-key rate limit, but the service is shared. Cache on your side, poll no more
than once per second per endpoint, and prefer the [onchain read functions](/onchain/reading-data) for
tight loops.
