Quickstart
Create keys, sign a request, and call the Bit2Me gateway.
Get an authenticated response from https://gateway.bit2me.com in a few minutes. Bit2Me does not provide a sandbox API host. The same production gateway is used with your keys.
Open Get API keys and create a key. Copy the key and the secret once. HMAC uses the secret. Rotate in that dashboard if a secret leaks (Authentication).
Scopes (as documented on the gateway):
- Read — private reads; cannot create or cancel orders or transfers
- Trade — create or cancel orders
- Withdraw — withdrawals (these withdrawals bypass two-factor authentication)
Use the smallest scope. Add trusted IPs for Trade or Withdraw keys.
HMAC is SHA256(message) then HMAC-SHA512(secret, hash) encoded as Base64.
Message format:
- No body:
{nonce}:{path} - With JSON body:
{nonce}:{path}:{JSON.stringify(body)}
nonce is Unix time in milliseconds (Date.now() / int(time.time() * 1000)). The documented clock-skew window is 5 seconds. Sync the client clock with NTP.
Sign JSON bodies with compact JSON (JSON.stringify in JavaScript; json.dumps(..., separators=(",", ":")) in Python). Full algorithm and a known-answer fixture: Authentication.
Pro REST and Wallet pair look like BTC/EUR. MCP tools use BTC-EUR. Do not mix formats on the same call.
Example: list pockets on the parent account.
Compute $BIT2ME_SIGNATURE locally (nonce in milliseconds, message {nonce}:/v1/wallet/pocket, no JSON body). Do not POST {} to signin/apikey unless you also sign {}.
curl -sS "https://gateway.bit2me.com/v1/wallet/pocket" \
-H "Content-Type: application/json" \
-H "x-api-key: $BIT2ME_API_KEY" \
-H "api-signature: $BIT2ME_SIGNATURE" \
-H "x-nonce: $BIT2ME_NONCE"const axios = require("axios");
const crypto = require("crypto");
const API_KEY = process.env.BIT2ME_API_KEY;
const SECRET = process.env.BIT2ME_API_SECRET;
const SERVER = "https://gateway.bit2me.com";
const PATH = "/v1/wallet/pocket";
const nonce = Date.now();
const message = `${nonce}:${PATH}`;
const hashDigest = crypto.createHash("sha256").update(message).digest("binary");
const signature = crypto
.createHmac("sha512", SECRET)
.update(hashDigest, "binary")
.digest("base64");
const { data } = await axios.get(`${SERVER}${PATH}`, {
headers: {
"x-api-key": API_KEY,
"api-signature": signature,
"x-nonce": nonce
}
});
console.log(data);import hashlib, hmac, os, time, base64, urllib.request
key = os.environ["BIT2ME_API_KEY"]
secret = os.environ["BIT2ME_API_SECRET"]
path = "/v1/wallet/pocket"
nonce = str(int(time.time() * 1000))
message = f"{nonce}:{path}".encode()
digest = hashlib.sha256(message).digest()
signature = base64.b64encode(
hmac.new(secret.encode(), digest, hashlib.sha512).digest()
).decode()
req = urllib.request.Request(
"https://gateway.bit2me.com" + path,
headers={
"x-api-key": key,
"api-signature": signature,
"x-nonce": nonce,
"Content-Type": "application/json",
},
)
print(urllib.request.urlopen(req).read().decode())After POST /v1/account/subaccount, send X-SUBACCOUNT-ID: {userId} on every call for that end user. See Account model.
Next
Authentication
Headers, nonce window, TOTP, and a signature fixture you can unit-test against.