# Sign

## 1. Signature Description

### 1.1. Update History

| Version Number | Date       | Author | Description                            |
| -------------- | ---------- | ------ | -------------------------------------- |
| 1.0.0          | 2024-04-10 | -      | Basic Information and Signature Method |

### 1.2. Basic Information

#### 1.1.1. API Basic Information

* API Key, secretKey

The interface requires the merchant's API Key. Please contact the business to apply. After the application is successful, the user's secretKey will be created at the same time for interface signature. This platform does not retain the secretKey, and merchants need to keep it properly.

* In this document, the data format of all interface requests and responses is in JSON format;
* In this document, the test environment format of all interfaces is <https://baseUrl/webhook/global/bizType>
* Where bizType is resource information, please refer to the permission description.
* baseUrl is the requested domain name or IP, please contact the operator to provide it
* All times, including requests and responses, are timestamps (UNIX time) in **milliseconds**.
* Test environment address: <https://pre-api-test.cmfbl.com/webhook>
* Formal environment address: <https://api.multimarkets.org/webhook>

#### 1.1.2. HTTP response status code

* HTTP 4XX error codes are used to indicate incorrect request content, behavior, and format. The problem lies with the requester.
* HTTP 403 error code indicates a violation of WAF restrictions (Web Application Firewall).
* HTTP 429 error code indicates a warning that the access frequency has exceeded the limit and the IP will be blocked.
* HTTP 418 indicates that the IP will be blocked if the access continues after receiving 429.
* HTTP 5XX error code is used to indicate problems on the service side of this platform.

#### 1.1.3. Access restrictions

* Currently, a single API-KEY cannot be accessed more than 100 times in 1 minute, otherwise 429 will be returned
* If you continue to access after 429 is returned, 418 will be returned
* When 418 is returned for the first time, it will be disabled for 5 minutes, and the next access will be disabled for 10 minutes, and so on.

### 1.2. Request method and authentication

#### 1.2.1 Request header

The general parameters related to the request need to be placed in the http request header. The request header parameters are as follows:

Request header description parameter description:

| Parameter name | Description                                                          | Data type | Required     |
| -------------- | -------------------------------------------------------------------- | --------- | ------------ |
| apiKey         | api\_key applied for through the platform                            | String    | Required     |
| recvWindow     | Time window, see "Request time security limit" below for its meaning | Integer   | Not required |
| timestamp      | Time when the request is sent (timestamp format, milliseconds)       | Integer   | Required     |
| signature      | Signature, see "Signature" below for signature calculation method.   | string    | required     |
| companyId      | company ID                                                           | integer   | required     |
| trace          | global link unique flag                                              | string    | required     |
| version        | resource version number                                              | string    | optional     |
| group          | resource grouping                                                    | string    | optional     |
| lang           | language information, default zh-CN                                  | string    | optional     |

Note: API-keys and secretKey are case-sensitive;\*\* Signature is case-sensitive\*\*

#### 1.2.2 Signature

The signature uses the SHA1WithRSA algorithm. The secretKey is used as the key of SHA1WithRSA, and the corresponding parameter in param + timestamp is used as the operation object of SHA1WithRSA. The output is the signature.

For the specific calculation method, see the "Example" in this chapter.

#### 1.2.3 Request time security limit

* When the server receives a request, it will determine the request parameter timestamp and compare it with the current server time. If it is sent before 5000 milliseconds (this time is called the time window, the default value is 5000), the request will be rejected.
* This time window value can be customized by sending the optional parameter recvWindow.

The logical pseudo code is as follows:

```
if (timestamp < (serverTime ) && (serverTime - timestamp) <= recvWindow){
// process request
}else{
// reject request
}
```

#### 1.2.4. Signature example

***Api Key***, ***secretKey***

```
companyId: 439 
apiKey: 1710e1f6b4b54c15bea72e8669966591 
secretKey: MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAI5WJjsBgtiuQQZDs5qe8LBDUm2ZSa4gTBJ+ztq 6HkY5P88MqPJuQA8GJ3ZJqAzS8xfFsSfdVDpbFiAjtZYzIbQM0g8e5bER55uGjxLaC2c1BdiHi49KfUdJHwZ1HWoKOtO6NRnNMWo94oBiYSP z4CJSzS2XPDHmGbfo/wOj/IQRAgMBAAECgYAFJAlnciuGpeyFTGatO/ZXd2b/vFyT5Gi69keEUNqNEL5EPSHQ97hqkn9UX16pb+kFv8chOHY1UVrgOEnzrc8Wws6bDb4JbniapUuT4kXZLlA13tO1MNwI xSZoEfajMZ4LUTx7TgDcCYgFhMJrk6dgQQEAsPMNlFy4YWxEV3A9TQJBANPiyCYujM1LN6lITX7HORne12Ns1cHuzZJMu1zMALR5xrktGSmP3kc5gVfmrEgI9YU0dw/I2hSnPc NzW5VogqMCQQCr+HxA88wRV5d28FYwynVA9r982guPj+vnlGfS6jc7cm4YhboSCc12YiZuvloHc676qz2CnH4PR1oCbwVs7v27AkEAqFOhbbPNZ8o5jeJCrlTWqBbARdxQdKCh73fF4RKv/LBB jxqkwr/odezZNFuswg1b/1aOv5twpLe3+W3LdAZywQJBAKVO6XIuaN3Ky0iD4vZnx6q5Bn1nxHEuMeCcoej3SDyW1QoxkhnA3oaL9tHBnR1IsM05SpmBARSCzB1Gx3pdif0CQQCygtbpk ypR+dbuj+P9x0ei49IMJZCSB7wlehJtWlRjvK3IFeOaG0lN0ioO9/jET33eo1ekCwvGZDB72FKgcYb/
```

**The actual business request parameters are as follows**

```
{"companyId":1,"lang":"zh-CN","customerNo":"86001308"}
```

**Calculate the signature:**

**The first step** is to get the request parameters in the body. After the parameters are sorted alphabetically, they form the following string:

```
{"companyId":1,"customerNo":"86001308","lang":"zh-CN"}
```

Description:

* The sorting method of "parameters sorted alphabetically" is to sort from small to large letters, starting from the first letter, and if they are the same, compare the second letter, and if they are the same, compare the third letter, and so on.
* Remove all double quotes, whether they are in the field name or the field value;
* No spaces in the middle;
* If the field is null, it will not be included in the signature

**Step 2**, get the timestamp parameter of the request header and concatenate it after the result of the first step:

```
{companyId:1,customerNo:86001308,lang:zh-CN}1650361143685
```

**Step 3**, use secretKey to sign the result of the second step through SHA1WithRSA, the result is as follows :

```
Dihl6oOt5UkaHo9sEouquP3EqbukLX2dAOoKTSGicYryTvH1m9r6vtSLHGutZn7u34/06gjhdpbXRFPdjb51GVHvG75qWXZ1P/boL89xtuja6eTEy9q/aS8R270Q1A+m/MOTxdiifCy0IByrSpCs4VJKaj2d8jlJo2GHznsH+q0=
```

**Attachment:** **java** **version** [**demo**](https://github.com/CTradeExchange/sign-demo)**.**

#### 1.2.5 Response format

Use JSON format.

All responses, unified format:

```
{
"msg": "description",
"fail": true,
"trace": "request unique identifier",
"code": "response code",
"data": {},
"bizCode": "business code",
"tm": 0,
"msgParams": "abnormal parameters",
"ok": true
}
```

Description:

* code: judge whether the response is successful based on the code, code "0" means success; others are error codes, see "Response Error Code".
* message: is the description information corresponding to the code, such as "request successful".
* data is the business data part of the response. See each interface for details.

### 1.3. General error code

| Code     | Description                                 |
| -------- | ------------------------------------------- |
| 00012001 | Failed to verify signature                  |
| 00012002 | Request has exceeded time window            |
| 00012003 | Requested API\_KEY does not exist           |
| 00012004 | Currently no permission to request this API |
| 00012005 | Too frequent requests                       |
| 00012006 | API has expired                             |
| 00012007 | Illegal IP address                          |

Note: For specific business interface error codes, please refer to the specific interface description document


---

# 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.multimarkets.org/bridge-api/access-instructions/sign.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.
