Skip to main content
All requests go to the base URL: https://exchange.jamesxu.dev A machine-readable OpenAPI schema and Swagger UI are also available:
https://exchange.jamesxu.dev/api-doc/openapi.json
https://exchange.jamesxu.dev/docs

Public endpoints

No authentication required.
MethodPathPurpose
GET/healthService and persistence health
GET/api/v1/marketsList configured markets
Returns the service status and current persistence state. No authentication required.Response fields
status
string
required
ok when persistence is disabled or ok. degraded when persistence is retrying, backpressured, or stopped.
service
string
required
Always exchange.
now
string
required
Current server time in RFC 3339 format.
persistence
object
required
Current persistence status including mode.
curl https://exchange.jamesxu.dev/health
{
  "status": "ok",
  "service": "exchange",
  "now": "2026-03-18T15:27:00.000000Z",
  "persistence": {
    "backend": "in_memory",
    "mode": "disabled",
    "queue_depth": 0,
    "last_error": null
  }
}
Returns the list of all configured markets. No authentication required.
curl https://exchange.jamesxu.dev/api/v1/markets
[
  {
    "market_id": "BTC-USD",
    "display_name": "Bitcoin",
    "base_asset": "BTC",
    "quote_asset": "USD",
    "tick_size": 1,
    "min_order_quantity": 1,
    "reference_price": 100,
    "settlement_price": null,
    "status": "enabled",
    "created_at": "2026-03-18T15:00:00.000000Z",
    "updated_at": "2026-03-18T15:00:00.000000Z"
  }
]

Trader routes require the x-api-key header. API keys are provisioned by an admin and are prefixed with exch_.
x-api-key: exch_1d4208be6fa84b8cb0a2e5cfa9508d5f
MethodPathPurpose
GET/api/v1/userAuthenticated user profile
GET/api/v1/positionsUser positions across markets
GET/api/v1/portfolioPortfolio snapshot with PnL
GET/api/v1/leaderboardLeaderboard ranked by marked net PnL
GET/api/v1/open-ordersOpen orders, optional ?market= filter
GET/api/v1/fillsFills, optional ?market= filter
POST/api/v1/ordersSubmit a limit order
PATCH/api/v1/orders/{order_id}Amend remaining quantity
DELETE/api/v1/orders/{order_id}Cancel an order
Returns the authenticated trader’s profile.
curl \
  -H "x-api-key: YOUR_API_KEY" \
  https://exchange.jamesxu.dev/api/v1/user
{
  "trader_id": "9d64e278-8b56-46e9-9cab-18c5b22f2fb9",
  "username": "team-alpha",
  "api_key": "exch_1d4208be6fa84b8cb0a2e5cfa9508d5f",
  "created_at": "2026-03-18T15:27:42.159901Z"
}
Returns all open positions for the authenticated trader.
curl \
  -H "x-api-key: YOUR_API_KEY" \
  https://exchange.jamesxu.dev/api/v1/positions
[
  {
    "market": "BTC-USD",
    "net_quantity": 5,
    "average_entry_price": 98,
    "realized_pnl": 50,
    "updated_at": "2026-03-18T15:30:00.000000Z"
  }
]
  • net_quantity is a signed integer. Positive values are long, negative values are short.
  • realized_pnl accumulates as fills close or reduce the position.
Returns a portfolio snapshot including position limit and all current positions.
curl \
  -H "x-api-key: YOUR_API_KEY" \
  https://exchange.jamesxu.dev/api/v1/portfolio
{
  "trader_id": "9d64e278-8b56-46e9-9cab-18c5b22f2fb9",
  "position_limit": 1000,
  "positions": [
    {
      "market": "BTC-USD",
      "net_quantity": 5,
      "average_entry_price": 98,
      "realized_pnl": 50,
      "updated_at": "2026-03-18T15:30:00.000000Z"
    }
  ]
}
position_limit reflects the exchange-wide per-market net position limit of +/-1000.
Returns traders ranked by their current marked net PnL. Marking uses settled prices, orderbook mid prices, or market reference prices.Query parameters
query.limit
number
Optional. Maximum number of rows to return. Omit to return all traders.
curl \
  -H "x-api-key: YOUR_API_KEY" \
  "https://exchange.jamesxu.dev/api/v1/leaderboard?limit=10"
[
  {
    "rank": 1,
    "trader_id": "9d64e278-8b56-46e9-9cab-18c5b22f2fb9",
    "username": "team-alpha",
    "net_pnl": 420,
    "realized_pnl": 300,
    "unrealized_pnl": 120,
    "gross_exposure": 1000
  }
]
Returns all resting open orders for the authenticated trader. Filter by market using the optional market query parameter.Query parameters
query.market
string
Optional. Filter results to a single market, e.g. BTC-USD.
curl \
  -H "x-api-key: YOUR_API_KEY" \
  "https://exchange.jamesxu.dev/api/v1/open-orders?market=BTC-USD"
[
  {
    "id": "66377526-7b98-485a-8c40-7024e68fa3c5",
    "trader_id": "9d64e278-8b56-46e9-9cab-18c5b22f2fb9",
    "market": "BTC-USD",
    "side": "BUY",
    "price": 100,
    "quantity": 2,
    "remaining": 2,
    "created_at": "2026-03-18T15:28:01.342510Z"
  }
]
Returns all fills for the authenticated trader. Filter by market using the optional market query parameter.Query parameters
query.market
string
Optional. Filter results to a single market, e.g. BTC-USD.
curl \
  -H "x-api-key: YOUR_API_KEY" \
  "https://exchange.jamesxu.dev/api/v1/fills?market=BTC-USD"
[
  {
    "fill_id": "a1b2c3d4-0000-0000-0000-000000000001",
    "market": "BTC-USD",
    "maker_order_id": "aaa00000-0000-0000-0000-000000000001",
    "taker_order_id": "66377526-7b98-485a-8c40-7024e68fa3c5",
    "price": 100,
    "quantity": 2,
    "occurred_at": "2026-03-18T15:29:10.000000Z"
  }
]
Submits a limit order. Returns the order, any fills that occurred, and whether the order is resting in the book.Request body
body.market
string
required
Market symbol, e.g. BTC-USD. Must follow the BASE-QUOTE format.
body.side
string
required
BUY or SELL.
body.price
number
required
Limit price. Must be greater than zero and align to the market’s tick_size.
body.quantity
number
required
Order quantity. Must be at least the market’s min_order_quantity.
Response fields
order
object
required
The submitted order with its assigned id and current remaining quantity.
fills
array
required
List of fills that occurred immediately on submission. Empty if the order rested.
resting
boolean
required
true if the order has remaining quantity in the book after matching.
curl \
  -X POST \
  -H "x-api-key: YOUR_API_KEY" \
  -H "content-type: application/json" \
  https://exchange.jamesxu.dev/api/v1/orders \
  -d '{"market":"BTC-USD","side":"BUY","price":100,"quantity":2}'
{
  "order": {
    "id": "66377526-7b98-485a-8c40-7024e68fa3c5",
    "trader_id": "9d64e278-8b56-46e9-9cab-18c5b22f2fb9",
    "market": "BTC-USD",
    "side": "BUY",
    "price": 100,
    "quantity": 2,
    "remaining": 2,
    "created_at": "2026-03-18T15:28:01.342510Z"
  },
  "fills": [],
  "resting": true
}
Order admission checks worst-case net exposure from all resting open orders. A position limit of +/-1000 applies per market. Exceeding this returns 409 Conflict.
Amends the remaining quantity of a resting order. You can only reduce remaining — increasing it is not allowed.Path parameters
path.order_id
string
required
UUID of the resting order to amend.
Request body
body.remaining
number
required
New remaining quantity. Must be greater than zero and less than or equal to the current remaining.
curl \
  -X PATCH \
  -H "x-api-key: YOUR_API_KEY" \
  -H "content-type: application/json" \
  https://exchange.jamesxu.dev/api/v1/orders/ORDER_ID \
  -d '{"remaining":1}'
{
  "order": {
    "id": "66377526-7b98-485a-8c40-7024e68fa3c5",
    "trader_id": "9d64e278-8b56-46e9-9cab-18c5b22f2fb9",
    "market": "BTC-USD",
    "side": "BUY",
    "price": 100,
    "quantity": 2,
    "remaining": 1,
    "created_at": "2026-03-18T15:28:01.342510Z"
  }
}
Cancels a resting order. Returns the canceled order.Path parameters
path.order_id
string
required
UUID of the order to cancel.
curl \
  -X DELETE \
  -H "x-api-key: YOUR_API_KEY" \
  https://exchange.jamesxu.dev/api/v1/orders/ORDER_ID
{
  "order": {
    "id": "66377526-7b98-485a-8c40-7024e68fa3c5",
    "trader_id": "9d64e278-8b56-46e9-9cab-18c5b22f2fb9",
    "market": "BTC-USD",
    "side": "BUY",
    "price": 100,
    "quantity": 2,
    "remaining": 2,
    "created_at": "2026-03-18T15:28:01.342510Z"
  }
}

Data model notes

  • side is BUY or SELL
  • price, quantity, and remaining are unsigned 64-bit integers (u64)
  • The per-market net position limit is +/-1000
  • Traders can sell from flat and go short; order admission is based on worst-case net exposure if all resting open orders were to execute
  • Realized PnL is tracked on positions; no pre-seeded inventory or cash balance is required to open a long or short position
  • Leaderboard ranking uses settled prices, orderbook marks, or market reference prices
  • Pagination is not yet implemented

Build docs developers (and LLMs) love