Introduction
Most API requests are completed successfully, but sometimes things go wrong and an error message is returned instead of the expected response.
Our API provides a variety of descriptive error messages intended to provide the reason for the error and provide suggestions for the appropriate solution.
API error messages can be divided into several different groups (depending upon the type of error, the underlying cause, and the optimal solution), but the format of the API error messages is consistent, and is as follows:
"Severity Level""Error Category":"Error Message"
The "Severity Level" can be either E for an error or W for a warning. The "Error Category" can be one of General, API, Query, Order, Trade, Funding or Service. The "Error Message" can be any text string that describes the reason for the error (such as Invalid arguments).
For example, an error indicating that an invalid currency pair had been used in a ticker query would be as follows:
EQuery:Unknown asset pair
Note that some third party software (mobile apps, trading bots, etc.) choose to hide the original API error and present a customized error instead, hence an alternative error format or content is possible depending upon the software being used.
General usage errors
EGeneral:Permission denied
EAPI:Invalid key
EQuery:Unknown asset pair
EGeneral:Invalid arguments
EAPI:Invalid signature
For additional reference, the following is example Python code to implement the API signature algorithm. The appropriate API public key should be copied and pasted from account management, and the API method and POST data should be updated appropriately. The output value can be used directly as the value for the API-Sign HTTP header.
#!/usr/bin/env python # Import required Python libraries import time import base64 import hashlib import hmac # Decode API private key from base64 format displayed in account management api_secret = base64.b64decode("nmlrD83t1J+yVWKUBx9vD6j26C5zhC11tFfXpN+Ww+8oOVuGgse5AeADcvl95jYaD+UAi3D5CrVfFr8GfQ7zhA==") # Variables (API method, nonce, and POST data) api_path = "/0/private/TradeBalance" api_nonce = str(int(time.time()*1000)) api_post = "nonce=" + api_nonce + "&asset=xxbt" # Cryptographic hash algorithms api_sha256 = hashlib.sha256(api_nonce + api_post).digest() api_hmac = hmac.new(api_secret, api_path + api_sha256, hashlib.sha512) # Encode signature into base64 format used in API-Sign value api_signature = base64.b64encode(api_hmac.digest()) # API authentication signature for use in API-Sign HTTP header print(api_signature)
The SHA256 is calculated using the nonce value itself and the POST data for the API method and the POST DATA is comprised of the name/value pairs for the nonce (again) and the API method parameters. An example of the data that should be passed to the SHA256 for the TradeBalance method would be as follows:
SHA256 = SHA256 of "1541933977000nonce=1541933977000&asset=xxbt"
The string value that is passed to the SHA256 should not contain any additional null (\0) values and the string value should not be encoded as base64 or hex (i.e. the string value should be a plain text string).
The URI path is the entire URL of the API method except for the "https://api.kraken.com" prefix, so the URI path of the TradeBalance method (for example) would be the string value "/0/private/TradeBalance" without any additional null values.
The HMAC SHA512 is calculated using the URI path and the previously calculated SHA256 digest, with the base64 decoded API private key as the HMAC key. An example of the data that should be passed to the HMAC would be as follows:
HMAC SHA512 using base64 decoded private key = HMAC of "/0/private/TradeBalanceSHA256"
The API-Key and API-Sign HTTP headers are the only two required custom HTTP headers. The API-Key header is an exact duplicate of the API public key from account management. The API-Sign header is the HMAC SHA512 digest encoded using base64.
EAPI:Invalid nonce
And more about Nonce and Nonce Window here:
ESession:Invalid session
The solution is simply to request a new authentication token via the REST API GetWebSocketsToken endpoint, and use the new token for all subsequent authenticated (private) subscription requests.
EAPI:Bad request
% curl --data "" https://api.kraken.com/0/private/GetWebSocketsToken {"error":["EAPI:Bad request"]}
EGeneral:Unknown Method
Rate limit errors
EAPI:Rate limit exceeded
EOrder:Rate limit exceeded
EGeneral:Temporary lockout
Temporary lockouts last approximately 15 minutes. After receiving the temporary lock out error, please wait 15 minutes before sending any new API requests. If you are triggering several invalid nonce errors, please increase the nonce window as this can help reduce the frequency that these errors will occur. Please try to reduce the frequency of your private API calls also.
Trading errors
EOrder:Cannot open position
Another reasons may be that spot positions on margin are not currently available for clients residing in certain countries.
EOrder:Cannot open opposing position
If wishing to open a long and short position for the same currency, please choose different trading pairs with the same currency as the base or quote currency. Ex: short XBT/USD, long XBT/EUR.
EOrder:Margin allowance exceeded
EOrder:Insufficient margin
EOrder:Insufficient funds (insufficient user funds)
EOrder:Order minimum not met (volume too low)
EOrder:Orders limit exceeded
These limits are based on your verification level. Please close some of your open orders or verify your account to a higher level.
EOrder:Positions limit exceeded
These limits are based on your verification level. Please close or settle some or all of your open positions or verify your account to a higher level if possible.
EOrder:Order not editable
EOrder:Not enough leaves qty
EOrder:Margin position size exceeded
EGeneral:Invalid arguments:display volume minimum not met
EGeneral:Invalid arguments:display-volume
EGeneral:Invalid arguments:iceberg:ordertype
Funding errors
EFunding:Too many addresses
EFunding:No funding method
EFunding:Unknown withdraw key
EFunding:Invalid amount
EFunding:Failed
EGeneral:Invalid arguments:beneficiary_recipient
Service status errors
Internal errors
EGeneral:Internal error
ETrade:Locked
EAPI:Feature disabled
Cloudflare errors
HTTP status codes 5xx and 10xx
A side effect of this issue is that an order can be placed successfully even though a 5xx or 10xx error is returned instead of the expected response. This is possible because Cloudflare sometimes experiences the error after the call to the API has been handled, hence the API call has been successful but returning the results via Cloudflare is not.
A solution to this side effect is to use user references (the userref parameter) for all orders. By placing each order with a unique user reference, the OpenOrders method can be used to confirm whether the order was placed successfully or not, thereby determining if the order needs to be placed again or not.
For example, if a call to the AddOrder method for a limit order includes the parameter "userref=12345678", a subsequent call to the OpenOrders method using the parameter "userref=12345678" would return the order information (including the order ID) for successfully placed orders, but would return no order information (such as only "result":"open":) for failed orders.