Skip to main content
Use the REST API when you want direct HTTP/JSON access from backends, scripts, custom clients, mobile apps, or API tooling. SDKs are available when you want Monaco auth, signing, and request formatting handled for you.
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-empty User-Agent header. Requests that send an empty or absent User-Agent are rejected at the edge with 403 Forbidden before reaching the API.
Official SDKs set a User-Agent automatically. Direct HTTP clients — curl, shell scripts, and generated or custom clients — must set one explicitly, or requests will be rejected.

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.
  1. Generate a session key -> create an ed25519 keypair locally.
  2. Create challenge -> request a nonce, passing the session public key.
  3. Sign message -> sign the challenge message with the wallet.
  4. Verify signature -> Monaco registers the session public key and opens a session.
  5. Sign requests -> sign each subsequent request with the session private key.
There are no access or refresh tokens.

Authenticating Requests

Every authenticated request is signed with the session private key. Two protocols are accepted over the same key: the legacy X-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 as GET or POST.
  • path?query — request path including query string, exactly as sent.
  • timestamp_ms — the same value sent in X-Monaco-Timestamp.
  • SHA256_hex(body) — hex SHA-256 of the raw request body, or of the empty byte string when there is no body.
For RFC 9421 signing, send 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 engine
  • PARTIALLY_FILLED - Partially executed
  • FILLED - Fully executed (match complete, pending settlement)
  • SETTLED - Settlement initiated
  • SETTLED_ON_CHAIN - Fully settled on-chain (terminal state)
  • CANCELLED - Order cancelled
  • EXPIRED - Order expired (GTC orders expire after 90 days by default)
  • REJECTED - Order rejected
Note: All enum values use uppercase format with underscores for consistency across the API.

Authentication Endpoints

1. Create Authentication Challenge

Creates a unique challenge that must be signed by the user’s wallet.
Request Body:
Response:
Request Fields:
  • address (string, required) - User’s Ethereum wallet address
  • clientId (string, optional) - Your application’s public client ID
  • sessionPublicKey (string, required) - 64-char lowercase-hex ed25519 session public key generated locally. The returned message embeds this key so the wallet signature authorizes it.
Response Fields:
  • nonce (string) - Unique challenge identifier
  • message (string) - Message to sign with wallet
  • expiresAt (number) - Challenge expiration timestamp (Unix)

2. Verify Signature

Verifies the signed challenge, registers the session public key, and opens a session.
Request Body:
Response:
Request Fields:
  • address (string, required) - Ethereum wallet address that signed the message
  • signature (string, required) - Hex-encoded signature from wallet
  • nonce (string, required) - Nonce from the challenge request
  • clientId (string, optional) - Your application’s public client ID
  • sessionPublicKey (string, required) - Same 64-char hex session public key sent to /auth/challenge; the server binds it to the new session
Response Fields:
  • expiresAt (number) - Session expiration timestamp (Unix)
  • user (object) - Authenticated user information (id, address, username)
No tokens are returned. Sign subsequent requests with the session private key matching 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.
Headers:
Response:

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.
Headers:
Response:
Note: This endpoint revokes the session identified by the signing key on the request.

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.
Headers:
Response:
Fields:
  • id (string) - User unique identifier
  • address (string) - User wallet address
  • username (string, optional) - User’s display name
  • accountType (string) - Account type: “master” or “sub”
  • canWithdraw (boolean) - Whether user can withdraw
  • createdAt (string) - Account creation timestamp (ISO 8601, UTC)

6. Get User Balances

Retrieves the current user’s token balances with pagination support.
Headers:
Query Parameters:
  • page (number, optional) - Page number, starts from 1 (default: 1)
  • pageSize (number, optional) - Items per page, max 100 (default: 20)
Response:
Balance Fields:
  • assetId (string) - Asset UUID
  • token (string) - Token contract address
  • symbol (string | null) - Token symbol (if available)
  • decimals (number) - Token decimals
  • availableBalance (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.
Headers:
Path Parameters:
  • assetId (string) - Asset UUID (get from trading pair’s baseAssetId or quoteAssetId)
Response:
Error Responses:
  • 401 Unauthorized - Authentication required
  • 404 Not Found - Asset not found

8. Get User Movements

Retrieves the current user’s ledger movements (transaction history) with pagination and filtering support.
Headers:
Query Parameters:
  • 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 type
  • transactionType (string, optional) - Filter by transaction type
  • assetId (UUID, optional) - Filter by asset ID
Response:
Movement Fields:
  • entryType (string) - Entry type
  • transactionType (string) - Transaction type

9. List Sub-Accounts with Balances

Lists all sub-accounts with their token balances for a master account.
Headers:
Response:
Error Responses:
  • 401 Unauthorized - Authentication required
  • 403 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.
Headers:
Request Body:
Request Fields:
  • subAccountId (string, required) - Sub-account UUID
  • assetId (string, required) - Asset UUID (get from trading pair’s baseAssetId or quoteAssetId)
  • maxAmount (string, required) - Maximum amount allowed for the sub-account
  • dailyLimit (string, optional) - Daily limit amount
Response:
Response Fields:
  • token (string) - Token contract address (resolved from assetId)
  • maxAmount (string) - Maximum amount allowed
  • dailyLimit (string, optional) - Daily limit amount
  • usedToday (string) - Amount used today
  • lastResetAt (string, optional) - Last daily reset timestamp
Error Responses:
  • 400 Bad Request - Invalid request or limit already exists
  • 403 Forbidden - Only master accounts can set sub-account limits
  • 404 Not Found - Sub-account relationship not found or asset not found

11. Get Sub-Account Limits

Gets all limits for a sub-account.
Headers:
Path Parameters:
  • subAccountId (string) - Sub-account UUID
Response:

12. Update Sub-Account Limit

Updates an existing limit for a sub-account.
Headers:
Path Parameters:
  • subAccountId (string) - Sub-account UUID
  • assetId (string) - Asset UUID (get from trading pair’s baseAssetId or quoteAssetId)
Request Body:
Response:

13. Delete Sub-Account Limit

Deletes a limit for a sub-account.
Headers:
Path Parameters:
  • subAccountId (string) - Sub-account UUID
  • assetId (string) - Asset UUID (get from trading pair’s baseAssetId or quoteAssetId)
Response:

Application Configuration Endpoint

14. Get Application Configuration

Returns the configuration for the authenticated application.
Headers:
Response:

Application Backend Endpoints

These endpoints are for backend services only and require your sk_ 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.
Headers:
Query Parameters:
  • page (number, optional) - Page number, starts from 1
  • pageSize (number, optional) - Items per page, max 100
  • isActive (boolean, optional) - Filter by active status
  • accountType (string, optional) - Filter by account type: “master” or “sub”
  • address (string, optional) - Filter by wallet address (partial match)
Response:

16. List Application Balances (Backend Only)

Returns a paginated list of all user balances for this application.
Headers:
Query Parameters:
  • page (number, optional) - Page number, starts from 1
  • pageSize (number, optional) - Items per page, max 100
  • userId (string, optional) - Filter by user ID
  • token (string, optional) - Filter by token address
Response:

17. List Application Orders (Backend Only)

Returns a paginated list of all orders for this application.
Headers:
Query Parameters:
  • page (number, optional) - Page number, starts from 1; at most 10,000, the last page the listing counts towards
  • pageSize (number, optional) - Items per page, max 100
  • status (string, optional) - Filter by order status
  • tradingPairId (string, optional) - Filter by trading pair UUID
  • userId (string, optional) - Filter by user ID
  • side (string, optional) - Filter by order side: “BUY” or “SELL”
  • orderType (string, optional) - Filter by order type: “LIMIT” or “MARKET”
Response:
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.
Headers:
Query Parameters:
  • page (number, optional) - Page number, starts from 1; at most 10,000, the last page the listing counts towards
  • pageSize (number, optional) - Items per page, max 100
  • userId (string, optional) - Filter by user ID
  • entryType (string, optional) - Filter by entry type
  • transactionType (string, optional) - Filter by transaction type
  • token (string, optional) - Filter by token address
Response:
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.
Headers:
Query Parameters:
  • since (string, optional) - Only include trades at or after this timestamp (ISO 8601)
Response:
  • volume (string) - Total quote volume (normalized) for trades where this application’s users were the taker
  • makerFee (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 its WITHDRAWAL_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.
Headers:
Request Body:
Request Fields:
  • assetId (string, required) - Asset UUID to withdraw (get from a trading pair’s baseAssetId or quoteAssetId)
  • 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
Response:
Response Fields:
  • withdrawalIndex (number) - Allocated withdrawal index; matches executeSignedWithdrawal.index on-chain
  • vaultAddress (string) - 0x-prefixed lowercase vault contract address to send the calldata to (returned so you don’t have to query /applications/config separately)
  • calldata (string) - 0x-prefixed ABI-encoded calldata for executeSignedWithdrawal(...), already signed by the server. Submit it as tx.data to vaultAddress.

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.
Headers:
Query Parameters:
  • tradingPairId (string, required) - Trading pair UUID
  • side (string, required) - Order side: “BUY” or “SELL”
  • price (string, required) - Price per unit
  • quantity (string, required) - Quantity to trade
Response:
Response Fields:
  • notional (string) - Total trade value (price × quantity)
  • monacoTakerFee (string) - Monaco protocol taker fee
  • monacoMakerRebate (string) - Monaco protocol maker rebate (negative = rebate)
  • applicationTakerFee (string) - Application-specific taker fee
  • totalTakerFees (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 to monacoTakerFee / notional
  • monacoMakerRebateBpsExact (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. Use monacoTakerFeeBpsExact or GET /api/v1/fees/tier
  • monacoMakerRebateBps (number) - Deprecated. Whole-bps maker rebate; same integer limitation. Use monacoMakerRebateBpsExact or GET /api/v1/fees/tier
  • applicationTakerFeeBps (number) - Application fee rate in basis points
  • applicationName (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 the orderType field.
Headers:
Request Body (Limit Order):
Note: expirationDate is an optional field for limit orders (default: 90 days for GTC orders). Request Body (Market Order):
Note: Market orders execute inside a mandatory 1,000 bps server-side price band. 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:
Request Fields:
  • 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 string
  • price (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 band
  • useMasterBalance (boolean, optional) - For sub-accounts: use master account’s balance
Response Fields:
  • orderId (string) - Unique order identifier (UUID)
  • status (string) - “SUCCESS” or “FAILED”
  • message (string) - Operation message
  • matchResult (object, optional) - Immediate execution results if order matched:
    • tradesCount (number) - Number of trades executed
    • totalFilled (string) - Total quantity filled
    • remainingQuantity (string) - Remaining unfilled quantity
    • averageFillPrice (string, optional) - Average fill price across all trades
    • status (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 submitted
    • executionPriceRange (object, optional) - Price range: bestPrice, worstPrice

23. Cancel Order

Cancels an existing open order by its ID.
Headers:
Request Body:
Response:
Request Fields:
  • orderId (string) - ID of the order to cancel
Response Fields:
  • orderId (string) - ID of the cancelled order
  • status (string) - “SUCCESS” or “FAILED”
  • message (string) - Response message
Error Responses:
  • 400 Bad Request - Invalid order ID, order already filled/cancelled/expired, or order not found
  • 401 Unauthorized - Authentication required or order doesn’t belong to user
  • 500 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.
Headers:
Query Parameters:
  • cancel_all (boolean, optional) - If true, cancels all active orders for the user (ignores orderIds in body). Default: false
Request Body (when cancel_all=false):
Request Body (when cancel_all=true):
Response:
Response Fields:
  • success (boolean) - True if all orders cancelled successfully
  • totalRequested (number) - Number of orders requested to cancel
  • totalCancelled (number) - Number successfully cancelled
  • totalFailed (number) - Number that failed to cancel
  • results (array) - Per-order results:
    • orderId (string) - Order ID
    • success (boolean) - Whether this specific order was cancelled
    • cancelledAt (string, optional) - Cancellation timestamp (ISO 8601, UTC)
    • error (object, optional) - Error details if failed (code, message)
Error Responses:
  • 400 Bad Request - No order IDs provided when cancel_all is false, or invalid order IDs
  • 401 Unauthorized - Authentication required
  • 500 Internal Server Error - Server error during cancellation
Note: This is a best-effort operation. Some cancellations may fail while others succeed; failures don’t roll back successful cancellations.

25. Replace Order

Replaces an existing order by canceling it and creating a new order atomically. Returns a new order ID.
Headers:
Request Body:
Response:
Request Fields:
  • price (string, optional) - New order price (omit to keep original price)
  • quantity (string, optional) - New order quantity (omit to keep remaining quantity)
Response Fields:
  • orderId (string) - New order ID after replacement
  • status (string) - “SUCCESS” or “FAILED”
  • message (string) - Operation message
  • updatedFields (object) - Fields that were updated
  • originalOrderId (string) - Original order ID that was replaced
  • matchResult (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: filter status 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.
Headers:
Query Parameters:
  • 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 when pageToken is present
  • status (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 UUID
  • pageToken (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’s nextPageToken to continue; the walk is exhausted when a page returns no rows and an empty nextPageToken. Cursor mode ignores page (it comes back as 0), but total / totalPages ARE populated — bounded by a server count ceiling (exact up to it, then reported as the ceiling with totalCapped: true; see the response below)
Response:
Order Fields:
  • 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 when orderType is “TWAP”: the full TWAP parent, identical to what GET /api/v1/orders/twap/{twapOrderId} returns
  • conditional (object, optional) - Present only when orderType is “CONDITIONAL”: the full conditional order, identical to what the conditional-order endpoints return
  • conditionalOrderId (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 and GET /api/v1/orders/{orderId}; no WebSocket frame carries it
  • side (string) - “BUY” or “SELL”
  • price (string, optional) - Order price (null for market orders)
  • quantity (string) - Order quantity
  • filledQuantity (string) - Quantity filled so far
  • averageFillPrice (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 date
  • applicationTakerFee (string, optional) - Application taker fee amount
  • monacoTakerFee (string, optional) - Monaco protocol taker fee amount
  • monacoMakerRebate (string, optional) - Monaco protocol maker rebate amount
  • totalTakerFees (string, optional) - Total taker fees (monaco + application)
  • takerTotalPayment (string, optional) - Total amount taker paid
  • makerTotalReceipt (string, optional) - Total amount maker received

27. Get Order by ID

Retrieves detailed information about a specific order by its ID.
Headers:
Path Parameters:
  • orderId (string) - Order UUID
Response:
Error Responses:
  • 401 Unauthorized - Authentication required
  • 403 Forbidden - Order doesn’t belong to user
  • 404 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.
Query Parameters:
  • 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 reads live — not merely its launch phase — so a pending, warming or halted managed launch is hidden and isActive=false does not surface it. A pair with no managed launch keeps its ordinary visibility.
Response:
Fields:
  • id (string) - Trading pair UUID (use as tradingPairId in order requests)
  • symbol (string) - Trading pair symbol (e.g., “ETH/USDC”)
  • baseToken (string) - Base token symbol
  • baseAssetName (string) - Human-readable base asset display name (e.g., “Robinhood Markets” for HOOD) — useful for matching markets by company/asset name in search
  • quoteToken (string) - Quote token symbol
  • quoteAssetName (string) - Human-readable quote asset display name
  • baseTokenContract (string) - Base token contract address
  • quoteTokenContract (string) - Quote token contract address
  • baseAssetId (string) - Base asset UUID (use for withdrawal requests)
  • quoteAssetId (string) - Quote asset UUID (use for withdrawal requests)
  • baseDecimals (number) - Base token decimals
  • quoteDecimals (number) - Quote token decimals
  • baseIconUrl (string) - Base token icon URL
  • quoteIconUrl (string) - Quote token icon URL
  • minOrderSize (string) - Minimum order size
  • maxOrderSize (string) - Maximum order size
  • tickSize (string) - Minimum price increment
  • makerFeeBps (number) - Deprecated. Flat pair-level maker fee in basis points (negative = rebate); this is not the per-user tiered rate. Use GET /api/v1/fees/tier for the caller’s real rate
  • takerFeeBps (number) - Deprecated. Flat pair-level taker fee in basis points; this is not the per-user tiered rate. Use GET /api/v1/fees/tier for the caller’s real rate
  • marketType (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.
Path Parameters:
  • tradingPairId (string) - Trading pair UUID (e.g., “123e4567-e89b-12d3-a456-426614174000”)
Response:
Error Responses:
  • 404 Not Found - Trading pair not found

30. Get Market Metadata

Retrieves current price, 24-hour statistics, and market information for a trading pair.
Path Parameters:
  • tradingPairId (string) - Trading pair UUID
Response:
Response Fields:
  • symbol (string) - Trading pair symbol (e.g., “BTC/USDC”)
  • baseIconUrl (string) - Base token icon URL
  • quoteIconUrl (string) - Quote token icon URL
  • lastPrice (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)
Error Responses:
  • 404 Not Found - Trading pair not found or inactive
  • 500 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.
Path Parameters:
  • tradingPairId (string) - Trading pair UUID (get from /api/v1/market/pairs)
  • interval (string) - Candlestick interval: “1m”, “5m”, “15m”, “1h”, “4h”, or “1d”
Query Parameters:
  • 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)
Response:
Candlestick Fields:
  • T (number) - Candle start timestamp (Unix milliseconds)
  • t (number) - Candle end timestamp (Unix milliseconds)
  • o (string) - Open price
  • h (string) - High price
  • l (string) - Low price
  • c (string) - Close price
  • v (string) - Volume (base token)
  • s (string) - Symbol
  • i (string) - Interval
  • n (number) - Number of trades in this candle
Supported Intervals:
  • 1m - 1 minute
  • 5m - 5 minutes
  • 15m - 15 minutes
  • 1h - 1 hour
  • 4h - 4 hours
  • 1d - 1 day
Error Responses:
  • 400 Bad Request - Invalid interval or time range
  • 404 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.
Path Parameters:
  • tradingPairId (string) - Trading pair UUID
Query Parameters:
  • 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 levels
  • denomination (string, optional) - Quantity denomination: “base” (default) or “quote”. When “quote”, quantities are multiplied by price
Response:
Response Fields:
  • eventType (string) - Event type (“orderbook_snapshot” for HTTP)
  • tradingPairId (string) - Trading pair UUID
  • pair (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 updates
  • baseToken (string) - Base token symbol
  • quoteToken (string) - Quote token symbol
  • baseDecimals (number) - Base token decimals
  • quoteDecimals (number) - Quote token decimals
  • data (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 price
    • bestAsk (string) - Current best ask price
    • bidVolume (string) - Total bid volume
    • askVolume (string) - Total ask volume
    • priceChange (object, optional) - Price change information
Error Responses:
  • 400 Bad Request - Invalid magnitude or denomination value
  • 404 Not Found - Trading pair not found
  • 500 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 on agentAddress, so calling again with the same address updates the existing delegation and its policy.
Headers:
Request Body:
Request Fields:
  • agentAddress (string, required) - Agent wallet address (EVM, 42 chars including 0x)
  • name (string, optional) - Human-friendly label for the agent
  • expiresAt (string, optional) - Delegation expiry timestamp (ISO 8601). Omit for no expiry
  • allowedActions (array, optional) - Actions the agent may perform: CREATE_ORDER, CANCEL_ORDER, REPLACE_ORDER
  • allowedTradingPairIds (array, optional) - Trading pair UUIDs the agent may trade. An order is allowed if its market or its margin account is permitted
  • allowedMarginAccountIds (array, optional) - Margin account UUIDs the agent may trade against. An order is allowed if its market or its margin account is permitted
  • allowedOrderTypes (array, optional) - Permitted order types (LIMIT, MARKET). Empty means unrestricted
  • allowedTimeInForce (array, optional) - Permitted time-in-force values (GTC, IOC, FOK). Empty means unrestricted
  • maxLeverage (string, optional) - Maximum leverage the agent may use (decimal string). Omit for no limit
  • maxOrderNotional (string, optional) - Maximum order notional (price × quantity, decimal string). Omit for no limit
  • maxOpenOrders (number, optional) - Maximum concurrent open orders. Omit for no limit
Response:
Response Fields:
  • id (string) - Delegation UUID
  • ownerUserId (string) - Owner account UUID the agent acts on behalf of
  • agentAddress (string) - Agent wallet address (EVM)
  • name (string, optional) - Human-friendly label for the agent
  • isActive (boolean) - Whether the delegation is active
  • expiresAt (string, optional) - Delegation expiry timestamp (ISO 8601), if set
  • revokedAt (string, optional) - Revocation timestamp (ISO 8601), if revoked
  • allowedActions, allowedTradingPairIds, allowedMarginAccountIds, allowedOrderTypes, allowedTimeInForce (arrays) - The policy as stored
  • maxLeverage, maxOrderNotional (string, optional) / maxOpenOrders (number, optional) - Policy limits, if set
Error Responses:
  • 401 Unauthorized - Authentication required
  • 403 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.
Headers:
Response:
Response Fields: Error Responses:
  • 401 Unauthorized - Authentication required
  • 403 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 the ownerUserId to pass to Create Delegated Session. Returns only active (non-revoked, non-expired) delegations.
Headers:
Response:
Response Fields:
  • owners (array) - Owners that have an active delegation to the calling agent:
    • ownerUserId (string) - Owner account UUID to pass to Create Delegated Session
    • delegationId (string) - Delegation UUID for the (owner, agent) pair
    • name (string, optional) - Human-friendly label the owner gave this agent, if any
    • isActive (boolean) - Whether the delegation is active
    • expiresAt (string, optional) - Delegation expiry timestamp (ISO 8601), if set
Error Responses:
  • 401 Unauthorized - Authentication required

36. Revoke Delegated Agent

Revokes the delegation identified by delegatedAgentId. Master accounts only. Existing delegated sessions are not invalidated; only future session creation is blocked.
Headers:
Path Parameters:
  • delegatedAgentId (string) - Delegation UUID to revoke
Response:
Error Responses:
  • 400 Bad Request - Invalid delegatedAgentId
  • 401 Unauthorized - Authentication required
  • 403 Forbidden - Only master accounts can revoke delegated agents
  • 404 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 the ownerUserId 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.
Headers:
Request Body:
Request Fields:
  • 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
Response:
Response Fields:
  • expiresAt (number) - Session expiry as a Unix timestamp (seconds)
  • delegationId (string) - Delegation UUID for the active (owner, agent) pair
  • ownerUserId (string) - Owner account UUID the session acts on behalf of
  • agentAddress (string) - Agent wallet address recorded on the session for policy enforcement
Error Responses:
  • 400 Bad Request - Invalid request
  • 401 Unauthorized - Authentication required
  • 403 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
Error Response Format:
When a rejection originates in the matching engine, the envelope additionally carries a stable machine-readable 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 return 401 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 your clientId for frontend authentication.

Backend Services

Contact the Monaco Protocol team to obtain your secretKey for backend authentication.

Migration from SDK

If you’re migrating from the TypeScript SDK, note these key differences:
  1. Field Names: API uses snake_case (e.g., clientId) while SDK uses camelCase (e.g., clientId)
  2. Manual Request Signing: You must generate a session keypair and sign every request with it (no token to store)
  3. Wallet Signing: You must implement wallet message signing separately
  4. Error Handling: Parse HTTP status codes instead of SDK error classes

Withdrawal Usage Examples

These examples assume the MonacoAPI 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

  1. Store Secret Keys Securely - Never expose backend secret keys in client-side code
  2. Handle Session Expiry - Detect 401 responses and re-run the challenge/verify flow
  3. Validate Responses - Always validate API responses before using data
  4. Use HTTPS - All API requests must use HTTPS in production
  5. Revoke Sessions - Implement logout by calling POST /api/v1/auth/revoke, and never persist the session private key insecurely