Trading API
The MonoHub Trading API is a REST + WebSocket API for order management, trade execution, and real-time market data. It uses JWT-based wallet authentication via EIP-191 signatures.
Base URL: https://api.monohub.xyz
Authentication
All authenticated endpoints require either a JWT token or an API key. The authentication flow uses EIP-191 wallet signatures to prove ownership of an Ethereum address.
Step 1: Request a Signing Message
POST /api/v1/auth/message
Returns a timestamped message for the wallet to sign. The message must be signed within 5 minutes.
Response:
{
"message": "MonoHub API Access: 1706140800000",
"timestamp": 1706140800000,
"expiresIn": 300000
}
Step 2: Exchange Signature for JWT
POST /api/v1/auth/token
Submit the signed message to receive a JWT token valid for 24 hours.
Request body:
{
"address": "0xYourWalletAddress",
"message": "MonoHub API Access: 1706140800000",
"signature": "0x...",
"chainId": 262146
}
Response:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expiresIn": "24h"
}
Step 3: Create an API Key (Optional)
POST /api/v1/auth/api-key
Requires authentication. Creates a long-lived API key for programmatic access. API keys carry specific permissions and do not expire, but can be revoked.
Headers: Authorization: Bearer <jwt_token>
Request body:
{
"permissions": ["read", "trade"]
}
Response:
{
"apiKey": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"permissions": ["read", "trade"],
"warning": "Store this key securely. It will not be shown again."
}
Using Credentials
For JWT tokens, include the header:
Authorization: Bearer <token>
For API keys, include the header:
Authorization: ApiKey <api_key>
Get Current User
GET /api/v1/auth/me
Returns the authenticated user's address, chain, tier, and whether the request uses an API key.
Response:
{
"address": "0xabc...",
"chainId": 262146,
"tier": "free",
"isApiKey": false
}
Public Endpoints
These endpoints do not require authentication.
List Markets
GET /api/v1/markets?chain_id=262146
Returns all trading pairs for the specified chain. Defaults to Sprintnet (chain ID 262146) if omitted.
Response:
{
"markets": [
{
"pair": "0xPairAddress",
"baseToken": "0xToken0Address",
"quoteToken": "0xToken1Address",
"baseSymbol": "TOKEN",
"quoteSymbol": "WLYTH",
"lastPrice": "0.00123",
"volume24h": "45000",
"priceChange24h": "0.05",
"chainId": 262146
}
],
"chain": "Sprintnet"
}
Try It
Query live market data directly:
List Markets
Fetch all trading pairs on a chain.
Market Detail
GET /api/v1/markets/:pair?chain_id=262146
Returns detailed information for a specific market pair, including reserves, transaction count, and price data.
Response:
{
"pair": "0xPairAddress",
"baseToken": "0xToken0",
"quoteToken": "0xToken1",
"baseSymbol": "TOKEN",
"quoteSymbol": "WLYTH",
"reserve0": "1000000",
"reserve1": "500000",
"lastPrice": "0.5",
"volume24h": "45000",
"priceChange24h": "0.05",
"txCount24h": 120,
"chainId": 262146
}
Recent Trades
GET /api/v1/markets/:pair/trades?chain_id=262146&limit=50
Returns the most recent trades for a pair. The limit parameter accepts values up to 100 (default: 50).
Response:
{
"trades": [
{
"txHash": "0x...",
"timestamp": "2025-01-25T12:00:00Z",
"side": "buy",
"price": "0.00123",
"amount": "1000",
"quoteAmount": "1.23",
"maker": "0xSenderAddress"
}
]
}
OHLCV Candles
GET /api/v1/markets/:pair/candles?chain_id=262146&interval=1h&from=1706140800&to=1706227200
Returns OHLCV candlestick data for charting. The interval parameter accepts standard values such as 1m, 5m, 15m, 1h, 4h, 1d.
Response:
{
"candles": [
{
"timestamp": "2025-01-25T12:00:00Z",
"open": "0.00120",
"high": "0.00130",
"low": "0.00118",
"close": "0.00125",
"volume": "50000",
"quoteVolume": "62.5",
"trades": 45
}
]
}
Orderbook
GET /api/v1/markets/:pair/orderbook?chain_id=262146
Returns a simulated orderbook derived from the AMM constant-product bonding curve. The orderbook shows 10 levels of depth on each side at 0.5% price intervals.
Response:
{
"bids": [
["0.00124500", "500.000000"],
["0.00124000", "1000.000000"]
],
"asks": [
["0.00125500", "500.000000"],
["0.00126000", "1000.000000"]
],
"timestamp": 1706140800000
}
Authenticated Endpoints
All endpoints below require a valid JWT token or API key with read permission.
Account Overview
GET /api/v1/account
Returns the authenticated wallet's portfolio overview, including native token balance and tier.
Response:
{
"address": "0xYourAddress",
"chainId": 262146,
"chain": "Sprintnet",
"nativeBalance": "1.5",
"tier": "free"
}
Token Balances
GET /api/v1/account/balances?tokens=0xToken1,0xToken2
Returns ERC-20 token balances for the authenticated wallet. Pass a comma-separated list of token contract addresses.
Response:
{
"balances": [
{
"token": "0xToken1",
"symbol": "TOKEN",
"decimals": 18,
"balance": "1000000000000000000",
"formatted": "1.000000"
}
]
}
Trade History
GET /api/v1/account/history
Returns the authenticated wallet's trade history.
Response:
{
"trades": [],
"pagination": { "page": 1, "pageSize": 50, "total": 0 }
}
List API Keys
GET /api/v1/account/api-keys
Returns metadata for the authenticated wallet's API keys (key values are not included).
Revoke API Key
DELETE /api/v1/account/api-keys/:keyId
Revokes a specific API key by its ID.
Trading Endpoints
All trading endpoints require authentication with trade permission. JWT tokens have full access. API keys must include the trade permission.
Get Quote
POST /api/v1/orders/quote
Returns a price quote for a swap, including price impact and fee estimates. Quotes are valid for 30 seconds.
Request body:
{
"pair": "0xPairAddress",
"side": "buy",
"amount": "1000000000000000000"
}
Response:
{
"pair": "0xPairAddress",
"side": "buy",
"amountIn": "1000000000000000000",
"amountOut": "800000000000000000",
"price": "0.8",
"priceImpact": "0.05",
"fee": "0.003",
"route": ["0xPairAddress"],
"validFor": 30
}
Place Order
POST /api/v1/orders
Creates an order (swap). The API returns unsigned transaction data that the caller must sign and broadcast.
Request body:
{
"pair": "0xPairAddress",
"side": "buy",
"amount": "1000000000000000000",
"minReceived": "790000000000000000"
}
Response:
{
"orderId": "ord_1706140800000_abc12345",
"status": "pending_signature",
"pair": "0xPairAddress",
"side": "buy",
"amount": "1000000000000000000",
"minReceived": "790000000000000000",
"message": "Order created. Sign transaction in your wallet to execute.",
"tx": {
"to": "0xRouterAddress",
"data": "0x...",
"value": "1000000000000000000"
}
}
List Orders
GET /api/v1/orders
Returns pending orders for the authenticated wallet.
Get Order Status
GET /api/v1/orders/:orderId
Returns the status of a specific order.
Cancel Order
DELETE /api/v1/orders/:orderId
Cancels a pending order that has not yet been executed on-chain.
WebSocket API
The WebSocket endpoint provides real-time streaming data for trades, tickers, orderbook updates, and authenticated user events.
Connection
wss://api.monohub.xyz/api/v1/stream
On connection, the server sends a welcome message listing available channels:
{
"type": "welcome",
"message": "Connected to MonoHub WebSocket API",
"channels": ["trades", "orderbook", "candles", "ticker"],
"userChannels": ["orders", "fills", "positions"]
}
Authentication
To access user channels (orders, fills, positions), send an auth message after connecting:
{ "type": "auth", "token": "eyJhbGciOiJIUzI1NiI..." }
Or with an API key:
{ "type": "auth", "apiKey": "eyJhbGciOiJIUzI1NiI..." }
On success:
{ "type": "authenticated", "address": "0xYourAddress" }
Subscribing to Channels
Public channels (no auth required):
{ "type": "subscribe", "channel": "trades", "market": "0xPairAddress" }
{ "type": "subscribe", "channel": "orderbook", "market": "0xPairAddress" }
{ "type": "subscribe", "channel": "candles", "market": "0xPairAddress", "interval": "1h" }
{ "type": "subscribe", "channel": "ticker", "market": "0xPairAddress" }
User channels (auth required):
{ "type": "subscribe", "channel": "orders" }
{ "type": "subscribe", "channel": "fills" }
{ "type": "subscribe", "channel": "positions" }
Unsubscribing
{ "type": "unsubscribe", "channel": "trades", "market": "0xPairAddress" }
Heartbeat
Send periodic pings to keep the connection alive:
{ "type": "ping" }
Response:
{ "type": "pong", "timestamp": 1706140800000 }
Data Messages
All data arrives as messages with type: "data" and a channel field:
{
"type": "data",
"channel": "trades:0xPairAddress",
"trades": [
{
"txHash": "0x...",
"price": "0.00125",
"amount": "500",
"side": "buy",
"timestamp": "2025-01-25T12:00:00Z"
}
]
}
{
"type": "data",
"channel": "ticker:0xPairAddress",
"ticker": {
"pair": "0xPairAddress",
"lastPrice": "0.00125",
"volume24h": "45000",
"priceChange24h": "0.05"
}
}
Polling intervals: trades update every 2 seconds; tickers update every 5 seconds.
Rate Limits
Rate limits are applied per IP address on a 1-minute rolling window.
| Tier | Requests per Minute |
|---|---|
| Free | 60 |
| Basic | 300 |
| Pro | 1,200 |
When the limit is exceeded, the API returns HTTP 429 with standard RateLimit-* headers.
Supported Chains
The API currently supports the following chains:
| Chain ID | Name | Status |
|---|---|---|
| 262146 | Sprintnet | Testnet |
| 43113 | Avalanche Fuji | Testnet |
| 59141 | Linea Sepolia | Testnet |
Pass ?chain_id=<id> on any market endpoint to query a specific chain. Defaults to 262146 (Sprintnet).
Code Examples
JavaScript (fetch)
// Step 1: Get auth message
const msgRes = await fetch("https://api.monohub.xyz/api/v1/auth/message", {
method: "POST",
});
const { message } = await msgRes.json();
// Step 2: Sign with wallet (ethers.js example)
const signature = await signer.signMessage(message);
// Step 3: Get JWT
const authRes = await fetch("https://api.monohub.xyz/api/v1/auth/token", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
address: await signer.getAddress(),
message,
signature,
chainId: 262146,
}),
});
const { token } = await authRes.json();
// Step 4: Use authenticated endpoints
const accountRes = await fetch("https://api.monohub.xyz/api/v1/account", {
headers: { Authorization: `Bearer ${token}` },
});
const account = await accountRes.json();
cURL
# Get auth message
curl -X POST https://api.monohub.xyz/api/v1/auth/message
# List markets on Sprintnet
curl https://api.monohub.xyz/api/v1/markets?chain_id=262146
# Get trades for a pair
curl "https://api.monohub.xyz/api/v1/markets/0xPairAddress/trades?limit=20&chain_id=262146"
# Authenticated request (replace YOUR_TOKEN)
curl -H "Authorization: Bearer YOUR_TOKEN" https://api.monohub.xyz/api/v1/account
# Get a quote (authenticated)
curl -X POST https://api.monohub.xyz/api/v1/orders/quote \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"pair":"0xPairAddress","side":"buy","amount":"1000000000000000000"}'
WebSocket (JavaScript)
const ws = new WebSocket("wss://api.monohub.xyz/api/v1/stream");
ws.onopen = () => {
// Authenticate (optional, for user channels)
ws.send(JSON.stringify({ type: "auth", token: "YOUR_TOKEN" }));
// Subscribe to trade feed
ws.send(JSON.stringify({
type: "subscribe",
channel: "trades",
market: "0xPairAddress",
}));
};
ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
if (msg.type === "data") {
console.log(`[${msg.channel}]`, msg);
}
};