基本信息
API 基本信息¶
- 本篇列出接口的baseurl: https://papi.asterdex-testnet.com
- 所有接口的响应都是 JSON 格式。
- 所有时间、时间戳均为UNIX时间,单位为毫秒。
API Agent Address 设置¶
- 很多接口需要API Key才可以访问.
- 设置API Key的同时,为了安全,建议设置IP访问白名单.
- 永远不要把你的API Agent Address/Private Key告诉给任何人
注意事项¶
- TESTUSDT 或任何其他以 TEST 开头的交易对仅用于 Aster 的内部测试。请不要在这些以 TEST 开头的交易品种上进行交易。Aster 对因交易这些交易对而造成的资金损失不承担任何责任。但是,如果您遇到问题,您可以随时联系支持人员,我们将尽力帮助您收回资金。
HTTP 返回代码¶
- HTTP
4XX错误码用于指示错误的请求内容、行为、格式。问题在于请求者。 - HTTP
403错误码表示违反WAF限制(Web应用程序防火墙)。 - HTTP
429错误码表示警告访问频次超限,即将被封IP。 - HTTP
418表示收到429后继续访问,IP已经被封禁。 - HTTP
5XX错误码用于指示Aster服务侧的问题。
接口错误代码¶
- 使用接口
/api/v3, 每个接口都有可能抛出异常;API的错误代码返回形式如下:
{ "code": -1121, "msg": "Invalid symbol." }
接口的基本信息¶
GET方法的接口, 参数必须在query string中发送。POST,PUT, 和DELETE方法的接口,参数可以在内容形式为application/x-www-form-urlencoded的query string中发送,也可以在request body中发送。- 对参数的顺序不做要求。
V3 Nonce 机制¶
-
Nonce 用于校验请求的有效性、唯一性和防重放。客户端应使用当前时间戳(微秒级)作为 nonce,且与服务端时间误差不超过 10 秒。
-
请求处理流程:
-
若 nonce 已使用过 → 判定为重复请求并拒绝
-
否则判断是否过旧
-
为提升性能,每个用户仅维护最近 100 个 nonce:
-
若已满且新 nonce 小于当前最小值 → 判定为过期并拒绝
-
否则移除最旧的 nonce,加入新的
-
总体效果:防重复、防过期,仅保留近期有效请求
访问限制¶
访问限制基本信息¶
- 在
/api/v3/prediction/exchangeInforateLimits数组中包含与交易的有关REQUEST_WEIGHT和ORDERS速率限制相关的对象。这些在限制种类 (rateLimitType)下的枚举定义部分中进一步定义。 - 违反任何一个速率限制时,将返回429。
IP 访问限制¶
- 每个请求的回报中包含一个
X-MBX-USED-WEIGHT-(intervalNum)(intervalLetter)的头,其中包含当前IP所有请求的已使用权重。 - 每一个接口均有一个相应的权重(weight),有的接口根据参数不同可能拥有不同的权重。越消耗资源的接口权重就会越大。
- 收到429时,您有责任停止发送请求,不得滥用API。
- 收到429后仍然继续违反访问限制,会被封禁IP,并收到418错误码
- 频繁违反限制,封禁时间会逐渐延长,从最短2分钟到最长3天。
Retry-After的头会与带有418或429的响应发送,并且会给出以秒为单位的等待时长(如果是429)以防止禁令,或者如果是418,直到禁令结束。- 访问限制是基于IP的,而不是API Key
下单频率限制¶
- 每个成功的下单回报将包含一个
X-MBX-ORDER-COUNT-(intervalNum)(intervalLetter)的头,其中包含当前账户已用的下单限制数量。 - 当下单数超过限制时,会收到带有429但不含
Retry-After头的响应。请检查GET api/v3/prediction/exchangeInfo的下单频率限制 (rateLimitType = ORDERS) 并等待封禁时间结束。 - 被拒绝或不成功的下单并不保证回报中包含以上头内容。
- 下单频率限制是基于每个账户计数的。
WEB SOCKET 连接限制¶
- Websocket服务器每秒最多接受5个消息。消息包括:
- PING帧
- PONG帧
- JSON格式的消息, 比如订阅, 断开订阅.
- 如果用户发送的消息超过限制,连接会被断开连接。反复被断开连接的IP有可能被服务器屏蔽。
- 单个连接最多可以订阅 1024 个Streams。
接口鉴权类型¶
- 每个接口都有自己的鉴权类型,鉴权类型决定了访问时应当进行何种鉴权
- 如果需要使用API_WALLET鉴权,应当在请求体中添加signer
- 如果需要使用主地址鉴权,应当在请求体中添加user
| 鉴权类型 | 描述 |
|---|---|
| NONE | 不需要鉴权的接口 |
| SPOT_TRADE | 需要有效的signer和签名 |
| USER_DATA | 需要有效的signer和签名 |
| USER_STREAM | 需要有效的signer和签名 |
| MARKET_DATA | 不需要鉴权的接口 |
POST /api/v3/order 的示例¶
示例 : 以下参数为api注册信息,user,signer,privateKey仅供示范(privateKey为signer的私钥)¶
| Key | Value | Desc |
|---|---|---|
| user | 0x63DD5aCC6b1aa0f563956C0e534DD30B6dcF7C4e | 登陆钱包地址 |
| signer | 0x21cF8Ae13Bb72632562c6Fff438652Ba1a151bb0 | 点击这里获取 |
| privateKey | 0x4fd0a42218f3eae43a6ce26d22544e986139a01e5b34a62db53757ffca81bae1 | 点击这里获取 |
示例 : nonce参数为当前系统微秒值,超过系统时间,或者落后系统时间超过10s为非法请求¶
#python
nonce = math.trunc(time.time()*1000000)
print(nonce)
#1748310859508867
//java
Instant now = Instant.now();
long microsecond = now.getEpochSecond() * 1000000 + now.getNano() / 1000;
示例 : 下单 (方法以python为例)¶
import time
import urllib
import threading
import requests
from eth_account.messages import encode_structured_data
from eth_account import Account
typed_data = {
"types": {
"EIP712Domain": [
{"name": "name", "type": "string"},
{"name": "version", "type": "string"},
{"name": "chainId", "type": "uint256"},
{"name": "verifyingContract", "type": "address"}
],
"Message": [
{ "name": "msg", "type": "string" }
]
},
"primaryType": "Message",
"domain": {
"name": "AsterSignTransaction",
"version": "1",
"chainId": 714,
"verifyingContract": "0x0000000000000000000000000000000000000000"
},
"message": {
"msg": "$msg"
}
}
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'User-Agent': 'PythonApp/1.0'
}
host = 'https://papi.asterdex-testnet.com'
# config your user and agent info here
user = '*'
signer = '*'
private_key = "*"
place_order = {"url":"/api/v3/order","method":"POST","params":{"symbol": "ASTERUSDT", "type": "LIMIT", "side": "BUY",
"timeInForce": "GTC", "quantity": "100", "price": "0.4"}}
_last_ms = 0
_i = 0
_nonce_lock = threading.Lock()
def get_nonce():
global _last_ms, _i
with _nonce_lock:
now_ms = int(time.time())
if now_ms == _last_ms:
_i += 1
else:
_last_ms = now_ms
_i = 0
return now_ms * 1_000_000 + _i
def send_by_url(api) :
my_dict = api['params']
url = host + api['url']
my_dict['nonce'] = str(get_nonce())
my_dict['signer'] = signer
param = urllib.parse.urlencode(my_dict)
print(param)
typed_data['message']['msg'] = param
message = encode_structured_data(typed_data)
signed = Account.sign_message(message, private_key=private_key)
url = url + '?' + param + '&signature=' + signed.signature.hex()
print(url)
res = requests.post(url, headers=headers)
print(res.text)
def send_by_body(api) :
my_dict = api['params']
url = host +api['url']
my_dict['nonce'] = str(get_nonce())
my_dict['signer'] = signer
param = urllib.parse.urlencode(my_dict)
typed_data['message']['msg'] = param
message = encode_structured_data(typed_data)
signed = Account.sign_message(message, private_key=private_key)
print(signed.signature.hex())
my_dict['signature'] = signed.signature.hex()
print(my_dict)
res = requests.post(url, data=my_dict, headers=headers)
print(res.text)
if __name__ == '__main__':
send_by_url(place_order)
# send_by_body(place_order)
公开 API 参数¶
术语¶
这里的术语适用于全部文档,建议特别是新手熟读,也便于理解。
base asset指一个交易对的交易对象,即写在靠前部分的资产名, 比如BTCUSDT,BTC是base asset。quote asset指一个交易对的定价资产,即写在靠后部分的资产名, 比如BTCUSDT,USDT是quote asset。
枚举定义¶
交易对状态 (状态 status):
- TRADING 交易中
交易对类型:
- SPOT 现货
订单状态 (状态 status):
| 状态 | 描述 |
|---|---|
NEW |
订单被交易引擎接受 |
PARTIALLY_FILLED |
部分订单被成交 |
FILLED |
订单完全成交 |
CANCELED |
用户撤销了订单 |
REJECTED |
订单没有被交易引擎接受,也没被处理 |
EXPIRED |
订单被交易引擎取消, 比如 LIMIT FOK 订单没有成交 市价单没有完全成交 交易所维护期间被取消的订单 |
订单类型 (orderTypes, type):
- LIMIT 限价单
- MARKET 市价单
订单返回类型 (newOrderRespType):
- ACK
- RESULT
- FULL
订单方向 (方向 side):
- BUY 买入
- SELL 卖出
有效方式 (timeInForce):
这里定义了订单多久能够失效
| Status | Description |
|---|---|
GTC |
成交为止 订单会一直有效,直到被成交或者取消。 |
IOC |
无法立即成交的部分就撤销 订单在失效前会尽量多的成交。 |
FOK |
无法全部立即成交就撤销 如果无法全部成交,订单会失效。 |
GTX |
直到挂单成交 限价只挂单。 |
K线间隔:
m -> 分钟
- 1s
- 1m
新增了1s参数
限制种类 (rateLimitType)
REQUEST_WEIGHT
{ "rateLimitType": "REQUEST_WEIGHT", "interval": "MINUTE", "intervalNum": 1, "limit": 1200 }ORDERS
{ "rateLimitType": "ORDERS", "interval": "MINUTE", "intervalNum": 1, "limit": 100 }
-
REQUEST_WEIGHT 单位时间请求权重之和上限
-
ORDERS 单位时间下单次数限制
限制间隔 (interval)
- MINUTE 分
过滤器¶
过滤器,即Filter,定义了一系列交易规则。
共有两类,分别是针对交易对的过滤器symbol filters,和针对整个交易所的过滤器exchange filters(暂不支持)
交易对过滤器¶
PRICE_FILTER 价格过滤器¶
/exchangeInfo 响应中的格式:
{ "minPrice": "556.72", "maxPrice": "4529764", "filterType": "PRICE_FILTER", "tickSize": "0.01" }
价格过滤器 用于检测订单中 price 参数的合法性。包含以下三个部分:
minPrice定义了price/stopPrice允许的最小值。maxPrice定义了price/stopPrice允许的最大值。tickSize定义了price/stopPrice的步进间隔,即price必须等于minPrice+(tickSize的整数倍)
以上每一项均可为0,为0时代表这一项不再做限制。
逻辑伪代码如下:
price>=minPriceprice<=maxPrice- (
price-minPrice) %tickSize== 0
PERCENT_PRICE 价格振幅过滤器¶
/exchangeInfo 响应中的格式:
{ "multiplierDown": "0.9500", "multiplierUp": "1.0500", "multiplierDecimal": "4", "filterType": "PERCENT_PRICE" }
PERCENT_PRICE过滤器基于指数价格来定义价格的有效范围。
为了通过"价格百分比","价格"必须符合以下条件:
price<=indexPrice*multiplierUpprice> =indexPrice*multiplierDown
LOT_SIZE 订单尺寸¶
/exchangeInfo 响应中的格式:
{ "stepSize": "0.00100000", "filterType": "LOT_SIZE", "maxQty": "100000.00000000", "minQty": "0.00100000" }
Lots是拍卖术语,LOT_SIZE 过滤器对订单中的 quantity 也就是数量参数进行合法性检查。包含三个部分:
minQty表示quantity允许的最小值。maxQty表示quantity允许的最大值。stepSize表示quantity允许的步进值。
逻辑伪代码如下:
quantity>=minQtyquantity<=maxQty- (
quantity-minQty) %stepSize== 0
MARKET_LOT_SIZE 市价订单尺寸¶
*/exchangeInfo 响应中的格式:
{ "stepSize": "0.00100000", "filterType": "MARKET_LOT_SIZE" "maxQty": "100000.00000000", "minQty": "0.00100000" }
MARKET_LOT_SIZE过滤器为交易对上的MARKET订单定义了数量(即拍卖中的"手数")规则。 共有3部分:
minQty定义了允许的最小quantity。maxQty定义了允许的最大数量。stepSize定义了可以增加/减少数量的间隔。
为了通过market lot size,quantity必须满足以下条件:
quantity>=minQtyquantity<=maxQty- (
quantity-minQty) %stepSize== 0
predictionEvents 预测事件¶
*/exchangeInfo 响应中的格式:
{ "predictionEvents": [ { "eventName": "Who will win the 2026 FIFA World Cup?", // 预测事件名称 "eventId": "EVENT4", // 事件标识符 "oracleSymbol": "", // 预测标的(非价格预测事件为空) "predictionType": "MARKETONLY_MULTIPREDICT", // 预测类型(MARKETONLY_MULTIPREDICT 仅白名单做市商可用) "sides": [ "YES", "NO" ], // 预测方向 "period": null, // 预测周期(分钟) "startTime": 1780840786140, // 事件开始时间(Unix 毫秒) "endTime": 0, // 事件结束时间(0 = 未设置结束时间) "status": "LIVE", // 事件状态 "currentRoundId": null, // 当前轮次ID "settleIntervalSeconds": 0, // TWAP 价格采样间隔(秒) "settlementDataPointCount": 0, // TWAP 价格数据点数量 "reduceOnly": false, // 是否只允许减仓订单 "category": "FIFA2026", // 事件分类 "orderTypes": [ "LIMIT", "MARKET" ], // 支持的订单类型 "timeInForce": [ "GTC", "IOC", "FOK", "GTX" ], // 支持的 TIF 类型 "liveRound": null, // 当前进行中的轮次 "rounds": null, // 历史轮次 "markets": [ // 各结果的预测市场列表 { "marketName": "EVENT4_ALGERIA_WIN", // 预测市场名称 "symbols": [ "EVENT4_ALGERIA_WIN_YUSDT", "EVENT4_ALGERIA_WIN_NUSDT" ], // 该市场的两个交易对;Y = YES,N = NO "assets": [ "EVENT4_ALGERIA_WIN_Y", "EVENT4_ALGERIA_WIN_N" ], // 该市场的两个资产;Y = YES,N = NO "roundId": 0, // 轮次ID "tradingStartTime": 1780840786140, // 交易开始时间(Unix 毫秒) "tradingEndTime": 0, // 交易结束时间(0 = 未设置结束时间) "windowStartTime": 1780840786140, // 窗口开始时间(Unix 毫秒) "windowEndTime": 0, // 窗口结束时间(0 = 未设置结束时间) "roundStatus": "TRADING", // 市场状态 "openPrice": null, // 开盘价(结算前为 null) "endPrice": null, // 结算价(结算前为 null) "winAsset": "EVENT4_ALGERIA_WIN_N", // 获胜资产:Y 代表 YES 胜,N 代表 NO 胜 "settleTime": 0, // 结算时间(0 = 未结算) "settleHash": null // 链上结算哈希(未结算时为 null) } ] }, { "eventName": "USD1_UP_DOWN_5M", // 预测事件名称 "oracleSymbol": "USD1USDT", // 预测标的 "predictionType": "UP_DOWN", // 预测类型 "sides": [ "UP", "DOWN" ], // 预测方向 "period": "10080M", // 预测周期(分钟) "startTime": 1778476080000, // 事件开始时间(Unix 毫秒) "endTime": 1780376880000, // 事件结束时间(Unix 毫秒) "status": "LIVE", // 事件状态 "currentRoundId": 3, // 当前轮次ID "orderTypes": [ "LIMIT", "MARKET" ], // 支持的订单类型 "settleIntervalSeconds": 5, // TWAP 价格采样间隔(秒) "settlementDataPointCount": 5, // TWAP 价格数据点数量 "reduceOnly": false, // 是否只允许减仓订单 "category": "", // 事件分类 "timeInForce": [ "GTC", "IOC", "FOK", "GTX" ], // 支持的 TIF 类型 "liveRound": { // 当前进行中的轮次 "marketName": "USD1_UP_DOWN_5M_1778483280", // 预测市场名称 "symbols": [ "USD1_UP_DOWN_5M_1778483280_YUSDT", "USD1_UP_DOWN_5M_1778483280_NUSDT" ], // 该市场的两个交易对;Y = 涨,N = 跌 "assets": [ "USD1_UP_DOWN_5M_1778483280_Y", "USD1_UP_DOWN_5M_1778483280_N" ], // 该市场的两个资产;Y = 涨,N = 跌 "roundId": 2, // 轮次ID "tradingStartTime": 1778482970000, // 交易开始时间(Unix 毫秒) "tradingEndTime": 1778483520000, // 交易结束时间(Unix 毫秒) "windowStartTime": 1778483280000, // 窗口开始时间(Unix 毫秒) "windowEndTime": 1778483580000, // 窗口结束时间(Unix 毫秒) "roundStatus": "SETTLED", // 市场状态 "openPrice": "0.99920000", // 开盘价 "endPrice": "0.99910000", // 结算价 "winAsset": "USD1_UP_DOWN_5M_1778483280_N", // 获胜资产:Y 代表涨,N 代表跌 "settleTime": 1778483582057, // 结算时间(Unix 毫秒) "settleHash": "0x3bc0aff52472dafd4b70d3423386a2dabf675fe7cd604e92391e2a4702cf0980" // 链上结算哈希 }, "rounds": [ // 历史轮次 { "marketName": "USD1_UP_DOWN_5M_1778483280", // 预测市场名称 "symbols": [ "USD1_UP_DOWN_5M_1778483280_YUSDT", "USD1_UP_DOWN_5M_1778483280_NUSDT" ], // 该市场的两个交易对;Y = 涨,N = 跌 "assets": [ "USD1_UP_DOWN_5M_1778483280_Y", "USD1_UP_DOWN_5M_1778483280_N" ], // 该市场的两个资产;Y = 涨,N = 跌 "roundId": 2, // 轮次ID "tradingStartTime": 1778482970000, // 交易开始时间(Unix 毫秒) "tradingEndTime": 1778483520000, // 交易结束时间(Unix 毫秒) "windowStartTime": 1778483280000, // 窗口开始时间(Unix 毫秒) "windowEndTime": 1778483580000, // 窗口结束时间(Unix 毫秒) "roundStatus": "SETTLED", // 市场状态 "openPrice": "0.99920000", // 开盘价 "endPrice": "0.99910000", // 结算价 "winAsset": "USD1_UP_DOWN_5M_1778483280_N", // 获胜资产:Y 代表涨,N 代表跌 "settleTime": 1778483582057, // 结算时间(Unix 毫秒) "settleHash": "0x3bc0aff52472dafd4b70d3423386a2dabf675fe7cd604e92391e2a4702cf0980" // 链上结算哈希 } ] } ] }
status 为事件的状态
| Status | Description |
|---|---|
LIVE |
正在运行。 |
CLOSED |
INVALID。 |
INVALID |
无效。 |
roundStatus 为市场的状态
| RoundStatus | Description |
|---|---|
PREMARKET |
预先准备好的市场(可以提前交易) |
TRADING |
交易中的市场 |
SETTLED |
已结算的市场 |
- 结算完成一段时间(24H)后,会自动下架,下架后的市场不再展示
status为CLOSED或者INVALID的事件对应的市场,只能下reduceOnly的Market Sell订单
predictionType 为预测事件类型:
| PredictionType | 描述 |
|---|---|
UP_DOWN |
价格方向预测(涨或跌) |
MULTIVARIATE |
多变量预测,有多个可能结果 |
MARKETONLY_MULTIPREDICT |
仅白名单做市商可用的多结果预测 |