สาเหตุทั่วไปของ Invalid Key Error

อัปเดตล่าสุด: 5 มิถุนายน 2568

เพื่อให้การเรียกใช้ส่วนตัวสำเร็จ จะต้องส่ง HTTP POST request ไปยัง endpoint ที่เหมาะสม

request นี้จะรวม Header API-Sign (signature) ซึ่งใช้ Post_data ที่เข้ารหัสเป็นส่วนหนึ่งของ hashing algorithm

หากมีความคลาดเคลื่อนระหว่าง Signature ที่รวมอยู่ใน header และ POST data ที่รวมอยู่ใน request จะมีการส่งคืน Invalid API Key error

ด้านล่างนี้คือตัวอย่างของการเรียกใช้ที่จัดรูปแบบอย่างถูกต้อง ซึ่งข้อมูลที่ใช้ใน Authentication Algorithm ตรงกับข้อมูลในส่วน body ของ request:

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'}}}

อย่างไรก็ตาม เมื่อมีการสลับ ordertype และ volume จะเกิด Invalid Key error

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']}

ข้อบ่งชี้หนึ่งที่อาจเป็นสาเหตุของ Invalid Key error คือ หากการเรียกใช้ไปยัง endpoints ที่ไม่ต้องการ parameters หลายตัวสำเร็จ (Balance, OpenOrders) หากคุณได้รับ valid response จากการเรียกใช้เหล่านี้อย่างต่อเนื่อง ทฤษฎีความไม่ตรงกันก็ดูน่าเชื่อถือมากขึ้น

*โปรดทราบว่าในตัวอย่างข้างต้น มีการใช้ Validate Parameter ซึ่งเพียงแค่ตรวจสอบ inputs เท่านั้น แต่ไม่ได้ส่ง order parameter ควรถูกละทิ้งสำหรับการ live trading*

การมีความไม่ตรงกันระหว่าง content type ของ body และ header ก็อาจนำไปสู่ Invalid API Key ได้เช่นกัน

โปรดดูสถานการณ์ด้านล่างนี้ที่ทั้ง Header และ Post data ถูก URL encoded:

 

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"}}

อย่างไรก็ตาม เมื่อเราเพิ่ม Content Type ของ Header เป็น JSON เราจะได้รับ

EAPI:Invalid Key Error

 

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"]}

*โปรดทราบว่าสามารถใช้ URL encoded data หรือ JSON encoded data ได้ แต่ข้อมูลจะต้องตรงกันอย่างสมบูรณ์ทั้งใน SHA256 input และ HTTP request*

Invalid Key error อาจเกิดจากการส่ง endpoint URI ที่ไม่สมบูรณ์หรือขาดหายไป (เช่น "AddOrder" แทนที่จะเป็น “/0/private/AddOrder”)

เพื่อให้ Authentication Algorithm สร้าง API-Sign Header ได้อย่างถูกต้อง จะต้องใช้ URI ทั้งหมด (เช่น "/0/private/AddOrder”) หากส่วนใดส่วนหนึ่งของ URI นี้ถูกตัดทอน จะนำไปสู่ค่าที่ไม่ถูกต้องสำหรับ API-Sign และทำให้เกิด Invalid Key error

ด้านล่างนี้คือตัวอย่างของการส่งเพียง “AddOrder” สำหรับการเข้ารหัส แทนที่จะเป็น endpoint URI เต็ม “/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']}

ปัญหาทั่วไปอีกประการหนึ่งที่ทำให้เกิด Invalid Key Error คือความไม่ตรงกันของการเข้ารหัสระหว่าง POST request และ HTTP authentication

ในตัวอย่างด้านล่างนี้ ‘Data’ ที่ส่งไปยัง POST request ถูกจัดรูปแบบ URL (โดยมีช่องว่างเข้ารหัสเป็น ‘+’) เป็น application /x-www-form-urlencoded content-type ในขณะที่ ‘data_formatted’ เข้ารหัสช่องว่างเป็น ‘%20’

แม้ว่าในทั้งสองตัวอย่างช่องว่างจะถูกเข้ารหัส แต่ข้อมูลที่ส่งไปยัง authentication algorithm และ POST request ไม่ได้เหมือนกันทุกประการ ซึ่งจะนำไปสู่ Invalid Key error

 

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']}

เพื่อแสดงให้เห็นอย่างชัดเจน โปรดดูรูปแบบ Data ที่แตกต่างกัน 2 แบบด้านล่างนี้:

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

*สามารถใช้ plain text หรือ percent encoded ได้ ตราบใดที่รูปแบบเหมือนกันทั้งใน Authentication data และ request*

ต้องการความช่วยเหลือเพิ่มเติมหรือไม่