Skip to content

API keys

Manage RSA API keys programmatically — list, create with a BYO public key, have the server mint a fresh pair, or delete.

Auth required throughout (you need an existing key to manage keys).

Quick reference

Method Endpoint
list() GET /api_keys
create(*, name, public_key, scopes=None) POST /api_keys
generate(*, name, scopes=None) POST /api_keys/generate
delete(api_key) DELETE /api_keys/{api_key}

List

resp = client.api_keys.list()
for key in resp.api_keys:
    print(key.api_key, key.name, key.scopes, key.created_ts)

Server-minted pair (generate)

The simplest path — Kalshi mints the keypair, you store the private key once:

resp = client.api_keys.generate(name="ci-bot-2026", scopes=["read", "write"])
private_pem = resp.private_key.get_secret_value()   # SecretStr — see warning
print(resp.api_key.api_key)                          # the key id
# Persist private_pem somewhere safe; you will not see it again.

private_key is a SecretStr — and you only see it once

resp.private_key is a pydantic.SecretStr. print(resp.private_key) will print **********, not the key. Use .get_secret_value() to extract the PEM, and store it before the response goes out of scope. Kalshi cannot retrieve a server-minted private key after this call.

Scopes

Scope Allows
read All GET endpoints
write All write endpoints — requires read

The server default when you omit scopes is ["read", "write"].

BYO public key (create)

If you'd rather mint the keypair yourself (better for HSM / KMS workflows), generate locally and upload only the public half:

from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization

key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
public_pem = key.public_key().public_bytes(
    encoding=serialization.Encoding.PEM,
    format=serialization.PublicFormat.SubjectPublicKeyInfo,
).decode()

resp = client.api_keys.create(name="self-minted", public_key=public_pem)
print(resp.api_key.api_key)

The private half never touches Kalshi.

Rotate a key

# 1) Mint the replacement.
new = client.api_keys.generate(name="prod-bot-2026-q2")
new_pem = new.private_key.get_secret_value()

# 2) Swap your application's credentials over to `new`.

# 3) Once you've confirmed the new key works:
client.api_keys.delete("old-key-id")

Reference

kalshi.resources.api_keys.ApiKeysResource

ApiKeysResource(transport: SyncTransport)

Bases: SyncResource

Sync API keys resource.

All endpoints require authentication. create takes a caller-minted RSA public key; generate has Kalshi mint a pair and returns the private key once (see :class:GenerateApiKeyResponse).

kalshi.resources.api_keys.AsyncApiKeysResource

AsyncApiKeysResource(transport: AsyncTransport)

Bases: AsyncResource

Async API keys resource.