NAV
shell java python javascript

Introduction

Welcome to the Earn enterprise OpenAPI Documentation! This guide equips enterprise user with essential tools for seamless integration with our platform. Explore endpoints, request/response formats, authentication methods, and best practices to optimize your earn strategies.

Our support team is available for any assistance. Let's enhance financial together!

Prod urls

We have following base urls:

env Prod
UI https://m2.com
REST API https://openapi.m2.com

HTTP Response Handling

We have three types of responses:

  1. Normal response with a 200 HTTP header.
  2. Error response with a 4xx/5xx HTTP header.
  3. Error response with a 200 HTTP header (legacy part).

You need to handle all three cases to successfully integrate, especially the third one. For the third case, you should validate each response for internal body content to understand if you get an error or not. Your program should validate each 200 HTTP header response to ensure it doesn't contain keywords "code" and "msg". If it does, validate the string value of "code". If it's not 200, assume that you have an error.

Examples:

Normal Response: Status: 200

{
    "orderId": 3000000013200078,
    "clOrdId": "api_99313426_1699341538302",
    "symbol": "MMX-USDT",
    "transactTime": 1699341538302
}

Error Response: Status: 400 (can be any 4xx status, but in most cases just 400)

{
    "code": "100200",
    "msg": "business error",
    "userMsg": "Invalid field for market buy order: orderQty"
}

Error Response: Status: 200 (handle this case too to ensure your 200 is not a real error)

{
    "code": "500",
    "msg": "amount_too_small",
    "data": null
}

API Key & Signature

All private endpoints, including 2 websocket private endpoints, require authentication using an apiKey.

Get apiKey & secretKey

Currently, you can generate an apiKey from the UI directly. Below is a 5-step example of how to get an apiKey:

  1. Login into the UI.
  2. Go to the API Manage page to create api key.

Step 5 (create apiKey with read & write privilege, select the permission group you want)

  1. Enable reading (Read only)
    • /earn-api/v1/user/apply/currentList
    • /earn-api/v1/user/apply/detail
    • /earn-api/v1/user/apply/interest
    • /earn-api/v1/user/apply/preview
    • /earn-api/v1/user/plan/detail
    • /earn-api/v1/user/redeem/preview
  2. Create/modify subscription (Include Enable Reading)
    • /earn-api/v1/user/plan/apply
    • /earn-api/v1/user/plan/detail/edit
  3. Early redemption (Include Enable Reading)
    • /earn-api/v1/user/apply/redeem
  4. Enterprise Admin (Include Enable Reading)
    • /earn-api/v1/user/earn/plans/list
    • /earn-api/v1/user/edit/enterpriseMargin
    • /earn-api/v1/user/yield/manage/list

Sign the request with secretKey

Example to request position API

# Generate signature using HMAC SHA256 algorithm
API_KEY=YOUR_API_KEY
SECRET=YOUR_SECRET
# Send GET request to query earn plans
# Replace YOUR_TIMESTAMP with timestamp
curl -H 'Content-Type: application/json' -H "EXCHANGE-API-TIMESTAMP: YOUR_TIMESTAMP" -H "EXCHANGE-API-KEY: $API_KEY" -H "EXCHANGE-API-SIGN: $SIG" https://openapi.m2.com/earn-api/v1/user/plan/list
# Generate signature using HMAC SHA256 algorithm
# Replace YOUR_TIMESTAMP with timestamp
SIG=hmac('YOUR_TIMESTAMPPOST/earn-api/v1/user/plan/list', $SECRET)
# Send POST request to validate write API (moduleId=6)
# Replace YOUR_TIMESTAMP with timestamp
curl -H 'Content-Type: application/json' -H "EXCHANGE-API-TIMESTAMP: YOUR_TIMESTAMP" -H "EXCHANGE-API-KEY: $API_KEY" -H "EXCHANGE-API-SIGN: $SIG" -d '{"planId": "11","amount": 15,"autoRenew":true,"lockDay":15}' https://openapi.m2.com/earn-api/v1/user/plan/apply
# generate signature using HMAC SHA256 algo for POST request
SIG=hmac('YOUR_TIMESTAMPPOST/earn-api/v1/user/plan/apply{"planId": "11","amount": 15,"autoRenew":true,"lockDay":15}', $SECRET)
# Generate signature using HMAC SHA256 algorithm (pay attention that we don't use `?` in signature, we concatenate path+query without `?`)
# Replace YOUR_TIMESTAMP with timestamp
SIG=hmac('YOUR_TIMESTAMPGET/earn-api/v1/user/apply/detailapplyId=2000032', $SECRET)
# Send GET request to validate read API (moduleId=6) with "URL query params"
# Replace YOUR_TIMESTAMP with timestamp
curl -H 'Content-Type: application/json' -H "EXCHANGE-API-TIMESTAMP: YOUR_TIMESTAMP" -H "EXCHANGE-API-KEY: $API_KEY" -H "EXCHANGE-API-SIGN: $SIG" 'https://openapi.m2.com/earn-api/v1/user/apply/detail?applyId=2000032'
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.io.IOException;
import java.time.Instant;

public class Main {
 private static final String API_KEY = "YOUR_API_KEY";
    private static final String SECRET = "YOUR_SECRET_KEY";

    public static void main(String[] args) {
        sendGetRequestForPlanList();
        sendPostRequestApplyEarnPlan();
        sendGetRequestForApplyDetails();
    }

    private static void sendGetRequestForPlanList() {
        try {
            String url = "https://openapi.m2.com/earn-api/v1/user/plan/list";
            String timestamp = String.valueOf(Instant.now().toEpochMilli());
            String signature = generateSignature("GET", "/earn-api/v1/user/plan/list", "", timestamp);

            URL apiUrl = new URL(url);
            HttpURLConnection connection = (HttpURLConnection) apiUrl.openConnection();
            connection.setRequestMethod("GET");
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setRequestProperty("EXCHANGE-API-TIMESTAMP", timestamp);
            connection.setRequestProperty("EXCHANGE-API-KEY", API_KEY);
            connection.setRequestProperty("EXCHANGE-API-SIGN", signature);

            // Handle response...
            handleResponse(connection);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void sendPostRequestApplyEarnPlan() {
        try {
            String url = "https://openapi.m2.com/earn-api/v1/user/plan/apply";
            String timestamp = String.valueOf(Instant.now().toEpochMilli());
            String requestBody = "{\"planId\": \"11\",\"amount\": 15,\"autoRenew\":true,\"lockDay\":15}";
            String signature = generateSignature("POST", "/earn-api/v1/user/plan/apply", requestBody, timestamp);

            URL apiUrl = new URL(url);
            HttpURLConnection connection = (HttpURLConnection) apiUrl.openConnection();
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setRequestProperty("EXCHANGE-API-TIMESTAMP", timestamp);
            connection.setRequestProperty("EXCHANGE-API-KEY", API_KEY);
            connection.setRequestProperty("EXCHANGE-API-SIGN", signature);

            connection.setDoOutput(true);
            connection.getOutputStream().write(requestBody.getBytes(StandardCharsets.UTF_8));

            // Handle response...
            handleResponse(connection);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void sendGetRequestForApplyDetails() {
        try {
            String url = "https://openapi.m2.com/earn-api/v1/user/apply/detail?applyId=2000032";
            String timestamp = String.valueOf(Instant.now().toEpochMilli());
            String signature = generateSignature("GET", "/earn-api/v1/user/apply/detail", "applyId=2000032", timestamp);

            URL apiUrl = new URL(url);
            HttpURLConnection connection = (HttpURLConnection) apiUrl.openConnection();
            connection.setRequestMethod("GET");
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setRequestProperty("EXCHANGE-API-TIMESTAMP", timestamp);
            connection.setRequestProperty("EXCHANGE-API-KEY", API_KEY);
            connection.setRequestProperty("EXCHANGE-API-SIGN", signature);

            // Handle response...
            handleResponse(connection);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

 private static String generateSignature(String method, String path, String params, String timestamp) throws NoSuchAlgorithmException, InvalidKeyException {
        String data = timestamp + method + path + params;
        Mac mac = Mac.getInstance("HmacSHA256");
        SecretKeySpec secretKeySpec = new SecretKeySpec(SECRET.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
        mac.init(secretKeySpec);
        byte[] hmacData = mac.doFinal(data.getBytes(StandardCharsets.UTF_8));
        // convert bytes to hex
        StringBuilder result = new StringBuilder();
        for (byte b : hmacData) {
            result.append(String.format("%02x", b));
        }
        return result.toString();
    }

    private static void handleResponse(HttpURLConnection connection) throws IOException {
        int responseCode = connection.getResponseCode();
        System.out.println("Response Code: " + responseCode);

        BufferedReader in;
        if (responseCode == HttpURLConnection.HTTP_OK) {
            in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        } else {
            in = new BufferedReader(new InputStreamReader(connection.getErrorStream()));
        }

        StringBuilder response = new StringBuilder();
        String inputLine;
        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();

        // Print the response body
        System.out.println("Response Body: " + response.toString());
    }
}
import requests
import hashlib
import hmac
import time
import json

API_KEY = "YOUR_API_KEY"
SECRET = "YOUR_API_SECRET"


def send_get_request_for_plan_list():
    try:
        url = "https://openapi.m2.com/earn-api/v1/user/plan/list"
        timestamp = str(int(time.time() * 1000))
        signature = generate_signature("GET", "/earn-api/v1/user/plan/list", "", timestamp)

        headers = {
            "Content-Type": "application/json",
            "EXCHANGE-API-TIMESTAMP": timestamp,
            "EXCHANGE-API-KEY": API_KEY,
            "EXCHANGE-API-SIGN": signature
        }

        response = requests.get(url, headers=headers)
        handle_response(response)

    except Exception as e:
        print(e)


def send_post_request_for_apply_plan():
    try:
        url = "https://openapi.m2.com/earn-api/v1/user/plan/apply"
        timestamp = str(int(time.time() * 1000))
        request_body = {
            "planId": "11",
            "amount": 15,
            "autoRenew": true,
            "lockDay": "15"
        }
        request_body_json = json.dumps(request_body)
        signature = generate_signature("POST", "/earn-api/v1/user/plan/apply", request_body_json, timestamp)

        headers = {
            "Content-Type": "application/json",
            "EXCHANGE-API-TIMESTAMP": timestamp,
            "EXCHANGE-API-KEY": API_KEY,
            "EXCHANGE-API-SIGN": signature
        }

        response = requests.post(url, headers=headers, data=request_body_json)
        handle_response(response)

    except Exception as e:
        print(e)


def send_get_request_for_apply_detail():
    try:
        url = "https://openapi.m2.com/earn-api/v1/user/apply/detail?applyId=2000032"
        timestamp = str(int(time.time() * 1000))
        signature = generate_signature("GET", "/earn-api/v1/user/apply/detail", "applyId=2000032", timestamp)

        headers = {
            "Content-Type": "application/json",
            "EXCHANGE-API-TIMESTAMP": timestamp,
            "EXCHANGE-API-KEY": API_KEY,
            "EXCHANGE-API-SIGN": signature
        }

        response = requests.get(url, headers=headers)
        handle_response(response)

    except Exception as e:
        print(e)


def generate_signature(method, path, params, timestamp):
    data = timestamp + method + path + params
    signature = hmac.new(SECRET.encode('utf-8'), data.encode('utf-8'), hashlib.sha256).hexdigest()
    return signature


def handle_response(response):
    print("Response Code:", response.status_code)
    print("Response Body:", response.text)


def main():
    send_get_request_for_positions()
    send_post_request_for_order()
    send_get_request_for_completed_orders()


if __name__ == "__main__":
    main()
const axios = require('axios');
const crypto = require('crypto');

const API_KEY = "YOUR_API_KEY"
const SECRET = "YOUR_SECRET_KEY"


function sendGetRequestForPlanList() {
    try {
        const url = "https://openapi.m2.com/earn-api/v1/user/plan/list";
        const timestamp = Math.floor(Date.now());
        const signature = generateSignature("GET", "/earn-api/v1/user/plan/list", "", timestamp);

        const headers = {
            "Content-Type": "application/json",
            "EXCHANGE-API-TIMESTAMP": timestamp,
            "EXCHANGE-API-KEY": API_KEY,
            "EXCHANGE-API-SIGN": signature
        };

        axios.get(url, { headers })
            .then(response => handleResponse(response))
            .catch(error => console.error(error));
    } catch (error) {
        console.error(error);
    }
}

function sendPostRequestApplyEarnPlan() {
    try {
        const url = "https://openapi.m2.com/earn-api/v1/user/plan/apply";
        const timestamp = Math.floor(Date.now());
        const requestBody = {
            planId: "11",
            amount: 15,
            autoRenew: true,
            lockDay: 15
        };
        const request_body_json = JSON.stringify(requestBody);
        const signature = generateSignature("POST", "/earn-api/v1/user/plan/apply", request_body_json, timestamp);

        const headers = {
            "Content-Type": "application/json",
            "EXCHANGE-API-TIMESTAMP": timestamp,
            "EXCHANGE-API-KEY": API_KEY,
            "EXCHANGE-API-SIGN": signature
        };

        axios.post(url, request_body_json, { headers })
            .then(response => handleResponse(response))
            .catch(error => console.error(error));
    } catch (error) {
        console.error(error);
    }
}

function sendGetRequestForApplyDetails() {
    try {
        const url = "https://openapi.m2.com/earn-api/v1/user/apply/detail?applyId=2000032";
        const timestamp = Math.floor(Date.now());
        const signature = generateSignature("GET", "/earn-api/v1/user/apply/detail", "applyId=2000032, timestamp);

        const headers = {
            "Content-Type": "application/json",
            "EXCHANGE-API-TIMESTAMP": timestamp,
            "EXCHANGE-API-KEY": API_KEY,
            "EXCHANGE-API-SIGN": signature
        };

        axios.get(url, { headers })
            .then(response => handleResponse(response))
            .catch(error => console.error(error));
    } catch (error) {
        console.error(error);
    }
}

function generateSignature(method, path, params, timestamp) {
    const data = timestamp + method + path + params;
    const signature = crypto.createHmac('sha256', SECRET).update(data).digest('hex');
    return signature;
}

function handleResponse(response) {
    console.log("Response Code:", response.status);
    console.log("Response Body:", response.data);
}

function main() {
    sendGetRequestForPlanList();
    sendPostRequestApplyEarnPlan();
    sendGetRequestForApplyDetails();
}

main();

REST API

Public Endpoints

Query Earn Plans

Get all available earn plans.

Request

// No Request Param
# Request
curl -X GET https://openapi.m2.com/earn-api/v1/user/plan/list

// Request
import java.net.HttpURLConnection;
import java.net.URL;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class HttpRequest {
    public static void main(String[] args) {
        try {
            String url = "https://openapi.m2.com/earn-api/v1/user/plan/list";
            URL apiUrl = new URL(url);
            HttpURLConnection connection = (HttpURLConnection) apiUrl.openConnection();
            connection.setRequestMethod("GET");
            connection.setRequestProperty("Content-Type", "application/json");

            // Handle response...
            int responseCode = connection.getResponseCode();

            System.out.println("Response Code: " + responseCode);

            BufferedReader in;
            if (responseCode == HttpURLConnection.HTTP_OK) {
                in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            } else {
                in = new BufferedReader(new InputStreamReader(connection.getErrorStream()));
            }

            StringBuilder response = new StringBuilder();
            String inputLine;
            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();

            // Print the response body
            System.out.println("Response Body: " + response.toString());
        } catch (Exception e) {
              e.printStackTrace();
        }
    }
}
// Request
const axios = require("axios");

axios.get('https://openapi.m2.com/earn-api/v1/user/plan/list')
    .then(response => {
        console.log(response.data);
    })
    .catch(error => {
        console.error('Error:', error);
    });
# Request
import requests

response = requests.get('https://openapi.m2.com/earn-api/v1/user/plan/list')
print("Response Code:", response.status_code)
print("Response:", response.json())

Request Fields
N/A

Response

// Response
{
    "code": "0",
    "msg": "success",
    "data": [
        {
            "planId": "2000015",
            "planType": 2,
            "planName": "CAKE Fixed 15",
            "apr": null,
            "coin": "CAKE",
            "lockDay": 15,
            "minLockDay": null,
            "maxLockDay": null,
            "userAmountMin": 2,
            "userAmountMax": 4,
            "supportEarlyRedemption": true,
            "label": "POPULAR",
            "applyId": null,
            "maxApr": null,
            "minApr": null,
            "supportAutoRenew": true
        },
        {
            "planId": "3009763",
            "planType": 3,
            "planName": "SHIB Custom 15 to 60",
            "apr": null,
            "coin": "SHIB",
            "lockDay": null,
            "minLockDay": 15,
            "maxLockDay": 60,
            "userAmountMin": 1,
            "userAmountMax": 11,
            "supportEarlyRedemption": true,
            "label": "POPULAR",
            "applyId": null,
            "maxApr": null,
            "minApr": null,
            "supportAutoRenew": true
        }
    ],
    "succ": true
}

Response Fields

json field name type description
planId string plan id
planType int 1-flexible, 2-fix, 3-customized
apr decimal plan apr - annual percentage yield
coin string plan coin
label decimal plan label
lockDay int for fix plan
supportEarlyRedemption boolean it's support early redeem
userAmountMax decimal user amount max
userAmountMin decimal user amount min
minlockDay int for customized plan
maxLockDay int for customized plan
supportAutoRenew boolean support auto renew
maxApr decimal max Apr
minApr decimal min Apr

Private Endpoints

For private endpoints, we've included a few examples demonstrating signature generation. For all other endpoints, remember to include a signature to ensure successful requests.

Query one plan detail

Request

// Request parameters 
- planId: required = true;
# Request
curl -H "EXCHANGE-API-TIMESTAMP: YOUR_TIMESTAMP" -H "EXCHANGE-API-KEY: $API_KEY" -H "EXCHANGE-API-SIGN: $SIG" 'https://openapi.m2.com/earn-api/v1/user/plan/detail?planId=FIX00002' 
// Request
import java.net.HttpURLConnection;
import java.net.URL;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class HttpRequest {
    public static void main(String[] args) {
       try {
            String planId = "FIX00002";
            String url = "https://openapi.m2.com/earn-api/v1/user/plan/detail?planId=" + planId;
            URL apiUrl = new URL(url);
            HttpURLConnection connection = (HttpURLConnection) apiUrl.openConnection();
            connection.setRequestMethod("GET");
            connection.setRequestProperty("Content-Type", "application/json");

            // Handle response...
            int responseCode = connection.getResponseCode();

            System.out.println("Response Code: " + responseCode);

            BufferedReader in;
            if (responseCode == HttpURLConnection.HTTP_OK) {
                in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            } else {
                in = new BufferedReader(new InputStreamReader(connection.getErrorStream()));
            }

            StringBuilder response = new StringBuilder();
            String inputLine;
            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();

            // Print the response body
            System.out.println("Response Body: " + response.toString());
        } catch (Exception e) {
              e.printStackTrace();
        }
    }
}
// Request
const axios = require('axios');

const planId = 'FIX00002';
const url = `https://openapi.m2.com/earn-api/v1/user/plan/detail?planId=${planId}`;

axios.get(url)
    .then(response => {
        console.log(response.data);
    })
    .catch(error => {
        console.error('Error:', error);
    });
# Request
import requests

planId = 'FIX00002'
url = f'https://openapi.m2.com/earn-api/v1/user/plan/detail?planId={planId}'

response = requests.get(url)
print("Response Code:", response.status_code)
print("Response:", response.json())

Request Fields

json field name type required description
planId string Y earn plan id

Response

// Response
{
    "code": "0",
    "msg": "success",
    "data": {
        "apy": 0.12,
        "coin": "BTC",
        "label": "NEW",
        "lockDay": 10, // for fix plan
        "planId": "FIX00002",
        "planType": 2, // 1-flexible,2-fix,3-customized
        "supportEarlyRedemption": true,
        "userAmountMax": 0,
        "userAmountMin": 0,
        "minlockDay":20, // for customized plan
        "maxLockDay":360, // for customized plan
        "supportAutoRenew": true
    }
}

Response Fields

json field name type description
planId string plan id
planType int 1-flexible, 2-fix, 3-customized
apr decimal plan apr - annual percentage yield
coin string plan coin
label decimal plan label
lockDay int for fix plan
supportEarlyRedemption boolean it's support early redeem
userAmountMax decimal user amount max
userAmountMin decimal user amount min
minlockDay int for customized plan
maxLockDay int for customized plan
supportAutoRenew boolean support auto renew
maxApr decimal max Apr
minApr decimal min Apr

Apply plan Preview

When you have applied for a flexible plan, the response is an overview of add funds, otherwise it is an apply plan overview

curl -H "EXCHANGE-API-TIMESTAMP: YOUR_TIMESTAMP" -H "EXCHANGE-API-KEY: $API_KEY" -H "EXCHANGE-API-SIGN: $SIG" 'https://openapi.m2.com/earn-api/v1/user/apply/preview?planId=FIX00002&amount=10&day=10' 
import java.net.HttpURLConnection;
import java.net.URL;
import java.io.OutputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class HttpRequest {
    public static void main(String[] args) {
        try {
            String planId = "FIX00002";
            BigDecimal amount = 10;
            Integer day = 10;
            String url = "https://openapi.m2.com/earn-api/v1/user/apply/preview?planId=" + planId + "&amount=" + amount + "&day=" + day;
            URL apiUrl = new URL(url);
            HttpURLConnection connection = (HttpURLConnection) apiUrl.openConnection();
            connection.setRequestMethod("GET");
            connection.setRequestProperty("Content-Type", "application/json");

            // Handle response...
            int responseCode = connection.getResponseCode();

            System.out.println("Response Code: " + responseCode);

            BufferedReader in;
            if (responseCode == HttpURLConnection.HTTP_OK) {
                in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            } else {
                in = new BufferedReader(new InputStreamReader(connection.getErrorStream()));
            }

            StringBuilder response = new StringBuilder();
            String inputLine;
            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();

            // Print the response body
            System.out.println("Response Body: " + response.toString());
        } catch (Exception e) {
              e.printStackTrace();
        }
    }
}
import requests
planId = 'FIX00002'
amount = 10
day = 10
url = f'https://openapi.m2.com/earn-api/v1/user/apply/preview?planId={planId}&amount={amount}&day={day}'

response = requests.get(url)
print("Response Code:", response.status_code)
print("Response:", response.json())
// Request
const axios = require('axios');

const planId = 'FIX00002';
const amount = 10;
const day =10
const url = `https://openapi.m2.com/earn-api/v1/user/apply/preview?planId=${planId}&amount=${amount}&day=${day}`;

axios.get(url)
    .then(response => {
        console.log(response.data);
    })
    .catch(error => {
        console.error('Error:', error);
    });

Request Fields

json field name type required description
planId string Y earn plan id
amount string N calculate earn amount
day string N customize plan calculate

Response

// Response
{
  "code": "0",
  "msg": "success",
  "data": {
    "planId": "10",
    "amount": 100,
    "coin": "BTC",
    "apy": 0.056,
    "totalApy":0.068, // apy + booster apy
    "planType": 2, // 1-flexible,2-fix,3-customized
    "lockDay": 10,
    "interestAmount": 5.6, // not boost interestAmount
    "totalInterestAmount":12.2, // interestAmount + booste interestAmount
    "rewardFrequency": 1, // unit is day
    "appliedAmount": 2, // only flexible plan add funds will have value
    "userAmountMin":1, // user amount mininum amount
    "userAmountMax":3, // user amount max amount
    "startDate":1669197621000, // earn start date,timestamp in millisecond
    "endDate":1669207621000, // earn end date if plan type is flexible will be null,timestamp in millisecond
    "boosterInfo": { // booster info
      "apy": 0.012, //boosted apy
      "boosterAmount": 100, //boost need amount
      "coin": "MMX", // boost coin symbol
      "interestAmount": 6.6 //boost interest amount
    },
    "supportAutoRenew": true
  }
}

Response Fields

json field name type description
planId string plan id
amount decimal amount
apr decimal plan apr - annual percentage yield
coin string plan coin
totalApr decimal apr + booster apr
lockDay int for fix plan
planType boolean 1-flexible,2-fix,3-customized
interestAmount decimal not boost interestAmount
totalInterestAmount decimal interestAmount + booste interestAmount
rewardFrequency int unit is day
appliedAmount decimal only flexible plan add funds will have valu
userAmountMin decimal user amount mininum amount
userAmountMax decimal max Apr
startDate date earn start date,timestamp in millisecond
endDate date earn end date if plan type is flexible will be null,timestamp in millisecond
boosterInfo Object booster info
supportAutoRenew boolean booster info

Apply Plan Or Add Funds

Request

// Request body
{
  "planId": "11", // plan id
  "amount": 15,
  "lockDay":15 // only for customer plan
}
curl -H 'Content-Type: application/json' -H "EXCHANGE-API-TIMESTAMP: YOUR_TIMESTAMP" -H "EXCHANGE-API-KEY: $API_KEY" -H "EXCHANGE-API-SIGN: $SIG" -d '{"planId":"11","amount":15,"lockDay":15}' https://openapi.m2.com/earn-api/v1/user/plan/apply
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.io.IOException;
import java.time.Instant;

public class Main {

    private static final String API_KEY = "YOUR_API_KEY";
    private static final String SECRET = "YOUR_SECRET";

    private static final String REQUEST_METHOD = "POST";

    public static void main(String[] args) {
        try {
            String url = "https://openapi.m2.com/earn-api/v1/user/plan/apply";
            String timestamp = String.valueOf(System.currentTimeMillis());
            String requestBody = "{\"planId\":\"11\",\"amount\":15,\"lockDay\":15}";
            String signature = generateSignature(REQUEST_METHOD, "/earn-api/v1/user/plan/apply", requestBody, timestamp);

            URL apiUrl = new URL(url);
            HttpURLConnection connection = (HttpURLConnection) apiUrl.openConnection();
            connection.setRequestMethod(REQUEST_METHOD);
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setRequestProperty("EXCHANGE-API-TIMESTAMP", timestamp);
            connection.setRequestProperty("EXCHANGE-API-KEY", API_KEY);
            connection.setRequestProperty("EXCHANGE-API-SIGN", signature);
            connection.setDoOutput(true);

            try (OutputStream os = connection.getOutputStream()) {
                byte[] input = requestBody.getBytes(StandardCharsets.UTF_8);
                os.write(input);
            }

            int responseCode = connection.getResponseCode();
            System.out.println("Response Code: " + responseCode);


            BufferedReader in;
            if (responseCode == HttpURLConnection.HTTP_OK) {
                in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            } else {
                in = new BufferedReader(new InputStreamReader(connection.getErrorStream()));
            }

            StringBuilder response = new StringBuilder();
            String inputLine;
            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();

            // Print the response body
            System.out.println("Response Body: " + response.toString());

        } catch (IOException | NoSuchAlgorithmException | InvalidKeyException e) {
            e.printStackTrace();
        }
    }


    private static String generateSignature(String method, String path, String params, String timestamp) throws NoSuchAlgorithmException, InvalidKeyException {
        String data = timestamp + method + path + params;
        Mac mac = Mac.getInstance("HmacSHA256");
        SecretKeySpec secretKeySpec = new SecretKeySpec(SECRET.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
        mac.init(secretKeySpec);
        byte[] hmacData = mac.doFinal(data.getBytes(StandardCharsets.UTF_8));
        // convert bytes to hex
        StringBuilder result = new StringBuilder();
        for (byte b : bytes) {
            result.append(String.format("%02x", b));
        }
        return result.toString();
    }


}
import requests
import hashlib
import hmac
import time
import json

API_KEY = "YOUR_API_KEY"
SECRET = "YOUR_API_SECRET"


def send_post_request_for_order():
    try:
        url = "https://openapi.m2.com/earn-api/v1/user/plan/apply"
        timestamp = str(int(time.time() * 1000))
        request_body = {
            "planId": "11",
            "amount": 15,
            "lockDay": 15
        }
        request_body_json = json.dumps(request_body)
        signature = generate_signature("POST", "/earn-api/v1/user/plan/apply", request_body_json, timestamp)

        headers = {
            "Content-Type": "application/json",
            "EXCHANGE-API-TIMESTAMP": timestamp,
            "EXCHANGE-API-KEY": API_KEY,
            "EXCHANGE-API-SIGN": signature
        }

        response = requests.post(url, headers=headers, data=request_body_json)
        handle_response(response)

    except Exception as e:
        print(e)


def generate_signature(method, path, params, timestamp):
    data = timestamp + method + path + params
    signature = hmac.new(SECRET.encode('utf-8'), data.encode('utf-8'), hashlib.sha256).hexdigest()
    return signature


def handle_response(response):
    print("Response Code:", response.status_code)
    print("Response Body:", response.text)


def main():
    send_post_request_for_order()


if __name__ == "__main__":
    main()

const axios = require('axios');
const crypto = require('crypto');

const API_KEY = "YOUR_API_KEY"
const SECRET = "YOUR_SECRET_KEY"

function sendPostRequestForOrder() {
    try {
        const url = "https://openapi.m2.com/earn-api/v1/user/plan/apply";
        const timestamp = Math.floor(Date.now());
        const requestBody = {
            planId: "11",
            amount: 15,
            lockDay: 15
        };
        const request_body_json = JSON.stringify(requestBody);
        const signature = generateSignature("POST", "/earn-api/v1/user/plan/apply", request_body_json, timestamp);

        const headers = {
            "Content-Type": "application/json",
            "EXCHANGE-API-TIMESTAMP": timestamp,
            "EXCHANGE-API-KEY": API_KEY,
            "EXCHANGE-API-SIGN": signature
        };

        axios.post(url, request_body_json, { headers })
            .then(response => handleResponse(response))
            .catch(error => console.error(error));
    } catch (error) {
        console.error(error);
    }
}

function generateSignature(method, path, params, timestamp) {
    const data = timestamp + method + path + params;
    const signature = crypto.createHmac('sha256', SECRET).update(data).digest('hex');
    return signature;
}

function handleResponse(response) {
    console.log("Response Code:", response.status);
    console.log("Response Body:", response.data);
}

function main() {
    sendPostRequestForOrder();
}

main()

Request Fields

json field name type Required Description
planId string Y plan id
amount decimal Y earn plan amount
lockDay int N 1 = Buy, 2 = Sell
autoRenew boolean N true: open autoRenew false: close autoRenew

Response

// Response body
{
  "code": "0",
  "msg": "success",
  "data": {
    "applyId":"1",
    "amount":15
  }
}

Response Fields

json field name type Description
applyId string apply id for apply detail
amount decimal apply success amount

Plan Subscription Detail

// Request body
- applyId: required = true
curl -H "EXCHANGE-API-TIMESTAMP: YOUR_TIMESTAMP" -H "EXCHANGE-API-KEY: $API_KEY" -H "EXCHANGE-API-SIGN: $SIG" 'https://openapi.m2.com/earn-api/v1/user/apply/detailapplyId=SUB000002'
import java.net.HttpURLConnection;
import java.net.URL;
import java.io.OutputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class HttpRequest {
    public static void main(String[] args) {
       try {
            String applyId = "SUB000002";
            String url = "https://openapi.m2.com/earn-api/v1/user/apply/detail?applyId=" + applyId
            URL url = new URL(url);
            HttpURLConnection connection = (HttpURLConnection) apiUrl.openConnection();
            connection.setRequestMethod("GET");
            connection.setRequestProperty("Content-Type", "application/json");

            // Handle response...
            int responseCode = connection.getResponseCode();

            System.out.println("Response Code: " + responseCode);

            BufferedReader in;
            if (responseCode == HttpURLConnection.HTTP_OK) {
                in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            } else {
                in = new BufferedReader(new InputStreamReader(connection.getErrorStream()));
            }

            StringBuilder response = new StringBuilder();
            String inputLine;
            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();

            // Print the response body
            System.out.println("Response Body: " + response.toString());
        } catch (Exception e) {
              e.printStackTrace();
        }
    }
}
import requests

applyId = 'SUB000002'
url = f'https://openapi.m2.com/earn-api/v1/user/apply/detail?applyId={applyId}'

response = requests.get(url)
print("Response Code:", response.status_code)
print("Response:", response.json())
const axios = require('axios');

const applyId = 'SUB000002';
const url = `https://openapi.m2.com/earn-api/v1/user/apply/detail?applyId=${applyId}`;

axios.get(url)
    .then(response => {
        console.log(response.data);
    })
    .catch(error => {
        console.error('Error:', error);
    });

Request

json field name type required description
applyId string Y earn plan apply id

Response

// Response
{
    "code": "0",
    "msg": "success",
    "data": {
        "amount": 10,
        "applyId": "SUB000002",
        "apy": 0.2,
        "coin": "BTC",
        "endDate": "123123412",
        "lockDay": 10,
        "planId": "FIX000002",
        "planName": "BTC_FIX_10",
        "planType": 2,// 
        "rewardFrequency": 1,
        "startDate": "",
        "redeemHistories": [
          {
            "amount": 2, //  redeemed amount
            "createTime": "1699500082000",//redeem create time,timestamp in millisecond
            "redeemLockTime": 0,
            "status": 1 // redeem status,1-redeeming,2-redeemed
          }
        ],
        "status": 0, //
        "supportEarlyRedemption": true,
        "totalEarnedAmount": 0,
        "autoRenew": true
    }
}
json field name type description
amount decimal ID of order
applyId string uniquely-generated client orderId (if not present would be generated by the server)
apy decimal
coin string
endDate date timestamp in millisecond
lockDay int
planId string
planName string
planType int 1-flexible,2-fix,3-customized
rewardFrequency int
startDate date
redeemHistories object redeemed history array
status int apply status,0-In processing,1-in redeeming,2-Partial Redeeming
supportEarlyRedemption boolean
totalEarnedAmount decimal
autoRenew boolean

Redeem an applied plan

Cancel all open orders for a specific trading pair like BTC-USDT

Request

You can use this API to either:

json field name type required description
applyId string Y
amount decimal Y
// Request body
{
  "applyId": "12",
  "amount": 10
}
curl -H 'Content-Type: application/json' -H "EXCHANGE-API-TIMESTAMP: YOUR_TIMESTAMP" -H "EXCHANGE-API-KEY: $API_KEY" -H "EXCHANGE-API-SIGN: $SIG" -d '{"applyId":"12","amount":10}' https://openapi.m2.com/earn-api/v1/user/apply/redeem
import java.net.HttpURLConnection;
import java.net.URL;
import java.io.OutputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class HttpRequest {
    public static void main(String[] args) throws Exception {
        URL url = new URL("https://openapi.m2.com/earn-api/v1/user/apply/redeem");
        HttpURLConnection con = (HttpURLConnection) url.openConnection();
        con.setRequestMethod("POST");
        con.setRequestProperty("Content-Type", "application/json");
        con.setDoOutput(true);

        String jsonInputString = "{" +
                "\"applyId\": \"12\"," +
                "\"amount\": 1" +
                "}";

        try (OutputStream os = con.getOutputStream()) {
            byte[] input = jsonInputString.getBytes("utf-8");
            os.write(input, 0, input.length);
        }

        int responseCode = con.getResponseCode();
        BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
        String inputLine;
        StringBuffer response = new StringBuffer();
        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();
        System.out.println("Response Code: " + responseCode);
        System.out.println("Response: " + response.toString());
    }
}
import requests

url = "https://openapi.m2.com/earn-api/v1/user/apply/redeem"
data = {
    "applyId": "12",
    "amount": 10
}

response = requests.post(url, json=data)
print("Response Code:", response.status_code)
print("Response:", response.json())
const axios = require('axios');

const url = 'https://openapi.m2.com/earn-api/v1/user/apply/redeem';
const data = {
    applyId: '12',
    amount: 10
};

axios.post(url, data, {
    headers: {
        'Content-Type': 'application/json'
    }
})
.then(response => {
    console.log(response.data);
})
.catch(error => {
    console.error('Error:', error);
});

Response

// Response
{
  "code": "0",
  "data": true,
  "msg": "success"
}
json field name type description

Redeem preview

Request

json field name type required description
applyId string Y
amount decimal N
// Request params
<br>
N/A
curl -X GET 'https://openapi.m2.com//earn-api/v1/user/redeem/preview?applyId=SUB000002&amount=10'
import java.net.HttpURLConnection;
import java.net.URL;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class HttpRequest {
    public static void main(String[] args) throws Exception {
        String url = "https://openapi.m2.com//earn-api/v1/user/redeem/preview?applyId=SUB000002&amount=10";

        URL apiUrl = new URL(url);
        HttpURLConnection con = (HttpURLConnection) apiUrl.openConnection();
        con.setRequestMethod("GET");

        int responseCode = con.getResponseCode();
        BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
        String inputLine;
        StringBuffer response = new StringBuffer();
        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();
        System.out.println("Response Code: " + responseCode);
        System.out.println("Response: " + response.toString());
    }
}
import requests

url = "https://openapi.m2.com//earn-api/v1/user/redeem/preview"
params = {
    "applyId": "SUB000002",
    "amount": 10
}

response = requests.get(url, params=params)
print("Response Code:", response.status_code)
print("Response:", response.json())
const axios = require('axios');

const url = 'https://openapi.m2.com//earn-api/v1/user/redeem/preview';
const params = {
    applyId: "SUB000002",
    amount: 10
};

axios.get(url, { params })
    .then(response => {
        console.log(response.data);
    })
    .catch(error => {
        console.error('Error:', error);
    });

Response

// Response
{
  "code": "string",
  "data": {
    "boosterAmount": 10, 
    "boosterCoin": "MMX", 
    "earnedAmount": 0.2,
    "forfeitedEarningAmount": 0.4,
    "timeToRedeem": 10   
  },
  "msg": "success"
}

Pagination

json field name type description
boosterAmount decimal if had booster will be have value
boosterCoin string if had booster will be have value
earnedAmount decimal has earned amount
forfeitedEarningAmount decimal fix and customized Early Redemption will have forfeited earn amount
timeToRedeem int redeem lock time, unit is hour

Query current subscription list

GET /earn-api/v1/user/apply/currentList

Request

// Request params
<br>
N/A
curl -X GET https://openapi.m2.com/earn-api/v1/user/apply/currentList
import java.net.HttpURLConnection;
import java.net.URL;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class HttpRequest {
    public static void main(String[] args) throws Exception {
        URL url = new URL("https://openapi.m2.com/earn-api/v1/user/apply/currentList");
        HttpURLConnection con = (HttpURLConnection) url.openConnection();
        con.setRequestMethod("GET");

        int responseCode = con.getResponseCode();
        BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
        String inputLine;
        StringBuffer response = new StringBuffer();
        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();
        System.out.println("Response Code: " + responseCode);
        System.out.println("Response: " + response.toString());
    }
}
import requests

url = "https://openapi.m2.com/earn-api/v1/user/apply/currentList"

response = requests.get(url)
print("Response Code:", response.status_code)
print("Response:", response.json())
const axios = require('axios');

const url = 'https://openapi.m2.com/earn-api/v1/user/apply/currentList';

axios.get(url)
    .then(response => {
        console.log(response.data);
    })
    .catch(error => {
        console.error('Error:', error);
    });

Response

// Response
{
  "code": "0",
  "data": [
    {
        "amount": 10,
        "applyId": "SUB000002",
        "apy": 0.2,
        "apyPct": 20,
        "autoCompound": true,
        "coin": "BTC",
        "startDate": "1699400082000",//timestamp in millisecond
        "endDate": "1699500082000",// timestamp in millisecond
        "hadBooster": true,
        "lockDay": 10,
        "planId": "FIX000002",
        "planName": "BTC_FIX_10",
        "planType": 2,// 1-flexible,2-fix,3-customized
        "rewardFrequency": 1,
        "status": 0, //apply status,0-In processing,1-in redeeming,2-Partial Redeeming
        "supportEarlyRedemption": true,
        "totalEarnedAmount": 0
      }
  ],
  "msg": "success"
}

The response consists of two main parts:

Request

json field name type required description

Response

json field name type description
amount decimal
applyId string
apy string
apyPct decimal
autoCompound boolean
coin string
startDate long
endDate long
hadBooster boolean
lockDay int
planId string
planName string
planType int
rewardFrequency boolean
status boolean
supportEarlyRedemption boolean
totalEarnedAmount decimal

Subscription plan interest history

Request

// Request params
{
  "applyId": "SUB00001",
  "currentPage": 1,
  "pageSize": 10
}
curl -X GET https://openapi.m2.com/earn-api/v1/user/apply/interest
import java.net.HttpURLConnection;
import java.net.URL;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class HttpRequest {
    public static void main(String[] args) throws Exception {
        URL url = new URL("https://openapi.m2.com/earn-api/v1/user/apply/interest?applyId=SUB00001");
        HttpURLConnection con = (HttpURLConnection) url.openConnection();
        con.setRequestMethod("GET");

        int responseCode = con.getResponseCode();
        BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
        String inputLine;
        StringBuffer response = new StringBuffer();
        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();
        System.out.println("Response Code: " + responseCode);
        System.out.println("Response: " + response.toString());
    }
}
import requests
applyId = 'SUB000002'
url = "https://openapi.m2.com/earn-api/v1/user/apply/interest?applyId={applyId}"

response = requests.get(url)
print("Response Code:", response.status_code)
print("Response:", response.json())
const axios = require('axios');
const applyId = 'SUB000002';
const url = `https://openapi.m2.com/earn-api/v1/user/apply/interest?applyId=${applyId}`;

axios.get(url)
    .then(response => {
        console.log(response.data);
    })
    .catch(error => {
        console.error('Error:', error);
    });

Response

// Response
[{
  "code": "0",
  "data": {
    "currentPage": 1, 
    "items": [
      {
        "coin": "BTC",
        "date": 1699400082000, //Interest date, timestamp in millisecond
        "earnedAmount": 10 // interest amount
      }
    ],
    "pageSize": 20,
    "totalNum": 1,
    "totalPage": 1
  },
  "msg": "success"
}

Request

json field name type required description
applyId string Y
currentPage int N
pageSize int N

Response

json field name type description
coin string
date long Interest date, timestamp in millisecond
earnedAmount string interest amount

Edit Plan

Request: POST /earn-api/v1/user/plan/detail/edit

GET /spot-api/api/private/v1/wallet/positions

Request

// Request params
{
  "applyId":"1", 
  "uid": 2553845,
  "autoRenew": true
}
curl -H 'Content-Type: application/json' -H "EXCHANGE-API-TIMESTAMP: YOUR_TIMESTAMP" -H "EXCHANGE-API-KEY: $API_KEY" -H "EXCHANGE-API-SIGN: $SIG" -d '{"applyId":"1","uid":2553845,"autoRenew":true}' https://openapi.m2.com/earn-api/v1/user/plan/detail/edit
import java.net.HttpURLConnection;
import java.net.URL;
import java.io.OutputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class HttpRequest {
    public static void main(String[] args) throws Exception {
        URL url = new URL("https://openapi.m2.com/earn-api/v1/user/plan/detail/edit");
        HttpURLConnection con = (HttpURLConnection) url.openConnection();
        con.setRequestMethod("POST");
        con.setRequestProperty("Content-Type", "application/json");
        con.setDoOutput(true);

        String jsonInputString = "{\"applyId\":\"1\",\"uid\":2553845,\"autoRenew\":true}";

        try (OutputStream os = con.getOutputStream()) {
            byte[] input = jsonInputString.getBytes("utf-8");
            os.write(input, 0, input.length);
        }

        int responseCode = con.getResponseCode();
        BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
        String inputLine;
        StringBuffer response = new StringBuffer();
        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();
        System.out.println("Response Code: " + responseCode);
        System.out.println("Response: " + response.toString());
    }
}
url = "https://openapi.m2.com/earn-api/v1/user/plan/detail/edit"
data = {
    "applyId": "1",
    "uid": 2553845,
    "autoRenew": true
}

response = requests.post(url, json=data)
print("Response Code:", response.status_code)
print("Response:", response.json())
const axios = require('axios');

const url = 'https://openapi.m2.com/earn-api/v1/user/plan/detail/edit';
const data = {
    "applyId": "1",
    "uid": 2553845,
    "autoRenew": true
};

axios.post(url, data, {
    headers: {
        'Content-Type': 'application/json'
    }
})
.then(response => {
    console.log(response.data);
})
.catch(error => {
    console.error('Error:', error);
});
const axios = require('axios');

Response

// Response
{
  "code": "0",
  "msg": "success",
  "data": true
}

Request

json field name type required description
applyId string N
uid int N
autoRenew boolean N

Response

json field name type description

**Note: Fields with double asterisks are optional.

Enterprise user earn subscription list

Request: POST /earn-api/v1/user/earn/plans/list

Request

// Request params
{
  "planType": 1, //1-flexible,2-fix,3-customized
  "symbol": "MATIC"
}
curl -H 'Content-Type: application/json' -H "EXCHANGE-API-TIMESTAMP: YOUR_TIMESTAMP" -H "EXCHANGE-API-KEY: $API_KEY" -H "EXCHANGE-API-SIGN: $SIG" -d '{"planType":1,"symbol": "MATIC"}' https://openapi.m2.com/earn-api/v1/user/earn/plans/list
import java.net.HttpURLConnection;
import java.net.URL;
import java.io.OutputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class HttpRequest {
    public static void main(String[] args) throws Exception {
        URL url = new URL("https://openapi.m2.com/earn-api/v1/user/earn/plans/list");
        HttpURLConnection con = (HttpURLConnection) url.openConnection();
        con.setRequestMethod("POST");
        con.setRequestProperty("Content-Type", "application/json");
        con.setDoOutput(true);

        String jsonInputString = "{\"symbol\":\"MATIC\",\"planType\":1}";

        try (OutputStream os = con.getOutputStream()) {
            byte[] input = jsonInputString.getBytes("utf-8");
            os.write(input, 0, input.length);
        }

        int responseCode = con.getResponseCode();
        BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
        String inputLine;
        StringBuffer response = new StringBuffer();
        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();
        System.out.println("Response Code: " + responseCode);
        System.out.println("Response: " + response.toString());
    }
}

```python
url = "https://openapi.m2.com/earn-api/v1/user/earn/plans/list"
data = {
    "planType": 1,
    "symbol": "MATIC"
}

response = requests.post(url, json=data)
print("Response Code:", response.status_code)
print("Response:", response.json())
const axios = require('axios');

const url = 'https://openapi.m2.com/earn-api/v1/user/earn/plans/list';
const data = {
    "planType": 1,
    "symbol": "MATIC"
};

axios.post(url, data, {
    headers: {
        'Content-Type': 'application/json'
    }
})
.then(response => {
    console.log(response.data);
})
.catch(error => {
    console.error('Error:', error);
});
const axios = require('axios');

Response

// Response
{
    "code": "0",
    "msg": "success",
    "data": {
        "items": [
            {
                "subscriptionId": "SB013040",
                "planId": "1000002",
                "planType": 1,
                "asset": "MATIC",
                "startTime": 1717581600000,
                "maturityTime": null,
                "principal": 1,
                "earnings": 0.00416675,
                "redemptionStatus": "ACTIVE",
                "maturityAmount": 1.06083455,
                "marginAllocation": 0
            }
        ],
        "currentPage": 1,
        "pageSize": 10,
        "totalNum": 1,
        "totalPage": 1
    },
    "succ": true
}

Request

json field name type required description
planType int N
symbol string N

Response

json field name type description
subscriptionId string
planId string
planType int
asset string
startTime long
maturityTime long
principal decimal
earnings decimal
redemptionStatus string
maturityAmount decimal
marginAllocation decimal

Enterprise user earn subscription list

Request: POST /earn-api/v1/user/yield/manage/list

Request

// Request params
{
    "asset": "AAVE",
    "pageNum": 1,
    "pageSize": 10
}
curl -H 'Content-Type: application/json' -H "EXCHANGE-API-TIMESTAMP: YOUR_TIMESTAMP" -H "EXCHANGE-API-KEY: $API_KEY" -H "EXCHANGE-API-SIGN: $SIG" -d '{"asset":"AAVE","pageNum": 1, "pageSize": 10}' https://openapi.m2.com/earn-api/v1/user/yield/manage/list
import java.net.HttpURLConnection;
import java.net.URL;
import java.io.OutputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class HttpRequest {
    public static void main(String[] args) throws Exception {
        URL url = new URL("https://openapi.m2.com/earn-api/v1/user/yield/manage/list");
        HttpURLConnection con = (HttpURLConnection) url.openConnection();
        con.setRequestMethod("POST");
        con.setRequestProperty("Content-Type", "application/json");
        con.setDoOutput(true);

        String jsonInputString = "{\"asset\":\"AAVE\",\"pageNum\":1,\"pageSize\":10}";

        try (OutputStream os = con.getOutputStream()) {
            byte[] input = jsonInputString.getBytes("utf-8");
            os.write(input, 0, input.length);
        }

        int responseCode = con.getResponseCode();
        BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
        String inputLine;
        StringBuffer response = new StringBuffer();
        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();
        System.out.println("Response Code: " + responseCode);
        System.out.println("Response: " + response.toString());
    }
}

```python
url = "https://openapi.m2.com/earn-api/v1/user/yield/manage/list"
data = {
    "pageNum": 1,
    "pageSize": 10,
    "asset": "MATIC"
}

response = requests.post(url, json=data)
print("Response Code:", response.status_code)
print("Response:", response.json())
const axios = require('axios');

const url = 'https://openapi.m2.com/earn-api/v1/user/yield/manage/list';
const data = {
    "pageNum": 1,
    "pageSize": 10,
    "asset": "MATIC"
};

axios.post(url, data, {
    headers: {
        'Content-Type': 'application/json'
    }
})
.then(response => {
    console.log(response.data);
})
.catch(error => {
    console.error('Error:', error);
});
const axios = require('axios');

Response

// Response
{
    "code": "0",
    "msg": "success",
    "data": {
        "items": [
            {
                "asset": "AAVE",
                "planDuration": 30,
                "apy": 0.061,
                "apyPct": 6.1,
                "enterpriseMargin": 7,
                "userId": 202307479,
                "planId": "2000067",
                "planType": "FIXED"
            },
            {
                "asset": "AAVE",
                "planDuration": 7,
                "apy": 0.061,
                "apyPct": 6.1,
                "enterpriseMargin": 0,
                "userId": 202307479,
                "planId": "2000068",
                "planType": "FIXED"
            }
        ],
        "currentPage": 1,
        "pageSize": 2,
        "totalNum": 10,
        "totalPage": 5
    },
    "succ": true
}

Request

json field name type required description
asset string N
pageNum int Y
pageSize int Y

Response

json field name type description
asset string
planId string
planDuration int
apy decimal
apyPct decimal
enterpriseMargin decimal
userId int
planId string
planType string

Enterprise user edit plan enterprise margin

Request: POST /earn-api/v1/user/edit/enterpriseMargin?planId=2000067&margin=7 Request

// Request params
<br>
N/A
curl -H 'Content-Type: application/json' -H "EXCHANGE-API-TIMESTAMP: YOUR_TIMESTAMP" -H "EXCHANGE-API-KEY: $API_KEY" -H "EXCHANGE-API-SIGN: $SIG"  https://openapi.m2.com//earn-api/v1/user/edit/enterpriseMarginplanId=2000067&margin=7
import java.net.HttpURLConnection;
import java.net.URL;
import java.io.OutputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class HttpRequest {
    public static void main(String[] args) throws Exception {
        URL url = new URL("https://openapi.m2.com/earn-api/v1/user/edit/enterpriseMargin?planId=2000067&margin=7");
        HttpURLConnection con = (HttpURLConnection) url.openConnection();
        con.setRequestMethod("POST");
        con.setRequestProperty("Content-Type", "application/json");
        con.setDoOutput(true);

        String jsonInputString = "{}";

        try (OutputStream os = con.getOutputStream()) {
            byte[] input = jsonInputString.getBytes("utf-8");
            os.write(input, 0, input.length);
        }

        int responseCode = con.getResponseCode();
        BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
        String inputLine;
        StringBuffer response = new StringBuffer();
        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();
        System.out.println("Response Code: " + responseCode);
        System.out.println("Response: " + response.toString());
    }
}

```python
url = "https://openapi.m2.com/earn-api/v1/user/edit/enterpriseMargin?planId=2000067&margin=7"
data = {}

response = requests.post(url, json=data)
print("Response Code:", response.status_code)
print("Response:", response.json())
const axios = require('axios');

const url = 'https://openapi.m2.com/earn-api/v1/user/edit/enterpriseMargin?planId=2000067&margin=7';
const data = {};

axios.post(url, data, {
    headers: {
        'Content-Type': 'application/json'
    }
})
.then(response => {
    console.log(response.data);
})
.catch(error => {
    console.error('Error:', error);
});
const axios = require('axios');

Response

// Response
{
    "code": "0",
    "msg": "success",
    "data": true,
    "succ": true
}

Request

json field name type required description

Response

json field name type description

Errors

Definitions errors in the REST API and Websocket is as follow

REST API Errors

There are 3 types of orders:

JSON Body Example

4xx errors

{
    "code": "100200",
    "msg": "business error",
    "userMsg": "Instrument not found: symbol=BNB-AED"
}

200 errors

{
    "code": "40000",
    "msg": "earn.plan.invalid",
    "data": null
}

List of 200 errors (code would always be 500, and data would always be null):

msg Error Explanation
40000 earn.plan.invalid pan is not exist
40001 earn.plan.invalid_param invalid param
40002 earn.plan.user_min_amount user minimum purchase per individual
40003 earn.plan.user_max_amount user max purchase per individual
40004 earn.plan.pool_capacity_limits pool capacity limits
40005 earn.plan.invalid_user the plan user is not eq login user
40006 earn.plan.add_funds_flexible_only only flexible plan support add funds
40007 earn.plan.flexible_holding only holding flexible plan can add funds
40008 earn.request.transaction_error save transaction error
40009 earn.request.transfer_error transfer balance error
40010 earn.redeem.amount_over redeem amount over the apply amount
40011 earn.need.kyc" earn op need user have kyc
40012 earn.booster.plan_type.error booster not support the plan type
40013 earn.redeem.not_support_partial not support partial redeem
40014 earn.plan.not_support_booster not ssupport booster
40015 earn.plan.user_min_day customer lock day less than user minimum lock day
40016 earn.plan.user_max_day customer lock day greater than user max lock day
40017 earn.booster.amount_not_greater_than_0 booster amount Less than or equal to zero
40018 earn.plan.not_support_early_redemption not support early redemption
40019 earn.atc.interface.error Internal dependency service error
40020 earn.transfer.insufficient_balance account insufficient balance

Feel free to reach out to support if you have any questions or need further assistance!