Quick Start
Quick Start
Access Setupâ
To use the API, please log in to the web page and complete the API key application and permission configuration, and then proceed with development and trading based on the documentation details.
You can click API Key Management to create an API Key.
Each UID can create up to 50 API key sets, with each key supporting two types of permissions: read and write.
Sub-account API Keyâ
Sub-accounts (virtual sub-accounts and standard sub-accounts) can create and manage their own API Keys independently, without requiring the main account to operate on their behalf.
Prerequisite: The main account must enable the API Key Management permission for the sub-account. This setting is disabled by default. The main account can configure it under sub-account permission settings.
Once enabled, the sub-account can perform the following operations on its own API Keys:
- Create API Key
- View API Key
- Edit API Key permissions
- Delete API Key
The main account retains full control and can view, edit, or delete any sub-account's API Keys at any time.
The permissions are outlined below:
- Unified account trade, read-only: Enables access to trade information.
- Unified account trade, read and write: In addition to read-only permissions, it allows order placement, cancellation, and more.
- Unified account management, read-only: Enables access to account information.
- Unified account management, read and write: In addition to read-only permissions, it allows account settings, such as leverage adjustment, Holding mode switching, and more.
After creation, please note the following information:
APIKeyThe identity of the API transaction, generated by a random algorithm.Secretkeyprivate key, randomly generated by the system, used for signature generation.PassphrasePassword is set by the user. It should be noted that if the Passphrase is forgotten, it cannot be retrieved and the APIKey needs to be re-created.
Demo Tradingâ
Demo trading allows you to practice trading and test strategies in a real-market environment using virtual funds, helping you improve your skills and reduce the risk of losses.
API Keyâ
To perform demo trading via API, you'll need to create a Demo API Key in the first place. The steps are as follows:
Log in to your account â Switch to Demo mode â Go to the Personal Center â Go to the API Key Management â Create a Demo API Key â Use the Demo API Key to start trading.RESTâ
Please use the created Demo API Key for API calls, and add
paptradingin the request header, with the value set to1.WebSocketâ
Please use the created Demo API Key for WebSocket connections and request the demo trading service address:
Public: wss://wspap.bitget.com/v3/ws/public
Private: wss://wspap.bitget.com/v3/ws/private
Domain Nameâ
| Domain Name | Domain | Recommended |
|---|---|---|
| REST | https://api.bitget.com | main domain name |
| Websocket public channel | wss://ws.bitget.com/v3/ws/public | main domain name, public channel |
| websocket private channel | wss://ws.bitget.com/v3/ws/private | main domain name, private channel |
Headerâ
All REST request headers must contain the following keys:
ACCESS-KEY: The API key, represented as a string.ACCESS-SIGN: Sign using base64 encoding (see messages for details).ACCESS-TIMESTAMP: The request's timestamp.ACCESS-PASSPHRASE: The passphrase you set when creating the API KEY.Content-Type: Set to application/json by default.locale: Language. e.g., Chinese (zh-CN), English (en-US)
Responseâ
X-BG-REQUEST-ACCEPT-TIME: The time the server received the requestX-BG-RESPONSE-COMPLETE-TIME: The time the server completed request processingx-mbx-used-remain-limit: Remaining rate limit quota for the current endpoint
SDKâ
Bitget V3 provides official SDKs for the following languages:
| Language | Link |
|---|---|
| Java | Java |
| Python | Python |
| Node.js | Node.js |
| Golang | Golang |
| PHP | PHP |
Signatureâ
Generate Signatureâ
The ACCESS-SIGN request header is generated by encrypting the timestamp + method.toUpperCase() + requestPath + "?" + queryString + body string (+ means string concatenation) using the HMAC SHA256 algorithm with secretKey, then encoding the result with BASE64.
Description of each parameter in the signatureâ
- timestamp: Same as
ACCESS-TIMESTAMPrequest header. Value equals milliseconds since Epoch. - method: Request method (POST/GET), all uppercase.
- requestPath: Request interface path.
- queryString: The query string in the request URL (the request parameter after
?). - body: The request body as a string. If the request body is empty (usually a GET request), the body can be omitted.
If the queryString is empty, signature content:
timestamp + method.toUpperCase() + requestPath + body
If the queryString is not empty, signature content:
timestamp + method.toUpperCase() + requestPath + "?" + queryString + body
Sample Codeâ
GET example â Get account fee rate (BTCUSDT spot):
- timestamp = 16273667805456
- method = "GET"
- requestPath = "/api/v3/account/fee-rate"
- queryString = "category=SPOT&symbol=BTCUSDT"
Content to be signed:
16273667805456GET/api/v3/account/fee-rate?category=SPOT&symbol=BTCUSDT
POST example â Place a spot limit order (BTCUSDT):
- timestamp = 16273667805456
- method = "POST"
- requestPath = "/api/v3/trade/place-order"
- body = {"category":"SPOT","symbol":"BTCUSDT","side":"buy","orderType":"limit","qty":"0.1","price":"30000","timeInForce":"gtc"}
Content to be signed:
16273667805456POST/api/v3/trade/place-order{"category":"SPOT","symbol":"BTCUSDT","side":"buy","orderType":"limit","qty":"0.1","price":"30000","timeInForce":"gtc"}
Steps to generate the final signatureâ
HMAC
String payload = hmac_sha256(secretkey, Message);
String signature = base64.encode(payload);
RSA
Step 1. Use the RSA privateKey privateKey to encrypt the string to be signed with SHA-256.
Step 2. Base64 encoding for Signature.
HMAC Signature Demo Codeâ
- Java
- Python
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.management.RuntimeErrorException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import org.springframework.util.Base64Utils;
@Slf4j
public class CheckSign {
private static final String secretKey = "";
public static void main(String[] args) throws Exception {
//POST sign example
// String timestamp = "1684813405151";
// String body = "{\"symbol\":\"BTCUSDT\",\"productType\":\"usdt-futures\",\"marginMode\":\"crossed\",\"marginCoin\":\"USDT\",\"size\":\"8\",\"side\":\"buy\",\"orderType\":\"limit\",\"price\":\"30000\"}";
//
// String sign = generate(timestamp,"POST","/api/v3/trade/place-order" ,null,body,secretKey);
// log.info("sign:{}",sign);
//GET sign example
String timestamp = "1684814440729";
String queryString = "category=SPOT&symbol=BTCUSDT"; // Need to be sorted in ascending alphabetical order by key
String sign = generate(timestamp,"GET","/api/v3/account/fee-rate" ,queryString,null,secretKey);
log.info("sign:{}",sign);
}
private static Mac MAC;
static {
try {
CheckSign.MAC = Mac.getInstance("HmacSHA256");
} catch (NoSuchAlgorithmException var1) {
throw new RuntimeErrorException(new Error("Can't get Mac's instance."));
}
}
public static String generate(String timestamp, String method, String requestPath,
String queryString, String body, String secretKey)
throws CloneNotSupportedException, InvalidKeyException, UnsupportedEncodingException {
method = method.toUpperCase();
body = StringUtils.defaultIfBlank(body, StringUtils.EMPTY);
queryString = StringUtils.isBlank(queryString) ? StringUtils.EMPTY : "?" + queryString;
String preHash = timestamp + method + requestPath + queryString + body;
log.info("preHash:{}",preHash);
byte[] secretKeyBytes = secretKey.getBytes("UTF-8");
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKeyBytes, "HmacSHA256");
Mac mac = (Mac) CheckSign.MAC.clone();
mac.init(secretKeySpec);
return Base64.getEncoder().encodeToString(mac.doFinal(preHash.getBytes("UTF-8")));
}
}
import hmac
import base64
import json
import time
def get_timestamp():
return int(time.time() * 1000)
def sign(message, secret_key):
mac = hmac.new(bytes(secret_key, encoding='utf8'), bytes(message, encoding='utf-8'), digestmod='sha256')
d = mac.digest()
return base64.b64encode(d)
def pre_hash(timestamp, method, request_path, body):
return str(timestamp) + str.upper(method) + request_path + body
def parse_params_to_str(params):
params = [(key, val) for key, val in params.items()]
params.sort(key=lambda x: x[0])
url = '?' +toQueryWithNoEncode(params);
if url == '?':
return ''
return url
def toQueryWithNoEncode(params):
url = ''
for key, value in params:
url = url + str(key) + '=' + str(value) + '&'
return url[0:-1]
if __name__ == '__main__':
API_SECRET_KEY = ""
timestamp = "1685013478665" # get_timestamp()
request_path = "/api/v3/trade/place-order"
# POST
params = {"category": "SPOT", "symbol": "BTCUSDT", "side": "buy", "orderType": "limit", "qty": "0.1", "price": "30000", "timeInForce": "gtc"}
body = json.dumps(params)
sign = sign(pre_hash(timestamp, "POST", request_path, str(body)), API_SECRET_KEY)
print(sign)
# GET
body = ""
request_path = "/api/v3/account/fee-rate"
params = {"category": "SPOT", "symbol": "BTCUSDT"}
request_path = request_path + parse_params_to_str(params) # Need to be sorted in ascending alphabetical order by key
sign = sign(pre_hash(timestamp, "GET", request_path, body), API_SECRET_KEY)
print(sign)
RSA Signature Demo Codeâ
- Python
import base64
import json
import time
from Crypto.Hash import SHA256
from Crypto.Signature import PKCS1_v1_5
from Crypto.PublicKey import RSA
def get_timestamp():
return int(time.time() * 1000)
def rsa_sign(message, private_key):
pri_key = RSA.importKey(private_key)
encoded_param = SHA256.new(bytes(message, encoding='utf-8'))
sign_str = PKCS1_v1_5.new(pri_key).sign(encoded_param)
return base64.b64encode(sign_str).decode()
def pre_hash(timestamp, method, request_path, body):
return str(timestamp) + str.upper(method) + request_path + body
def parse_params_to_str(params):
params = [(key, val) for key, val in params.items()]
params.sort(key=lambda x: x[0])
from urllib.parse import urlencode
url = '?' +urlencode(params);
if url == '?':
return ''
return url
if __name__ == '__main__':
private_key = '''-----BEGIN PRIVATE KEY-----
YOUR_PRIVATE_KEY_HERE
-----END PRIVATE KEY-----'''
timestamp = get_timestamp()
request_path = "/api/v3/trade/place-order"
# POST
params = {"category": "SPOT", "symbol": "BTCUSDT", "side": "buy", "orderType": "limit", "qty": "0.1", "price": "30000", "timeInForce": "gtc"}
body = json.dumps(params)
sign = rsa_sign(pre_hash(timestamp, "POST", request_path, str(body)), private_key)
print(sign)
# GET
body = ""
request_path = "/api/v3/account/fee-rate"
params = {"category": "SPOT", "symbol": "BTCUSDT"}
request_path = request_path + parse_params_to_str(params) # Need to be sorted in ascending alphabetical order by key
sign = rsa_sign(pre_hash(timestamp, "GET", request_path, body), private_key)
print(sign)
Rate Limitâ
If requests are too frequent, the system will automatically limit the request and return the 429 Too Many Requests status code.
Rate limit rules:
- The rate limit for each API endpoint is marked on the respective doc page;
- Each API endpoint's rate limit is calculated independently;
- REST and WebSocket share the same rate limit quota;
- The overall rate limit is 6000 requests/IP/min
WebSocketâ
Overviewâ
WebSocket is a new HTML5 protocol that achieves full-duplex data transmission between the client and server, allowing data to be transferred effectively in both directions. A connection between the client and server can be established with just one handshake. The server will then be able to push data to the client according to preset rules. Its advantages include:
- The WebSocket request header size for data transmission between client and server is only 2 bytes.
- Either the client or server can initiate data transmission.
- There is no need to repeatedly create and delete TCP connections, saving bandwidth and server resources.
It is strongly recommended that developers use the WebSocket API to obtain market information and order book data.
Connectâ
Connection limit: 300 connection requests/IP/5min, max 100 connections/IP
Subscription limit: 240 subscription requests/hour/connection, max 1000 channel subscriptions/connection
To keep the connection stable and effective, it is recommended to:
- Set a 30-second timer to send the string
"ping", and expect the string"pong"as a response. If no"pong"is received, please reconnect. - The WebSocket server will disconnect if no
"ping"is received for 2 minutes. - The WebSocket server accepts up to 10 messages per second per connection. Messages include:
- String
"ping" - JSON messages, including login, subscribe, and unsubscribe
- String
- If a user sends more messages than the limit, the connection will be disconnected. IPs that are repeatedly disconnected may be blocked by the server.
- It is strongly recommended to subscribe to fewer than 50 channels per connection. Connections with fewer channel subscriptions are more stable.
Loginâ
apiKey: Unique identifier for invoking the API. Users need to apply for one.
passphrase: The APIKey password.
timestamp: Unix timestamp in milliseconds. Expires in 30 seconds.
sign: Signature string. The signing algorithm is as follows:
The message to be signed is: timestamp + "GET" + "/user/verify"
const timestamp = '' + Date.now()
sign = CryptoJS.enc.Base64.Stringify(CryptoJS.HmacSHA256(timestamp + 'GET' + '/user/verify', secretKey))
method: Always 'GET'.
requestPath: Always '/user/verify'.
The request will expire 30 seconds after the timestamp. If your server time differs from the API server time, we recommend using the REST API to query the API server time and then synchronize the timestamp.
Steps to generate the final signatureâ
HMAC
Step 1. Concatenate the content:
Long timestamp = System.currentTimeMillis() / 1000;
String content = timestamp + "GET" + "/user/verify";
Step 2. Use the private key secretkey to encrypt the string with HMAC SHA256:
String hash = hmac_sha256(content, secretkey);
Step 3. Base64 encode the hash:
String sign = base64.encode(hash);
RSA
Step 1. Use the RSA privateKey privateKey to encrypt the string to be signed with SHA-256.
Step 2. Base64 encoding for Signature.
If login fails, the connection will be automatically disconnected.
{
"op":"login",
"args":[
{
"apiKey":"<api_key>",
"passphrase":"<passphrase>",
"timestamp":"<timestamp>",
"sign":"<sign>"
}
]
}
{
"op":"login",
"args":[
{
"apiKey":"xx_xxx",
"passphrase":"xxx",
"timestamp":"1538054050",
"sign":"8RCOqCJAhhEh4PWcZB/96QojLDqMAg4qNynIixFzS3E="
}
]
}
{
"event":"login",
"code":"0",
"msg":""
}
{
"event":"error",
"code":"30005",
"msg":"error"
}
Contact usâ
- Bitget Telegram official group Click to join
- API Telegram official group Click to join