NAV Navbar
shell

Introduction

Welcome to the MCDEX API! You can use our API to access all market data, trading, and account management endpoints.

We have code example in Shell! You can view them in the dark area to the right.

API endpoints

Rest:

https://mcdex.io/api (mainnet)

https://ropsten.mcdex.io/api (ropsten)

Websocket:

wss://mcdex.io/ws (mainnet)

wss://ropsten.mcdex.io/ws (ropsten)

Authentication

API Authentication Header

Header Details

Mai-Authentication: {AA}#{BB}@{CC}#{DD}

{AA}: your ETH address begin with '0x'

{BB}: any string without '#'

{CC}: timestamp in milliseconds (ex: 1562076420000) or RFC3389 nano time string (ex: 2019-07-02T13:57:56.862Z)

{DD}: personalSign of "BB@CC" begin with '0x'. The sign format is "0x{r}{s}{v}" where {v} should be "1b" or "1c" according to HomsteadHash in EIP155.

JWT Authentication Header

GET /jwt with "Mai-Authentication" header described above.

Response:

{
  "status": 0,
  "desc": "success",
  "data": {
    "expires": 86400000, // in milliseconds
    "jwt": "<data>"
  }
}

Then save data into local storage. The next time send the following header instead of Mai-Authentication:

Authentication: Bearer <data>

Public REST API

List Markets

curl "https://mcdex.io/api/markets"

Response:

{
  "status": 0,
  "desc": "success",
  "data": {
    "markets": [
      {
        "id": "ETHPERP",
        "symbol": "ETH-PERP",
        "collateralTokenSymbol": "ETH",
        "contractType": "Perpetual",
        "contractSizeSymbol": "USD",
        "lotSize": "10",
        "priceTick": "0.01",
        "priceDecimals": 18,
        "priceSymbol": "USD",
        "amountDecimals": 18,
        "asMakerFeeRate": "-0.00025",
        "asTakerFeeRate": "0.00075",
        "isPublished": true,
        "brokerAddress": "0xc257f36e5b4490370e5efdbde14a701668cf0875",
        "perpetualAddress": "0x92c506d3dd51a37650cc8e352a7551c26e2c607d",
        "perpetualType": "Inverse",
        "supportedOrderTypes": [
          "limit",
          "market"
        ]
      },
      {
        "id": "b2tods",
        "symbol": "BTC1220-USDT",
        "mpContractName": "BTC_USDT_COINCAP_1576828800",
        "mpContractAddress": "0xa8ae6634f0acd034fb88aabd535aff7576bb046e",
        "expirationAt": "2019-12-20T08:00:00Z",
        "collateralTokenSymbol": "USDT",
        "collateralTokenName": "Tether USD",
        "collateralTokenDecimals": 6,
        "collateralTokenAddress": "0xdac17f958d2ee523a2206206994597c13d831ec7",
        "longTokenSymbol": "LBTC_20191220",
        "longTokenName": "MARKET Protocol Long Position Token",
        "longTokenAddress": "0x22a7ea7d08319d7791f2098389e4b9ff66b43582",
        "shortTokenSymbol": "SBTC_20191220",
        "shortTokenName": "MARKET Protocol Short Position Token",
        "shortTokenAddress": "0x8914b374d507de405b18f91e2308b746c72a2dc5",
        "positionTokenDecimals": 5,
        "contractType": "MarketProtocol",
        "contractSizeSymbol": "BTC",
        "mpContractStatus": "NORMAL",
        "settlePrice": "0",
        "settleTime": null,
        "lotSize": "0.001",
        "priceFloor": "5500",
        "priceCap": "9000",
        "priceTick": "0.1",
        "priceDecimals": 1,
        "priceSymbol": "USDT",
        "oracleID": "https://api.coincap.io/v2/rates/bitcoin",
        "amountDecimals": 5,
        "asMakerFeeRate": "0",
        "asTakerFeeRate": "0",
        "gasFeeAmount": "0.5683222031232233",
        "supportedOrderTypes": [
          "limit",
          "market"
        ]
      }
    ]
  }
}

List all markets, including active markets and closed markets.

HTTP Request

GET /markets

Details

lotSize : The minimum order size of the order you can place and the minimum order size increment.

priceTick : The minimum price increment.

perpetualType : The perpetual type, 'Inverse' or 'Vanilla'.

Get a Market

curl "https://mcdex.io/api/markets/b2tods"

Response:

{
  "status": 0,
  "desc": "success",
  "data": {
    "market": {
      "id": "b2tods",
      "symbol": "BTC1220-USDT",
      "mpContractName": "BTC_USDT_COINCAP_1576828800",
      "mpContractAddress": "0xa8ae6634f0acd034fb88aabd535aff7576bb046e",
      "expirationAt": "2019-12-20T08:00:00Z",
      "collateralTokenSymbol": "USDT",
      "collateralTokenName": "Tether USD",
      "collateralTokenDecimals": 6,
      "collateralTokenAddress": "0xdac17f958d2ee523a2206206994597c13d831ec7",
      "longTokenSymbol": "LBTC_20191220",
      "longTokenName": "MARKET Protocol Long Position Token",
      "longTokenAddress": "0x22a7ea7d08319d7791f2098389e4b9ff66b43582",
      "shortTokenSymbol": "SBTC_20191220",
      "shortTokenName": "MARKET Protocol Short Position Token",
      "shortTokenAddress": "0x8914b374d507de405b18f91e2308b746c72a2dc5",
      "positionTokenDecimals": 5,
      "contractType": "MarketProtocol",
      "contractSizeSymbol": "BTC",
      "mpContractStatus": "NORMAL",
      "settlePrice": "0",
      "settleTime": null,
      "lotSize": "0.001",
      "priceFloor": "5500",
      "priceCap": "9000",
      "priceTick": "0.1",
      "priceDecimals": 1,
      "priceSymbol": "USDT",
      "oracleID": "https://api.coincap.io/v2/rates/bitcoin",
      "amountDecimals": 5,
      "asMakerFeeRate": "0",
      "asTakerFeeRate": "0",
      "gasFeeAmount": "0.5690071305575178",
      "supportedOrderTypes": [
        "limit",
        "market"
      ]
    }
  }
}

Get a market by ID.

HTTP Request

GET /markets/<id>

URL Parameters

Parameter Description
id The ID of the market.

Market Status

curl "https://mcdex.io/api/markets/b2tods/status"

Response(v1):

{
  "status": 0,
  "desc": "success",
  "data": {
    "marketID": "b2tods",
    "lastPrice": "7061.6",
    "price24hGrowthRate": "-0.0031198385024775",
    "amount24h": "0.008",
    "volume24h": "56.6591",
    "openInterest": "0.003",
    "lastIndex": "7131.843151665215032"
  }
}
curl "https://mcdex.io/api/markets/ETHPERP/status"

Response(v2/perpetual):

{
  "status": 0,
  "desc": "success",
  "data": {
    "marketID": "ETHPERP",
    "contractType": "Perpetual",
    "price24hGrowthRate": "0.008659433609481429",
    "lastPrice": "188.135157556840473696",
    "amount24h": "121320",
    "volume24h": "650.08495667447205723",
    "lastIndex": "187.670000000000000266",
    "openInterest": "97070",
    "markPrice": "187.708721779810608314",
    "fundingRate": "0",
    "fundingRate8h": "0.000000354372341794",
    "perpetualGovParams": {
      "amm": "0xf4ce6d5e9cdcd6c91e303b87e27688f01b9bb7bf",
      "poolAccount": "0xda9f6fb1ef188e081cfbea74ec820a3718e91f21",
      "withdrawalLockBlockCount": 3,
      "brokerLockBlockCount": 3,
      "initialMargin": "0.1",
      "maintenanceMargin": "0.075",
      "liquidationPenaltyRate": "0.005",
      "penaltyFundRate": "0.005",
      "makerDevRate": "0",
      "takerDevRate": "0",
      "lotSize": "10",
      "tradingLotSize": "10",
      "poolFeeRate": "0.0006",
      "poolDevFeeRate": "0.00015",
      "emaAlpha": "0.003327787021630616",
      "updatePremiumPrize": "0",
      "markPremiumLimit": "0.005",
      "fundingDampener": "0.0005"
    },
    "perpetualStorage": {
      "collateralTokenAddress": "0x0000000000000000000000000000000000000000",
      "shareTokenAddress": "0x6d5b330523017e2d4ec36ff973a49a440ab763ef",
      "totalSize": "97070",
      "longSocialLossPerContract": "0",
      "shortSocialLossPerContract": "0",
      "insuranceFundBalance": "1.212428074535051028",
      "isEmergency": false,
      "isGlobalSettled": false,
      "globalSettlePrice": "0",
      "accumulatedFundingPerContract": "0.000001844229394313",
      "lastEMAPremium": "-0.000003500384346191",
      "lastPremium": "-0.000001088303888144",
      "lastIndexPrice": "0.005328502158043374",
      "lastFundingTimestamp": 1589269353
    },
    "perpetualType": "Inverse"
  }
}

Return the status of a specific market.

HTTP Request

GET /markets/<id>/status

URL Parameters

Parameter Description
id The ID of the market.

Candles

curl "https://mcdex.io/api/markets/b2tods/candles?from=1576465225&to=1576485225&granularity=300"

Response:

{
  "status": 0,
  "desc": "success",
  "data": {
    "candles": [
      {
        "time": 1576466400,
        "open": "7081.9",
        "close": "7081.9",
        "low": "7081.9",
        "high": "7081.9",
        "volume": "0.001"
      },
      {
        "time": 1576470300,
        "open": "7034.5",
        "close": "7034.5",
        "low": "7034.5",
        "high": "7034.5",
        "volume": "0.001"
      },
      {
        "time": 1576476300,
        "open": "7061.6",
        "close": "7061.6",
        "low": "7061.6",
        "high": "7061.6",
        "volume": "0.001"
      }
    ]
  }
}

Get "candles" for the market. This data is usually used to draw the k-line chart.

HTTP Request

GET /markets/<id>/candles

URL Parameters

Parameter Description
id The ID of the market.

Query Parameters

Parameter Description Required Type Example
from The first unix timestamp of the time range. True number 1576465225
to The last unix timestamp of the time range. True number 1576485225
granularity The seconds of each candle last, valid values: 300, 3600, 43200, 86400. True number 300

Details

If a candle has no trade, it won't be returned.

Orderbook(snapshot)

curl "https://mcdex.io/api/markets/b2tods/orderbook"

Response:

{
  "status": 0,
  "desc": "success",
  "data": {
    "status": 0,
    "desc": "",
    "orderBook": {
      "sequence": "6769832519740604027",
      "updatedAt": "2019-12-16T08:39:18.2064109Z",
      "bids": [
        {
          "price": "7058.9",
          "amount": "0.049"
        },
        {
          "price": "7058.5",
          "amount": "0.051"
        },
        {
          "price": "7058.1",
          "amount": "0.049"
        },
        {
          "price": "6998.7",
          "amount": "0.02"
        },
        {
          "price": "6960",
          "amount": "0.02"
        },
        {
          "price": "6921.3",
          "amount": "0.02"
        }
      ],
      "asks": [
        {
          "price": "7065.5",
          "amount": "0.001"
        },
        {
          "price": "7069.1",
          "amount": "0.054"
        },
        {
          "price": "7069.5",
          "amount": "0.412"
        },
        {
          "price": "7114.7",
          "amount": "0.02"
        },
        {
          "price": "7153.3",
          "amount": "0.02"
        },
        {
          "price": "7192",
          "amount": "0.02"
        }
      ]
    }
  }
}

Return the order book snapshot of a specific market.

HTTP Request

GET /markets/<id>/orderbook

URL Parameters

Parameter Description
id The ID of the market.

Query Parameters

Parameter Description Required Type Example
level Aggregation level, 2(default) means aggregating the same price orders. currently, only 2 is valid False number 2

Trade History(snapshot)

curl "https://mcdex.io/api/markets/b2tods/trades"

Response:

{
  "status": 0,
  "desc": "success",
  "data": {
    "count": 1,
    "trades": [
      {
        "id": "590",
        "marketID": "b2tods",
        "transactionHash": "0x4e96f33ffb24874631e9ae6a3d8cfb69d727e86be33a55f3444f946b353e6906",
        "transactionStatus": "SUCCESS",
        "status": "SUCCESS",
        "takerSide": "buy",
        "maker": "0x799b976ad9b5266631414c876e9635fa8f2dce96",
        "taker": "0x08312bb82a9e30d068f6b4faf854df9066e02b1f",
        "amount": "0.001",
        "price": "7065.5",
        "executedAt": "2019-12-16T08:41:30Z",
        "createdAt": "2019-12-16T08:41:32.616598Z",
        "makerFeeRate": "0",
        "takerFeeRate": "0"
      }
    ]
  }
}

Return the trade history snapshot of a specific market.

HTTP Request

GET /markets/<id>/trades

URL Parameters

Parameter Description
id The ID of the market.

Details

Only succeeded trades will be returned.

Fees

curl "https://mcdex.io/api/fees?marketID=b2tods&price=8000&amount=1"

Response:

{
  "status": 0,
  "desc": "success",
  "data": {
    "fees": {
      "gasFeeAmount": "0.5690385899380904",
      "asMakerTotalFeeAmount": "0.5690385899380904",
      "asMakerTradeFeeAmount": "0",
      "asMakerFeeRate": "0",
      "asTakerTotalFeeAmount": "0.5690385899380904",
      "asTakerTradeFeeAmount": "0",
      "asTakerFeeRate": "0"
    }
  }
}

Return the fees of a specific market for the specific price and amount.

HTTP Request

GET /fees

Query Parameters

Parameter Description Required Type Example
marketID market id True string b2tods
price trade price True number 8000
amount trade amount True number 1

Details

total fee = trade fee + gas fee, trade fee = trade fee rate * (cap - floor) * 0.5 * amount.

Note that fees are different for maker and taker.

Private REST API

My Market Trades

curl "https://mcdex.io/api/markets/b2tods/trades/mine" -H "Mai-Authentication: xxx"

Response:

{
  "status": 0,
  "desc": "success",
  "data": {
    "count": 25,
    "trades": [
      {
        "id": "590",
        "transactionID": "626",
        "status": "SUCCESS",
        "marketID": "b2tods",
        "maker": "0x799b976ad9b5266631414c876e9635fa8f2dce96",
        "taker": "0x08312bb82a9e30d068f6b4faf854df9066e02b1f",
        "takerSide": "buy",
        "makerOrderID": "0xf1dda2ef3cfabbca6ec5c4f3dd58f133ef8c22addb762ca219e2dbafe5988d55",
        "takerOrderID": "0x4852b0aa277454f29c103014320881d534f8046b8df949490773705a8369b9bb",
        "sequence": 0,
        "amount": "0.001",
        "price": "7065.5",
        "createdAt": "2019-12-16T08:41:32.616598Z",
        "makerFeeRate": "0",
        "takerFeeRate": "0",
        "makerRebateRate": "0",
        "transactionStatus": "SUCCESS",
        "transactionHash": "0x4e96f33ffb24874631e9ae6a3d8cfb69d727e86be33a55f3444f946b353e6906",
        "executedAt": "2019-12-16T08:41:30Z"
      }
    ]
  }
}

Return your trades of a specific market.

HTTP Request

GET /markets/<id>/trades/mine

URL Parameters

Parameter Description
id The ID of the market

Query Parameters

Parameter Description Required Type Example
status Only the trades with the specific status will be returned. Valid values: all(default), INIT, SIGNED, SIGN_FAIL, PENDING, SUCCESS, EXECUTE_FAIL, OVERWRITTEN. False string all
page Used for pagination. Default 1. False number 1
perPage Used for pagination. The maximum valid value is 10000. Default 20. False number 20

All My Trades

curl "https://mcdex.io/api/trades/mine" -H "Mai-Authentication: xxx"

Response:

{
  "status": 0,
  "desc": "success",
  "data": {
    "count": 1,
    "trades": [
      {
        "id": "575",
        "transactionID": "611",
        "status": "SUCCESS",
        "marketID": "b2tods",
        "maker": "0x799b976ad9b5266631414c876e9635fa8f2dce96",
        "taker": "0xd4ead225ed5448ec531c2dc06f0d22a64db6ad1f",
        "takerSide": "sell",
        "makerOrderID": "0x1c9e4cf73b784dac6c81daaf1c4e9c586286ee1485d9c9e75cf89a07ecbf0d6d",
        "takerOrderID": "0x00d03a25688bce18b6495013adccfdb91bf58d284d8c493d55d47ee1021f951a",
        "sequence": 0,
        "amount": "0.001",
        "price": "7118.2",
        "createdAt": "2019-12-15T22:11:14.102954Z",
        "makerFeeRate": "0",
        "takerFeeRate": "0",
        "makerRebateRate": "0",
        "transactionStatus": "SUCCESS",
        "transactionHash": "0xdee4bd71e852f4be255646a570b891ac93c4d094212e60a42f921f3f66f20545",
        "executedAt": "2019-12-15T22:11:38Z"
      }
    ]
  }
}

Return all your trades.

HTTP Request

GET /trades/mine

Query Parameters

Parameter Description Required Type Example
status Only the trades with the specific status will be returned. Valid values: all(default), INIT, SIGNED, SIGN_FAIL, PENDING, SUCCESS, EXECUTE_FAIL, OVERWRITTEN. False string all
page Used for pagination. Default 1. False number 1
perPage Used for pagination. The maximum valid value is 10000. Default 20. False number 20

My Orders

curl "https://mcdex.io/api/orders?marketID=b2tods" -H "Mai-Authentication: xxx"

Response:

{
  "status": 0,
  "desc": "success",
  "data": {
    "count": 1, // never > 5000
    "orders": [
      {
        "id": "0xec1bb8c3adfa8305e2c8b5e02992e812cfc013e183e772f7e2c5b51b69828111",
        "traderAddress": "0x799b976ad9b5266631414c876e9635fa8f2dce96",
        "marketID": "b2tods",
        "side": "sell",
        "price": "7057",
        "amount": "0.001",
        "status": "pending",
        "type": "limit",
        "version": "mai-v1",
        "availableAmount": "0.001",
        "confirmedAmount": "0",
        "filledPrice": "0",
        "canceledAmount": "0",
        "pendingAmount": "0",
        "makerFeeRate": "0",
        "takerFeeRate": "0",
        "makerRebateRate": "0",
        "gasFeeAmount": "0.5684570058987931",
        "createdAt": "2019-12-16T09:03:22.063236Z",
        "updatedAt": "2019-12-16T09:03:22.063236Z",
        "expiresAt": "2019-12-16T09:33:22Z",
        "cancelReasons": []
      }
    ]
  }
}

Return your orders of a specific market.

HTTP Request

GET /orders

Query Parameters

Parameter Description Required Type Example
marketID Market id, return all if none False string b2tods
status Only the orders with this status will be returned. Valid values: all, canceled, pending(default), partial_filled, full_filled. False string pending
page Used for pagination. Default 1. False number 1
perPage Used for pagination. The maximum valid value is 5000. Default 20. False number 20

Details

Status pending means the order in the order book or the matched order is being broadcasted.

Status partial_filled means a part of order is filled and the rest is canceled. The partial_filled order is not in the order book.

My Orders by IDs

curl --data '{"orderIDs":["0xec1bb8c3adfa8305e2c8b5e02992e812cfc013e183e772f7e2c5b51b69828111"]}' 'https://mcdex.io/api/orders/byids' -H "Mai-Authentication: xxx" -H "Content-Type: application/json"

Response:

{
  "status": 0,
  "desc": "success",
  "data": {
    "count": 1,
    "orders": [
      {
        "id": "0xec1bb8c3adfa8305e2c8b5e02992e812cfc013e183e772f7e2c5b51b69828111",
        "traderAddress": "0x799b976ad9b5266631414c876e9635fa8f2dce96",
        "marketID": "b2tods",
        "side": "sell",
        "price": "7057",
        "amount": "0.001",
        "status": "full_filled",
        "type": "limit",
        "version": "mai-v1",
        "availableAmount": "0",
        "confirmedAmount": "0.001",
        "filledPrice": "7057",
        "canceledAmount": "0",
        "pendingAmount": "0",
        "makerFeeRate": "0",
        "takerFeeRate": "0",
        "makerRebateRate": "0",
        "gasFeeAmount": "0.5684570058987931",
        "createdAt": "2019-12-16T09:03:22.063236Z",
        "updatedAt": "2019-12-16T09:25:19.259812Z",
        "expiresAt": "2019-12-16T09:33:22Z",
        "cancelReasons": []
      }
    ]
  }
}

Return your orders by ids.

HTTP Request

POST /orders/byids

Body JSON Parameters

Parameter Description Required Type Example
orderIDs The list of order ids. True list [0xec1bb8c3adfa8305e2c8b5e02992e812cfc013e183e772f7e2c5b51b69828111]

My Order

curl "https://mcdex.io/api/orders/0xec1bb8c3adfa8305e2c8b5e02992e812cfc013e183e772f7e2c5b51b69828111" -H "Mai-Authentication: xxx"

Response:

{
  "status": 0,
  "desc": "success",
  "data": {
    "order": {
      "id": "0xec1bb8c3adfa8305e2c8b5e02992e812cfc013e183e772f7e2c5b51b69828111",
      "traderAddress": "0x799b976ad9b5266631414c876e9635fa8f2dce96",
      "marketID": "b2tods",
      "side": "sell",
      "price": "7057",
      "amount": "0.001",
      "status": "full_filled",
      "type": "limit",
      "version": "mai-v1",
      "availableAmount": "0",
      "confirmedAmount": "0.001",
      "filledPrice": "7057",
      "canceledAmount": "0",
      "pendingAmount": "0",
      "makerFeeRate": "0",
      "takerFeeRate": "0",
      "makerRebateRate": "0",
      "gasFeeAmount": "0.5684570058987931",
      "createdAt": "2019-12-16T09:03:22.063236Z",
      "updatedAt": "2019-12-16T09:25:19.259812Z",
      "expiresAt": "2019-12-16T09:33:22Z",
      "cancelReasons": []
    }
  }
}

Return your order by a id.

HTTP Request

GET /orders/<id>

URL Parameters

Parameter Description
id The ID of the order.
curl "https://mcdex.io/api/orders/0xec1bb8c3adfa8305e2c8b5e02992e812cfc013e183e772f7e2c5b51b69828111/trades" -H "Mai-Authentication: xxx"

Response:

{
  "status": 0,
  "desc": "success",
  "data": {
    "count": 1,
    "trades": [
      {
        "id": "594",
        "transactionID": "630",
        "status": "SUCCESS",
        "marketID": "b2tods",
        "maker": "0x799b976ad9b5266631414c876e9635fa8f2dce96",
        "taker": "0x08312bb82a9e30d068f6b4faf854df9066e02b1f",
        "takerSide": "buy",
        "makerOrderID": "0xec1bb8c3adfa8305e2c8b5e02992e812cfc013e183e772f7e2c5b51b69828111",
        "takerOrderID": "0x1bdb7103d99d39f58718c0f724b8acc4f5453b0100bb463366d1b47d7dd8efd4",
        "sequence": 0,
        "amount": "0.001",
        "price": "7057",
        "createdAt": "2019-12-16T09:23:40.133561Z",
        "makerFeeRate": "0",
        "takerFeeRate": "0",
        "makerRebateRate": "0",
        "transactionStatus": "SUCCESS",
        "transactionHash": "0x78a6b0327f1d7a4b08a1fc28dee78b5528decadda860b9e50370b8bcfdb54f19",
        "executedAt": "2019-12-16T09:25:16Z"
      }
    ]
  }
}

Return the trades related to your specific order.

HTTP Request

GET /orders/<id>/trades

URL Parameters

Parameter Description
id The ID of the order.

My Positions

curl "https://mcdex.io/api/account/positions" -H "Mai-Authentication: xxx"

Response:

{
  "status": 0,
  "desc": "success",
  "data": {
    "positions": [
      {
        "trader": "0x799b976ad9b5266631414c876e9635fa8f2dce96",
        "marketID": "b2tods",
        "side": "long",
        "entryPrice": "7105.2294270833333334",
        "amount": "0.006",
        "unknownPriceAmount": "0",
        "openedAt": "2019-12-14T04:30:59Z",
        "symbol": "BTC1220-USDT",
        "priceSymbol": "USDT",
        "contractSizeSymbol": "BTC"
      }
    ]
  }
}

Return the positions of all markets.

HTTP Request

GET /account/positions

My Closed Positions

curl "https://mcdex.io/api/account/closed_positions" -H "Mai-Authentication: xxx"

Response:

{
  "status": 0,
  "desc": "success",
  "data": {
    "closedPositions": [
      {
        "id": "584",
        "transactionHash": "0x936ffd757e7ffc5056db77c7f8bf06b05920d7cc02c961a29546f9724468ce09",
        "trader": "0x799b976ad9b5266631414c876e9635fa8f2dce96",
        "marketID": "b2tods",
        "side": "long",
        "amount": "0.001",
        "openedAt": "2019-12-14T04:30:59Z",
        "closedAt": "2019-12-16T06:07:41Z",
        "protocol": "mai",
        "entryPrice": "7105.2294270833333334",
        "exitPrice": "7061.6",
        "symbol": "BTC1220-USDT",
        "priceSymbol": "USDT",
        "contractSizeSymbol": "BTC"
      }
    ],
    "count": 1
  }
}

Return the closed positions of all markets.

HTTP Request

GET /account/closed_positions

Query Parameters

Parameter Description Required Type Example
page Used for pagination. Default 1. False number 1
perPage Used for pagination. The maximum valid value is 10000. Default 20. False number 20

Balances

curl "https://mcdex.io/api/account/balances?marketID=b2tods" -H "Mai-Authentication: xxx"

Response(v1):

{
  "status": 0,
  "desc": "success",
  "data": {
    "balances": [
      {
        "collateral": {
          "address": "0x6b175474e89094c44da98b954eedeac495271d0f",
          "allowance": "999999999999999999999999999999999999999999056230000000000000000",
          "balance": "243401697568591571800",
          "decimals": 18,
          "locked": "0",
          "potential": "0",
          "symbol": "DAI"
        },
        "longPosition": {
          "address": "0xf577822d3673a8fc957dea1720dcf63c6e703e23",
          "allowance": "999999999999999999999999999999999400",
          "balance": "0",
          "decimals": 5,
          "locked": "0",
          "potential": "0",
          "symbol": "LBTC_20200522"
        },
        "marketID": "kcpj2j",
        "shortPosition": {
          "address": "0xee598eaf2295d854ae6f779c36382eb554b48bb2",
          "allowance": "999999999999999999999999999999999200",
          "balance": "200",
          "decimals": 5,
          "locked": "0",
          "potential": "0",
          "symbol": "SBTC_20200522"
        }
      }
    ]
  }
}
curl "https://mcdex.io/api/account/balances?marketID=ETHPERP" -H "Mai-Authentication: xxx"

Response(v2/perpetual):

{
  "status": 0,
  "desc": "success",
  "data": {
    "balances": [
      {
        "marketID": "ETHPERP",
        "contractType": "Perpetual",
        "accountStorage": {
          "cashBalance": "0.026475032549910798",
          "positionSide": 2,
          "positionSize": "40",
          "entryValue": "0.195218768645093987",
          "entrySocialLoss": "0",
          "entryFundingLoss": "-0.00212850163157972",
          "withdrawalApplicationAmount": "0",
          "withdrawalApplicationHeight": 0,
          "previousBroker": "0x0000000000000000000000000000000000000000",
          "previousAppliedHeight": 0,
          "currentBroker": "0xc63c0935626930895304da15218a3ed354f8e887",
          "currentAppliedHeight": 7726416
        },
        "accountComputed": {
          "entryPrice": "0.00488046921612735",
          "positionValue": "0.21050550333333388142828830097623576",
          "positionMargin": "0.021050550333333388142828830097623576",
          "maintenanceMargin": "0.015787912750000041107121622573217682",
          "socialLoss": "0",
          "fundingLoss": "-0.00010559172075468",
          "pnl1": "0.01528673468823989442828830097623576",
          "pnl2": "0.01539232640899457442828830097623576",
          "roe": "0.58139027326885895",
          "liquidationPrice": "0.004557787685795365",
          "marginBalance": "0.04186735895890537242828830097623576",
          "availableMargin": "0.020816808625571984285459470878612184",
          "maxWithdrawable": "0.020816808625571984285459470878612184",
          "withdrawableBalance": "0",
          "leverage": "5.027914551284549794",
          "isSafe": true,
          "inverseSide": 1,
          "inverseEntryPrice": "204.89833163900161305",
          "inverseLiquidationPrice": "219.404691253294565813"
        },
        "collateral": {
          "address": "0x0000000000000000000000000000000000000000",
          "decimals": 18,
          "balance": "9.5492951375",
          "allowance": "1000000000000000000000000000000000000000000000"
        },
        "targetLeverage": "9.9",
        "orderBalance": {
          "positionMargin": "0.02126318215488221",
          "orderMargin": "0",
          "available": "0.02060417680402316242828830097623576"
        }
      }
    ]
  }
}

Get status of account, "accountStorage" is on-chain data and "accountComputed" is realtime data. More details are in documents.

HTTP Request

GET /account/balances

URL Parameters

Parameter Description Required
marketID The ID of the market, return all markets if none. False

Details

positionSide : Contract position side.

0: flat 1: contract short position 2: contract long position

The eth-perp is an inversed perpetual (perpetualType = "Inverse" in /markets), so 1 = orderbook long, 2 = orderbook short

If there's a vanilla perpetual (perpetualType = "Vanilla" in /markets), 1 = orderbook short, 2 = orderbook long

Build Order

curl --data '{"amount": "0.01", "price": "6920", "side": "buy", "expires": 1800, "orderType": "limit", "marketID": "b2tods", isPostOnly: false}' "https://mcdex.io/api/orders/build" -H "Mai-Authentication: xxx" -H "Content-Type: application/json"

Response:

{
  "status": 0,
  "desc": "success",
  "data": {
    "order": {
      "id": "0xbddcc767dc44c8ec098833cadaa1ace0e09330f84ebf140ee0c9e541e1930ce7",
      "marketID": "b2tods",
      "side": "buy",
      "type": "limit",
      "price": "6920",
      "amount": "0.01",
      "json": {
        "trader": "0x08312bb82a9e30d068f6b4faf854df9066e02b1f",
        "relayer": "0x5ff086d54201ec4aa20a12537dfedd192015a26a",
        "marketContractAddress": "0xa8ae6634f0acd034fb88aabd535aff7576bb046e",
        "amount": "1000",
        "price": "69200",
        "gasTokenAmount": "568128",
        "signature": "",
        "data": "0x0100005df76a95000000000000005b27926ee6c6929400000000000000000000"
      },
      "asMakerFeeRate": "0",
      "asTakerFeeRate": "0",
      "makerRebateRate": "0",
      "gasFeeAmount": "0.5681285012630313",
      "expiresAt": 1576495765
    }
  }
}

Build an unsigned order. The next step is signing the returned id and placing order with id and signature.

HTTP Request

POST /orders/build

Body JSON Parameters

Parameter Description Required Type Example
amount Order amount. True string "1"
price Order price. True string "6920"
side Order side, "buy" or "sell". True string "buy"
expires The timespan before the order expires, in seconds True number 1800
orderType Order type, "limit" or "market". True string "limit"
marketId Market id. True string b2tods
targetLeverage(only for v2/perpetual) Target leverage for perpetual account. True string "5"
isPostOnly(only for v2/perpetual) Whether the order is post-only. False boolean false

Place Order

curl --data '{"orderID": "0xb767f3c7c1a828e7f2b73648cefb4e14ec158840695017fd0d7ecc97f2c10abe", "signature": "0x1c0100000000000000000000000000000000000000000000000000000000000063496baec1d4e92ddc853e01fe6a1a49459c0499a86cefacaa95e32979e0c0a548eb730a046cfcbc730f383214eefc3b723c9ef5ebf9a4de25cf1b1fefc0694a"}' "https://mcdex.io/api/orders" -H "Mai-Authentication: xxx" -H "Content-Type: application/json"

Response:

{
  "status":0,
  "desc":"success"
}

Sign and place order.

Sign Option 1: ethSign

// step 1: orderID => sign

web3.eth.sign(web3.eth.accounts[0], orderID, function(err, result) { console.log(err, result) } )

// step 2: padding v. The "signature": 0x{v}00000000000000000000000000000000000000000000000000000000000000{r}{s}

signature = '0x' + sign.slice(130) + '0'.repeat(62) + sign.slice(2, 130)

Sign Option 2: EIP712

// step 1: get eip712Msg

eip712Msg = {
  types: {
    EIP712Domain: [
      { name: 'name', type: 'string' }
    ],
    Order: [
      { name: 'trader', type: 'address' },
      { name: 'relayer', type: 'address' },
      { name: 'marketContractAddress', type: 'address' },
      { name: 'amount', type: 'uint256' },
      { name: 'price', type: 'uint256' },
      { name: 'gasTokenAmount', type: 'uint256' },
      { name: 'data', type: 'bytes32' }
    ]
  },
  domain: { name: 'Mai Protocol' },
  primaryType: 'Order',
  message: data.order.json
}

step 2: eip712Msg => signature

rsv = await provider.send('eth_signTypedData_v3', [from, JSON.stringify(eip712Msg)])

signature = vrs = '0x' + rsv.slice(130) + '01' + '0'.repeat(60) + rsv.slice(2, 130)

HTTP Request

POST /orders

Body JSON Parameters

Parameter Description Required Type Example
orderID Order id, the id returned when build order True string "0xb767f3c7c1a828e7f2b73648cefb4e14ec158840695017fd0d7ecc97f2c10abe"
signature Sign with one of the methods described above. True string "0x1c0100000000000000000000000000000000000000000000000000000000000063496baec1d4e92ddc853e01fe6a1a49459c0499a86cefacaa95e32979e0c0a548eb730a046cfcbc730f383214eefc3b723c9ef5ebf9a4de25cf1b1fefc0694a"

Cancel Order

curl -X "DELETE" "https://mcdex.io/api/orders/0xb767f3c7c1a828e7f2b73648cefb4e14ec158840695017fd0d7ecc97f2c10abe" -H "Mai-Authentication: xxx"

Response:

{
  "status":0,
  "desc":"success"
}

HTTP Request

DELETE /orders/<id>

URL Parameters

Parameter Description
id The ID of the order.

Cancel All Orders

proxychains curl -X "DELETE" --data '{"marketID": "b2tods"}' "https://mcdex.io/api/orders" -H "Mai-Authentication: xxx" -H 'Content-Type: application/json'

Response:

{
  "status":0,
  "desc":"success"
}

HTTP Request

DELETE /orders

Body JSON Parameters

Parameter Description Required Type Example
marketID The ID of the market. True string "b2tods"

WebSocket API

Market Channel

Commands

{"type":"unsubscribe","channels":["Market#{market_id}"]}

{"type":"subscribe","channels":["Market#{market_id}"]}

When connected
{
  "type":"level2OrderbookSnapshot",
  "marketID":"BTC190712-DAI",
  "sequence": 1,
  "updatedAt": "2019-11-15T09:21:20.441646431Z",
  "bids":[],
  "asks":[]
}
When order updated
{
  "type":"level2OrderbookUpdate",
  "marketID":"BTC190712-DAI",
  "sequence": 1,
  "updatedAt": "2019-11-15T09:21:20.441646431Z",
  "side":"buy",
  "price":"8000",
  "amount":"0.0001"
}
Trade history (update)
{
  "type": "newMarketTrade",
  "trade": {
    "amount": "0.001",
    "createdAt": "2020-05-12T10:59:27.203513Z",
    "executedAt": "2020-05-12T10:59:30Z",
    "id": 31790,
    "maker": "0x21a0063d36411a11b806e5ed63fbc0631b459245",
    "makerFeeRate": "0",
    "makerOrderID": "0x2fae17564c04a51fecceb18b5348cb37d96ca29f9e1bd07f1793c7f42e55e3c3",
    "makerRebateRate": "0",
    "marketID": "bzym5b",
    "price": "8768.3",
    "sequence": 0,
    "status": "SUCCESS",
    "taker": "0x799b976ad9b5266631414c876e9635fa8f2dce96",
    "takerFeeRate": "0",
    "takerOrderID": "0xd867e0fa019810b004121c84437414bff092ff7475addfc3fca85939961134b3",
    "takerSide": "buy",
    "transactionHash": "0x5c77fc5273fce1ab31c3b62e0ab978d41aa44c49784036994612b5313ca1dca8",
    "transactionID": 31126,
    "transactionStatus": "SUCCESS"
  }
}

Trader Channel

Login Command(API)

{"type":"login","maiAuth":{AA}#{BB}@{CC}#{DD}}

{AA}: your ETH address begin with '0x'

{BB}: any string without '#'

{CC}: timestamp in milliseconds (ex: 1562076420000) or RFC3389 nano time string (ex: 2019-07-02T13:57:56.862Z)

{DD}: personalSign of "BB@CC" begin with '0x'. The sign format is "0x{r}{s}{v}" where {v} should be "1b" or "1c" according to HomsteadHash in EIP155.

Login Command(JWT)

GET /jwt with "Mai-Authentication" header described above.

Response:

{
  "status": 0,
  "desc": "success",
  "data": {
    "expires": 86400000, // in milliseconds
    "jwt": "<data>"
  }
}

Then save data into local storage.

{"type":"login","jwt":{data}}

Commands

{"type":"unsubscribe","channels":["TraderAddress#{eth_address}"]}

{"type":"subscribe","channels":["TraderAddress#{eth_address}"]}

When login success
{
  "type": "login",
  "code": 0,
  "desc": "login success"
}
When balance/locking changed
{
  "market_id":"BTC190712-DAI",
  "type":"lockedBalanceChange"
}
When creating an order
{
  "type": "orderChange",
  "order": {
    "amount": "1",
    "availableAmount": "1",
    "canceledAmount": "0",
    "confirmedAmount": "0",
    "createdAt": "2019-09-04T03:45:04.766591635Z",
    "gasFeeAmount": "0.165", // in collateral. example: DAI
    "id": "0x5b84b0033f053f5210cd6713aa4bc81cb86ecc2118228f32e8688c9d8209697e",
    "makerFeeRate": "0.001",
    "makerRebateRate": "0",
    "marketID": "BTC190712-DAI",
    "pendingAmount": "0",
    "price": "8000",
    "side": "buy",
    "status": "pending", // order status: pending, partial_filled, full_filled, canceled
    "takerFeeRate": "0.003",
    "traderAddress": "0xfe4493ce82fee8dcf1a4ea59026509237fc4cf75",
    "type": "limit",
    "updatedAt": "2019-09-04T03:45:04.772992938Z",
    "version": "mai-v1",
    "cancelReasons": []
  }
}
When canceling an order
{
  "type": "orderChange",
  "order": {
    "amount": "1",
    "availableAmount": "0",
    "canceledAmount": "1",
    "confirmedAmount": "0",
    "createdAt": "2019-09-04T03:45:04.766592Z",
    "gasFeeAmount": "0.165", // in collateral. example: DAI
    "id": "0x5b84b0033f053f5210cd6713aa4bc81cb86ecc2118228f32e8688c9d8209697e",
    "makerFeeRate": "0.001",
    "makerRebateRate": "0",
    "marketID": "BTC190712-DAI",
    "pendingAmount": "0",
    "price": "8000",
    "side": "buy",
    "status": "canceled", // order status: pending, partial_filled, full_filled, canceled
    "takerFeeRate": "0.003",
    "traderAddress": "0xfe4493ce82fee8dcf1a4ea59026509237fc4cf75",
    "type": "limit",
    "updatedAt": "2019-09-04T03:47:33.321000377Z",
    "version": "mai-v1",
    "cancelReasons": []
  }
}
When trade established or changed
{
  "type": "tradeChange",
  "trade": {
    "amount": "1",
    "createdAt": "2019-09-04T04:02:40.514986846Z",
    "executedAt": "0001-01-01T00:00:00Z",
    "id": "25",
    "maker": "0xfe4493ce82fee8dcf1a4ea59026509237fc4cf75",
    "makerOrderID": "0xc5096de1615b17530648e5dc50778a9eb40b9064b3266e33b7af2379282b3828",
    "marketID": "BTC190712-DAI",
    "price": "8000",
    "sequence": 0,
    "status": "pending", // trade status: INIT, SIGNED, SIGN_FAIL, PENDING, SUCCESS, EXECUTE_FAIL, ABORT
    "taker": "0xfe4493ce82fee8dcf1a4ea59026509237fc4cf75",
    "takerOrderID": "0x9c3f094821b3d4a8d3a281516864f75e38a5c1c5e5a6325ccc7e3e23569cd255",
    "takerSide": "buy",
    "transactionHash": "",
    "transactionID": "21",
    "updatedAt": "2019-09-04T04:02:40.515333505Z"
  }
}
When user's position is reducing
// v1
{
  "closedPosition": {
    "amount": "0.1",
    "closedAt": "2020-05-14T09:14:39Z",
    "contractSizeSymbol": "BTC",
    "entryPrice": "0.6",
    "exitPrice": "0.7",
    "id": "269",
    "marketID": "eilcan",
    "openedAt": "2020-05-14T08:56:24Z",
    "priceSymbol": "DAI",
    "protocol": "mai",
    "side": "short",
    "symbol": "ZPT18",
    "trader": "0xd595f7c2c071d3fd8f5587931edf34e92f9ad39f",
    "transactionHash": "0xa1daaeb8e13678379b7eb304074be3cde227168ce65f20bb7d5df20a4a3c30dc"
  },
  "type": "newClosedPosition"
}
// v2/perpetual
{
  "type": "newClosedPosition",
  "closedPosition": {
    "id": "2810",
    "transactionHash": "0xa669b90e27bf26d557ab447d5d8f729b3431cab02c141045ad226f77dfa3b92a",
    "trader": "0x9757400188f2f54b83ac4dc290ab89dde526da10",
    "marketID": "ETHPERP",
    "side": "short",
    "amount": "10",
    "openedAt": "2020-05-13T08:05:09Z",
    "closedAt": "2020-05-13T08:05:09Z",
    "protocol": "Perpetual",
    "entryPrice": "212.299999999999986",
    "exitPrice": "188.7900000000000097",
    "contractAddress": "0x7ec890cd2518737bcc2aca07ea485e5a019ff5d6",
    "contractType": "Perpetual",
    "marginBalance": "0.062303592894667123",
    "pnl": "-0.00589174563857326"
  }
}

DexStatus Channel

Command

{"type":"subscribe","channels":["DexStatus"]}

when connected
{
  "type": "dexStatusSnapshot",
  "marketsStatus": [
    // v1 mp
    {
      "marketID": "zs5apn",
      "contractType": "",
      "price24hGrowthRate": "0",
      "lastPrice": "147.3",
      "amount24h": "0",
      "volume24h": "0",
      "lastIndex": "148.29",
      "openInterest": "0",
      "markPrice": "0",
      "fundingRate": "0",
      "fundingRate8h": "0"
    },
    // v2 perpetual
    {
      "marketID": "ETHPERP",
      "contractType": "Perpetual",
      "price24hGrowthRate": "0.004657657930265206",
      "lastPrice": "190.091275456985497137",
      "amount24h": "6210",
      "volume24h": "33.22974969404055008",
      "lastIndex": "190.169999999999990178",
      "openInterest": "114010",
      "markPrice": "190.197159959949572016",
      "fundingRate": "0",
      "fundingRate8h": "0.00009989399110561",
      "perpetualGovParams": {
        "amm": "0x2878e0d91790c8517eb5ce8d8ba813b49b0a3fb7",
        "poolAccount": "0x2e8161237892b5bfdf044ae30d4573963a5f2eef",
        "withdrawalLockBlockCount": 3,
        "brokerLockBlockCount": 3,
        "initialMargin": "0.1",
        "maintenanceMargin": "0.075",
        "liquidationPenaltyRate": "0.005",
        "penaltyFundRate": "0.005",
        "makerDevRate": "0",
        "takerDevRate": "0",
        "lotSize": "10",
        "tradingLotSize": "10",
        "poolFeeRate": "0.0006",
        "poolDevFeeRate": "0.00015",
        "emaAlpha": "0.003327787021630616",
        "updatePremiumPrize": "0",
        "markPremiumLimit": "0.005",
        "fundingDampener": "0.0005"
      },
      "perpetualStorage": {
        "collateralTokenAddress": "0x0000000000000000000000000000000000000000",
        "shareTokenAddress": "0x530ae128fd9aa212058416ff113dc9c39f28c359",
        "totalSize": "114010",
        "longSocialLossPerContract": "0",
        "shortSocialLossPerContract": "0",
        "insuranceFundBalance": "0.057265040136574816",
        "isEmergency": false,
        "isGlobalSettled": false,
        "globalSettlePrice": "0",
        "accumulatedFundingPerContract": "-0.000056189613250251",
        "lastEMAPremium": "-0.000002112871920702",
        "lastPremium": "-0.000000128979522821",
        "lastIndexPrice": "0.005258452963138245",
        "lastFundingTimestamp": 1589284938
      },
      "perpetualType": "Inverse"
    },
  ]
}
when lastPrice changed in ANY market
{
  "type":"dexLastPriceChange",
  "status":
    {
      "lastIndex":"0",
      "lastPrice":"8500",
      "marketID":"BTC20290604-DAI"
    }
}
when ANY market goes into SETTLING status
{
  "type":"dexMarketContractStatusChange",
  "status":
    {
      "marketID":"BTC291001-DAI",
      "mpContractStatus":"SETTLING",
      "settlePrice":"6000",
      "settleTime":"2019-11-20T06:39:01Z"
    }
}
when ANY market goes into SETTLED status
{
  "type":"dexMarketContractStatusChange",
  "status":
    {
      "marketID":"BTC291001-DAI",
      "mpContractStatus":"SETTLED",
      "settlePrice":"6000",
      "settleTime":"2019-11-20T06:39:01Z"
    }
}

Errors

The MCDEX API uses the following error codes:

Error Code Meaning
-1 internal server error
-2 validation error
-3 http params error
-4 market not found
-5 invalid price amount
-6 order id do not exist
-7 bad signature
-8 insufficient balance
-9 insufficient allowance
-10 http params validation fail
-11 authentication failed
-12 order id do not exist or is not owned by current address
-13 http error
-14 api rate-limit error
-15 order expires must in range [5m, 30days]
-16 the contract is settled, forbidden to place orders
-17 invalid price, long price is greater than or equal to the settlement price
-18 invalid price, short price is less than or equal to the settlement price
-19 can not enter position by market order when the contract is expired
-20 no more active orders in this market