Kraken Futures REST API Docs: A Trader's Guide
Master the Kraken Futures REST API with real code examples, auth setup, and endpoint breakdowns to automate your crypto trading strategy.
Master the Kraken Futures REST API with real code examples, auth setup, and endpoint breakdowns to automate your crypto trading strategy.
Kraken Futures offers one of the most well-documented REST APIs in the derivatives space. Whether you're coming from Binance Futures or switching from Bybit's USDT perpetuals, Kraken's API structure will feel familiar — but it has its own quirks worth knowing before you write a single line of code. This guide walks you through authentication, the most useful endpoints, and real examples you can run today.
Kraken Futures (formerly Crypto Facilities) runs a separate API stack from the spot Kraken exchange. The base URL for the Futures REST API is https://futures.kraken.com/derivatives/api/v3. This is distinct from api.kraken.com, which handles spot trading — a common source of confusion for traders migrating from the spot side.
The API supports both public and private endpoints. Public endpoints — like market tickers, orderbook snapshots, and instrument listings — require no authentication. Private endpoints — order placement, position management, account balance — require HMAC-SHA512 authentication with your API key and secret. Compared to OKX and Binance, which both use HMAC-SHA256, Kraken uses SHA512, so double-check your hashing implementation.
Kraken's authentication flow is more involved than Binance or Bitget — it requires you to construct a specific message string before signing. The nonce is a timestamp in milliseconds, and the signed message combines the endpoint path, nonce, and POST body (or empty string for GET requests). Here's a reusable auth class:
import hashlib
import hmac
import base64
import time
import urllib.parse
import requests
class KrakenFuturesClient:
BASE_URL = "https://futures.kraken.com/derivatives/api/v3"
def __init__(self, api_key: str, api_secret: str):
self.api_key = api_key
self.api_secret = api_secret
def _sign(self, endpoint: str, nonce: str, post_data: str = "") -> str:
# Concatenate: postData + nonce + endpoint (without /derivatives/api/v3)
message = post_data + nonce + endpoint
sha256_hash = hashlib.sha256(message.encode()).digest()
secret_decoded = base64.b64decode(self.api_secret)
signature = hmac.new(secret_decoded, sha256_hash, hashlib.sha512)
return base64.b64encode(signature.digest()).decode()
def get_private(self, endpoint: str, params: dict = None) -> dict:
nonce = str(int(time.time() * 1000))
query = urllib.parse.urlencode(params or {})
signature = self._sign(endpoint, nonce, query)
headers = {
"APIKey": self.api_key,
"Nonce": nonce,
"Authent": signature
}
url = self.BASE_URL + endpoint
if query:
url += "?" + query
resp = requests.get(url, headers=headers)
resp.raise_for_status()
return resp.json()
# Usage
client = KrakenFuturesClient(
api_key="YOUR_API_KEY",
api_secret="YOUR_API_SECRET"
)
account = client.get_private("/accounts")
print(account)
Kraken uses SHA-256 to hash the message first, then HMAC-SHA512 to sign the hash with your decoded secret. Skipping the intermediate SHA-256 step is the most common auth bug — and it returns a generic 'invalid signature' error with no additional detail.
The Kraken Futures API is organized into logical groups. Here are the endpoints you'll use most often when building a trading bot or data pipeline:
| Endpoint | Method | Auth | Description |
|---|---|---|---|
| /tickers | GET | No | All market tickers with mark price, bid, ask, volume |
| /orderbook | GET | No | L2 orderbook snapshot for a symbol |
| /history | GET | No | Historical price data (OHLCV) |
| /accounts | GET | Yes | Account balances and margin info |
| /openpositions | GET | Yes | All open positions with PnL |
| /sendorder | POST | Yes | Place a new order (limit, market, stop) |
| /cancelorder | POST | Yes | Cancel an existing order by order ID |
| /openorders | GET | Yes | All open orders for the account |
Instrument symbols on Kraken Futures follow a specific pattern. Linear perpetuals use the format PF_XBTUSD (PF = perpetual futures), while fixed-maturity contracts use FF_XBTUSD_230331. This is different from how Binance (BTCUSDT), OKX (BTC-USDT-SWAP), and Bybit (BTCUSDT) name their instruments — so be careful if you're building a multi-exchange system.
Order placement on Kraken Futures uses a POST request to /sendorder with form-encoded body parameters — not JSON. This is different from Binance and Bybit, which both accept JSON request bodies. Here's a working example that places a limit order and handles common errors:
import requests
import hashlib
import hmac
import base64
import time
import urllib.parse
def place_limit_order(
client,
symbol: str,
side: str, # 'buy' or 'sell'
size: float,
limit_price: float,
reduce_only: bool = False
) -> dict:
endpoint = "/sendorder"
nonce = str(int(time.time() * 1000))
params = {
"orderType": "lmt",
"symbol": symbol,
"side": side,
"size": size,
"limitPrice": limit_price,
"reduceOnly": "true" if reduce_only else "false"
}
post_data = urllib.parse.urlencode(params)
# Sign the request
message = post_data + nonce + endpoint
sha256_hash = hashlib.sha256(message.encode()).digest()
secret_decoded = base64.b64decode(client.api_secret)
sig = hmac.new(secret_decoded, sha256_hash, hashlib.sha512)
signature = base64.b64encode(sig.digest()).decode()
headers = {
"APIKey": client.api_key,
"Nonce": nonce,
"Authent": signature,
"Content-Type": "application/x-www-form-urlencoded"
}
url = client.BASE_URL + endpoint
try:
resp = requests.post(url, data=post_data, headers=headers, timeout=10)
resp.raise_for_status()
result = resp.json()
if result.get("result") != "success":
raise ValueError(f"Order failed: {result.get('error', 'unknown error')}")
order_id = result["sendStatus"]["order_id"]
print(f"Order placed: {order_id}")
return result
except requests.exceptions.Timeout:
print("Request timed out — check order status before retrying")
raise
except requests.exceptions.HTTPError as e:
print(f"HTTP error: {e.response.status_code} — {e.response.text}")
raise
# Example: buy 1 BTC perpetual at $65,000
result = place_limit_order(
client=client,
symbol="PF_XBTUSD",
side="buy",
size=1,
limit_price=65000
)
Always implement timeout handling on order requests. A timeout does NOT mean the order was rejected — it may have been accepted and you simply didn't receive the confirmation. Check /openorders before re-submitting to avoid duplicates.
For any live trading bot, position monitoring is as important as order placement. Kraken Futures returns open positions with unrealized PnL, entry price, and funding rate data. Pair this with real-time signals from a platform like VoiceOfChain and you have the foundation for a fully automated signal-execution pipeline.
def get_positions_summary(client) -> list:
"""Fetch open positions and format key metrics."""
data = client.get_private("/openpositions")
if data.get("result") != "success":
raise RuntimeError(f"Failed to fetch positions: {data}")
positions = data.get("openPositions", [])
summary = []
for pos in positions:
symbol = pos["symbol"]
side = pos["side"] # 'long' or 'short'
size = pos["size"] # number of contracts
entry = pos["price"] # average entry price
unrealized_pnl = pos.get("unrealizedFunding", 0) + pos.get("pnl", 0)
summary.append({
"symbol": symbol,
"side": side,
"size": size,
"entry_price": entry,
"unrealized_pnl": round(unrealized_pnl, 4)
})
print(f"{symbol} | {side.upper()} {size} @ {entry} | PnL: {unrealized_pnl:.4f}")
return summary
# Also fetch margin and available balance
def get_account_balance(client) -> dict:
data = client.get_private("/accounts")
if data.get("result") != "success":
raise RuntimeError("Failed to fetch account data")
accounts = data.get("accounts", {})
flex = accounts.get("flex", {})
return {
"balance": flex.get("balanceValue"),
"pnl": flex.get("unrealizedFunding"),
"margin_used": flex.get("initialMargin"),
"available": flex.get("availableMargin")
}
positions = get_positions_summary(client)
balance = get_account_balance(client)
print(f"Available margin: ${balance['available']:,.2f}")
Notice that Kraken Futures uses a 'flex' account structure by default — this is their cross-margin account where all positions share a common margin pool. If you're used to isolated margin on Binance or portfolio margin on OKX, this is worth understanding before you size positions. Kraken also offers separate margin accounts per currency, accessible via the /accounts endpoint under different keys.
Running a production trading bot on Kraken Futures requires disciplined rate limit management. Public endpoints allow 500 requests per 10-second window; private endpoints are capped at 100. Unlike Binance's weight-based system, Kraken uses a simple request-count model — easier to reason about, but you still need a request queue for any bot making frequent order updates.
For production deployments, combine the Kraken Futures REST API with their WebSocket feed for order book and trade updates. Poll REST for account state every 5-10 seconds rather than on every tick — this keeps you well within rate limits while maintaining accurate position awareness. Platforms like VoiceOfChain stream real-time market signals that you can feed directly into this architecture, triggering REST API order calls only when an actionable signal fires.
Keep a local order state cache. If your bot sends an order and the response is ambiguous (timeout, 5xx), query /openorders before retrying. Double-submitting a market order on a volatile day can result in an unintended 2x position that's expensive to unwind.
The Kraken Futures REST API is mature, well-documented, and reliable enough for production trading systems. The two things most developers get wrong early on are the HMAC signing order (SHA-256 then SHA-512, not just SHA-512) and the form-encoded POST body instead of JSON. Once those are dialed in, the rest of the API is clean to work with.
For serious algorithmic traders, the recommended stack is: REST API for order management and account polling, WebSocket for real-time market data, and an external signal source — whether your own analysis or a platform like VoiceOfChain — to drive trading decisions. Compared to building on Binance or Gate.io, Kraken Futures trades lower volume but offers a more regulated environment with cleaner API behavior and fewer unexpected downtime events during high-volatility periods.
Start with the demo environment, build your auth and order management layer, test thoroughly against paper positions, then migrate to production by swapping the base URL and live credentials. The foundation you build here transfers directly to any exchange's REST API — the concepts of signing, rate limiting, and stateful position tracking are universal.