Authentication
Ballast uses HMAC-SHA256 request signing for secure API authentication.
Generating API Keys
- Log in to your Ballast account dashboard
- Navigate to Settings → API Keys
- Click "Generate New API Key"
- Store your
API KeyandAPI Secretsecurely (secret shown only once)
Security
Never share your API secret or commit it to version control. Treat it like a password.
Request Signing
Every private API request must include:
Authorizationheader with API keyX-BM-Signatureheader with HMAC signatureX-BM-Timestampheader with current Unix timestamp (ms)
Signature Algorithm
- Create a message string:
timestamp + method + path + body - Compute HMAC-SHA256 using your API secret as the key
- Hex-encode the resulting hash
Example (Python)
import hmac
import hashlib
import time
import requests
API_KEY = "bmkt_live_abc123"
API_SECRET = "bmkt_secret_xyz789"
BASE_URL = "https://api.ballastmarkets.com/v1"
def sign_request(method, path, body=""):
timestamp = str(int(time.time() * 1000))
message = f"{timestamp}{method}{path}{body}"
signature = hmac.new(
API_SECRET.encode(),
message.encode(),
hashlib.sha256
).hexdigest()
return signature, timestamp
# Example: Get account balance
method = "GET"
path = "/account/balance"
signature, timestamp = sign_request(method, path)
headers = {
"Authorization": f"Bearer {API_KEY}",
"X-BM-Signature": signature,
"X-BM-Timestamp": timestamp
}
response = requests.get(f"{BASE_URL}{path}", headers=headers)
print(response.json())
Example (Node.js)
const crypto = require('crypto');
const axios = require('axios');
const API_KEY = 'bmkt_live_abc123';
const API_SECRET = 'bmkt_secret_xyz789';
const BASE_URL = 'https://api.ballastmarkets.com/v1';
function signRequest(method, path, body = '') {
const timestamp = Date.now().toString();
const message = `${timestamp}${method}${path}${body}`;
const signature = crypto
.createHmac('sha256', API_SECRET)
.update(message)
.digest('hex');
return { signature, timestamp };
}
// Example: Place an order
const method = 'POST';
const path = '/orders';
const body = JSON.stringify({
market_id: 'suez-apr2025',
side: 'buy',
type: 'limit',
price: 0.87,
size: 1000
});
const { signature, timestamp } = signRequest(method, path, body);
axios.post(`${BASE_URL}${path}`, JSON.parse(body), {
headers: {
'Authorization': `Bearer ${API_KEY}`,
'X-BM-Signature': signature,
'X-BM-Timestamp': timestamp,
'Content-Type': 'application/json'
}
}).then(response => {
console.log(response.data);
});
Timestamp Validation
- Timestamps must be within 5 minutes of server time
- Use
Date.now()ortime.time() * 1000for millisecond precision - Rejected requests return
TIMESTAMP_OUT_OF_RANGEerror
IP Whitelisting (Optional)
For added security, restrict API keys to specific IP addresses:
- Go to Settings → API Keys
- Click "Edit" on your key
- Add allowed IP addresses (comma-separated)
Revoking Keys
If a key is compromised:
- Navigate to Settings → API Keys
- Click "Revoke" next to the key
- All requests with that key will immediately fail with
401 Unauthorized