跳到主要内容

身份验证

所有私有 BTSE API 接口的每个请求都需要三个 HTTP 请求头。公开接口(市场数据、订单簿、交易记录)需要身份验证。

新手?请先阅读此处。

在调用任何私有接口之前,请先设置您的 API key 并了解签名流程。大多数集成失败都是身份验证问题。

需要验证您的签名代码? 使用身份验证测试工具在浏览器中计算签名并发送实时测试请求。


第 1 步 — 创建 API Key

  1. 登录 www.btse.com
  2. 点击右上角的 Account
  3. 选择 API 标签页
  4. 点击 New API 生成密钥和密码

重要提示: 密码仅在创建时显示一次。请妥善保管 — 之后无法再次获取。


第 2 步 — 了解三个请求头

每个已认证的请求必须包含以下三个请求头:

请求头类型说明
request-apiString您的 API key
request-nonceLong当前 UTC 时间戳,单位为毫秒(例如 1624985375123
request-signStringHMAC-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-nonce1624985375123
request-api4e9536c79f0fdd72bf04f2430982d3f61d9d76c996f0175bbba470d69d59816x
Secret848db84ac252b6726e5f6e7a711d9c96d9fd77d020151b45839a5b59c37203bx
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 请求头,指示解除封禁的时间戳。


环境

在不承担真实资金风险的情况下测试您的集成。测试网接口的行为与生产环境一致。

ProductProductionTestnet
Spot RESThttps://api.btse.com/spothttps://testapi.btse.io/spot
Spot WebSocketwss://ws.btse.com/ws/spotwss://testws.btse.io/ws/spot
Spot OSSwss://ws.btse.com/ws/oss/spotwss://testws.btse.io/ws/oss/spot
Futures RESThttps://api.btse.com/futureshttps://testapi.btse.io/futures
Futures WebSocketwss://ws.btse.com/ws/futureswss://testws.btse.io/ws/futures
Futures OSSwss://ws.btse.com/ws/oss/futureswss://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