To trade on Kalshi via the API you need two credentials: a Key ID (apiKey) and an RSA private key (privateKey). Public market data (prices, order books, etc.) does not require credentials.
- Log in to Kalshi.com and open your Account Settings.
- Go to the API tab and click Create API Key.
- Give the key a name, choose the scopes you need (read-only or trading), and click Generate.
- Copy the Key ID — this is your
KALSHI_API_KEY. - Download or copy the RSA Private Key (PEM format) — this is your
KALSHI_PRIVATE_KEY.
Tip: Kalshi supports both file paths and raw PEM strings as the private key value. It is recommended to generate the key pair with at least 2048-bit RSA.
Kalshi provides two independent environments:
| Environment | Base URL | Purpose |
|---|---|---|
| Production | api.elections.kalshi.com |
Live trading with real money |
| Demo | demo-api.elections.kalshi.com |
Safe paper-trading for testing |
The credentials for each environment are separate — generate them from the corresponding Kalshi dashboard (production or demo).
To switch between production and demo, simply instantiate the appropriate class. Both classes share identical methods but target different base URLs.
| Class | Target Environment | Use Case |
|---|---|---|
Kalshi / KalshiExchange |
Production | Live trading |
KalshiDemo / KalshiDemoExchange |
Demo | Paper-trading and testing |
# Kalshi
KALSHI_API_KEY= # Key ID from the Kalshi API settings page
KALSHI_PRIVATE_KEY= # RSA private key in PEM format (or file path)import os
import pmxt
# ── Public data — no credentials needed ──────────────────────────────────────
kalshi = pmxt.Kalshi()
markets = kalshi.fetch_markets(query="Fed rates")
# ── Production trading ────────────────────────────────────────────────────────
kalshi = pmxt.Kalshi(
api_key=os.getenv("KALSHI_API_KEY"),
private_key=os.getenv("KALSHI_PRIVATE_KEY"),
)
balance = kalshi.fetch_balance()
print(f"Available: {balance[0].available}")
order = kalshi.create_order(
market_id="FED-25JAN29-B4.75",
side="buy",
type="limit",
price=0.55,
amount=10,
)
# ── Demo / paper-trading environment ─────────────────────────────────────────
# Use demo credentials generated on demo.kalshi.com
kalshi_demo = pmxt.KalshiDemo(
api_key=os.getenv("KALSHI_API_KEY"), # demo API key
private_key=os.getenv("KALSHI_PRIVATE_KEY"),
)
balance = kalshi_demo.fetch_balance()import { KalshiExchange } from 'pmxt';
// ── Public data — no credentials needed ──────────────────────────────────────
const kalshi = new KalshiExchange();
const markets = await kalshi.fetchMarkets({ query: 'Fed rates' });
// ── Production trading ────────────────────────────────────────────────────────
const kalshi = new KalshiExchange({
credentials: {
apiKey: process.env.KALSHI_API_KEY,
privateKey: process.env.KALSHI_PRIVATE_KEY,
},
});
const balance = await kalshi.fetchBalance();
console.log(`Available: ${balance[0].available}`);
const order = await kalshi.createOrder({
marketId: 'FED-25JAN29-B4.75',
side: 'buy',
type: 'limit',
price: 0.55,
amount: 10,
});
// ── Demo / paper-trading environment ─────────────────────────────────────────
// Use demo credentials generated on demo.kalshi.com
import { KalshiDemoExchange } from 'pmxt';
const kalshiDemo = new KalshiDemoExchange({
credentials: {
apiKey: process.env.KALSHI_API_KEY, // demo API key
privateKey: process.env.KALSHI_PRIVATE_KEY,
},
});
const demoBalance = await kalshiDemo.fetchBalance();- Store credentials in a
.envfile and add.envto.gitignore— never commit secrets. - Use separate API keys for development (demo) and production.
- Grant only the minimum required scopes (read-only for market data scripts, trading only when needed).
- Rotate keys periodically and revoke any that are no longer in use.
- Keep your RSA private key file permissions restricted (
chmod 600 kalshi.pem).