Causas Comuns de Erro de Chave Inválida

Última atualização: 5/06/2025

Para que uma chamada privada seja efetuada com sucesso, é necessário enviar um pedido HTTP POST para o endpoint apropriado.

Este pedido inclui o cabeçalho API-Sign (assinatura) que utiliza os Post_data codificados como parte do seu algoritmo de hash.

Se houver uma discrepância entre a Assinatura incluída no cabeçalho e os dados POST incluídos no pedido, será devolvido um erro de Chave de API Inválida.

Abaixo está um exemplo de uma chamada corretamente formulada em que os dados utilizados no Algoritmo de Autenticação correspondem aos do corpo do pedido:

python

Python

#!/usr/bin/env python3

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

api_key = ''
secret_key = ''
nonce = str(int(1000 * time.time()))

# Define the URI path for the Kraken API request
uri_path = '/0/private/AddOrder'

# API URL
api_url = 'https://api.kraken.com'

# Create a dictionary for the request data
# Note that this is the data that will be used to calculate the Authentication Algorithm (API-Sign).
data = {
    'nonce': nonce,
    'ordertype': 'limit',
    'type': 'buy',
    'volume': '1',
    'pair': 'btcusd',
    'price': '58626.4',
    'validate': True
}

# Encode the data for the request
postdata = urllib.parse.urlencode(data)
encoded = (str(data['nonce']) + postdata).encode()

# Create a message to be signed
message = uri_path.encode() + hashlib.sha256(encoded).digest()

# Create the HMAC signature
mac = hmac.new(base64.b64decode(secret_key), message, hashlib.sha512)
sigdigest = base64.b64encode(mac.digest())

# Create headers for the request
headers = {}
headers['API-Key'] = api_key
headers['API-Sign'] = sigdigest.decode()

# Make the POST request
# Note that the data below is what is sent in the HTTP request.
req = requests.post(api_url + uri_path, headers=headers, data={
    'nonce': nonce,
    'ordertype': 'limit',
    'type': 'buy',
    'volume': '1',
    'pair': 'btcusd',
    'price': '58626.4',
    'validate': True
})

# Print the result
print(req.json())

# Result:
# {'error': [], 'result': {'descr': {'order': 'buy 1.00000000 XBTUSD @ limit 58626.4'}}}

No entanto, quando o tipo de ordem (ordertype) e o volume são trocados, é produzido um erro de Chave Inválida.

python

Python

#!/usr/bin/env python3
import time
import requests
import urllib.parse
import hashlib
import hmac
import base64

api_key = ''
secret_key = ''
nonce = str(int(1000 * time.time()))

# Define the URI path for the Kraken API request
uri_path = '/0/private/AddOrder'

# API URL
api_url = 'https://api.kraken.com'

# Create a dictionary for the request data
data = {
    'nonce': nonce,
    'ordertype': 'limit',
    'type': 'buy',
    'volume': '1',
    'pair': 'btcusd',
    'price': '58626.4',
    'validate': True
}

# Encode the data for the request
postdata = urllib.parse.urlencode(data)
encoded = (str(data['nonce']) + postdata).encode()

# Create a message to be signed
message = uri_path.encode() + hashlib.sha256(encoded).digest()

# Create the HMAC signature
mac = hmac.new(base64.b64decode(secret_key), message, hashlib.sha512)
sigdigest = base64.b64encode(mac.digest())

# Create headers for the request
headers = {}
headers['API-Key'] = api_key
headers['API-Sign'] = sigdigest.decode()

# Make the POST request
req = requests.post(api_url + uri_path, headers=headers, data={
    'nonce': nonce,
    'volume': '1',
    'type': 'buy',
    'ordertype': 'limit',
    'volume': '1',
    'pair': 'btcusd',
    'price': '58626.4',
    'validate': True
})

# Print the result
print(req.json())

# Result:
# {'error': ['EAPI:Invalid key']}

Uma indicação de que esta pode ser a causa do erro de Chave Inválida é se as chamadas para endpoints que não exigem múltiplos parâmetros forem bem-sucedidas (Saldo, Ordens Abertas). Se obtiver continuamente uma resposta válida destas chamadas, então a teoria da incompatibilidade parece mais plausível.

*Tenha em atenção que, no exemplo acima, o Parâmetro de Validação foi utilizado para simplesmente validar as entradas, mas não para submeter a ordem. O parâmetro deve ser descartado para negociação em tempo real*

Ter uma incompatibilidade entre o tipo de conteúdo do corpo e o cabeçalho também pode levar a uma Chave de API Inválida.

Consulte abaixo um cenário em que tanto o Cabeçalho como os dados Post estão codificados em URL:

 

python

Python

api_key = ""

api_secret = base64.b64decode("")

api_domain = "https://api.kraken.com"
api_path = "/0/private/"
api_endpoint = "Balance"  # {"error":[]} IS SUCCESS-EMPTY BALANCE
api_parameters = ""

api_nonce = str(int(time.time() * 1000))

api_postdata = api_parameters + "&nonce=" + api_nonce
api_postdata = api_postdata.encode('utf-8')

api_sha256Data = api_nonce.encode('utf-8') + api_postdata
api_sha256 = hashlib.sha256(api_sha256Data).digest()

api_hmacSha512Data = api_path.encode('utf-8') + api_endpoint.encode('utf-8') + api_sha256
api_hmacsha512 = hmac.new(api_secret, api_hmacSha512Data, hashlib.sha512)

api_sig = base64.b64encode(api_hmacsha512.digest())

api_url = api_domain + api_path + api_endpoint
api_request = urllib2.Request(api_url, api_postdata)
api_request.add_header("Content-Type", "application/x-www-form-urlencoded")
api_request.add_header("API-Key", api_key)
api_request.add_header("API-Sign", api_sig)
api_request.add_header("User-Agent", "Kraken REST API")

print("DEBUG DATA : ")
print("api_url : " + api_url)
print("api_endpoint : " + api_endpoint)
print("api_parameters : " + api_parameters)

print("")

api_reply = urllib2.urlopen(api_request).read()
api_reply = api_reply.decode()

print("API JSON DATA:")
print(api_reply)

sys.exit(0)

# Response:
# API JSON DATA:
# {"error":[],"result":{"ADA":"0.00000000","AIR":"0.0000000000","ALGO":"0.00000000","ATOM":"0.00000000",
# "AVAX":"0.0000000000","BONK":"0.24","BSX":"0.00","C98":"0.00000","CVC":"0.0000000000","DOT":"0.0000000058",
# "DYM":"1.001240","ETH2.S":"0.0000000000","FLOW":"0.0000000000","FLR":"0.0000","GRT":"0.0000000000","ICP":"0.00000000",
# "KAVA":"0.00000000","KFEE":"4619.88","KSM":"0.0457969620","KSM.S":"0.0000000000","MATIC":"0.0000000000",
# "MINA":"1.0067624751","MINA.S":"0.0000000000","PARA":"0.000","POLS":"0.00000","SBR":"0.00000000","SCRT":"0.00000000",
# "SCRT21.S":"0.00000000","SDN":"0.0000000000","SEI":"0.0000","SHIB":"0.00000","SOL":"0.0000069748","SOL.S":"0.0000000000",
# "SOL03.S":"0.0201035317","TIA":"0.000000","TRX":"0.00000000","USDC":"0.00000000","USDT":"0.00068726",
# "USDT.B":"3.53191423","WEN":"158958.59","WIF":"0.00000","XBT.M":"0.0001000103","XETH":"0.0000000000",
# "XTZ":"0.00000000","XXBT":"0.0000000000","XXDG":"24.34451185","XXMR":"0.0000000000","ZCAD":"0.0000",
# "ZEUR":"0.2732","ZUSD":"0.6353"}}

No entanto, quando adicionamos o Tipo de Conteúdo do Cabeçalho como JSON, obtemos um

Erro EAPI: Chave Inválida.

 

python

Python

api_key = ""

api_secret = base64.b64decode("")

api_domain = "https://api.kraken.com"
api_path = "/0/private/"
api_endpoint = "AddOrder"  # {"error":[]} IS SUCCESS-EMPTY BALANCE

# api_parameters = "pair=xbtusd&ordertype=market&type=buy&volume=0.0001&validate=True"
api_parameters = ''

api_nonce = str(int(time.time() * 1000))

api_postdata = api_parameters + "&nonce=" + api_nonce
api_postdata = api_postdata.encode('utf-8')

api_sha256Data = api_nonce.encode('utf-8') + api_postdata
api_sha256 = hashlib.sha256(api_sha256Data).digest()

api_hmacSha512Data = api_path.encode('utf-8') + api_endpoint.encode('utf-8') + api_sha256
api_hmacsha512 = hmac.new(api_secret, api_hmacSha512Data, hashlib.sha512)

api_sig = base64.b64encode(api_hmacsha512.digest())

api_url = api_domain + api_path + api_endpoint
api_request = urllib2.Request(api_url, api_postdata)

print("DEBUG DATA : ")
print("api_url : " + api_url)
print("api_endpoint : " + api_endpoint)
print("api_parameters : " + api_parameters)
print("")

headers = {}
headers['API-Key'] = api_key
headers['API-Sign'] = api_sig
headers['Content-Type'] = 'application/json'
headers['Accepts'] = 'application/json'
headers['User-Agent'] = "Kraken REST API"

api_reply = urllib2.urlopen(api_request).read()
api_reply = api_reply.decode()

data = {'nonce': api_nonce}
req = requests.post(api_url, headers=headers, data=data)
print(req.json())

print("API JSON DATA:")
print(api_reply)

sys.exit(0)

# API JSON DATA:
# {"error":["EAPI:Invalid key"]}

*Tenha em atenção que é possível utilizar dados codificados em URL ou dados codificados em JSON, mas os dados devem corresponder exatamente tanto na entrada SHA256 como no pedido HTTP.*

Um erro de Chave Inválida também pode ser causado pela passagem de um URI de endpoint incompleto ou em falta (por exemplo, "AddOrder" em vez de “/0/private/AddOrder”).

Para que o Algoritmo de Autenticação crie corretamente o Cabeçalho API-Sign, ele precisa de utilizar o URI na sua totalidade (por exemplo, "/0/private/AddOrder”). Se qualquer parte deste URI for truncada, levará a um valor incorreto para o API-Sign e, consequentemente, a um erro de Chave Inválida.

Abaixo está um exemplo de apenas “AddOrder” a ser passado para codificação em vez do URI completo do endpoint “/0/private/AddOrder”

python

Python

api_key = ''
secret_key = ''

# Define the URI path for the Kraken API request
uri_path = 'AddOrder'

# API URL
api_url = 'https://api.kraken.com/0/private/'

# Create a dictionary for the request data
data = {
    "nonce": str(int(1000 * time.time())),
    "ordertype": 'limit',
    'type': 'buy',
    'volume': '0.07617478622420963',
    'pair': 'SOLUSD',
    'price': '127.47',
    'validate': 'true'
}

# Encode the data for the request
postdata = urllib.parse.urlencode(data)
encoded = (str(data['nonce']) + postdata).encode()

# Create a message to be signed
message = uri_path.encode() + hashlib.sha256(encoded).digest()

# Create the HMAC signature
mac = hmac.new(base64.b64decode(secret_key), message, hashlib.sha512)
sigdigest = base64.b64encode(mac.digest())

# Create headers for the request
headers = {}
headers['API-Key'] = api_key
headers['API-Sign'] = sigdigest.decode()

# Make the POST request
req = requests.post(api_url + uri_path, headers=headers, data=data)

# Print the result
print(req.json())

# Result:
# {'error': ['EAPI:Invalid key']}

Outro problema comum que causa um erro de Chave Inválida é uma incompatibilidade de codificação entre o pedido POST e a autenticação HTTP.

No exemplo abaixo, ‘Data’ que é passado para o pedido POST é formatado em URL (com espaços codificados como ‘+’) como tipo de conteúdo application/x-www-form-urlencoded, enquanto ‘data_formatted’ está a codificar espaços como ‘%20’.

Embora em ambos os exemplos os espaços estejam codificados, os dados que são passados para o algoritmo de autenticação e para o pedido POST não são exatamente os mesmos. Isto levará a um erro de Chave Inválida.

 

python

Python

# Define the URI path for the Kraken API request
uri_path = '/0/private/DepositAddresses'

# API URL
api_url = 'https://api.kraken.com'

# Calculate Nonce for both data variables
nonce = str(int(1000 * time.time()))

# Create a dictionary for the request data
data = {
    "nonce": nonce,
    "asset": 'BTC',
    'method': 'Bitcoin Lightning',
    'amount': '0.2',
    'new': True
}

postdata_data = urllib.parse.urlencode(data)

# Encode the data for the request manually
data_formatted = f'nonce={nonce}&asset=BTC&method=Bitcoin%20Lightning&amount=0.2&new=True'
postdata = data_formatted
encoded = (nonce + postdata).encode()

# Create a message to be signed
message = uri_path.encode() + hashlib.sha256(encoded).digest()

# Create the HMAC signature
mac = hmac.new(base64.b64decode(secret_key), message, hashlib.sha512)
sigdigest = base64.b64encode(mac.digest())

# Create headers for the request
headers = {}
headers['API-Key'] = api_key
headers['API-Sign'] = sigdigest.decode()

# Make the POST request
req = requests.post(api_url + uri_path, headers=headers, data=data)

# Print the result
print(req.json())

# Result:
# {'error': ['EAPI:Invalid key']}

Para ilustrar isto claramente, consulte abaixo os 2 formatos diferentes para Dados:

bash

Bash

data = nonce=1719929687102&asset=BTC&method=Bitcoin+Lightning&amount=0.2&new=True

data_formatted = nonce=1719929687102&asset=BTC&method=Bitcoin%20Lightning&amount=0.2&new=True

*É possível utilizar texto simples ou codificação percentual, desde que o formato seja o mesmo tanto nos dados de Autenticação como no pedido.*

Precisa de mais ajuda?