This process is the same for the demo or production environment.
Generating an API Key
Access the Account Settings Page:
Log in to your account and navigate to the “Account Settings” page. You can typically find this option by clicking on your profile picture or account icon in the top-right corner of the application.
Generate a New API Key
In the “Profile Settings” page https://kalshi.com/account/profile, locate the “API Keys” section. Click on the “Create New API Key” button. This action will generate a new API key in the RSA_PRIVATE_KEY format.
Store Your API Key and Key ID:
After generating the key, you will be presented with:
• Private Key: This is your secret key in RSA_PRIVATE_KEY format.
• Key ID: This is a unique identifier associated with your private key.
Important: For security reasons, the private key will not be stored by our service, and you will not be able to retrieve it again once this page is closed. Please make sure to securely copy and save the private key immediately. The key will also be downloaded as txt file with the name provided.
Using a API Key
Each request to Kalshi trading api will need to be signed with the private key generated above.
The following header values will need to be provided with each request:
KALSHI-ACCESS-KEY- the Key ID
KALSHI-ACCESS-TIMESTAMP - the request timestamp in ms
KALSHI-ACCESS-SIGNATURE- request hash signed with private key
The above signature is generated by signing a concatenation of the timestamp, the HTTP method and the path.
Important: When signing requests, use the path without query parameters. For example, if your request is to /trade-api/v2/portfolio/orders?limit=5, sign only /trade-api/v2/portfolio/orders (strip the ? and everything after it).
Sample code for generating the required headers is below (alternatively use our example code here):
Python
Load the private key stored in a file
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.backends import default_backend
def load_private_key_from_file(file_path):
with open(file_path, "rb") as key_file:
private_key = serialization.load_pem_private_key(
key_file.read(),
password=None, # or provide a password if your key is encrypted
backend=default_backend()
)
return private_key
Sign text with private key
import base64
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding, rsa
from cryptography.exceptions import InvalidSignature
def sign_pss_text(private_key: rsa.RSAPrivateKey, text: str) -> str:
message = text.encode('utf-8')
try:
signature = private_key.sign(
message,
padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.DIGEST_LENGTH
),
hashes.SHA256()
)
return base64.b64encode(signature).decode('utf-8')
except InvalidSignature as e:
raise ValueError("RSA sign PSS failed") from e
Send a request to Kalshi API with signed header
import requests
import datetime
current_time = datetime.datetime.now()
timestamp = current_time.timestamp()
current_time_milliseconds = int(timestamp * 1000)
timestampt_str = str(current_time_milliseconds)
private_key = load_private_key_from_file('kalshi-key-2.key')
method = "GET"
base_url = 'https://demo-api.kalshi.co'
path='/trade-api/v2/portfolio/balance'
# Strip query parameters from path before signing
path_without_query = path.split('?')[0]
msg_string = timestampt_str + method + path_without_query
sig = sign_pss_text(private_key, msg_string)
headers = {
'KALSHI-ACCESS-KEY': 'a952bcbe-ec3b-4b5b-b8f9-11dae589608c',
'KALSHI-ACCESS-SIGNATURE': sig,
'KALSHI-ACCESS-TIMESTAMP': timestampt_str
}
response = requests.get(base_url + path, headers=headers)
print(response.text)
Javascript
Load the private key stored in a file
const fs = require('fs');
const path = require('path');
function loadPrivateKeyFromFile(filePath) {
const absolutePath = path.resolve(filePath);
const privateKeyPem = fs.readFileSync(absolutePath, 'utf8');
return privateKeyPem;
}
Sign text with private key
const crypto = require('crypto');
function signPssText(privateKeyPem, text) {
const sign = crypto.createSign('RSA-SHA256');
sign.update(text);
sign.end();
const signature = sign.sign({
key: privateKeyPem,
padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
saltLength: crypto.constants.RSA_PSS_SALTLEN_DIGEST,
});
return signature.toString('base64');
}
Send a request to Kalshi API with signed header
const axios = require('axios');
const currentTimeMilliseconds = Date.now();
const timestampStr = currentTimeMilliseconds.toString();
const privateKeyPem = loadPrivateKeyFromFile('path/to/your/private-key.pem');
const method = "GET";
const baseUrl = 'https://demo-api.kalshi.co';
const path = '/trade-api/v2/portfolio/balance';
// Strip query parameters from path before signing
const pathWithoutQuery = path.split('?')[0];
const msgString = timestampStr + method + pathWithoutQuery;
const sig = signPssText(privateKeyPem, msgString);
const headers = {
'KALSHI-ACCESS-KEY': 'your-api-key-id',
'KALSHI-ACCESS-SIGNATURE': sig,
'KALSHI-ACCESS-TIMESTAMP': timestampStr
};
axios.get(baseUrl + path, { headers })
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error('Error:', error);
});