- General usage errors
- Rate limit errors
- Trading (placing/cancelling orders) errors
- Service status errors
- Internal errors
- Cloudflare (networking) errors
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 customised error instead, hence an alternative error format or content is possible depending upon the software being used.
General usage errors
Invalid signature errors occurs if either your API key or API secret are written incorrectly in your program or because the POST data used in the authentication and the POST data sent to the API do not match.
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.
# Import required Python libraries
# 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
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.
You can find more information about this error here:
And more about Nonce and Nonce Window here:
Invalid session errors are returned via the WebSocket API, when an attempt is made to subscribe to an authenticated (private) feed using an authentication token that is no longer valid (has already expired, for example).
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.
Rate limit errors
You can find more information about this error here:
While adding/canceling orders does not count against our standard API counter limits, these operations do have their own add/cancel order counter. This counter works in a way where the longer orders are left on the order book, the more orders clients are able to add/cancel. Full details of the trading rate limits are available here:
Temporary lockout error messages can occur if you had too many failed API calls or too many invalid nonce errors in a short period of time or invalid signatures. Even though these calls return an error, that error still counts against your API limits and may result in a 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.
Opening new spot positions on margin has been temporarily suspended for trading engine maintenance. The feature will be making a return soon and you can follow along with updates on status.kraken.com.
Another reasons may be that spot positions on margin are not currently available for clients residing in certain countries. Please see this article for our geographical restrictions:
No hedging. Cannot open a long and short position for the same pair.
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.
This error occurs when you have exceeded the margin allowance limits for your current verification level. Margin allowance limits for each currency varies based on your current verification level. Please refer to this support article for more information regarding margin allowance limits:
You have not met the minimum order volume for this asset.
You can find more information about minimum order sizes here: https://support.kraken.com/hc/en-us/articles/205893708
You have exceeded the maximum amount of open orders available to your account.
These limits are based on your verification level. Please close some of your open orders or verify your account to a higher level.
You can learn more about the maximum amount of open orders you can have here:
You have exceeded the maximum amount of open positions available to your account.
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.
You can learn more about the maximum amount of open positions you can have here:
Service status errors
These 5xx and 10xx errors are not actually API errors, but rather are web server errors from Cloudflare. API errors are always returned in JSON format such as "error":["ErrorType:ErrorMessage"], so any time that an error in a different format is received (such as an HTTP status code of 520, 504, 502, 1020, etc.), the interim solution is to try the API call again shortly afterwards and hopefully the call will then be successful.
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.