REST SDKs are available for TypeScript, React, and Rust. See the TypeScript SDK, React SDK, or Rust REST SDK.
Endpoint
Base URLs
Use the staging base URL for private alpha and testnet integrations:Request Requirements
Every request must include a non-emptyUser-Agent header. Requests that send an empty or absent User-Agent are rejected at the edge with 403 Forbidden before reaching the API.
Routes
The generated route pages in this section are the source of truth for request parameters, request bodies, responses, and authentication headers. Use the left navigation to browse by endpoint group, or start with the health check route.OpenAPI
Every route page in this section is generated from Monaco’s OpenAPI specification, so the documented parameters, request bodies, responses, and authentication headers always match the live API. Public market-data routes can be called without authentication. Account, order, withdrawal, and margin routes require a wallet-authorized ed25519 session key.Authentication Flow
Monaco authenticates with a wallet-authorized ed25519 session key. The wallet signs once to authorize a session key; every authenticated request is then signed with that key.- Generate a session key -> create an ed25519 keypair locally.
- Create challenge -> request a nonce, passing the session public key.
- Sign message -> sign the challenge message with the wallet.
- Verify signature -> Monaco registers the session public key and opens a session.
- Sign requests -> sign each subsequent request with the session private key.
Authenticating Requests
Every authenticated request is signed with the session private key. Two protocols are accepted over the same key: the legacyX-Monaco-* headers below, and opt-in RFC 9421 HTTP message signatures. Send one or the other: a request carrying Signature or Signature-Input alongside any X-Monaco-* header is rejected with 401. Content-Digest is not a credential and may accompany a legacy-signed request on its own.
For legacy signing, set three headers:
The signing string is built from the request:
METHOD— uppercase HTTP method, such asGETorPOST.path?query— request path including query string, exactly as sent.timestamp_ms— the same value sent inX-Monaco-Timestamp.SHA256_hex(body)— hex SHA-256 of the raw request body, or of the empty byte string when there is no body.
Signature-Input, Signature, and Content-Digest instead. Monaco verifies a bounded profile — the label monaco, the components @method, @path, @query, content-digest in that order, created in Unix seconds within 30 seconds of server time, and alg="ed25519" — and never falls back to legacy verification when it fails. The HTTP message signatures reference has the complete profile and signature base.
Because the body hash is signed, a captured request cannot be reused with a modified body, and the timestamp bounds how long it remains valid. Freshness is an anti-stale control, not an anti-replay one: an identical signed request can be accepted again inside the window, and Monaco keeps no nonce or replay cache. Where an endpoint takes an idempotencyKey — order creation and batch creation do — treat it as required rather than optional on any retry, and reuse the original key and payload. An endpoint without one carries no exactly-once guarantee, so do not blindly retry a write against it. SDKs handle signing automatically. Use direct REST only when you need a custom client.
Network Configuration
The API base URL determines which network you’re targeting. Network configuration (vault contract, chain settings) is handled server-side for security.- Staging (Testnet):
https://staging.apimonaco.xyz- Sei Testnet (chain ID 1328)
Enum Value Formats
Monaco API uses consistent uppercase formatting for all enum values. Use these exact values in your requests:Market Types & Trading Modes
SPOT- Spot trading (uppercase)
Order Types
LIMIT- Limit order (uppercase)MARKET- Market order (uppercase)
Order Sides
BUY- Buy order (uppercase)SELL- Sell order (uppercase)
Order Status
SUBMITTED- Order submitted to matching enginePARTIALLY_FILLED- Partially executedFILLED- Fully executed (match complete, pending settlement)SETTLED- Settlement initiatedSETTLED_ON_CHAIN- Fully settled on-chain (terminal state)CANCELLED- Order cancelledEXPIRED- Order expired (GTC orders expire after 90 days by default)REJECTED- Order rejected
Authentication Endpoints
1. Create Authentication Challenge
Creates a unique challenge that must be signed by the user’s wallet.address(string, required) - User’s Ethereum wallet addressclientId(string, optional) - Your application’s public client IDsessionPublicKey(string, required) - 64-char lowercase-hex ed25519 session public key generated locally. The returnedmessageembeds this key so the wallet signature authorizes it.
nonce(string) - Unique challenge identifiermessage(string) - Message to sign with walletexpiresAt(number) - Challenge expiration timestamp (Unix)
2. Verify Signature
Verifies the signed challenge, registers the session public key, and opens a session.address(string, required) - Ethereum wallet address that signed the messagesignature(string, required) - Hex-encoded signature from walletnonce(string, required) - Nonce from the challenge requestclientId(string, optional) - Your application’s public client IDsessionPublicKey(string, required) - Same 64-char hex session public key sent to/auth/challenge; the server binds it to the new session
expiresAt(number) - Session expiration timestamp (Unix)user(object) - Authenticated user information (id, address, username)
sessionPublicKey — see Authenticating Requests.
3. Refresh Session
Extends the current session’s expiry. The request carries no body and is authenticated with the standard signing headers.4. Revoke Session
Revokes the current session. The request carries no body and is authenticated with the standard signing headers. The user will need to authenticate again.Account Endpoints
All account endpoints require a signed request — see Authenticating Requests.5. Get User Profile
Retrieves the current user’s core profile metadata. Does not include balances, movements, or orders — use the dedicated endpoints for those.id(string) - User unique identifieraddress(string) - User wallet addressusername(string, optional) - User’s display nameaccountType(string) - Account type: “master” or “sub”canWithdraw(boolean) - Whether user can withdrawcreatedAt(string) - Account creation timestamp (ISO 8601, UTC)
6. Get User Balances
Retrieves the current user’s token balances with pagination support.page(number, optional) - Page number, starts from 1 (default: 1)pageSize(number, optional) - Items per page, max 100 (default: 20)
assetId(string) - Asset UUIDtoken(string) - Token contract addresssymbol(string | null) - Token symbol (if available)decimals(number) - Token decimalsavailableBalance(string) - Available balance for trading (normalized)lockedBalance(string) - Balance locked in open orders (normalized)totalBalance(string) - Total balance (available + locked)availableBalanceRaw(string) - Available balance in raw format (smallest unit)lockedBalanceRaw(string) - Locked balance in raw format (smallest unit)
7. Get User Balance by Asset
Retrieves the current user’s balance for a specific asset. Returns zero balances if the user has no balance for a valid asset.assetId(string) - Asset UUID (get from trading pair’sbaseAssetIdorquoteAssetId)
401 Unauthorized- Authentication required404 Not Found- Asset not found
8. Get User Movements
Retrieves the current user’s ledger movements (transaction history) with pagination and filtering support.page(number, optional) - Page number, starts from 1 (default: 1)pageSize(number, optional) - Items per page, max 100 (default: 20)entryType(string, optional) - Filter by entry typetransactionType(string, optional) - Filter by transaction typeassetId(UUID, optional) - Filter by asset ID
entryType(string) - Entry typetransactionType(string) - Transaction type
9. List Sub-Accounts with Balances
Lists all sub-accounts with their token balances for a master account.401 Unauthorized- Authentication required403 Forbidden- Only master accounts can view sub-accounts
Sub-Account Limits Endpoints
Endpoints for managing trading limits on sub-accounts. Only master accounts can manage limits for their sub-accounts.10. Create Sub-Account Limit
Creates a new limit for a sub-account.subAccountId(string, required) - Sub-account UUIDassetId(string, required) - Asset UUID (get from trading pair’sbaseAssetIdorquoteAssetId)maxAmount(string, required) - Maximum amount allowed for the sub-accountdailyLimit(string, optional) - Daily limit amount
token(string) - Token contract address (resolved from assetId)maxAmount(string) - Maximum amount alloweddailyLimit(string, optional) - Daily limit amountusedToday(string) - Amount used todaylastResetAt(string, optional) - Last daily reset timestamp
400 Bad Request- Invalid request or limit already exists403 Forbidden- Only master accounts can set sub-account limits404 Not Found- Sub-account relationship not found or asset not found
11. Get Sub-Account Limits
Gets all limits for a sub-account.subAccountId(string) - Sub-account UUID
12. Update Sub-Account Limit
Updates an existing limit for a sub-account.subAccountId(string) - Sub-account UUIDassetId(string) - Asset UUID (get from trading pair’sbaseAssetIdorquoteAssetId)
13. Delete Sub-Account Limit
Deletes a limit for a sub-account.subAccountId(string) - Sub-account UUIDassetId(string) - Asset UUID (get from trading pair’sbaseAssetIdorquoteAssetId)
Application Configuration Endpoint
14. Get Application Configuration
Returns the configuration for the authenticated application.Application Backend Endpoints
These endpoints are for backend services only and require yoursk_ secret key in the x-server-key header. Pass the key directly — no token exchange needed. To get your secret key, email [email protected].
Backend Authentication Header
All backend endpoints require the server key header:15. List Application Users (Backend Only)
Returns a paginated list of all users for this application.page(number, optional) - Page number, starts from 1pageSize(number, optional) - Items per page, max 100isActive(boolean, optional) - Filter by active statusaccountType(string, optional) - Filter by account type: “master” or “sub”address(string, optional) - Filter by wallet address (partial match)
16. List Application Balances (Backend Only)
Returns a paginated list of all user balances for this application.page(number, optional) - Page number, starts from 1pageSize(number, optional) - Items per page, max 100userId(string, optional) - Filter by user IDtoken(string, optional) - Filter by token address
17. List Application Orders (Backend Only)
Returns a paginated list of all orders for this application.page(number, optional) - Page number, starts from 1; at most 10,000, the last page the listing counts towardspageSize(number, optional) - Items per page, max 100status(string, optional) - Filter by order statustradingPairId(string, optional) - Filter by trading pair UUIDuserId(string, optional) - Filter by user IDside(string, optional) - Filter by order side: “BUY” or “SELL”orderType(string, optional) - Filter by order type: “LIMIT” or “MARKET”
total and totalPages are exact up to 10,000 pages of the requested pageSize and saturate there (the last page the listing can reach), so an application with more matching orders than that reads the cap rather than its lifetime total.
18. List Application Movements (Backend Only)
Returns a paginated list of all ledger movements (deposits, withdrawals, trades, etc.) for this application.page(number, optional) - Page number, starts from 1; at most 10,000, the last page the listing counts towardspageSize(number, optional) - Items per page, max 100userId(string, optional) - Filter by user IDentryType(string, optional) - Filter by entry typetransactionType(string, optional) - Filter by transaction typetoken(string, optional) - Filter by token address
total and totalPages are exact up to 10,000 pages of the requested pageSize and saturate there (the last page the listing can reach), so an application with more matching movements than that reads the cap rather than its lifetime total.
19. Get Application Stats (Backend Only)
Returns aggregate volume and fee stats for this application. Stats are scoped to trades where the application’s users were the taker.since(string, optional) - Only include trades at or after this timestamp (ISO 8601)
volume(string) - Total quote volume (normalized) for trades where this application’s users were the takermakerFee(string) - Total maker fees collected (normalized, quote token units)takerFee(string) - Total taker fees collected (normalized, quote token units)applicationTakerFee(string) - Application revenue share from taker fees (normalized, quote token units)tradeCount(number) - Total number of trades
Withdrawal Endpoint
20. Initiate Withdrawal
Allocates a withdrawal and returns ready-to-submit vault calldata. The server signs the withdrawal with itsWITHDRAWAL_SIGNER; you submit the returned calldata to the vault contract (tx.data) to move funds on-chain — no further server-side signing is needed. Requires the Withdraw permission on the session.
assetId(string, required) - Asset UUID to withdraw (get from a trading pair’sbaseAssetIdorquoteAssetId)amount(string, required) - Raw token amount in the smallest unit as an integer string (e.g.,"100500000"for 100.5 USDC with 6 decimals). Multiply the human-readable amount by 10**decimals.destination(string, required) -0x-prefixed 20-byte address that will receive the withdrawal
withdrawalIndex(number) - Allocated withdrawal index; matchesexecuteSignedWithdrawal.indexon-chainvaultAddress(string) -0x-prefixed lowercase vault contract address to send the calldata to (returned so you don’t have to query/applications/configseparately)calldata(string) -0x-prefixed ABI-encoded calldata forexecuteSignedWithdrawal(...), already signed by the server. Submit it astx.datatovaultAddress.
Look Up a Withdrawal
Fetch a previously-allocated withdrawal by index. Public lookup — no authentication required. Returns the same shape as the initiate response.Fee Simulation Endpoint
21. Simulate Order Fees
Simulates the fees for an order before placing it. Useful for displaying accurate fee estimates to users.tradingPairId(string, required) - Trading pair UUIDside(string, required) - Order side: “BUY” or “SELL”price(string, required) - Price per unitquantity(string, required) - Quantity to trade
notional(string) - Total trade value (price × quantity)monacoTakerFee(string) - Monaco protocol taker feemonacoMakerRebate(string) - Monaco protocol maker rebate (negative = rebate)applicationTakerFee(string) - Application-specific taker feetotalTakerFees(string) - Total fees for taker orders (monaco + application)takerTotalPayment(string) - Total amount taker pays (notional + fees)makerTotalReceipt(string) - Total amount maker receives (notional + rebate)buyOrderLockAmount(string, optional) - Amount to lock for BUY orders (null for SELL)monacoTakerFeeBpsExact(string) - Tier-resolved Monaco taker rate as a decimal bps string (e.g."6.5") — the exact rate the ledger charges this caller, equal tomonacoTakerFee / notionalmonacoMakerRebateBpsExact(string) - Tier-resolved Monaco maker rebate as a decimal bps string (negative = rebate, e.g."-1")monacoTakerFeeBps(number) - Deprecated. Whole-bps taker rate; an integer cannot carry fractional tiered rates, so it echoes the flat trading-pair column. UsemonacoTakerFeeBpsExactorGET /api/v1/fees/tiermonacoMakerRebateBps(number) - Deprecated. Whole-bps maker rebate; same integer limitation. UsemonacoMakerRebateBpsExactorGET /api/v1/fees/tierapplicationTakerFeeBps(number) - Application fee rate in basis pointsapplicationName(string, optional) - Application name
Trading Endpoints
All trading endpoints require a signed request — see Authenticating Requests.22. Place Order
Creates a new limit or market order on the exchange. This endpoint handles both order types based on theorderType field.
expirationDate is an optional field for limit orders (default: 90 days for GTC orders).
Request Body (Market Order):
slippageToleranceBps is optional and only tightens that band (e.g., 100 = 1%); it cannot widen it. A market order may partially fill and cancel the remainder, or be rejected when no liquidity sits inside the band.
Response:
tradingPairId(string, required) - Trading pair UUID (get from/api/v1/market/pairs)orderType(string, required) - “LIMIT” or “MARKET”side(string, required) - “BUY” or “SELL”quantity(string, required) - Order quantity as decimal stringprice(string, optional) - Order price (required for LIMIT orders, ignored for MARKET)tradingMode(string, optional) - Trading mode: “SPOT” (default) or “MARGIN”timeInForce(string, optional) - “GTC” (default), “IOC”, or “FOK”expirationDate(string, optional) - Custom expiration in ISO 8601 format (default: 90 days for GTC)slippageToleranceBps(number, optional) - For market orders: tightens the mandatory 1,000 bps price band, in basis points (e.g., 100 = 1%). Cannot widen the banduseMasterBalance(boolean, optional) - For sub-accounts: use master account’s balance
orderId(string) - Unique order identifier (UUID)status(string) - “SUCCESS” or “FAILED”message(string) - Operation messagematchResult(object, optional) - Immediate execution results if order matched:tradesCount(number) - Number of trades executedtotalFilled(string) - Total quantity filledremainingQuantity(string) - Remaining unfilled quantityaverageFillPrice(string, optional) - Average fill price across all tradesstatus(string) - Order status after matching (e.g., “SUBMITTED”, “PARTIALLY_FILLED”, “FILLED”)actualSlippageBps(number, optional) - Actual slippage in basis points (positive = worse price)maxSlippageBps(number, optional) - Maximum slippage allowed when order was submittedexecutionPriceRange(object, optional) - Price range:bestPrice,worstPrice
23. Cancel Order
Cancels an existing open order by its ID.orderId(string) - ID of the order to cancel
orderId(string) - ID of the cancelled orderstatus(string) - “SUCCESS” or “FAILED”message(string) - Response message
400 Bad Request- Invalid order ID, order already filled/cancelled/expired, or order not found401 Unauthorized- Authentication required or order doesn’t belong to user500 Internal Server Error- Server error during cancellation
24. Batch Cancel Orders
Cancels multiple orders in a single request (best-effort per order). Supports canceling specific orders or all active orders for the user.cancel_all(boolean, optional) - If true, cancels all active orders for the user (ignoresorderIdsin body). Default: false
success(boolean) - True if all orders cancelled successfullytotalRequested(number) - Number of orders requested to canceltotalCancelled(number) - Number successfully cancelledtotalFailed(number) - Number that failed to cancelresults(array) - Per-order results:orderId(string) - Order IDsuccess(boolean) - Whether this specific order was cancelledcancelledAt(string, optional) - Cancellation timestamp (ISO 8601, UTC)error(object, optional) - Error details if failed (code, message)
400 Bad Request- No order IDs provided when cancel_all is false, or invalid order IDs401 Unauthorized- Authentication required500 Internal Server Error- Server error during cancellation
25. Replace Order
Replaces an existing order by canceling it and creating a new order atomically. Returns a new order ID.price(string, optional) - New order price (omit to keep original price)quantity(string, optional) - New order quantity (omit to keep remaining quantity)
orderId(string) - New order ID after replacementstatus(string) - “SUCCESS” or “FAILED”message(string) - Operation messageupdatedFields(object) - Fields that were updatedoriginalOrderId(string) - Original order ID that was replacedmatchResult(object, nullable) - Match result if order executed immediately
26. Get Orders
Retrieves a paginated list of orders for the authenticated user with optional filtering. Every kind of order comes back in one stream sorted by timestamp — book orders, TWAP parents and conditional orders — so there is no separate open-orders endpoint: filterstatus to SUBMITTED,PARTIALLY_FILLED for the working set across all three kinds. orderType names each row’s kind, and a TWAP parent or conditional order carries its full detail under twap or conditional respectively.
page(number, optional) - Page number, starts from 1 (default: 1)pageSize(number, optional) - Items per page (default: 20); max 100 in page-number mode, up to 1000 whenpageTokenis presentstatus(string, optional) - Filter by order status. Supports comma-separated list for multiple statuses (e.g., “FILLED,PARTIALLY_FILLED”). Valid values: “SUBMITTED”, “PARTIALLY_FILLED”, “FILLED”, “SETTLED”, “CANCELLED”, “EXPIRED”, “REJECTED”tradingPairId(string, optional) - Filter by trading pair UUIDpageToken(string, optional) - Cursor for cursor-mode pagination, which merges hot and archived rows. Send an empty string to start a walk over full history, then send each response’snextPageTokento continue; the walk is exhausted when a page returns no rows and an emptynextPageToken. Cursor mode ignorespage(it comes back as0), buttotal/totalPagesARE populated — bounded by a server count ceiling (exact up to it, then reported as the ceiling withtotalCapped: true; see the response below)
id(string) - Order unique identifier (UUID)tradingPairId(string) - Trading pair ID (UUID)orderType(string) - What kind of order this row is: “LIMIT” or “MARKET” for a book order, “TWAP” for a TWAP parent, “CONDITIONAL” for a price-triggered order. “TWAP” and “CONDITIONAL” appear only in responses — order creation still takes “LIMIT” or “MARKET”twap(object, optional) - Present only whenorderTypeis “TWAP”: the full TWAP parent, identical to whatGET /api/v1/orders/twap/{twapOrderId}returnsconditional(object, optional) - Present only whenorderTypeis “CONDITIONAL”: the full conditional order, identical to what the conditional-order endpoints returnconditionalOrderId(string, optional) - Present only on an order the engine placed for a take-profit or stop-loss trigger: the conditional order that fired it. Absent on orders the client placed, on TWAP slice children, and on triggered closes written before the field existed (there is no backfill). Served by this endpoint andGET /api/v1/orders/{orderId}; no WebSocket frame carries itside(string) - “BUY” or “SELL”price(string, optional) - Order price (null for market orders)quantity(string) - Order quantityfilledQuantity(string) - Quantity filled so faraverageFillPrice(string, optional) - Average fill price (null if not filled yet)status(string) - Order status (see Order Status enum)tradingMode(string) - “SPOT” or “MARGIN”timeInForce(string, optional) - “GTC”, “IOC”, or “FOK”createdAt(string) - Order creation timestamp (ISO 8601, UTC)updatedAt(string, optional) - Last update timestamp (ISO 8601, UTC)expirationDate(string, optional) - Order expiration dateapplicationTakerFee(string, optional) - Application taker fee amountmonacoTakerFee(string, optional) - Monaco protocol taker fee amountmonacoMakerRebate(string, optional) - Monaco protocol maker rebate amounttotalTakerFees(string, optional) - Total taker fees (monaco + application)takerTotalPayment(string, optional) - Total amount taker paidmakerTotalReceipt(string, optional) - Total amount maker received
27. Get Order by ID
Retrieves detailed information about a specific order by its ID.orderId(string) - Order UUID
401 Unauthorized- Authentication required403 Forbidden- Order doesn’t belong to user404 Not Found- Order not found
Market Data Endpoints
Public endpoints for accessing trading pairs and market data. Authentication is not required.28. Get Trading Pairs
Retrieves a paginated list of all available trading pairs with optional filtering.page(number, optional) - Page number, starts from 1 (default: 1)pageSize(number, optional) - Items per page, max 100 (default: 20)marketType(string, optional) - Filter by market type: “SPOT”baseToken(string, optional) - Filter by base token symbol (e.g., “ETH”)quoteToken(string, optional) - Filter by quote token symbol (e.g., “USD”)isActive(boolean, optional) - Filter by active status. An operator-managed market is public only while its launch’s durable runtime projection readslive— not merely its launch phase — so a pending, warming or halted managed launch is hidden andisActive=falsedoes not surface it. A pair with no managed launch keeps its ordinary visibility.
id(string) - Trading pair UUID (use astradingPairIdin order requests)symbol(string) - Trading pair symbol (e.g., “ETH/USDC”)baseToken(string) - Base token symbolbaseAssetName(string) - Human-readable base asset display name (e.g., “Robinhood Markets” for HOOD) — useful for matching markets by company/asset name in searchquoteToken(string) - Quote token symbolquoteAssetName(string) - Human-readable quote asset display namebaseTokenContract(string) - Base token contract addressquoteTokenContract(string) - Quote token contract addressbaseAssetId(string) - Base asset UUID (use for withdrawal requests)quoteAssetId(string) - Quote asset UUID (use for withdrawal requests)baseDecimals(number) - Base token decimalsquoteDecimals(number) - Quote token decimalsbaseIconUrl(string) - Base token icon URLquoteIconUrl(string) - Quote token icon URLminOrderSize(string) - Minimum order sizemaxOrderSize(string) - Maximum order sizetickSize(string) - Minimum price incrementmakerFeeBps(number) - Deprecated. Flat pair-level maker fee in basis points (negative = rebate); this is not the per-user tiered rate. UseGET /api/v1/fees/tierfor the caller’s real ratetakerFeeBps(number) - Deprecated. Flat pair-level taker fee in basis points; this is not the per-user tiered rate. UseGET /api/v1/fees/tierfor the caller’s real ratemarketType(string) - “SPOT” or “MARGIN”isActive(boolean) - Whether pair is active for trading
29. Get Trading Pair by ID
Retrieves detailed information about a specific trading pair by its UUID.tradingPairId(string) - Trading pair UUID (e.g., “123e4567-e89b-12d3-a456-426614174000”)
404 Not Found- Trading pair not found
30. Get Market Metadata
Retrieves current price, 24-hour statistics, and market information for a trading pair.tradingPairId(string) - Trading pair UUID
symbol(string) - Trading pair symbol (e.g., “BTC/USDC”)baseIconUrl(string) - Base token icon URLquoteIconUrl(string) - Quote token icon URLlastPrice(string, optional) - Current price from latest candle (null if no data)lastPriceTimestamp(number, optional) - Timestamp of last price in milliseconds (null if no data)high24h(string, optional) - 24-hour high price (null if less than 24h of data)low24h(string, optional) - 24-hour low price (null if less than 24h of data)volume24h(string, optional) - 24-hour trading volume in base asset (null if less than 24h of data)quoteVolume24h(string, optional) - 24-hour trading volume in quote token / USDC (null if less than 24h of data)priceChange24h(string, optional) - Price change in last 24 hours (null if less than 24h of data)priceChangePercent24h(string, optional) - Percentage change in last 24 hours (null if less than 24h of data)marketInitializationTimestamp(number, optional) - Timestamp when market first started trading (first candle)
404 Not Found- Trading pair not found or inactive500 Internal Server Error- Failed to fetch market data
31. Get Historical Candlestick Data
Retrieves historical OHLCV (Open, High, Low, Close, Volume) candlestick data for a trading pair.tradingPairId(string) - Trading pair UUID (get from/api/v1/market/pairs)interval(string) - Candlestick interval: “1m”, “5m”, “15m”, “1h”, “4h”, or “1d”
startTime(number, optional) - Start timestamp in Unix milliseconds (for forward pagination)endTime(number, optional) - End timestamp in Unix milliseconds (for backward pagination)limit(number, optional) - Maximum candlesticks to return (default: 350, max: 500)
T(number) - Candle start timestamp (Unix milliseconds)t(number) - Candle end timestamp (Unix milliseconds)o(string) - Open priceh(string) - High pricel(string) - Low pricec(string) - Close pricev(string) - Volume (base token)s(string) - Symboli(string) - Intervaln(number) - Number of trades in this candle
1m- 1 minute5m- 5 minutes15m- 15 minutes1h- 1 hour4h- 4 hours1d- 1 day
400 Bad Request- Invalid interval or time range404 Not Found- Trading pair not found or inactive
Orderbook Endpoints
32. Get Orderbook Snapshot
Gets the complete orderbook snapshot for a trading pair showing all bids and asks with their price levels. This is a public endpoint that does not require authentication.tradingPairId(string) - Trading pair UUID
levels(number, optional) - Number of price levels to return, max 100 (default: all levels)tradingMode(string, optional) - Trading mode: “Spot” or “Margin” (default: “Spot”)magnitude(string, optional) - Price grouping magnitude for aggregation. Valid values: “0.0001”, “0.001”, “0.01”, “0.1”, “1”, “10”, “100”, “1000”, “10000”. If not specified, returns ungrouped levelsdenomination(string, optional) - Quantity denomination: “base” (default) or “quote”. When “quote”, quantities are multiplied by price
eventType(string) - Event type (“orderbook_snapshot” for HTTP)tradingPairId(string) - Trading pair UUIDpair(string) - Trading pair symbol (e.g., “BTC/USDC”)tradingMode(string) - “Spot” or “Margin”timestamp(string) - Snapshot timestamp (ISO 8601, UTC)sequenceNumber(number) - Sequence number for ordering updatesbaseToken(string) - Base token symbolquoteToken(string) - Quote token symbolbaseDecimals(number) - Base token decimalsquoteDecimals(number) - Quote token decimalsdata(object) - Orderbook data:bids(array) - Buy orders sorted by price (highest first)asks(array) - Sell orders sorted by price (lowest first)bestBid(string) - Current best bid pricebestAsk(string) - Current best ask pricebidVolume(string) - Total bid volumeaskVolume(string) - Total ask volumepriceChange(object, optional) - Price change information
400 Bad Request- Invalid magnitude or denomination value404 Not Found- Trading pair not found500 Internal Server Error- Matching engine not initialized
Delegated Agents Endpoints
Delegated agents let a master account authorize an external agent wallet to trade on its behalf under a fine-grained policy. The owner registers an agent and policy; the agent then authenticates with its own session key and exchanges it for an owner-scoped delegated session. The management endpoints require a signed request — see Authenticating Requests.33. Upsert Delegated Agent
Registers or updates a delegated agent. Master accounts only. The delegation is keyed onagentAddress, so calling again with the same address updates the existing delegation and its policy.
agentAddress(string, required) - Agent wallet address (EVM, 42 chars including0x)name(string, optional) - Human-friendly label for the agentexpiresAt(string, optional) - Delegation expiry timestamp (ISO 8601). Omit for no expiryallowedActions(array, optional) - Actions the agent may perform:CREATE_ORDER,CANCEL_ORDER,REPLACE_ORDERallowedTradingPairIds(array, optional) - Trading pair UUIDs the agent may trade. An order is allowed if its market or its margin account is permittedallowedMarginAccountIds(array, optional) - Margin account UUIDs the agent may trade against. An order is allowed if its market or its margin account is permittedallowedOrderTypes(array, optional) - Permitted order types (LIMIT,MARKET). Empty means unrestrictedallowedTimeInForce(array, optional) - Permitted time-in-force values (GTC,IOC,FOK). Empty means unrestrictedmaxLeverage(string, optional) - Maximum leverage the agent may use (decimal string). Omit for no limitmaxOrderNotional(string, optional) - Maximum order notional (price × quantity, decimal string). Omit for no limitmaxOpenOrders(number, optional) - Maximum concurrent open orders. Omit for no limit
id(string) - Delegation UUIDownerUserId(string) - Owner account UUID the agent acts on behalf ofagentAddress(string) - Agent wallet address (EVM)name(string, optional) - Human-friendly label for the agentisActive(boolean) - Whether the delegation is activeexpiresAt(string, optional) - Delegation expiry timestamp (ISO 8601), if setrevokedAt(string, optional) - Revocation timestamp (ISO 8601), if revokedallowedActions,allowedTradingPairIds,allowedMarginAccountIds,allowedOrderTypes,allowedTimeInForce(arrays) - The policy as storedmaxLeverage,maxOrderNotional(string, optional) /maxOpenOrders(number, optional) - Policy limits, if set
401 Unauthorized- Authentication required403 Forbidden- Only master accounts can manage delegated agents
34. List Delegated Agents
Lists every agent the calling account owns, each with its policy. Master accounts only.agents(array) - The calling owner’s delegated agents (each object as in Upsert Delegated Agent)
401 Unauthorized- Authentication required403 Forbidden- Only master accounts can list delegated agents
35. List Delegating Owners
Reverse lookup keyed on the caller’s own wallet address: an agent that has authenticated with its own session key discovers which owners it may act on behalf of, and theownerUserId to pass to Create Delegated Session. Returns only active (non-revoked, non-expired) delegations.
owners(array) - Owners that have an active delegation to the calling agent:ownerUserId(string) - Owner account UUID to pass to Create Delegated SessiondelegationId(string) - Delegation UUID for the (owner, agent) pairname(string, optional) - Human-friendly label the owner gave this agent, if anyisActive(boolean) - Whether the delegation is activeexpiresAt(string, optional) - Delegation expiry timestamp (ISO 8601), if set
401 Unauthorized- Authentication required
36. Revoke Delegated Agent
Revokes the delegation identified bydelegatedAgentId. Master accounts only. Existing delegated sessions are not invalidated; only future session creation is blocked.
delegatedAgentId(string) - Delegation UUID to revoke
400 Bad Request- InvaliddelegatedAgentId401 Unauthorized- Authentication required403 Forbidden- Only master accounts can revoke delegated agents404 Not Found- Delegated agent not found
37. Create Delegated Session
Exchanges the agent’s own session for an owner-scoped delegated session. The agent authenticates with its own session key, then calls this with theownerUserId it wants to act for (discover it via List Delegating Owners) and a freshly generated session public key. The new session acts as the owner but records the agent’s address for policy enforcement. Requires an active delegation for the (owner, agent) pair.
ownerUserId(string, required) - Owner account UUID to act on behalf of (discover via List Delegating Owners)sessionPublicKey(string, required) - 64-char lowercase-hex ed25519 public key the agent generated for this delegated session. Subsequent requests acting on the owner’s behalf are signed with the matching private key
expiresAt(number) - Session expiry as a Unix timestamp (seconds)delegationId(string) - Delegation UUID for the active (owner, agent) pairownerUserId(string) - Owner account UUID the session acts on behalf ofagentAddress(string) - Agent wallet address recorded on the session for policy enforcement
400 Bad Request- Invalid request401 Unauthorized- Authentication required403 Forbidden- No active delegation for owner
Error Handling
All endpoints return standard HTTP status codes:- 200 - Success
- 400 - Bad Request (invalid parameters)
- 401 - Unauthorized (missing, invalid, or expired session signature)
- 403 - Forbidden (authenticated, but not allowed to access the resource)
- 500 - Internal Server Error
code (for example POST_ONLY_WOULD_CROSS for a post-only order that would cross the book). The field is omitted entirely when no engine code applies — match on code when present instead of parsing message:
Handling Session Expiry (401 Errors)
When a session expires or is revoked, authenticated endpoints return401 Unauthorized. Re-run the challenge/verify flow to start a new session. A clock more than 30 seconds out of sync with the server also produces 401 — keep the request timestamp accurate. The TypeScript SDK corrects for this itself, from each response’s Date header; a raw client should do the same or keep its clock synced.
Code Examples
cURL
Complete Authentication Flow:JavaScript (Node.js)
Getting Credentials
Frontend Applications
Contact the Monaco Protocol team to obtain yourclientId for frontend authentication.
Backend Services
Contact the Monaco Protocol team to obtain yoursecretKey for backend authentication.
Migration from SDK
If you’re migrating from the TypeScript SDK, note these key differences:- Field Names: API uses
snake_case(e.g.,clientId) while SDK usescamelCase(e.g.,clientId) - Manual Request Signing: You must generate a session keypair and sign every request with it (no token to store)
- Wallet Signing: You must implement wallet message signing separately
- Error Handling: Parse HTTP status codes instead of SDK error classes
Withdrawal Usage Examples
These examples assume theMonacoAPI class above (with signedHeaders()) and an authenticated api whose api.session is set. The session must hold the Withdraw permission.
Deposits are on-chain: send tokens directly to the vault contract and the indexer credits your balance — there is no deposit API. Withdrawals go through the API below, which returns signed vault calldata for you to submit on-chain.
JavaScript Example
Trading Usage Examples
JavaScript Example
Security Considerations
- Store Secret Keys Securely - Never expose backend secret keys in client-side code
- Handle Session Expiry - Detect
401responses and re-run the challenge/verify flow - Validate Responses - Always validate API responses before using data
- Use HTTPS - All API requests must use HTTPS in production
- Revoke Sessions - Implement logout by calling
POST /api/v1/auth/revoke, and never persist the session private key insecurely

