# Getting Started

## Prerequisites

* address
* active address
* apply to ZKEX Team to get `api key` and `api secret`
* depoly `market maker signer service` and send `signer url` to ZKEX Team

***

## Maintain trading pairs information

* Get all trading pairs infomation through the `REST` interface [BnGetProducts](https://github.com/ZKEX/dev-docs/tree/main/market-maker-apis#bngetproducts)
* Get any trading pair infomation through `ws`, subscribe channel [ws-level2](https://github.com/ZKEX/dev-docs/tree/main/market-maker-apis#ws-level2)
* When you subscribe to [ws-level2](https://github.com/ZKEX/dev-docs/tree/main/market-maker-apis#ws-level2) for the first time, you will receive the snapshot data by [push-snapshot](https://github.com/ZKEX/dev-docs/tree/main/market-maker-apis#push-snapshot)
* When the data of the [ws-level2](https://github.com/ZKEX/dev-docs/tree/main/market-maker-apis#ws-level2) changes, you will receive the data in the type of [l2update](https://github.com/ZKEX/dev-docs/tree/main/market-maker-apis#l2update)

***

## REST Interface (Recommend)

### Get the server time of ZKEX

{% tabs %}
{% tab title="Request" %}

* Http Method : `GET`
* Http Path : `/mm/api/server`
* Response :
  {% endtab %}

{% tab title="Response" %}

```
{
  "timeNow": 1650958799 
}
```

{% endtab %}
{% endtabs %}

***

### Get all trading pairs supported by ZKEX

{% tabs %}
{% tab title="Request" %}

* Http Method : `GET`
* Http Path : `/mm/api/products`
  {% endtab %}

{% tab title="Response" %}

```
[
    {
        "id": "XNY-USDT",
        "baseCurrency": "XNY",
        "quoteCurrency": "USDT",
        "baseMinSize": "10000000000000",      //base asset minimal amount
        "baseMaxSize": "10000000000000000000000000",    //unused
        "quoteIncrement": "10000000000000000",      //quote asset minimal amount
        "baseScale": -12,              //decimals
        "quoteScale": -16,      //decimals
        "l2symbolId": 2,                  // trading pair id on layer2
        "l2baseCurrencyId": 3,          // currency id on layer2
        "l2quoteCurrencyId": 4        // currency id on layer2
    },
    ......
]   
```

{% endtab %}
{% endtabs %}

***

### Get Market Maker's JWT-Token (use to subscribe Websocket)

{% tabs %}
{% tab title="Request" %}

* HTTP Method: `GET`
* HTTP Path: `/mm/api/users` (HMAC SHA256)
* HTTP Header: `X-MBX-APIKEY` : `api key`

**Parameters:**

<table><thead><tr><th width="154.21167883211677">Name</th><th width="106">Type</th><th width="108">Required</th><th>Example</th><th>Description</th></tr></thead><tbody><tr><td>timestamp</td><td>long</td><td>YES</td><td>1653983486</td><td>unix timestamp</td></tr></tbody></table>
{% endtab %}

{% tab title="Response" %}

<pre><code><strong>eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhZGRyZXNzIjoiMHgzNDk4ZjQ1NjY0NTI3MGVlMDAzNDQxZGY4MmM3MThiNTZjMGU2NjY2IiwiZXhwaXJlZEF0IjoxNjU0MDU1MDMzLCJpZCI6NDksInB1YmtleSI6IjBkZDRmNjAzNTMxYmQ3OGJiZWNkMDA1ZDllN2NjNjJhNzk0ZGNmYWRjZWZmZTAzZTI2OWZiYjZiNzJlOWM3MjQifQ.2S1wt6KxfJU8kxvESbrdUW1jxYyqxXlcIhL9DwtW3Yc
</strong></code></pre>

{% endtab %}
{% endtabs %}

***

### Get Market Maker's user info

{% tabs %}
{% tab title="Request" %}

* HTTP Method: `GET`
* HTTP Path: `/mm/api/self` (HMAC SHA256)
* HTTP Header: `X-MBX-APIKEY` : `api key`

**Parameters:**

<table><thead><tr><th width="158.21167883211677">Name</th><th width="80">Type</th><th width="123">Required</th><th>Example</th><th>Description</th></tr></thead><tbody><tr><td>timestamp</td><td>long</td><td>YES</td><td>1653983486</td><td>unix timestamp</td></tr></tbody></table>
{% endtab %}

{% tab title="Response" %}

```
{
    "id": 39,
    "address": "0x9f44be256f9b0797dc26bfeed70e57a4ac4258c6",
    "initHeight": 0,     
    "l2active": 1,            // 0: actived in layer2   1：not actived in layer2 
    "l2userId": 67,           // layer2 account id
    "userLevel": "v1",        // fee level
    "verifyType": 0,          // 0: common mode   1: unipass mode
    "chainId": 0              // layer2 chain id (only used in unipass mode)
}
```

{% endtab %}
{% endtabs %}

***

### Apply Order Slots Batchly

{% tabs %}
{% tab title="Request" %}

* HTTP Method: `GET`
* HTTP Path: `/mm/api/slot` (HMAC SHA256)
* HTTP Header: `X-MBX-APIKEY` : `api key`

**Parameters:**

<table><thead><tr><th width="141.21167883211677">Name</th><th width="93">Type</th><th width="117">Required</th><th>Example</th><th>Description</th></tr></thead><tbody><tr><td>timestamp</td><td>long</td><td>YES</td><td>1653983486</td><td>unix timestamp</td></tr><tr><td>count</td><td>int</td><td>YES</td><td>1</td><td></td></tr></tbody></table>
{% endtab %}

{% tab title="Response" %}

```
[
  {
    "slot":  10,             
    "nonce": 100
  }
]
```

{% endtab %}
{% endtabs %}

***

### New Order

Send in a new order.

{% tabs %}
{% tab title="Request" %}

* HTTP Method: `POST`
* HTTP Path: `/mm/api/orders` (HMAC SHA256)
* HTTP Header: `X-MBX-APIKEY` : `api key`
* API Limit: A single account is only allowed to send maximum of 30 new order per second

**Parameters:**

<table><thead><tr><th width="166.21167883211677">Name</th><th width="97">Type</th><th width="99">Required</th><th width="159">Example</th><th>Description</th></tr></thead><tbody><tr><td>clientOid</td><td>string</td><td>NO</td><td>1234</td><td>The order id from client</td></tr><tr><td>symbol</td><td>string</td><td>YES</td><td>UNI-USDC</td><td>The trading pair name</td></tr><tr><td>side</td><td>string</td><td>YES</td><td>SELL</td><td>SELL/BUY</td></tr><tr><td>type</td><td>string</td><td>YES</td><td>LIMIT</td><td>only support LIMIT now</td></tr><tr><td>timestamp</td><td>long</td><td>YES</td><td>1654060757</td><td>unix timestamp</td></tr><tr><td>timeInForce</td><td>string</td><td>YES</td><td>GTC</td><td>GTC/IOC/GTX/FOK</td></tr><tr><td>quantity</td><td>string</td><td>YES</td><td>20000000000000000000</td><td>decimals=18</td></tr><tr><td>price</td><td>string</td><td>YES</td><td>5000000000000000000</td><td>decimals=18</td></tr><tr><td>takerFeeRatio</td><td>int</td><td>YES</td><td>10</td><td>decimals=4</td></tr><tr><td>makerFeeRatio</td><td>int</td><td>YES</td><td>5</td><td>decimals=4</td></tr><tr><td>slot</td><td>int</td><td>YES</td><td>10</td><td></td></tr><tr><td>nonce</td><td>int</td><td>YES</td><td>310</td><td></td></tr><tr><td>userPubkey</td><td>string</td><td>YES</td><td>0dd4f603531bd78bbecd005d9e7cc62a794dcfadceffe03e269fbb6b72e9c724</td><td>zk-layer2 pubkey</td></tr><tr><td>orderSignature</td><td>string</td><td>YES</td><td>17039d98f87640c452ec4ab6bb91d2044a97ff516a920cd09bddacd774175a28d3836dc0d84c31cc862a1c1099f430adb3f7826bf97a086eba59b6ced3e4ef04</td><td>zk-layer2 signature for order</td></tr></tbody></table>
{% endtab %}

{% tab title="Response" %}

```
{
  "id": "1666371045063401472",
  "createdAt": 1650958799,
  "updatedAt": 1650958799,
  "productId": "UNI-USDT",
  "userId": 1,
  "clientOid": "1234",
  "size": "1000000000000000000",        
  "funds": "70000000",
  "filledSize": "0",
  "executedValue": "0", 
  "price": "70000000", 
  "fillFees": "0",
  "type": "limit",
  "side": "buy",
  "timeInForce": "GTC",     
  "status": "new",
  "l2Status": "none",
  "preSettled": false,
  "settled": false
}   
```

{% endtab %}
{% endtabs %}

***

### Cancel Order

{% tabs %}
{% tab title="Request" %}
Cancel an active order

* HTTP Method: `DELETE`
* HTTP Path: `/mm/api/order` (HMAC SHA256)
* HTTP Header: `X-MBX-APIKEY` : `api key`

**Parameters**

<table><thead><tr><th width="130.21167883211677">Name</th><th width="97">Type</th><th width="116">Required</th><th width="148">Example</th><th>Description</th></tr></thead><tbody><tr><td>timestamp</td><td>long</td><td>YES</td><td>1654060757</td><td>unix timestamp</td></tr><tr><td>symbol</td><td>string</td><td>YES</td><td>UNI-USDC</td><td>The trading pair name</td></tr><tr><td>orderId</td><td>int</td><td>YES</td><td>755</td><td></td></tr></tbody></table>
{% endtab %}

{% tab title="Response" %}
none
{% endtab %}
{% endtabs %}

***

### Cancel all Open Orders on a Symbol

{% tabs %}
{% tab title="Request" %}

* HTTP Meth: `DELETE`
* HTTP PATH: `/mm/api/orders` (HMAC SHA256)
* HTTP HEADER: `X-MBX-APIKEY` : `api key`

**Parameters:**

<table><thead><tr><th width="150.21167883211677">Name</th><th width="105">Type</th><th width="114">Required</th><th width="144">Example</th><th>Description</th></tr></thead><tbody><tr><td>timestamp</td><td>long</td><td>YES</td><td>1654060757</td><td>unix timestamp</td></tr><tr><td>symbol</td><td>string</td><td>YES</td><td>UNI-USDC</td><td>The trading pair name</td></tr></tbody></table>
{% endtab %}

{% tab title="Response" %}
none
{% endtab %}
{% endtabs %}

***

### Get all orders

{% tabs %}
{% tab title="Request" %}
Get all orders, includes `new`, `open`, `filled`, `cancelled`, `cancelling`, `partial`

* HTTP Method: `GET`
* HTTP PATH: `/mm/api/orders` (HMAC SHA256)
* HTTP HEADER: `X-MBX-APIKEY` : `api key`

**Parameters:**

<table><thead><tr><th width="137">Name</th><th width="87">Type</th><th width="102">Required</th><th width="139">Example</th><th>Description</th></tr></thead><tbody><tr><td>timestamp</td><td>long</td><td>YES</td><td>1654060757</td><td>unix timestamp</td></tr><tr><td>symbol</td><td>string</td><td>YES</td><td>UNI-USDC</td><td>The trading pair name</td></tr><tr><td>status</td><td>string</td><td>NO</td><td>filled filled,partial</td><td>The order status (support combined status)</td></tr><tr><td>startTime</td><td>long</td><td>YES</td><td>1</td><td></td></tr><tr><td>endTime</td><td>long</td><td>YES</td><td>1654063467</td><td></td></tr><tr><td>limit</td><td>int</td><td>YES</td><td>20</td><td></td></tr></tbody></table>
{% endtab %}

{% tab title="Response" %}

```
{
  "total": 1000,
  "orders": [{
    "id": "1666371045063401472",          # order id
    "userId": "28",      # user id
    "price": "9000000000000000",         
    "size": "2500000000",           
    "funds": "19997",                # price*size/pow(10,18)
    "productId": "UNI-USDT",
    "side": "sell",               # buy or sell
    "type": "limit",                
    "createdAt": 1650958799,
    "fillFees": "0",              
    "filledSize": "200000000",                 # The actual transaction quantity of the order
    "executedValue": "1800000",              # The actual transaction value of the order
    "status": "open",                   #order status   `new`, `open`,  `filled`, `cancelled`, `cancelling`, `partial`
    "l2Status": "none",                 #order layer2 status   `none`: init status          `confirming`:The order is fully filled, but not confirmed by layer2      `filled`:The order is fully filled, and confirmed by layer2      `cancelled`:The order has been cancelled, and cancelled in layer2          `partial`:The order is partial filled, and confirmed by layer2
    "preSettled": false,
    "settled": false,
    "chanFrom": 0,             #     0 : user order       1 : market maker order
    "trades": [{
     "id": 1,
     "time": 1650958799,
     "tradeSeq": 231628,
     "price": "9000000000000000",
     "takerOrderId": "1666371045063401472",
     "makerOrderId": "1666371045063401471",
     "size": "100000",
     "side": "buy",
     "status": 3,    # 0:not sent to layer2      1:sent to layer2      2:layer2 success    3:layer2 fail      9:matching fail(not sent to layer2)
     "productId": "UNI-USDT",
     "funds": "900",
     "txHash": "0x40acae664609d1115f5ab32d9f3c0fedd7609daa6a4a5515333f583fba10f545",
     "failReason": ""
    }, {
     "id": 2,
     "time": 1650958799,
     "tradeSeq": 231627,
     "price": "9000000000000000",
     "takerOrderId": "1666371045063401473",
     "makerOrderId": "1666371045063401474", 
     "size": "100000",
     "side": "buy",
     "status": 3,
     "productId": "UNI-USDT",
     "funds": "900",
     "txHash": "0x40acae664609d1115f5ab32d9f3c0fedd7609daa6a4a5515333f583fba10f545",
     "failReason": ""
    }],
    "cancelFill": {
     "id": 1,
     "time": 1650958799,
     "size": "199800000",
     "doneReason": "cancelled"
    }
    "isFullFill": true,   # If isFullFill is true, it means that the order has actually been filled completely. But `trade.status` may not be `filled` , but it will eventually become filled.
   }, {
    "id": "1666371045063401471",
    "userId": "28",      # user id
    "price": "8000000000000000",
    "size": "2500000000",
    "funds": "0",
    "productId": "BTC-USDT",
    "side": "buy",
    "type": "limit",
    "createdAt": 1650958799,
    "fillFees": "0",
    "filledSize": "0",
    "executedValue": "0",
    "status": "cancelled",
    "l2Status": "none",
    "preSettled": false,
    "settled": false,
    "trades": [{
     "id": 1,
     "time": 1650958799,
     "tradeSeq": 231628,
     "price": "8000000000000000",
     "takerOrderId": "1666371045063401471",
     "makerOrderId": "1666371045063401472",
     "size": "100000",
     "side": "buy",
     "status": 3,
     "productId": "UNI-USDT",
     "funds": "900",
     "txHash": "0x40acae664609d1115f5ab32d9f3c0fedd7609daa6a4a5515333f583fba10f545",
     "failReason": ""
    }, {
     "id": 2,
     "time": 1650958799,
     "tradeSeq": 231627,
     "price": "8000000000000000",
     "takerOrderId": "1666371045063401473",
     "makerOrderId": "1666371045063401474",
     "size": "100000",
     "side": "buy",
     "status": 3,
     "productId": "UNI-USDT",
     "funds": "900",
     "txHash": "0x40acae664609d1115f5ab32d9f3c0fedd7609daa6a4a5515333f583fba10f545",
     "failReason": ""
    }]
    "cancelFill": {
     "id": 1,
     "time": 1650958799,
     "size": "199800000",
     "doneReason": "cancelled"
   },
   "isFullFill": true   
  }]
 }    
```

{% endtab %}
{% endtabs %}

***

### Query Order

{% tabs %}
{% tab title="Request" %}
Check an order's status.

* HTTP Method: `GET`
* HTTP PATH: `/mm/api/order` (HMAC SHA256)
* HTTP Header: `X-MBX-APIKEY` : `api key`

**Parameters:**

<table><thead><tr><th width="143">Name</th><th width="95">Type</th><th width="112">Required</th><th width="147">Example</th><th>Description</th></tr></thead><tbody><tr><td>timestamp</td><td>long</td><td>YES</td><td>1654060757</td><td>unix timestamp</td></tr><tr><td>symbol</td><td>string</td><td>YES</td><td>UNI-USDC</td><td>The trading pair name</td></tr><tr><td>orderId</td><td>int</td><td>YES</td><td>755</td><td></td></tr></tbody></table>
{% endtab %}

{% tab title="Response" %}

<pre><code><strong>{
</strong>    "id": "1666371045063401472",    
    "userId": "28",
    "price": "9000000000000000",            
    "size": "2500000000",                
    "funds": "19997",              
    "productId": "UNI-USDT",
    "side": "sell",             
    "type": "limit",                      
    "createdAt": 1650958799,
    "fillFees": "0",                 
    "filledSize": "200000000",                
    "executedValue": "1800000",             
    "status": "open",  
    "l2Status": "none",
    "preSettled": false,
    "settled": false,
    "chanFrom": 0,              
    "trades": [{
     "id": 1,
     "time": 1650958799,
     "tradeSeq": 231628,
     "price": "9000000000000000",
     "takerOrderId": "1666371045063401473",
     "makerOrderId": "1666371045063401474",
     "size": "100000",
     "side": "buy",
     "status": 3,
     "productId": "UNI-USDT",
     "funds": "900",
     "txHash": "0x40acae664609d1115f5ab32d9f3c0fedd7609daa6a4a5515333f583fba10f545",
     "failReason": ""  
    }, {
     "id": 2,
     "time": 1650958799,
     "tradeSeq": 231627,
     "price": "9000000000000000",
     "takerOrderId": "1666371045063401472",
     "makerOrderId": "1666371045063401471", 
     "size": "100000",
     "side": "buy",
     "status": 3,
     "productId": "UNI-USDT",
     "funds": "900",
     "txHash": "0x40acae664609d1115f5ab32d9f3c0fedd7609daa6a4a5515333f583fba10f545",
     "failReason": ""
    }],
    "cancelFill": {
     "id": 1,
     "time": 1650958799,
     "size": "199800000",
     "doneReason": "cancelled"
    },
    "isFullFill": true 
}
</code></pre>

{% endtab %}
{% endtabs %}

***

### Get all open orders

{% tabs %}
{% tab title="Request" %}

* HTTP Method: `GET`
* HTTP Path: `/mm/api/openOrders` (HMAC SHA256)
* HTTP Header: `X-MBX-APIKEY` : `api key`

**Parameters:**

<table><thead><tr><th width="143">Name</th><th width="95">Type</th><th width="112">Required</th><th width="147">Example</th><th>Description</th></tr></thead><tbody><tr><td>timestamp</td><td>long</td><td>YES</td><td>1654060757</td><td>unix timestamp</td></tr><tr><td>symbol</td><td>string</td><td>YES</td><td>UNI-USDC</td><td>The trading pair name</td></tr><tr><td>limit</td><td>int</td><td>YES</td><td>20</td><td></td></tr></tbody></table>
{% endtab %}

{% tab title="Response" %}

```
{
  "total": 1000,
  "orders": [{
    "id": "1666371045063401472",          # order id
    "userId": "28",      # user id
    "price": "9000000000000000",         
    "size": "2500000000",           
    "funds": "19997",                # price*size/pow(10,18)
    "productId": "UNI-USDT",
    "side": "sell",               # buy or sell
    "type": "limit",                
    "createdAt": 1650958799,
    "fillFees": "0",              
    "filledSize": "200000000",                 # The actual transaction quantity of the order
    "executedValue": "1800000",              # The actual transaction value of the order
    "status": "open",                   #order status   `new`, `open`,  `filled`, `cancelled`, `cancelling`, `partial`
    "l2Status": "none",                 #order layer2 status   `none`: init status          `confirming`:The order is fully filled, but not confirmed by layer2      `filled`:The order is fully filled, and confirmed by layer2      `cancelled`:The order has been cancelled, and cancelled in layer2          `partial`:The order is partial filled, and confirmed by layer2
    "preSettled": false,
    "settled": false,
    "chanFrom": 0,             #     0 : user order       1 : market maker order
    "trades": [{
     "id": 1,
     "time": 1650958799,
     "tradeSeq": 231628,
     "price": "9000000000000000",
     "takerOrderId": "1666371045063401472",
     "makerOrderId": "1666371045063401471",
     "size": "100000",
     "side": "buy",
     "status": 3,    # 0:not sent to layer2      1:sent to layer2      2:layer2 success    3:layer2 fail      9:matching fail(not sent to layer2)
     "productId": "UNI-USDT",
     "funds": "900",
     "txHash": "0x40acae664609d1115f5ab32d9f3c0fedd7609daa6a4a5515333f583fba10f545",
     "failReason": ""
    }, {
     "id": 2,
     "time": 1650958799,
     "tradeSeq": 231627,
     "price": "9000000000000000",
     "takerOrderId": "1666371045063401473",
     "makerOrderId": "1666371045063401474", 
     "size": "100000",
     "side": "buy",
     "status": 3,
     "productId": "UNI-USDT",
     "funds": "900",
     "txHash": "0x40acae664609d1115f5ab32d9f3c0fedd7609daa6a4a5515333f583fba10f545",
     "failReason": ""
    }],
    "cancelFill": {
     "id": 1,
     "time": 1650958799,
     "size": "199800000",
     "doneReason": "cancelled"
    }
    "isFullFill": true,   # If isFullFill is true, it means that the order has actually been filled completely. But `trade.status` may not be `filled` , but it will eventually become filled.
   }, {
    "id": "1666371045063401471",
    "userId": "28",      # user id
    "price": "8000000000000000",
    "size": "2500000000",
    "funds": "0",
    "productId": "BTC-USDT",
    "side": "buy",
    "type": "limit",
    "createdAt": 1650958799,
    "fillFees": "0",
    "filledSize": "0",
    "executedValue": "0",
    "status": "cancelled",
    "l2Status": "none",
    "preSettled": false,
    "settled": false,
    "trades": [{
     "id": 1,
     "time": 1650958799,
     "tradeSeq": 231628,
     "price": "8000000000000000",
     "takerOrderId": "1666371045063401471",
     "makerOrderId": "1666371045063401472",
     "size": "100000",
     "side": "buy",
     "status": 3,
     "productId": "UNI-USDT",
     "funds": "900",
     "txHash": "0x40acae664609d1115f5ab32d9f3c0fedd7609daa6a4a5515333f583fba10f545",
     "failReason": ""
    }, {
     "id": 2,
     "time": 1650958799,
     "tradeSeq": 231627,
     "price": "8000000000000000",
     "takerOrderId": "1666371045063401473",
     "makerOrderId": "1666371045063401474",
     "size": "100000",
     "side": "buy",
     "status": 3,
     "productId": "UNI-USDT",
     "funds": "900",
     "txHash": "0x40acae664609d1115f5ab32d9f3c0fedd7609daa6a4a5515333f583fba10f545",
     "failReason": ""
    }]
    "cancelFill": {
     "id": 1,
     "time": 1650958799,
     "size": "199800000",
     "doneReason": "cancelled"
   },
   "isFullFill": true   
  }]
 }    
```

{% endtab %}
{% endtabs %}

***

### Account Info

{% tabs %}
{% tab title="Request" %}

* HTTP Method: `GET`
* HTTP Path: `/mm/api/accounts`
* HTTP HEADER: `X-MBX-APIKEY` : `api key`

**Parameters:**

<table><thead><tr><th width="143">Name</th><th width="95">Type</th><th width="112">Required</th><th width="147">Example</th><th>Description</th></tr></thead><tbody><tr><td>timestamp</td><td>long</td><td>YES</td><td>1654060757</td><td>unix timestamp</td></tr></tbody></table>
{% endtab %}

{% tab title="Response" %}

```
[
  {
   "id": "1",
   "currency": "USDC",
   "available": "952011220000",
   "hold": "1030410000000"
  }, {
   "id": "2",
   "currency": "USDT",
   "available": "4444030410000000",
   "hold": "766652011220000"
  }
]
```

{% endtab %}
{% endtabs %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.zkex.com/zkex2.0-market-maker-apis/getting-started.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
