身份验证
所有私有 BTSE API 接口的每个请求都需要三个 HTTP 请求头。公 开接口(市场数据、订单簿、交易记录)不需要身份验证。
新手?请先阅读此处。
在调用任何私有接口之前,请先设置您的 API key 并了解签名流程。大多数集成失败都是身份验证问题。
需要验证您的签名代码? 使用身份验证测试工具在浏览器中计算签名并发送实时测试请求。
第 1 步 — 创建 API Key
- 登录 www.btse.com
- 点击右上角的 Account
- 选择 API 标签页
- 点击 New API 生成密钥和密码
重要提示: 密码仅在创建时显示一次。请妥善保管 — 之后无法再次获取。
第 2 步 — 了解三个 请求头
每个已认证的请求必须包含以下三个请求头:
| 请求头 | 类型 | 说明 |
|---|---|---|
request-api | String | 您的 API key |
request-nonce | Long | 当前 UTC 时间戳,单位为毫秒(例如 1624985375123) |
request-sign | String | HMAC-SHA384 签名(见下文) |
第 3 步 — 构造签名
签名的计算方式为:
HMAC-SHA384(secret, urlpath + nonce + bodyStr)
其中:
secret— 您的 API 密钥(第 1 步中的密码)urlpath— 仅 URL 的路径部分(例如/api/v3.3/order)。请勿包含查询字符串。 查询参数会随 URL 发送到服务器,但不会纳入签名 payload — 若将其纳入签名会导致401 Signature verification failed。nonce— 与request-nonce中发送的值相同bodyStr— 原始 JSON 请求体。对于 GET 请求(无请求体),使用空字符串""
三个部分直接拼接,中间没有分隔符。
Shell
echo -n "/api/v3.3/order1624985375123{\"postOnly\":false,\"price\":8500.0,\"side\":\"BUY\",\"size\":0.002,\"stopPrice\":0.0,\"symbol\":\"BTC-USD\",\"time_in_force\":\"GTC\",\"trailValue\":0.0,\"triggerPrice\":0.0,\"txType\":\"LIMIT\",\"type\":\"LIMIT\"}" \
| openssl dgst -sha384 -hmac "YOUR_SECRET"
Python
import hmac, hashlib, time, json, requests
API_KEY = "your-api-key"
API_SECRET = "your-api-secret"
BASE_URL = "https://api.btse.com/spot"
def signed_request(method, path, body=None):
nonce = str(int(time.time() * 1000))
body_str = json.dumps(body) if body else ""
message = path + nonce + body_str
signature = hmac.new(
API_SECRET.encode(), message.encode(), hashlib.sha384
).hexdigest()
headers = {
"request-api": API_KEY,
"request-nonce": nonce,
"request-sign": signature,
"Content-Type": "application/json",
}
url = BASE_URL + path
resp = requests.request(method, url, headers=headers,
json=body if method != "GET" else None)
return resp.json()
# Example: query open orders
orders = signed_request("GET", "/api/v3.3/user/open_orders")
JavaScript / Node.js
import crypto from "crypto";
const API_KEY = "your-api-key";
const API_SECRET = "your-api-secret";
const BASE_URL = "https://api.btse.com/spot";
async function signedRequest(method, path, body) {
const nonce = Date.now().toString();
const bodyStr = body ? JSON.stringify(body) : "";
const message = path + nonce + bodyStr;
const signature = crypto
.createHmac("sha384", API_SECRET)
.update(message)
.digest("hex");
const resp = await fetch(BASE_URL + path, {
method,
headers: {
"request-api": API_KEY,
"request-nonce": nonce,
"request-sign": signature,
"Content-Type": "application/json",
},
body: body ? JSON.stringify(body) : undefined,
});
return resp.json();
}
// Example: query open orders
const orders = await signedRequest("GET", "/api/v3.3/user/open_orders");
Go
package main
import (
"crypto/hmac"
"crypto/sha512"
"encoding/hex"
"fmt"
"io"
"net/http"
"strconv"
"strings"
"time"
)
const (
apiKey = "your-api-key"
apiSecret = "your-api-secret"
baseURL = "https://api.btse.com/spot"
)
func signedRequest(method, path, body string) ([]byte, error) {
nonce := strconv.FormatInt(time.Now().UnixMilli(), 10)
message := path + nonce + body
mac := hmac.New(sha512.New384, []byte(apiSecret))
mac.Write([]byte(message))
signature := hex.EncodeToString(mac.Sum(nil))
req, _ := http.NewRequest(method, baseURL+path, strings.NewReader(body))
req.Header.Set("request-api", apiKey)
req.Header.Set("request-nonce", nonce)
req.Header.Set("request-sign", signature)
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
return io.ReadAll(resp.Body)
}
func main() {
data, err := signedRequest("GET", "/api/v3.3/user/open_orders", "")
if err != nil {
panic(err)
}
fmt.Println(string(data))
}
完整示例 — 下单
给定以下值:
| 字段 | 值 |
|---|---|
request-nonce | 1624985375123 |
request-api | 4e9536c79f0fdd72bf04f2430982d3f61d9d76c996f0175bbba470d69d59816x |
| Secret | 848db84ac252b6726e5f6e7a711d9c96d9fd77d020151b45839a5b59c37203bx |
| URL 路径 | /api/v3.3/order |
| 请求体 | {"postOnly":false,"price":8500.0,"side":"BUY","size":0.002,"stopPrice":0.0,"symbol":"BTC-USD","time_in_force":"GTC","trailValue":0.0,"triggerPrice":0.0,"txType":"LIMIT","type":"LIMIT"} |
待签名字符串:
/api/v3.3/order1624985375123{"postOnly":false,"price":8500.0,"side":"BUY","size":0.002,"stopPrice":0.0,"symbol":"BTC-USD","time_in_force":"GTC","trailValue":0.0,"triggerPrice":0.0,"txType":"LIMIT","type":"LIMIT"}
生成的 request-sign:
e9cd0babdf497b536d1e48bc9cf1fadad3426b36406b5747d77ae4e3cdc9ab556863f2d0cf78e0228c39a064ad43afb7
权限类型
API key 包含一个或多个权限。接口会强制执行所需的最低权限。您可以从每个接口部分顶部的标记查看该接口所需的权限。
| 标记 | 权限 | 解锁内容 |
|---|---|---|
| 🌐 Public | 无 | 市场数据、订单簿、公开交易记录 |
| 🔒 Read | 读取 | 账户余额、订单状态、交易历史、钱包记录 |
| 🔒 Trading | 交易 | 下单、修改、取消订单 |
| 🔒 Transfer | 转账 | 提现、充值、钱包间转账 |
速率限制
速率限制按 API 接口和用户账户分别执行。
| 类别 | 每个 API | 每个用户 |
|---|---|---|
| 查询 | 15 次/秒 | 30 次/秒 |
| 订单 | 75 次/秒 | 75 次/秒 |
分级封禁
超过速率限制将触发分级封禁:
| 级别 | 持续时间 |
|---|---|
| 第 1 次违规 | 1 秒 |
| 第 2 次违规 | 5 分钟 |
| 第 3 次违规 | 15 分钟 |
如果在 1 小时内没有进一步的违规行为,或在 15 分钟封禁到期后,封禁计时器将重置。
所有 429 响应中都包含 Retry-After 请求头,指示解除封禁的时间戳。
环境
在不承担真实资金风险的情况下测试您的集成。测试网接口的行为与生产环境一致。
| Product | Production | Testnet |
|---|---|---|
| Spot REST | https://api.btse.com/spot | https://testapi.btse.io/spot |
| Spot WebSocket | wss://ws.btse.com/ws/spot | wss://testws.btse.io/ws/spot |
| Spot OSS | wss://ws.btse.com/ws/oss/spot | wss://testws.btse.io/ws/oss/spot |
| Futures REST | https://api.btse.com/futures | https://testapi.btse.io/futures |
| Futures WebSocket | wss://ws.btse.com/ws/futures | wss://testws.btse.io/ws/futures |
| Futures OSS | wss://ws.btse.com/ws/oss/futures | wss://testws.btse.io/ws/oss/futures |
SDK 和库
BTSE 提供 Python、JavaScript、Java 三种语言的自动生成 SDK。请前往客户端 SDK页面下载。如需以其他语言手动整合,上述签名范例(Python、JavaScript、Go)可作为起点。
其他资源:
- API 浏览器提供交互式请求测试和自动生成的代码片段
- 本文档中的 OpenAPI 规范可与标准 OpenAPI 代码生成器(例如
openapi-generator-cli)配合使用,生成任意语言的客户端库 - 从 API 浏览器下载规范 — 每个产品的概览页面都包含规范下载链接
如果您构建了社区 SDK 并希望在此列出,请联系 support.btse.com。