◈   ⌘ api · Intermediate

Fixing Kraken API Errors: Auth, Codes and Rate Limits

Master Kraken API error handling — from unauthorized errors and invalid signatures to rate limits. Includes Python code examples for authentication setup and error recovery.

Uncle Solieditor · voc · 15.03.2026 ·views 52
◈   Contents
  1. → Understanding Kraken API Error Codes
  2. → Kraken API Authentication Errors: The Most Common Trap
  3. → Setting Up Kraken API Authentication Correctly
  4. → Fetching Kraken API Price Data Without Authentication
  5. → Handling Kraken API Rate Limits in Trading Bots
  6. → Frequently Asked Questions
  7. → Final Thoughts

Working with the Kraken API is a rite of passage for any serious crypto algo trader. The exchange offers one of the most reliable and well-documented REST APIs in the industry — but when you're setting up your first trading bot or building a portfolio dashboard, you will almost certainly run into a wall of cryptic error messages. A kraken api error unauthorized response when you are sure the credentials are right. A rate limit error that kills your bot at 3 AM. An invalid signature that makes zero sense until you understand exactly how Kraken's HMAC authentication works. These errors are not random. Every Kraken API error maps to a specific cause, and once you understand the patterns, they are almost always fixable in minutes. Whether you're connecting to check prices or automating full execution, this guide covers the real causes and the actual fixes — with working code.

Understanding Kraken API Error Codes

The Kraken API always returns a consistent JSON envelope. Every response has two top-level fields: error and result. If the error array is empty, the request succeeded. If anything is in that array, something went wrong. Each error string follows a Category:Subcategory format, which makes them machine-readable and easy to branch on in your code. This is actually more structured than what you get from Binance or KuCoin, where errors sometimes come back as HTTP status codes, sometimes as custom message fields, depending on the endpoint version. Knowing the category tells you immediately whether you are dealing with a credentials problem, a request problem, or a server-side issue — and that determines your retry strategy.

Common Kraken API Error Codes Reference
Error CodeCategoryMost Likely Cause
EAPI:Invalid keyAuthenticationAPI key copied with whitespace, deleted, or wrong account
EAPI:Invalid signatureAuthenticationSignature calculation error — wrong nonce or POST data encoding
EAPI:Invalid nonceAuthenticationNonce not strictly increasing, or clock drift between requests
EAPI:Rate limit exceededRate LimitingToo many private endpoint calls in a short window
EAPI:Feature disabledPermissionsAPI key missing required permission (e.g. Trade, Withdraw)
EGeneral:Invalid argumentsRequestMissing or malformed request parameter
EOrder:Insufficient fundsOrderAccount balance too low to place the order
EService:UnavailableServerKraken servers temporarily down — retry with backoff
EService:BusyServerServer overloaded — brief pause then retry

Kraken API Authentication Errors: The Most Common Trap

The kraken api authentication error category is where most developers get stuck on their first integration. The two most frequent offenders are EAPI:Invalid key and EAPI:Invalid signature. EAPI:Invalid key means Kraken cannot find your API key at all — it either does not exist, was deleted, or was copied incorrectly. This one is usually a copy-paste issue, often a trailing newline or whitespace character that is invisible but breaks the lookup. EAPI:Invalid signature is trickier because the key exists but the signature you computed does not match what Kraken expects. Kraken uses HMAC-SHA512 authentication where the signature is computed from a combination of the nonce, the URL-encoded POST body, and the endpoint path — in a specific order. Any deviation breaks it silently.

The nonce deserves special attention. Kraken requires nonces to be strictly increasing integers — each new request must have a nonce larger than the previous one. If you are running multiple bot instances sharing the same API key, or if your server clock drifts, or if you simply reuse a nonce by accident, you will get EAPI:Invalid nonce errors that appear completely random. The safest approach is to use millisecond timestamps as your nonce source and make sure each request generates a fresh one. Never hardcode a nonce for testing.

Pro tip: EAPI:Invalid nonce is often caused by running the same API key on two machines simultaneously. Each machine generates nonces independently, and Kraken only accepts strictly increasing values per key. Solution: use dedicated API keys per bot instance.

Setting Up Kraken API Authentication Correctly

Here is a complete Python implementation of Kraken API authentication. This follows the official signature algorithm exactly and includes a private endpoint call to fetch your account balance. Notice how the nonce is embedded in both the POST data and the signature computation — this is the step most people get wrong when rolling their own implementation.

import hashlib
import hmac
import base64
import time
import urllib.parse
import requests

API_KEY = "your_api_key_here"
API_SECRET = "your_api_secret_here"

def get_kraken_signature(urlpath, data, secret):
    postdata = urllib.parse.urlencode(data)
    encoded = (str(data['nonce']) + postdata).encode()
    message = urlpath.encode() + hashlib.sha256(encoded).digest()
    mac = hmac.new(base64.b64decode(secret), message, hashlib.sha512)
    return base64.b64encode(mac.digest()).decode()

def kraken_request(uri_path, data):
    headers = {
        'API-Key': API_KEY,
        'API-Sign': get_kraken_signature(uri_path, data, API_SECRET)
    }
    resp = requests.post(
        'https://api.kraken.com' + uri_path,
        headers=headers,
        data=data
    )
    return resp.json()

# Fetch account balance
data = {'nonce': str(int(1000 * time.time()))}
result = kraken_request('/0/private/Balance', data)

if result['error']:
    print(f"Auth failed: {result['error']}")
else:
    balances = result['result']
    print(f"BTC balance: {balances.get('XXBT', '0')}")
    print(f"USD balance: {balances.get('ZUSD', '0')}")

The get_kraken_signature function is the core of every authenticated request. It takes the URL path (like /0/private/Balance), the POST data dict including the nonce, and your API secret. The computation chain is: URL-encode the POST data, prepend the nonce string, SHA256-hash that, prepend the raw URL path bytes, then HMAC-SHA512 the whole thing using your base64-decoded secret. The result is base64-encoded and sent in the API-Sign header. If any step is out of order, you will get EAPI:Invalid signature every time.

Fetching Kraken API Price Data Without Authentication

Public endpoints like the ticker, orderbook, and OHLC data do not require authentication at all. These are useful for building price monitors, checking spreads, or pulling historical candle data for analysis. The kraken api price endpoint is /0/public/Ticker and accepts a comma-separated list of trading pairs. Compared to similar public APIs on Coinbase and Bybit, Kraken returns more data per call — including VWAP, trade count, and 24-hour volume alongside the bid/ask. Platforms like VoiceOfChain use aggregated price feeds across multiple exchanges to generate trading signals, combining real-time data from Kraken, Binance, and OKX for cross-exchange validation.

import requests

def get_kraken_price(pair="XBTUSD"):
    """Fetch current ticker - no authentication required"""
    url = f"https://api.kraken.com/0/public/Ticker?pair={pair}"
    resp = requests.get(url)
    data = resp.json()

    if data['error']:
        raise ValueError(f"Kraken API error: {data['error']}")

    ticker = data['result'][pair]
    return {
        'last':      float(ticker['c'][0]),
        'bid':       float(ticker['b'][0]),
        'ask':       float(ticker['a'][0]),
        'vwap_24h':  float(ticker['p'][1]),
        'volume_24h': float(ticker['v'][1]),
        'trades_24h': int(ticker['t'][1])
    }

# Get BTC/USD and ETH/USD prices in one call
def get_multiple_prices(pairs):
    pair_str = ','.join(pairs)
    url = f"https://api.kraken.com/0/public/Ticker?pair={pair_str}"
    resp = requests.get(url)
    data = resp.json()

    if data['error']:
        raise ValueError(f"Kraken error: {data['error']}")

    results = {}
    for pair, ticker in data['result'].items():
        results[pair] = {
            'last': float(ticker['c'][0]),
            'ask':  float(ticker['a'][0]),
            'bid':  float(ticker['b'][0])
        }
    return results

prices = get_multiple_prices(['XBTUSD', 'ETHUSD', 'SOLUSD'])
for pair, p in prices.items():
    print(f"{pair}: ${p['last']:,.2f} (bid ${p['bid']:,.2f} / ask ${p['ask']:,.2f})")

Handling Kraken API Rate Limits in Trading Bots

Kraken's rate limiting system is one of the more nuanced ones in the industry. Public endpoints allow roughly one request per second per IP address. Private endpoints use a counter-based system tied to your account verification tier. When the counter exceeds the limit, you get EAPI:Rate limit exceeded. The counter starts at a maximum value (15 for Starter, 20 for Intermediate and Pro tiers) and increments by 1 per request. It decays back down over time — at a rate of roughly 1 per second for Starter accounts, and faster for higher tiers. This means burst requests drain the counter quickly, but spacing your calls out lets it recover. Compare this to Binance's weight-based system or Bybit's category-specific request limits — Kraken's approach rewards steady, evenly-spaced calls over aggressive bursting. Gate.io and KuCoin both use similar decay mechanisms for their private APIs. The practical implication: if your bot fires 20 private requests in under 5 seconds, it will hit the limit and need to back off. Design for cadence, not throughput.

import time

def safe_kraken_request(uri_path, data, max_retries=4):
    """Kraken request with exponential backoff and error classification"""
    for attempt in range(max_retries):
        # Always refresh nonce on every attempt
        data['nonce'] = str(int(1000 * time.time()))
        result = kraken_request(uri_path, data)

        # Success
        if not result.get('error'):
            return result['result']

        errors = result['error']

        # Rate limited — exponential backoff
        if 'EAPI:Rate limit exceeded' in errors:
            wait = 2 ** attempt  # 1s, 2s, 4s, 8s
            print(f"Rate limited. Backing off {wait}s (attempt {attempt+1}/{max_retries})")
            time.sleep(wait)
            continue

        # Auth errors — fix the key/secret, no point retrying
        if any('EAPI:Invalid' in e for e in errors):
            raise Exception(f"Authentication error — check key/secret/nonce: {errors}")

        # Server busy — short pause then retry
        if any('EService' in e for e in errors):
            print(f"Kraken service error: {errors}. Retrying in 2s...")
            time.sleep(2)
            continue

        # All other errors — raise immediately
        raise Exception(f"Kraken API error: {errors}")

    raise Exception(f"Request failed after {max_retries} attempts")

# Usage example — place a limit order with retry handling
try:
    order_data = {
        'ordertype': 'limit',
        'type': 'buy',
        'volume': '0.001',
        'pair': 'XBTUSD',
        'price': '60000'
    }
    result = safe_kraken_request('/0/private/AddOrder', order_data)
    print(f"Order placed: {result['txid']}")
except Exception as e:
    print(f"Order failed: {e}")
Rate limit tip: Kraken recommends spacing private API calls at least 1 second apart for Starter accounts. For production bots, use a token bucket or leaky bucket algorithm to smooth out your request cadence rather than relying solely on retry logic. If you trade programmatically at volume, upgrading your account verification tier doubles the rate limit headroom.

Tools like VoiceOfChain's signal platform avoid this problem entirely for price monitoring by subscribing to Kraken's WebSocket feed instead of polling REST endpoints. WebSocket connections bypass the per-request rate limits for market data, making them far more efficient for real-time price tracking in bots. For private order management, the WebSocket private feed also supports authenticated order placement and status updates without hitting REST limits.

Frequently Asked Questions

What does kraken api error unauthorized mean?
It corresponds to EAPI:Invalid key, meaning Kraken cannot find or validate your API key. The most common causes are whitespace characters copied into the key string, using the wrong key for the account, or the key being deleted in the Kraken portal. Always trim your key and secret strings before storing them in environment variables.
How do I fix EAPI:Invalid signature on Kraken?
This error means your HMAC-SHA512 signature does not match what Kraken expects. Most commonly, it is caused by incorrect nonce embedding, wrong URL-encoding of POST data, or using the API Key instead of the API Secret as the signing key. Make sure you are base64-decoding the secret before using it as the HMAC key — it is not a plain string.
What are Kraken API rate limits for private endpoints?
Kraken uses a counter-based system that starts at a maximum of 15 (Starter) or 20 (Intermediate/Pro) and increments by 1 per request. The counter decays at 1 per second on Starter and faster on higher tiers. Hitting the maximum returns EAPI:Rate limit exceeded. Space requests at least 1 second apart to stay within Starter limits, or upgrade your verification tier for more headroom.
How do I use kraken api example code to get started quickly?
Start with the public Ticker endpoint — it requires no authentication and lets you verify your HTTP setup. Once that works, implement the HMAC signature function using the pattern in Kraken's official docs, then test with the /0/private/Balance endpoint. Getting auth working on Balance first means you have a solid foundation before attempting order placement.
Why does EAPI:Invalid nonce happen randomly on my bot?
Nonces must be strictly increasing per API key, and Kraken rejects any nonce equal to or lower than the last accepted one. If you run multiple bot instances on the same key, or if your server clock jumps backward due to NTP sync, you will see this intermittently. The fix is using separate API keys per bot instance and generating nonces from millisecond timestamps immediately before each request, never caching or reusing them.
Can I use the Kraken API to get price data without authentication?
Yes. All public endpoints — including Ticker (/0/public/Ticker), OHLC (/0/public/OHLC), Orderbook (/0/public/Depth), and Trades (/0/public/Trades) — require no API key at all. Only private endpoints for account data, order management, and withdrawals need authentication. For real-time price data at scale, Kraken's public WebSocket feed is more efficient than polling REST.

Final Thoughts

Kraken API errors follow a consistent, logical pattern once you know the vocabulary. Authentication errors (EAPI:Invalid key, EAPI:Invalid signature, EAPI:Invalid nonce) are almost always a credentials or nonce generation problem — fix the setup once and they go away permanently. Rate limit errors are a design signal telling you to space out your requests or use WebSockets for market data. Server errors (EService:Unavailable, EService:Busy) are transient and handled cleanly with exponential backoff. Build your error handling layer around these three categories from day one, and your Kraken-connected bots will be genuinely production-ready. If you want pre-built signals without managing raw API connections yourself, platforms like VoiceOfChain handle the exchange connectivity layer and deliver actionable alerts directly — letting you focus on strategy rather than infrastructure.

◈   more on this topic
◉ basics Mastering the ccxt library documentation for crypto traders ⌂ exchanges Mastering the Binance CCXT Library for Crypto Traders ⌬ bots Best Crypto Trading Bots 2025: Profitable AI-Powered Strategies