API Documentation
Complete API reference for the Arcex perpetual futures DEX. Build trading bots, custom frontends, and integrations with our high-performance matching engine.
Low Latency
Off-chain matching
On-chain Settlement
Arbitrum security
Real-time
WebSocket streams
Full Access
Complete API
Introduction
Overview
Arcex is a high-performance perpetual futures decentralized exchange (DEX) built on a hybrid architecture, combining the speed of an off-chain order book with the security of on-chain settlement. This model is used by industry leaders like Hyperliquid and dYdX v3.
Architecture Components
| Component | Type | Responsibility | Technology |
|---|---|---|---|
| Matching Engine | Off-Chain | Order matching, position tracking, PnL calculation | Node.js, TypeScript, Redis |
| Smart Contract | On-Chain | Collateral vault, final settlement | Solidity, EVM (Base) |
| Price Oracle | On-Chain | Real-time price feeds for mark price | Chainlink, Pyth |
| Client App | Frontend | User interface, wallet interaction | React Native, Privy |
Trading Flow
- Deposit (On-Chain): User deposits ETH/USDC into the smart contract vault
- Place Order (Off-Chain): User signs an order with their wallet and sends it to the matching engine API
- Order Matching (Off-Chain): The matching engine matches buy and sell orders
- Position Update (Off-Chain): The matching engine updates the user's position in Redis
- Settlement (On-Chain): Periodically, the matching engine submits a batch of settled trades to the smart contract
- Withdraw (On-Chain): User initiates a withdrawal from the smart contract
Key Benefit: This architecture provides a CEX-like trading experience (fast, no gas for orders) with DEX-level security (self-custody, on-chain settlement).
Base URL
1https://api.arcex.app/api/v1API Capabilities
- Real-time market data (orderbook, trades, tickers, prices)
- Order management (place, cancel, query orders)
- Position management (open positions, close, PnL tracking)
- Collateral management (balances, deposits, withdrawals)
- Funding rates and liquidation data
- WebSocket streams for real-time updates
- Fee tier and builder program integration
Smart Contract Addresses
| Contract | Address | Network |
|---|---|---|
| Perpetual DEX | 0x913f29701b2617B486f4Fb582AbBB080Ee36Bb08 | Base Sepolia |
| USDC (Collateral) | TBD | Base Sepolia |
Authentication
Arcex uses a fully decentralized authentication system. There are no JWT tokens or sessions. Every action that modifies state is signed directly by the user's wallet.
Key Principle: There is NO login/logout. Users simply connect their wallet and sign each action.
Authentication Types
| Endpoint Type | Auth Method | Description |
|---|---|---|
| Public (GET) | None | Market data, orderbook, ticker |
| Read User Data (GET) | X-Wallet-Address header | Orders, positions, account |
| Modify State (POST/DELETE) | Signed Action | Place order, cancel, withdraw |
| Admin | Signed Action + Admin check | Admin operations |
Signed Action Format
Every action that modifies state must be signed with the following structure:
1interface SignedAction {
2 action: {
3 type: string; // Action type: 'placeOrder', 'cancelOrder', etc.
4 data: object; // Action-specific data
5 timestamp: number; // Unix timestamp in milliseconds
6 nonce: string; // Random 32-char hex string
7 };
8 signature: string; // Wallet signature of JSON.stringify(action)
9}Signing Flow
1// 1. Get a nonce from the server (or generate locally)
2const nonceResponse = await fetch('/api/v1/auth/nonce');
3const { nonce, timestamp } = await nonceResponse.json();
4
5// 2. Create the action object
6const action = {
7 type: 'placeOrder',
8 data: {
9 marketId: 'ETH-PERP',
10 side: 'buy',
11 type: 'limit',
12 quantity: '1.0',
13 price: '3000.00',
14 },
15 timestamp: Date.now(),
16 nonce: nonce,
17};
18
19// 3. Create the message to sign (deterministic JSON)
20const message = JSON.stringify(action);
21
22// 4. Sign with wallet (Privy, ethers, etc.)
23const signature = await wallet.signMessage(message);
24
25// 5. Send to API
26const response = await fetch('/api/v1/orders', {
27 method: 'POST',
28 headers: { 'Content-Type': 'application/json' },
29 body: JSON.stringify({ action, signature }),
30});Auth Helper Endpoints
Get a fresh nonce for signing. Nonces expire after 30 seconds.
Response
1{
2 "success": true,
3 "data": {
4 "nonce": "a1b2c3d4e5f6...",
5 "timestamp": 1705752000000,
6 "expiresIn": 30
7 }
8}Get example message format for signing. Useful for testing.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
type(optional) | string | Action type (default: 'placeOrder') |
data(optional) | string | JSON-encoded action data |
Response
1{
2 "success": true,
3 "data": {
4 "action": { ... },
5 "messageToSign": "{\"data\":{...},\"nonce\":\"...\",\"timestamp\":...,\"type\":\"placeOrder\"}",
6 "instructions": [...]
7 }
8}Verify a signed action (for testing purposes).
Body Parameters
| Parameter | Type | Description |
|---|---|---|
action | object | The action object that was signed |
signature | string | The wallet signature (0x...) |
Response
1{
2 "success": true,
3 "data": {
4 "valid": true,
5 "walletAddress": "0x1234...",
6 "isAdmin": false
7 }
8}Get authentication system information and configuration.
Response
1{
2 "success": true,
3 "data": {
4 "type": "signature-based",
5 "nonceExpiry": 30,
6 "timestampWindow": 30,
7 "supportedActions": ["placeOrder", "cancelOrder", "cancelAllOrders", "withdraw"]
8 }
9}Example: Place Order Request
1{
2 "action": {
3 "type": "placeOrder",
4 "data": {
5 "marketId": "ETH-PERP",
6 "side": "buy",
7 "type": "limit",
8 "quantity": "1.0",
9 "price": "3000.00",
10 "timeInForce": "GTC",
11 "reduceOnly": false,
12 "postOnly": false
13 },
14 "timestamp": 1705752000000,
15 "nonce": "abc123..."
16 },
17 "signature": "0x..."
18}Example: Cancel Order Request
1{
2 "action": {
3 "type": "cancelOrder",
4 "data": {
5 "orderId": "uuid"
6 },
7 "timestamp": 1705752000000,
8 "nonce": "abc123..."
9 },
10 "signature": "0x..."
11}Read-Only Endpoints
For read-only user data, include the X-Wallet-Address header instead of signing:
1curl -X GET "https://api.arcex.app/api/v1/orders" \
2 -H "X-Wallet-Address: 0x1234..." \
3 -H "Content-Type: application/json"Endpoints that accept X-Wallet-Address:
GET /api/v1/orders- Get user's ordersGET /api/v1/orders/:orderId- Get specific orderGET /api/v1/account- Get account infoGET /api/v1/account/positions- Get positions
Security Features
Replay Protection
Each action requires a unique nonce. Nonces are stored in Redis for 5 minutes and cannot be reused.
Timestamp Validation
Action timestamps must be within 30 seconds of server time. Old messages cannot be replayed.
Signature Verification
Uses ethers.js verifyMessage to recover signer. Wallet address is extracted from signature, not trusted from request.
Authentication Error Codes
| Code | HTTP Status | Description |
|---|---|---|
| MISSING_SIGNATURE | 400 | Request missing action or signature |
| INVALID_ACTION | 400 | Action missing type, timestamp, or nonce |
| INVALID_SIGNATURE | 401 | Signature verification failed |
| SIGNATURE_EXPIRED | 401 | Timestamp outside 30-second window |
| NONCE_USED | 401 | Nonce already used (replay attack) |
| MISSING_WALLET | 401 | X-Wallet-Address header required |
| UNAUTHORIZED | 403 | Not authorized for this resource |
| FORBIDDEN | 403 | Admin access required |
Rate Limits
API requests are rate limited to ensure fair usage and system stability.
| Endpoint Type | Rate Limit | Window |
|---|---|---|
| Public endpoints | 100 requests | 1 minute |
| Authenticated endpoints | 300 requests | 1 minute |
| Order placement | 50 requests | 1 second |
| Admin endpoints | 30 requests | 1 minute |
Rate limit headers are included in all responses: X-RateLimit-Limit,X-RateLimit-Remaining, X-RateLimit-Reset
Fee Structure
Arcex uses a tiered fee structure based on 30-day trading volume. Makers (limit orders that add liquidity) pay lower fees than takers (market orders that remove liquidity).
Fee Tiers
| Tier | 30d Volume (USD) | Maker Fee | Taker Fee |
|---|---|---|---|
| Tier 1 | < $100,000 | 0.02% | 0.06% |
| Tier 2 | $100,000 - $1M | 0.015% | 0.05% |
| Tier 3 | $1M - $10M | 0.01% | 0.04% |
| Tier 4 | $10M - $50M | 0.005% | 0.03% |
| Tier 5 | > $50M | 0.00% | 0.02% |
Builder Rebates
Builders (frontend operators) can earn rebates on trades executed through their interface. Include the builder parameter when placing orders to attribute volume.
Builder Program
The Builder Program allows developers to build frontends, trading bots, and other applications on top of Arcex while earning rebates on trading volume.
How It Works
- Register as a builder through the admin API or contact the team
- Receive a unique builder address/code
- Include your builder code in order submissions
- Earn rebates on all trades attributed to your builder code
Using Builder Codes
1{
2 "marketId": "BTC-USD-PERP",
3 "side": "BUY",
4 "type": "LIMIT",
5 "quantity": "0.1",
6 "price": "100000.00",
7 "builder": "0xBuilderAddress..."
8}Public Endpoints
Public endpoints do not require authentication and provide access to market data.
Check the health of the matching engine.
Response
1{
2 "success": true,
3 "data": {
4 "status": "ok",
5 "timestamp": 1674222000000
6 },
7 "timestamp": 1674222000000
8}Get a list of all available markets.
Response
1{
2 "success": true,
3 "data": {
4 "markets": [
5 {
6 "id": "BTC-USD-PERP",
7 "baseAsset": "BTC",
8 "quoteAsset": "USD",
9 "priceDecimals": 2,
10 "sizeDecimals": 4
11 }
12 ]
13 },
14 "timestamp": 1674222000000
15}Get the order book for a specific market.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
marketId | string | The market ID (e.g., BTC-USD-PERP) |
Query Parameters
| Parameter | Type | Description |
|---|---|---|
level(optional) | integer | The level of depth (1, 2, or 3) |
Response
1{
2 "success": true,
3 "data": {
4 "marketId": "BTC-USD-PERP",
5 "bids": [
6 ["100000.00", "0.5"],
7 ["99999.00", "1.0"]
8 ],
9 "asks": [
10 ["100001.00", "0.75"],
11 ["100002.00", "0.25"]
12 ],
13 "timestamp": 1674222000000
14 },
15 "timestamp": 1674222000000
16}Get recent trades for a specific market.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
marketId | string | The market ID (e.g., BTC-USD-PERP) |
Query Parameters
| Parameter | Type | Description |
|---|---|---|
limit(optional) | integer | Number of trades to return (max 100) |
Response
1{
2 "success": true,
3 "data": {
4 "trades": [
5 {
6 "id": "trade-123",
7 "price": "100001.00",
8 "quantity": "0.1",
9 "side": "BUY",
10 "timestamp": 1674222000000
11 }
12 ]
13 },
14 "timestamp": 1674222000000
15}Authenticated Endpoints
These endpoints require authentication via JWT token in the Authorization header.
Place a new order.
Body Parameters
| Parameter | Type | Description |
|---|---|---|
marketId | string | The market ID (e.g., BTC-USD-PERP) |
side | string | BUY or SELL |
type | string | LIMIT or MARKET |
quantity | string | The order quantity |
price(optional) | string | The order price (for LIMIT orders) |
builder(optional) | string | Builder address for rebates |
Response
1{
2 "success": true,
3 "data": {
4 "orderId": "order-456",
5 "status": "ACCEPTED"
6 },
7 "timestamp": 1674222000000
8}Get the status of a specific order.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
orderId | string | The order ID |
Response
1{
2 "success": true,
3 "data": {
4 "order": {
5 "id": "order-456",
6 "marketId": "BTC-USD-PERP",
7 "side": "BUY",
8 "type": "LIMIT",
9 "quantity": "0.1",
10 "price": "100000.00",
11 "filledQuantity": "0.0",
12 "status": "OPEN",
13 "createdAt": 1674222000000
14 }
15 },
16 "timestamp": 1674222000000
17}Cancel an existing order.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
orderId | string | The order ID |
Response
1{
2 "success": true,
3 "data": {
4 "orderId": "order-456",
5 "status": "CANCELLED"
6 },
7 "timestamp": 1674222000000
8}Get the user's account information.
Response
1{
2 "success": true,
3 "data": {
4 "userId": "0x123...",
5 "positions": [
6 {
7 "marketId": "BTC-USD-PERP",
8 "size": "0.5",
9 "entryPrice": "95000.00",
10 "liquidationPrice": "80000.00"
11 }
12 ],
13 "openOrders": []
14 },
15 "timestamp": 1674222000000
16}Price Endpoints
Real-time price feeds from on-chain oracles (Chainlink, Pyth).
Returns price feeds for all markets including mark price, index price, and last traded price.
Response
1{
2 "success": true,
3 "data": {
4 "prices": [
5 {
6 "marketId": "BTC-USD-PERP",
7 "markPrice": "100021.62",
8 "indexPrice": "100020.00",
9 "lastPrice": "100021.62",
10 "source": "chainlink",
11 "updatedAt": 1737420000000
12 },
13 {
14 "marketId": "ETH-USD-PERP",
15 "markPrice": "3500.50",
16 "indexPrice": "3500.00",
17 "lastPrice": "3500.50",
18 "source": "chainlink",
19 "updatedAt": 1737420000000
20 }
21 ]
22 },
23 "timestamp": 1737420000000
24}Returns the price for a specific market.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
marketId | string | Market ID (e.g., BTC-USD-PERP) |
Response
1{
2 "success": true,
3 "data": {
4 "marketId": "BTC-USD-PERP",
5 "markPrice": "100021.62",
6 "indexPrice": "100020.00",
7 "lastPrice": "100021.62",
8 "source": "chainlink",
9 "updatedAt": 1737420000000
10 },
11 "timestamp": 1737420000000
12}Position Endpoints
Manage and view user positions. Requires wallet header for read operations and signed action for modifications.
Returns the user's open positions. Requires X-Wallet-Address header.
Response
1{
2 "success": true,
3 "data": {
4 "positions": [
5 {
6 "id": "pos-uuid-1234",
7 "marketId": "BTC-USD-PERP",
8 "side": "LONG",
9 "size": "0.1",
10 "entryPrice": "100000",
11 "leverage": 5,
12 "margin": "2000",
13 "liquidationPrice": "80000",
14 "unrealizedPnl": "50.00",
15 "realizedPnl": "0",
16 "fundingAccrued": "-1.50",
17 "status": "OPEN",
18 "openedAt": 1737420000000
19 }
20 ],
21 "summary": {
22 "totalUnrealizedPnl": "50.00",
23 "totalMarginUsed": "2000.00"
24 }
25 },
26 "timestamp": 1737420000000
27}Closes an open position. Requires a signed action.
Body Parameters
| Parameter | Type | Description |
|---|---|---|
action | object | Signed action with type 'closePosition' |
action.data.positionId | string | The position ID to close |
signature | string | Wallet signature (0x...) |
Response
1{
2 "success": true,
3 "data": {
4 "positionId": "pos-uuid-1234",
5 "status": "CLOSED",
6 "realizedPnl": "50.00"
7 },
8 "timestamp": 1737420000000
9}Collateral Endpoints
Manage user collateral balances and withdrawals.
Returns the user's collateral balance. Requires X-Wallet-Address header.
Response
1{
2 "success": true,
3 "data": {
4 "walletAddress": "0x1234...",
5 "totalBalance": "10000.00",
6 "availableBalance": "8000.00",
7 "lockedMargin": "2000.00"
8 },
9 "timestamp": 1737420000000
10}Initiates a withdrawal from the smart contract. Requires a signed action.
Body Parameters
| Parameter | Type | Description |
|---|---|---|
action | object | Signed action with type 'withdraw' |
action.data.amount | string | Amount to withdraw |
signature | string | Wallet signature (0x...) |
Response
1{
2 "success": true,
3 "data": {
4 "withdrawalId": "withdraw-uuid-1234",
5 "amount": "1000",
6 "status": "PENDING",
7 "estimatedCompletionTime": 1737420600000
8 },
9 "timestamp": 1737420000000
10}Funding Rate Endpoints
Funding rates are exchanged between long and short positions every 8 hours to keep perpetual prices aligned with the index.
Returns funding rates for all markets.
Response
1{
2 "success": true,
3 "data": {
4 "fundingRates": [
5 {
6 "marketId": "BTC-USD-PERP",
7 "currentRate": "0.0001",
8 "predictedRate": "0.00012",
9 "nextFundingTime": 1737424800000,
10 "annualizedRate": "0.0876"
11 },
12 {
13 "marketId": "ETH-USD-PERP",
14 "currentRate": "0.00008",
15 "predictedRate": "0.00009",
16 "nextFundingTime": 1737424800000,
17 "annualizedRate": "0.0701"
18 }
19 ]
20 },
21 "timestamp": 1737420000000
22}Returns the funding rate for a specific market with historical data.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
marketId | string | Market ID (e.g., BTC-USD-PERP) |
Response
1{
2 "success": true,
3 "data": {
4 "marketId": "BTC-USD-PERP",
5 "currentRate": "0.0001",
6 "predictedRate": "0.00012",
7 "nextFundingTime": 1737424800000,
8 "annualizedRate": "0.0876",
9 "history": [
10 { "rate": "0.00009", "timestamp": 1737396000000 },
11 { "rate": "0.0001", "timestamp": 1737417600000 }
12 ]
13 },
14 "timestamp": 1737420000000
15}Liquidation Endpoints
Monitor liquidation statistics and at-risk positions. Liquidations occur when a position's margin ratio falls below the maintenance margin requirement.
Returns liquidation statistics for the platform.
Response
1{
2 "success": true,
3 "data": {
4 "positionsAtRisk": 5,
5 "insuranceFundBalance": "500000.00",
6 "liquidations24h": 12,
7 "totalLiquidationVolume24h": "1500000.00"
8 },
9 "timestamp": 1737420000000
10}Returns positions at risk of liquidation (margin ratio below 5%).
Response
1{
2 "success": true,
3 "data": {
4 "positions": [
5 {
6 "positionId": "pos-uuid-5678",
7 "walletAddress": "0x5678...",
8 "marketId": "BTC-USD-PERP",
9 "side": "LONG",
10 "size": "1.0",
11 "marginRatio": "0.03",
12 "liquidationPrice": "95000"
13 }
14 ]
15 },
16 "timestamp": 1737420000000
17}Fee Endpoints
Endpoints for fee information, estimation, and user fee tiers.
Get all available fee tiers based on 30-day trading volume. Public endpoint.
Response
1{
2 "success": true,
3 "data": {
4 "tiers": [
5 {
6 "tier": 0,
7 "name": "Default",
8 "minVolume": "0",
9 "minVolumeFormatted": "$0.00",
10 "makerFeeRate": 200,
11 "makerFeePercent": "0.0200%",
12 "takerFeeRate": 500,
13 "takerFeePercent": "0.0500%"
14 },
15 {
16 "tier": 1,
17 "name": "Bronze",
18 "minVolume": "100000",
19 "minVolumeFormatted": "$100.00K",
20 "makerFeeRate": 180,
21 "makerFeePercent": "0.0180%",
22 "takerFeeRate": 450,
23 "takerFeePercent": "0.0450%"
24 },
25 {
26 "tier": 2,
27 "name": "Silver",
28 "minVolume": "1000000",
29 "minVolumeFormatted": "$1.00M",
30 "makerFeeRate": 150,
31 "makerFeePercent": "0.0150%",
32 "takerFeeRate": 400,
33 "takerFeePercent": "0.0400%"
34 },
35 {
36 "tier": 3,
37 "name": "Gold",
38 "minVolume": "10000000",
39 "minVolumeFormatted": "$10.00M",
40 "makerFeeRate": 100,
41 "makerFeePercent": "0.0100%",
42 "takerFeeRate": 350,
43 "takerFeePercent": "0.0350%"
44 },
45 {
46 "tier": 4,
47 "name": "Platinum",
48 "minVolume": "50000000",
49 "minVolumeFormatted": "$50.00M",
50 "makerFeeRate": 50,
51 "makerFeePercent": "0.0050%",
52 "takerFeeRate": 300,
53 "takerFeePercent": "0.0300%"
54 },
55 {
56 "tier": 5,
57 "name": "Diamond",
58 "minVolume": "100000000",
59 "minVolumeFormatted": "$100.00M",
60 "makerFeeRate": 0,
61 "makerFeePercent": "0.0000%",
62 "takerFeeRate": 250,
63 "takerFeePercent": "0.0250%"
64 }
65 ],
66 "feePrecision": 1000000,
67 "description": "Fee rates are in parts per million (1e6). Divide by 10000 to get percentage."
68 },
69 "timestamp": 1705789200000
70}Estimate fees for a hypothetical trade before placing it. Public endpoint.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
market | string | Market ID (e.g., BTC-USD-PERP) |
size | number | Trade size in base currency |
price | number | Trade price |
side | string | BUY or SELL |
builder(optional) | string | Builder address for rebate calculation |
Response
1{
2 "success": true,
3 "data": {
4 "market": "BTC-USD-PERP",
5 "side": "BUY",
6 "size": 1,
7 "price": 100000,
8 "notionalValue": 100000,
9 "fees": {
10 "makerFee": "20.000000",
11 "takerFee": "50.000000",
12 "makerFeeRate": 200,
13 "takerFeeRate": 500,
14 "builderRebate": "5.000000",
15 "netTakerFee": "45.000000"
16 },
17 "builder": {
18 "address": "0x1234...",
19 "rebateRate": 1000
20 },
21 "note": "These are estimated fees using default rates. Actual fees depend on your fee tier."
22 },
23 "timestamp": 1705789200000
24}Get the authenticated user's current fee tier, rates, and volume progress. Requires JWT authentication.
Response
1{
2 "success": true,
3 "data": {
4 "userId": "0xUserWalletAddress",
5 "tier": {
6 "index": 0,
7 "name": "Default"
8 },
9 "feeRates": {
10 "makerFeeRate": 200,
11 "makerFeePercent": "0.0200%",
12 "takerFeeRate": 500,
13 "takerFeePercent": "0.0500%"
14 },
15 "volume": {
16 "last30Days": "0",
17 "last30DaysFormatted": "$0.00"
18 },
19 "nextTier": {
20 "volumeRequired": "100000",
21 "volumeRemaining": "100000",
22 "volumeRemainingFormatted": "$100.00K"
23 }
24 },
25 "timestamp": 1705789200000
26}Get the authenticated user's daily volume breakdown. Requires JWT authentication.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
days(optional) | number | Number of days (default: 30, max: 90) |
Response
1{
2 "success": true,
3 "data": {
4 "userId": "0xUserWalletAddress",
5 "totalVolume": "150000",
6 "totalVolumeFormatted": "$150.00K",
7 "dailyBreakdown": [
8 { "date": "2026-01-20", "volume": "50000" },
9 { "date": "2026-01-19", "volume": "75000" },
10 { "date": "2026-01-18", "volume": "25000" }
11 ]
12 },
13 "timestamp": 1705789200000
14}Builder (Referral) Endpoints
Endpoints for the builder/referral program. Builders can earn rebates on trades attributed to their code.
Get all active builders (referral partners). Public endpoint.
Response
1{
2 "success": true,
3 "data": {
4 "builders": [
5 {
6 "address": "0xBuilderAddress1",
7 "name": "TradingBot Pro",
8 "description": "Professional trading interface",
9 "website": "https://tradingbot.pro",
10 "rebateRate": 1000,
11 "rebatePercent": "10.00%"
12 },
13 {
14 "address": "0xBuilderAddress2",
15 "name": "DeFi Dashboard",
16 "description": "All-in-one DeFi dashboard",
17 "website": "https://defidash.io",
18 "rebateRate": 500,
19 "rebatePercent": "5.00%"
20 }
21 ],
22 "count": 2
23 },
24 "timestamp": 1705789200000
25}Get detailed information about a specific builder. Public endpoint.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
address | string | Builder's wallet address |
Response
1{
2 "success": true,
3 "data": {
4 "address": "0xBuilderAddress",
5 "name": "TradingBot Pro",
6 "description": "Professional trading interface with advanced charting",
7 "website": "https://tradingbot.pro",
8 "isActive": true,
9 "rebateRate": 1000,
10 "rebatePercent": "10.00%",
11 "createdAt": "2026-01-15T10:00:00.000Z"
12 },
13 "timestamp": 1705789200000
14}Get public statistics for a builder. Public endpoint.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
address | string | Builder's wallet address |
Response
1{
2 "success": true,
3 "data": {
4 "address": "0xBuilderAddress",
5 "totalVolume": "5000000",
6 "totalVolumeFormatted": "$5.00M",
7 "totalTrades": 1250,
8 "last24hVolume": "250000",
9 "last24hVolumeFormatted": "$250.00K",
10 "last24hTrades": 62
11 },
12 "timestamp": 1705789200000
13}Validate if a builder code/address is valid and active. Public endpoint.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
address | string | Builder's wallet address to validate |
Response
1{
2 "success": true,
3 "data": {
4 "address": "0xBuilderAddress",
5 "isValid": true,
6 "builder": {
7 "name": "TradingBot Pro",
8 "rebateRate": 1000,
9 "rebatePercent": "10.00%"
10 }
11 },
12 "timestamp": 1705789200000
13}Get authenticated builder's full statistics including rebate earnings. Requires JWT authentication and builder registration.
Response
1{
2 "success": true,
3 "data": {
4 "address": "0xMyBuilderAddress",
5 "totalVolume": "5000000",
6 "totalVolumeFormatted": "$5.00M",
7 "totalTrades": 1250,
8 "rebates": {
9 "total": "25000.00",
10 "totalFormatted": "$25000.00",
11 "pending": "5000.00",
12 "pendingFormatted": "$5000.00",
13 "claimed": "20000.00",
14 "claimedFormatted": "$20000.00"
15 },
16 "last24h": {
17 "volume": "250000",
18 "volumeFormatted": "$250.00K",
19 "trades": 62,
20 "rebates": "1250.00",
21 "rebatesFormatted": "$1250.00"
22 }
23 },
24 "timestamp": 1705789200000
25}Admin Endpoints
Admin endpoints require JWT authentication and admin privileges. Used for system management.
Admin Only: These endpoints require admin authentication and are not available to regular users.
Builder Management
Register a new builder (referral partner).
Body Parameters
| Parameter | Type | Description |
|---|---|---|
address | string | Builder's wallet address |
name | string | Display name (1-100 chars) |
description(optional) | string | Description (max 500 chars) |
website(optional) | string | Valid URL |
rebateRate(optional) | number | Rebate rate in basis points (0-5000) |
Response
1{
2 "success": true,
3 "data": {
4 "message": "Builder registered successfully",
5 "builder": {
6 "address": "0xNewBuilderAddress",
7 "name": "New Trading App",
8 "rebateRate": 1000,
9 "isActive": true
10 }
11 },
12 "timestamp": 1705789200000
13}Update an existing builder's information. All fields are optional.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
address | string | Builder's wallet address |
Body Parameters
| Parameter | Type | Description |
|---|---|---|
name(optional) | string | Updated display name |
description(optional) | string | Updated description |
website(optional) | string | Updated URL |
rebateRate(optional) | number | Updated rebate rate |
isActive(optional) | boolean | Active status |
Response
1{
2 "success": true,
3 "data": {
4 "message": "Builder updated successfully",
5 "builder": {
6 "address": "0xBuilderAddress",
7 "name": "Updated Name",
8 "rebateRate": 1500,
9 "isActive": true
10 }
11 },
12 "timestamp": 1705789200000
13}Deactivate a builder (soft delete).
Path Parameters
| Parameter | Type | Description |
|---|---|---|
address | string | Builder's wallet address |
Response
1{
2 "success": true,
3 "data": {
4 "message": "Builder deactivated successfully",
5 "address": "0xBuilderAddress"
6 },
7 "timestamp": 1705789200000
8}Get all builders with full statistics (admin view).
Response
1{
2 "success": true,
3 "data": {
4 "builders": [
5 {
6 "address": "0xBuilderAddress1",
7 "name": "TradingBot Pro",
8 "description": "Professional trading interface",
9 "website": "https://tradingbot.pro",
10 "isActive": true,
11 "rebateRate": 1000,
12 "createdAt": "2026-01-15T10:00:00.000Z",
13 "updatedAt": "2026-01-18T14:30:00.000Z",
14 "stats": {
15 "totalVolume": "5000000",
16 "totalTrades": 1250,
17 "totalRebates": "25000.00",
18 "pendingRebates": "5000.00"
19 }
20 }
21 ],
22 "count": 1
23 },
24 "timestamp": 1705789200000
25}Treasury & Fees
Get overall fee statistics for the platform.
Response
1{
2 "success": true,
3 "data": {
4 "totalFeesCollected": "150000.00",
5 "totalFeesCollectedFormatted": "$150000.00",
6 "totalBuilderRebates": "15000.00",
7 "totalBuilderRebatesFormatted": "$15000.00",
8 "netProtocolFees": "135000.000000",
9 "tradesProcessed": 5000
10 },
11 "timestamp": 1705789200000
12}Get treasury information including on-chain balances.
Response
1{
2 "success": true,
3 "data": {
4 "treasury": {
5 "address": "0xTreasuryAddress",
6 "ethBalance": "10.5"
7 },
8 "fees": {
9 "totalCollected": "150000.0",
10 "totalBuilderRebates": "15000.0",
11 "netProtocolFees": "135000.0"
12 },
13 "contract": "0xPerpetualContractAddress"
14 },
15 "timestamp": 1705789200000
16}Withdraw collected fees from the treasury.
Body Parameters
| Parameter | Type | Description |
|---|---|---|
amount | string | Amount to withdraw |
recipient | string | Recipient wallet address |
Response
1{
2 "success": true,
3 "data": {
4 "message": "Withdrawal successful",
5 "transaction": {
6 "hash": "0xTransactionHash...",
7 "blockNumber": 12345678
8 },
9 "amount": "1000.0",
10 "recipient": "0xRecipientAddress"
11 },
12 "timestamp": 1705789200000
13}Set a new treasury address.
Body Parameters
| Parameter | Type | Description |
|---|---|---|
address | string | New treasury wallet address |
Response
1{
2 "success": true,
3 "data": {
4 "message": "Treasury address updated",
5 "transaction": {
6 "hash": "0xTransactionHash...",
7 "blockNumber": 12345678
8 },
9 "newTreasury": "0xNewTreasuryAddress"
10 },
11 "timestamp": 1705789200000
12}Get fee tiers from the blockchain (on-chain source of truth).
Response
1{
2 "success": true,
3 "data": {
4 "tiers": [
5 {
6 "index": 0,
7 "minVolume": "0.0",
8 "makerFeeRate": 200,
9 "takerFeeRate": 500,
10 "makerFeePercent": "0.0200%",
11 "takerFeePercent": "0.0500%"
12 }
13 ],
14 "count": 6,
15 "source": "blockchain"
16 },
17 "timestamp": 1705789200000
18}Add or update a fee tier on-chain.
Body Parameters
| Parameter | Type | Description |
|---|---|---|
index | number | Tier index (0-based) |
minVolume | string | Minimum volume threshold (in USD) |
makerFeeRate | number | Maker fee in parts per million (200 = 0.02%) |
takerFeeRate | number | Taker fee in parts per million (500 = 0.05%) |
Response
1{
2 "success": true,
3 "data": {
4 "message": "Fee tier updated",
5 "transaction": {
6 "hash": "0xTransactionHash...",
7 "blockNumber": 12345678
8 },
9 "tier": {
10 "index": 1,
11 "minVolume": "100000",
12 "makerFeeRate": 180,
13 "takerFeeRate": 450
14 }
15 },
16 "timestamp": 1705789200000
17}Settlement & System Management
Get settlement service status.
Response
1{
2 "success": true,
3 "data": {
4 "isRunning": true,
5 "isConfigured": true,
6 "settlerAddress": "0xSettlerWalletAddress",
7 "stats": {
8 "totalBatches": 150,
9 "successfulBatches": 148,
10 "failedBatches": 2,
11 "totalTradesSettled": 1500,
12 "totalGasUsed": "15000000000000000",
13 "totalFeesCollected": "75000.00",
14 "totalBuilderRebates": "7500.00"
15 },
16 "pendingBatches": 0,
17 "pendingTrades": 3
18 },
19 "timestamp": 1705789200000
20}Authorize a new settler address on the contract.
Body Parameters
| Parameter | Type | Description |
|---|---|---|
address | string | New settler wallet address |
Response
1{
2 "success": true,
3 "data": {
4 "message": "Settler added",
5 "transaction": {
6 "hash": "0xTransactionHash...",
7 "blockNumber": 12345678
8 },
9 "settler": "0xNewSettlerAddress"
10 },
11 "timestamp": 1705789200000
12}Remove authorization from a settler address.
Body Parameters
| Parameter | Type | Description |
|---|---|---|
address | string | Settler address to remove |
Response
1{
2 "success": true,
3 "data": {
4 "message": "Settler removed",
5 "transaction": {
6 "hash": "0xTransactionHash...",
7 "blockNumber": 12345678
8 },
9 "settler": "0xSettlerToRemove"
10 },
11 "timestamp": 1705789200000
12}Add a new trading market on-chain.
Body Parameters
| Parameter | Type | Description |
|---|---|---|
marketId | string | Human-readable market ID |
maxLeverage | number | Maximum leverage (1-200) |
maintenanceMargin | number | Maintenance margin in basis points (1-10000) |
maxPositionSize | string | Max position size in USD |
Response
1{
2 "success": true,
3 "data": {
4 "message": "Market added",
5 "transaction": {
6 "hash": "0xTransactionHash...",
7 "blockNumber": 12345678
8 },
9 "market": {
10 "id": "SOL/USD",
11 "idBytes": "0xKeccak256Hash...",
12 "maxLeverage": 20,
13 "maintenanceMargin": 500,
14 "maxPositionSize": "1000000"
15 }
16 },
17 "timestamp": 1705789200000
18}Update market parameters. All fields are optional.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
marketId | string | Market ID |
Body Parameters
| Parameter | Type | Description |
|---|---|---|
maxLeverage(optional) | number | Maximum leverage |
maintenanceMargin(optional) | number | Maintenance margin in basis points |
maxPositionSize(optional) | string | Max position size |
isActive(optional) | boolean | Active status |
Response
1{
2 "success": true,
3 "data": {
4 "message": "Market updated",
5 "transaction": {
6 "hash": "0xTransactionHash...",
7 "blockNumber": 12345678
8 },
9 "marketId": "SOL/USD"
10 },
11 "timestamp": 1705789200000
12}Get comprehensive system statistics.
Response
1{
2 "success": true,
3 "data": {
4 "fees": {
5 "totalCollected": "150000.00",
6 "totalBuilderRebates": "15000.00",
7 "tradesProcessed": 5000
8 },
9 "settlement": {
10 "isRunning": true,
11 "pendingTrades": 3,
12 "totalSettled": 4997,
13 "successfulBatches": 500,
14 "failedBatches": 2
15 },
16 "builders": {
17 "total": 10,
18 "active": 8
19 },
20 "timestamp": 1705789200000
21 },
22 "timestamp": 1705789200000
23}Trigger synchronization of user volumes to the blockchain.
Response
1{
2 "success": true,
3 "data": {
4 "message": "Volume sync initiated"
5 },
6 "timestamp": 1705789200000
7}WebSocket API
Connect to our WebSocket server for real-time updates on order books, trades, and account changes.
Connection
1wss://api.arcex.app/wsFor authenticated channels (user orders, positions), include your JWT token:
1wss://api.arcex.app/ws?token=<your_jwt_token>Available Channels
| Channel | Authentication | Description |
|---|---|---|
| orderbook:{marketId} | No | Real-time orderbook updates |
| trades:{marketId} | No | Real-time trade feed |
| user:orders | Yes | User's order updates |
| user:positions | Yes | User's position updates |
| user:account | Yes | User's account updates |
Subscribe to Channel
1{
2 "type": "subscribe",
3 "channel": "orderbook:BTC-USD-PERP"
4}Orderbook Update
1{
2 "channel": "orderbook:BTC-USD-PERP",
3 "data": {
4 "bids": [["100000.00", "0.5"]],
5 "asks": [["100001.00", "0.75"]],
6 "timestamp": 1674222000000
7 }
8}Trade Update
1{
2 "channel": "trades:BTC-USD-PERP",
3 "data": {
4 "id": "trade-123",
5 "price": "100001.00",
6 "quantity": "0.1",
7 "side": "BUY",
8 "timestamp": 1674222000000
9 }
10}User Order Update
1{
2 "channel": "user:orders",
3 "data": {
4 "orderId": "order-456",
5 "status": "FILLED",
6 "filledQuantity": "0.1",
7 "timestamp": 1674222000000
8 }
9}Type Definitions
Complete type definitions for all API data structures.
1// Market Types
2interface Market {
3 id: string; // Market ID (e.g., "BTC-USD-PERP")
4 baseAsset: string; // Base asset (e.g., "BTC")
5 quoteAsset: string; // Quote asset (e.g., "USD")
6 priceDecimals: number;
7 sizeDecimals: number;
8 minOrderSize: string;
9 maxOrderSize: string;
10 tickSize: string;
11 maxLeverage: number;
12 status: MarketStatus;
13}
14
15type MarketStatus = "ACTIVE" | "INACTIVE" | "SETTLEMENT";
16
17// Order Types
18interface Order {
19 id: string;
20 marketId: string;
21 userId: string;
22 side: OrderSide;
23 type: OrderType;
24 status: OrderStatus;
25 price: string;
26 quantity: string;
27 filledQuantity: string;
28 remainingQuantity: string;
29 avgFillPrice?: string;
30 leverage: number;
31 reduceOnly: boolean;
32 postOnly: boolean;
33 timeInForce: TimeInForce;
34 createdAt: number;
35 updatedAt: number;
36}
37
38type OrderSide = "BUY" | "SELL";
39type OrderType = "LIMIT" | "MARKET" | "STOP_LIMIT" | "STOP_MARKET";
40type OrderStatus = "OPEN" | "PARTIALLY_FILLED" | "FILLED" | "CANCELLED" | "REJECTED";
41type TimeInForce = "GTC" | "IOC" | "FOK";
42
43// Position Types
44interface Position {
45 marketId: string;
46 userId: string;
47 side: PositionSide;
48 size: string;
49 entryPrice: string;
50 markPrice: string;
51 liquidationPrice: string;
52 margin: string;
53 unrealizedPnl: string;
54 realizedPnl: string;
55 leverage: number;
56}
57
58type PositionSide = "LONG" | "SHORT";
59
60// Trade Types
61interface Trade {
62 id: string;
63 marketId: string;
64 orderId: string;
65 price: string;
66 quantity: string;
67 side: OrderSide;
68 fee: string;
69 feeAsset: string;
70 isMaker: boolean;
71 timestamp: number;
72}
73
74// Fee Types
75interface FeeTier {
76 tier: number;
77 minVolume: string;
78 makerFee: string;
79 takerFee: string;
80}
81
82interface UserFees {
83 tier: number;
84 makerFee: string;
85 takerFee: string;
86 volume30d: string;
87}
88
89// Builder Types
90interface Builder {
91 address: string;
92 name: string;
93 rebateRate: string;
94 isActive: boolean;
95 totalVolume: string;
96 totalRebates: string;
97}Error Codes
Comprehensive list of error codes returned by the API.
General Errors
| Code | Description |
|---|---|
| VALIDATION_ERROR | Request parameters failed validation |
| NOT_FOUND | Requested resource not found |
| UNAUTHORIZED | Authentication required or token is invalid |
| FORBIDDEN | You don't have permission to access this resource |
| RATE_LIMITED | Too many requests, please slow down |
| INTERNAL_ERROR | Unexpected server error |
| NOT_CONFIGURED | Blockchain/service not configured |
| INVALID_ADDRESS | Invalid Ethereum address provided |
Trading Errors
| Code | Description |
|---|---|
| INSUFFICIENT_BALANCE | Not enough balance to execute the order |
| INSUFFICIENT_MARGIN | Not enough margin for the position |
| INSUFFICIENT_FEES | Not enough fees available for withdrawal |
| ORDER_NOT_FOUND | The specified order does not exist |
| ORDER_ALREADY_FILLED | Cannot cancel an already filled order |
| ORDER_ALREADY_CANCELLED | The order has already been cancelled |
| MARKET_NOT_FOUND | The specified market does not exist |
| MARKET_CLOSED | The market is currently closed for trading |
| INVALID_PRICE | The price is outside acceptable range |
| INVALID_QUANTITY | The quantity is outside acceptable range |
| POSITION_NOT_FOUND | No position exists for this market |
| LIQUIDATION_PENDING | Cannot modify position during liquidation |
Builder & Admin Errors
| Code | Description |
|---|---|
| NOT_BUILDER | User is not registered as a builder |
| BUILDER_NOT_FOUND | The specified builder does not exist |
| BUILDER_INACTIVE | The builder is not currently active |
| REGISTRATION_FAILED | Builder registration failed |
| UPDATE_FAILED | Update operation failed |
| DEACTIVATION_FAILED | Builder deactivation failed |
| WITHDRAWAL_FAILED | Fee withdrawal failed |
| SET_TREASURY_FAILED | Treasury update failed |
| ADD_SETTLER_FAILED | Settler authorization failed |
| REMOVE_SETTLER_FAILED | Settler removal failed |
| ADD_MARKET_FAILED | Market creation failed |
| UPDATE_MARKET_FAILED | Market update failed |
| SYNC_FAILED | Volume sync failed |
| ON_CHAIN_REQUIRED | Operation must be done on-chain |
Fee Calculation Reference
Fee Rate Units
- Fee rates are stored in parts per million (PPM)
- To convert to percentage:
rate / 10000 - Example: 200 PPM = 0.02%
Fee Calculation Formula
1makerFee = notionalValue * makerFeeRate / 1,000,000
2takerFee = notionalValue * takerFeeRate / 1,000,000
3builderRebate = takerFee * builderRebateRate / 10,000
4netTakerFee = takerFee - builderRebateBuilder Rebate Rates
- Builder rebate rates are in basis points (BPS)
- To convert to percentage:
rate / 100 - Example: 1000 BPS = 10%
- Max rebate rate: 5000 BPS (50%)
Code Examples
Complete code examples for integrating with the Arcex API, including React Native with Privy wallet integration.
React Native API Service (Privy)
A centralized API service for handling all DEX interactions with signature-based authentication.
1const BASE_URL = 'https://api.arcex.app/api/v1';
2
3// Helper to sort object keys recursively (required for deterministic signing)
4function sortObject(obj: any): any {
5 if (typeof obj !== 'object' || obj === null) return obj;
6 if (Array.isArray(obj)) return obj.map(sortObject);
7 return Object.keys(obj).sort().reduce((result: any, key) => {
8 result[key] = sortObject(obj[key]);
9 return result;
10 }, {});
11}
12
13// Create signable message with sorted keys
14function createSignableMessage(action: any): string {
15 const sortedAction = {
16 type: action.type,
17 data: sortObject(action.data),
18 timestamp: action.timestamp,
19 nonce: action.nonce,
20 };
21 return JSON.stringify(sortedAction);
22}
23
24// Get fresh nonce from server
25async function getNonce(): Promise<string> {
26 const res = await fetch(`${BASE_URL}/auth/nonce`);
27 const data = await res.json();
28 return data.data.nonce;
29}
30
31// Generic signed request for state-changing operations
32export async function signedRequest(
33 method: 'POST' | 'DELETE',
34 endpoint: string,
35 actionType: string,
36 actionData: any,
37 signMessage: (message: string) => Promise<string>
38): Promise<any> {
39 const nonce = await getNonce();
40
41 const action = {
42 type: actionType,
43 data: actionData,
44 timestamp: Date.now(),
45 nonce,
46 };
47
48 const message = createSignableMessage(action);
49 const signature = await signMessage(message);
50
51 const res = await fetch(`${BASE_URL}${endpoint}`, {
52 method,
53 headers: { 'Content-Type': 'application/json' },
54 body: JSON.stringify({ action, signature }),
55 });
56
57 return res.json();
58}
59
60// Generic read request (wallet header only)
61export async function readRequest(
62 endpoint: string,
63 walletAddress: string
64): Promise<any> {
65 const res = await fetch(`${BASE_URL}${endpoint}`, {
66 headers: { 'X-Wallet-Address': walletAddress },
67 });
68 return res.json();
69}
70
71// Public request (no auth)
72export async function publicRequest(endpoint: string): Promise<any> {
73 const res = await fetch(`${BASE_URL}${endpoint}`);
74 return res.json();
75}React Native Trading Hook
A custom hook for trading operations using Privy for wallet management.
1import { usePrivy } from '@privy-io/react-auth';
2import { signedRequest, readRequest, publicRequest } from '../services/dexApi';
3
4export function useTrading() {
5 const { user, signMessage } = usePrivy();
6 const walletAddress = user?.wallet?.address;
7
8 const placeOrder = async (orderData: {
9 marketId: string;
10 side: 'BUY' | 'SELL';
11 type: 'LIMIT' | 'MARKET';
12 size: string;
13 price?: string;
14 leverage: number;
15 margin: string;
16 }) => {
17 if (!signMessage) throw new Error('Wallet not connected');
18 return signedRequest('POST', '/orders', 'placeOrder', orderData, signMessage);
19 };
20
21 const cancelOrder = async (orderId: string) => {
22 if (!signMessage) throw new Error('Wallet not connected');
23 return signedRequest('DELETE', `/orders/${orderId}`, 'cancelOrder', { orderId }, signMessage);
24 };
25
26 const closePosition = async (positionId: string) => {
27 if (!signMessage) throw new Error('Wallet not connected');
28 return signedRequest('POST', '/positions/close', 'closePosition', { positionId }, signMessage);
29 };
30
31 const getOrders = async () => {
32 if (!walletAddress) throw new Error('Wallet not connected');
33 return readRequest('/orders', walletAddress);
34 };
35
36 const getPositions = async () => {
37 if (!walletAddress) throw new Error('Wallet not connected');
38 return readRequest('/positions', walletAddress);
39 };
40
41 const getBalance = async () => {
42 if (!walletAddress) throw new Error('Wallet not connected');
43 return readRequest('/collateral/balance', walletAddress);
44 };
45
46 const getMarkets = () => publicRequest('/markets');
47 const getOrderBook = (marketId: string) => publicRequest(`/markets/${marketId}/orderbook`);
48 const getPrices = () => publicRequest('/prices');
49 const getFundingRates = () => publicRequest('/funding');
50
51 return {
52 placeOrder,
53 cancelOrder,
54 closePosition,
55 getOrders,
56 getPositions,
57 getBalance,
58 getMarkets,
59 getOrderBook,
60 getPrices,
61 getFundingRates,
62 walletAddress,
63 isConnected: !!walletAddress,
64 };
65}Place Order with Privy (React Native)
1import { usePrivy } from '@privy-io/react-auth';
2
3const placeOrder = async (orderData) => {
4 const { signMessage } = usePrivy();
5
6 // 1. Get a fresh nonce from the server
7 const nonceRes = await fetch('https://api.arcex.app/api/v1/auth/nonce');
8 const { data: { nonce } } = await nonceRes.json();
9
10 // 2. Construct the action object
11 const action = {
12 type: 'placeOrder',
13 data: orderData, // { marketId, side, size, price, leverage, margin }
14 timestamp: Date.now(),
15 nonce,
16 };
17
18 // 3. Create the signable message (sorted keys)
19 const message = createSignableMessage(action);
20
21 // 4. Sign the message with Privy
22 const signature = await signMessage(message);
23
24 // 5. Send the signed action to the API
25 const response = await fetch('https://api.arcex.app/api/v1/orders', {
26 method: 'POST',
27 headers: { 'Content-Type': 'application/json' },
28 body: JSON.stringify({ action, signature }),
29 });
30
31 return response.json();
32};
33
34// Helper to create the signable message with sorted keys
35function createSignableMessage(action) {
36 const sortedAction = {
37 type: action.type,
38 data: sortObject(action.data),
39 timestamp: action.timestamp,
40 nonce: action.nonce,
41 };
42 return JSON.stringify(sortedAction);
43}
44
45// Recursive key sorting helper
46function sortObject(obj) {
47 if (typeof obj !== 'object' || obj === null) return obj;
48 if (Array.isArray(obj)) return obj.map(sortObject);
49 return Object.keys(obj).sort().reduce((result, key) => {
50 result[key] = sortObject(obj[key]);
51 return result;
52 }, {});
53}Read-Only Request (Wallet Header)
1// For read-only endpoints, simply provide the wallet address in the header
2const fetchUserPositions = async (walletAddress: string) => {
3 const response = await fetch('https://api.arcex.app/api/v1/positions', {
4 headers: {
5 'X-Wallet-Address': walletAddress,
6 },
7 });
8 return response.json();
9};
10
11// Example usage
12const positions = await fetchUserPositions('0x1234...');
13console.log('Open positions:', positions.data.positions);WebSocket Subscription (JavaScript)
1const ws = new WebSocket('wss://api.arcex.app/ws');
2
3ws.onopen = () => {
4 console.log('Connected to WebSocket');
5
6 // Subscribe to orderbook
7 ws.send(JSON.stringify({
8 type: 'subscribe',
9 channel: 'orderbook',
10 marketId: 'BTC-USD-PERP',
11 }));
12
13 // Subscribe to trades
14 ws.send(JSON.stringify({
15 type: 'subscribe',
16 channel: 'trades',
17 marketId: 'BTC-USD-PERP',
18 }));
19};
20
21ws.onmessage = (event) => {
22 const data = JSON.parse(event.data);
23
24 if (data.channel === 'orderbook') {
25 console.log('Order book update:', data.data);
26 }
27
28 if (data.channel === 'trades') {
29 console.log('New trade:', data.data);
30 }
31};WebSocket User Updates
1// Subscribe to user-specific updates (orders, positions, account)
2ws.send(JSON.stringify({
3 type: 'subscribe',
4 channel: 'user',
5 walletAddress: '0x1234...',
6}));
7
8ws.onmessage = (event) => {
9 const data = JSON.parse(event.data);
10
11 if (data.channel === 'user') {
12 switch (data.type) {
13 case 'orderUpdate':
14 console.log('Order filled/updated:', data.data);
15 break;
16 case 'positionUpdate':
17 console.log('Position changed:', data.data);
18 break;
19 case 'accountUpdate':
20 console.log('Balance changed:', data.data);
21 break;
22 }
23 }
24};Ready to Build?
Start integrating with the Arcex API today. Join the builder program to earn rebates on your trading volume.