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:
- Normal response with a 200 HTTP header.
- Error response with a 4xx/5xx HTTP header.
- 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:
- Login into the UI.
- Go to the API Manage page to create api key.
Step 5 (create apiKey with read & write privilege, select the permission group you want)
- 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
- Create/modify subscription (Include Enable Reading)
- /earn-api/v1/user/plan/apply
- /earn-api/v1/user/plan/detail/edit
- Early redemption (Include Enable Reading)
- /earn-api/v1/user/apply/redeem
- 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
- Each request sent to a private REST API endpoint should be signed.
- We use HMAC sha256 signature.
- Sig = ${timestamp} + ${http method} + ${http request path} + ${request param} + ${request body}.
- Timestamp should be an up-to-date value within a 10 min range from the current timestamp, otherwise 401 returned.
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:
- Cancel all orders for a specific pair by sending the symbol
- Cancel all orders across all pairs by not sending a symbol (just send an empty body
{}
)
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 url https://openapi.m2.com//earn-api/v1/user/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:
- data: A list of execution report responses representing the trades.
- pagination: Information about pagination.
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: GET /earn-api/v1/user/apply/interest
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:
Auth error:
- httpStatus=401 (by apiGateway) - invalid signature
- httpStatus=403 (by earn) - signature is valid, but user tries to submit request on behalf of not-his-own account
4xx errors. httpStatus=4xx, json body with error details
200 errors. httpStatus=200, json body with error details
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!