API 域名
您可以自行使用 Rest API 存取方式進行操作。
域名 | API | 描述 |
---|---|---|
現貨 rest 域名 | https://api-spot.weex.com | 主域名 |
合約 rest 域名 | https://api-contract.weex.com | 主域名 |
簽名
ACCESS-SIGN 的請求頭是對 timestamp + method.toUpperCase() + requestPath + “?” + queryString + body 字串 (+表示字串連接) 使用 HMAC SHA256 方法加密,透過 BASE64 編碼輸出而得到的。
簽名各欄位說明
- timestamp:與 ACCESS-TIMESTAMP 請求頭相同。
- method:請求方法 (POST/GET),字母全部大寫。
- requestPath:請求接口路徑。
- queryString:請求 URL中 (?後的請求參數) 的查詢字串。
- body:請求主體對應的字串,如果請求沒有主體(通常為 GET 請求)則 body 可省略。
queryString 為空時,簽名格式
- timestamp + method.toUpperCase() + requestPath + body
queryString 不為空時,簽名格式
- timestamp + method.toUpperCase() + requestPath + “?” + queryString + body
舉例說明
取得深度訊息,以 btcusdt 為例:
- Timestamp = 1591089508404
- Method = “GET”
- requestPath = “/api/v2/market/depth”
- queryString= “?symbol=btcusdt_spbl&limit=20”
產生待簽章的字串:
- ‘1591089508404GET/api/v2/market/depth?symbol=btcusdt_spbl&limit=20’
下單,以 btcusdt 為例:
- Timestamp = 1561022985382
- Method = “POST”
- requestPath = “/api/v2/order/order”
- body =
{"symbol":"btcusdt_spbl","quantity":"8","side":"buy","price":"1","orderType":"limit","clientOrderId":"ww#123456"}
產生待簽章的字串:
'1561022985382POST/api/spotPro/v3/order/order{"symbol":"btcusdt_spbl","size":"8","side":"buy","price":"1","orderType":"limit","clientOrderId":"ww#123456"}'
產生最終簽名的步驟**
- 將待簽章字串使用私鑰 secretkey 進行 hmac sha256 加密
- Signature = hmac_sha256(secretkey, Message)
- 對於 Signature 進行 base64 編碼
- Signature = base64.encode(Signature)
请求交互
package com.weex.lcp.utils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class ApiClient {
// API信息
private static final String API_KEY = ""; // 替换为实际的 API Key
private static final String SECRET_KEY = ""; // 替换为实际的 Secret Key
private static final String ACCESS_PASSPHRASE = ""; // 替换为实际的 Access Passphrase
private static final String BASE_URL = ""; // 替换为实际的 API 地址
// 生成签名(POST请求)
public static String generateSignature(String secretKey, String timestamp, String method, String requestPath, String queryString, String body) throws Exception {
String message = timestamp + method.toUpperCase() + requestPath + queryString + body;
return generateHmacSha256Signature(secretKey, message);
}
// 生成签名(GET请求)
public static String generateSignatureGet(String secretKey, String timestamp, String method, String requestPath, String queryString) throws Exception {
String message = timestamp + method.toUpperCase() + requestPath + queryString;
return generateHmacSha256Signature(secretKey, message);
}
// 生成 HMAC SHA256 签名
private static String generateHmacSha256Signature(String secretKey, String message) throws Exception {
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(secretKeySpec);
byte[] signatureBytes = mac.doFinal(message.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(signatureBytes);
}
// 发送 POST 请求
public static String sendRequestPost(String apiKey, String secretKey, String accessPassphrase, String method, String requestPath, String queryString, String body) throws Exception {
String timestamp = String.valueOf(System.currentTimeMillis());
String signature = generateSignature(secretKey, timestamp, method, requestPath, queryString, body);
HttpPost postRequest = new HttpPost(BASE_URL + requestPath);
postRequest.setHeader("ACCESS-KEY", apiKey);
postRequest.setHeader("ACCESS-SIGN", signature);
postRequest.setHeader("ACCESS-TIMESTAMP", timestamp);
postRequest.setHeader("ACCESS-PASSPHRASE", accessPassphrase);
postRequest.setHeader("Content-Type", "application/json");
postRequest.setHeader("locale", "zh-CN");
StringEntity entity = new StringEntity(body, StandardCharsets.UTF_8);
postRequest.setEntity(entity);
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
CloseableHttpResponse response = httpClient.execute(postRequest);
return EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
}
}
// 发送 GET 请求
public static String sendRequestGet(String apiKey, String secretKey, String accessPassphrase, String method, String requestPath, String queryString) throws Exception {
String timestamp = String.valueOf(System.currentTimeMillis());
String signature = generateSignatureGet(secretKey, timestamp, method, requestPath, queryString);
HttpGet getRequest = new HttpGet(BASE_URL + requestPath+queryString);
getRequest.setHeader("ACCESS-KEY", apiKey);
getRequest.setHeader("ACCESS-SIGN", signature);
getRequest.setHeader("ACCESS-TIMESTAMP", timestamp);
getRequest.setHeader("ACCESS-PASSPHRASE", accessPassphrase);
getRequest.setHeader("Content-Type", "application/json");
getRequest.setHeader("locale", "zh-CN");
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
CloseableHttpResponse response = httpClient.execute(getRequest);
return EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
}
}
// 示例调用
public static void main(String[] args) {
try {
// GET 请求示例
String requestPath = "/api/uni/v3/order/currentPlan";
String queryString = "?symbol=cmt_bchusdt&delegateType=0&startTime=1742213127794&endTime=1742213506548";
String response = sendRequestGet(API_KEY, SECRET_KEY, ACCESS_PASSPHRASE, "GET", requestPath, queryString);
System.out.println("GET Response: " + response);
// POST 请求示例
String body = "{\"symbol\": \"ETHUSDT_SPBL\", \"limit\": \"2\"}";
response = sendRequestPost(API_KEY, SECRET_KEY, ACCESS_PASSPHRASE, "POST", requestPath, "", body);
System.out.println("POST Response: " + response);
} catch (Exception e) {
e.printStackTrace();
}
}
}
import time
import hmac
import hashlib
import base64
import requests
import json
api_key = ""
secret_key = ""
access_passphrase = ""
def generate_signature(secret_key, timestamp, method, request_path, query_string, body): message = timestamp + method.upper() + request_path + query_string + str(body)
signature = hmac.new(secret_key.encode(), message.encode(), hashlib.sha256).digest()
print(base64.b64encode(signature).decode())
return base64.b64encode(signature).decode()
def generate_signature_get(secret_key, timestamp, method, request_path, query_string):
message = timestamp + method.upper() + request_path + query_string
signature = hmac.new(secret_key.encode(), message.encode(), hashlib.sha256).digest()
# print(base64.b64encode(signature).decode())
return base64.b64encode(signature).decode()
def send_request_post(api_key, secret_key, access_passphrase, method, request_path, query_string, body):
timestamp = str(int(time.time() * 1000))
# print(timestamp)
body = json.dumps(body)
signature = generate_signature(secret_key, timestamp, method, request_path, query_string, body)
headers = {
"ACCESS-KEY": api_key,
"ACCESS-SIGN": signature,
"ACCESS-TIMESTAMP": timestamp,
"ACCESS-PASSPHRASE": access_passphrase,
"Content-Type": "application/json",
"locale": "zh-CN"
}
url = "https://contract-openapi.weex.com" # 请替换为实际的API地址
if method == "GET":
response = requests.get(url + request_path, headers=headers)
elif method == "POST":
response = requests.post(url + request_path, headers=headers, data=body)
return response
def send_request_get(api_key, secret_key, access_passphrase, method, request_path, query_string):
timestamp = str(int(time.time() * 1000))
# print(timestamp)
signature = generate_signature_get(secret_key, timestamp, method, request_path, query_string)
headers = {
"ACCESS-KEY": api_key,
"ACCESS-SIGN": signature,
"ACCESS-TIMESTAMP": timestamp,
"ACCESS-PASSPHRASE": access_passphrase,
"Content-Type": "application/json",
"locale": "zh-CN"
}
url = "https://contract-openapi.weex.com" # 请替换为实际的API地址
if method == "GET":
response = requests.get(url + request_path, headers=headers)
return response
# 示例调用 GET 请求
request_path = "/api/spot/v1/account/assets"
# request_path = "/api/spot/v1/public/currencies" # 查看币对列表
query_string = ''
body = ''
response = send_request_get(api_key, secret_key, access_passphrase, "GET", request_path, query_string)
# 示例调用 POST 请求
# request_path = "/api/spot/v1/trade/fills"
# body = {"symbol": "ETHUSDT_SPBL", "limit": "2"}
# query_string = ""
# response = send_request_post(api_key, secret_key, access_passphrase, "POST", request_path, query_string, body)
print(response.status_code)
print(response.text)
所有請求基於Https協議,請求頭資訊中 Content-Type 需要統一設定為: ‘application/json’。
請求互動說明
- 請求參數:根據接口請求參數規定進行參數封裝。
- 提交請求參數:將封裝好的請求參數透過GET/POST方式提交至伺服器。
- 伺服器回應:伺服器首先對使用者請求資料進行參數安全校驗,透過校驗後根據業務邏輯將回應資料以JSON格式傳回給使用者。
- 資料處理:對伺服器回應資料進行處理。
成功
HTTP 狀態碼 200 表示成功回應,並可能包含內容。如果回應含有內容,則會顯示在對應的回傳內容裡面。
常見錯誤碼
- 400 Bad Request – Invalid request format 請求格式無效
- 401 Unauthorized – Invalid API Key 無效的API Key
- 403 Forbidden – You do not have access to the requested resource 請求無權
- 404 Not Found 沒有找到請求
- 429 Too Many Requests 請求太頻繁被系統限流
- 500 Internal Server Error – We had a problem with our server 伺服器內部錯誤
- 如果失敗body帶有錯誤描述訊息
標準規範
時間戳
請求簽名中的 ACCESS-TIMESTAMP 的單位是毫秒。請求的時間戳記必須在 API 服務時間的 30 秒內,否則請求將被視為過期並被拒絕。 如果本地伺服器時間和API伺服器時間之間存在較大的偏差,那麼我們建議您使用透過查詢API伺服器時間來更新 http header。
限頻規則
如果請求過於頻繁系統將自動限制請求,並在 http header 中傳回 429 too many requests 狀態碼。
- 公共接口:如行情接口,統一限頻為 2 秒最多 20 個請求。
- 授權接口:透過 apikey 限制授權接口的調用,參考每個接口的限頻規則限頻。
請求格式
目前只有兩種格式的請求方法:GET 和 POST
- GET: 參數透過 queryString 在路徑中傳輸到伺服器。
- POST: 參數依照 json 格式傳送 body 傳送到伺服器。
WEEX唯客官網:www.weex.com
你也可以在 CMC| Coingecko|非小號|X(Twitter)|Youtube|Facebook|Linkedin|微博 上關注我们,第一时间获取更多投資導航和福利活動!了解平台幣 WXT 最新資訊請訪問 WXT專區
在線諮詢:
WEEX唯客中文交流群:https://t.me/weex_group
WEEX唯客英文交流群:https://t.me/Weex_Global