Connect your own Kalshi account by storing its API credentials
Kalshi is the one venue where Kairos does NOT custody or provision an identity — you trade against your own Kalshi account, so you supply your own Kalshi API key and RSA private key here. The server validates the PEM, proves the credentials work by calling Kalshi’s balance endpoint, then encrypts them (AES-256-GCM) and stores them.
You are handing over a live private key. It is stored encrypted and used only to sign Kalshi requests on your behalf. Rotate it at Kalshi and re-run this endpoint to replace it.
Both PKCS#1 and PKCS#8 PEM encodings are accepted, and a key pasted as a single line with literal \n escapes is normalized before parsing.
POST /exchanges/kalshi_offchain/enable-trading is a deprecated alias of this route, kept for clients that are not deployed in lockstep.
Error shape. Minimal
{"error": "...", "code": "..."}(OrderSimpleErrorResponse), not the structured envelope. Auth & scope. Requirestrade:executeforkalshiand the mutation gate.
curl --request POST \
--url https://execution.kairos.trade/exchanges/kalshi/enable-trading \
--header 'Content-Type: application/json' \
--header 'X-Api-Key: <api-key>' \
--header 'X-Api-Secret: <api-key>' \
--header 'X-Client-Id: <api-key>' \
--data '
{
"api_key_id": "<string>",
"private_key_pem": "<string>"
}
'import requests
url = "https://execution.kairos.trade/exchanges/kalshi/enable-trading"
payload = {
"api_key_id": "<string>",
"private_key_pem": "<string>"
}
headers = {
"X-Client-Id": "<api-key>",
"X-Api-Key": "<api-key>",
"X-Api-Secret": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-Client-Id': '<api-key>',
'X-Api-Key': '<api-key>',
'X-Api-Secret': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({api_key_id: '<string>', private_key_pem: '<string>'})
};
fetch('https://execution.kairos.trade/exchanges/kalshi/enable-trading', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://execution.kairos.trade/exchanges/kalshi/enable-trading",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'api_key_id' => '<string>',
'private_key_pem' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-Api-Key: <api-key>",
"X-Api-Secret: <api-key>",
"X-Client-Id: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://execution.kairos.trade/exchanges/kalshi/enable-trading"
payload := strings.NewReader("{\n \"api_key_id\": \"<string>\",\n \"private_key_pem\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Client-Id", "<api-key>")
req.Header.Add("X-Api-Key", "<api-key>")
req.Header.Add("X-Api-Secret", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://execution.kairos.trade/exchanges/kalshi/enable-trading")
.header("X-Client-Id", "<api-key>")
.header("X-Api-Key", "<api-key>")
.header("X-Api-Secret", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"api_key_id\": \"<string>\",\n \"private_key_pem\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://execution.kairos.trade/exchanges/kalshi/enable-trading")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Client-Id"] = '<api-key>'
request["X-Api-Key"] = '<api-key>'
request["X-Api-Secret"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"api_key_id\": \"<string>\",\n \"private_key_pem\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"message": "<string>"
}{
"error": "Insufficient scope",
"code": "<string>"
}{
"error": "Unauthorized"
}{
"error": "Insufficient scope",
"code": "<string>"
}{
"error": "Insufficient scope",
"code": "<string>"
}Authorizations
Credential client id (kairos_ck_...). Must be sent together with X-Api-Key and X-Api-Secret.
64-char hex API key.
64-char hex API secret.
Body
Body for POST /exchanges/kalshi/enable-trading. Kalshi trades against the user's OWN Kalshi account, so the caller supplies their own Kalshi API credentials — Kairos does not provision them.
Kalshi API Key ID (the public identifier). Must be non-blank.
The matching RSA private key, PEM-encoded. Both PKCS#1 (BEGIN RSA PRIVATE KEY) and PKCS#8 (BEGIN PRIVATE KEY) are accepted, and a key pasted as a single line with literal \n escape sequences is normalized server-side.
Was this page helpful?
curl --request POST \
--url https://execution.kairos.trade/exchanges/kalshi/enable-trading \
--header 'Content-Type: application/json' \
--header 'X-Api-Key: <api-key>' \
--header 'X-Api-Secret: <api-key>' \
--header 'X-Client-Id: <api-key>' \
--data '
{
"api_key_id": "<string>",
"private_key_pem": "<string>"
}
'import requests
url = "https://execution.kairos.trade/exchanges/kalshi/enable-trading"
payload = {
"api_key_id": "<string>",
"private_key_pem": "<string>"
}
headers = {
"X-Client-Id": "<api-key>",
"X-Api-Key": "<api-key>",
"X-Api-Secret": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-Client-Id': '<api-key>',
'X-Api-Key': '<api-key>',
'X-Api-Secret': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({api_key_id: '<string>', private_key_pem: '<string>'})
};
fetch('https://execution.kairos.trade/exchanges/kalshi/enable-trading', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://execution.kairos.trade/exchanges/kalshi/enable-trading",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'api_key_id' => '<string>',
'private_key_pem' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-Api-Key: <api-key>",
"X-Api-Secret: <api-key>",
"X-Client-Id: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://execution.kairos.trade/exchanges/kalshi/enable-trading"
payload := strings.NewReader("{\n \"api_key_id\": \"<string>\",\n \"private_key_pem\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Client-Id", "<api-key>")
req.Header.Add("X-Api-Key", "<api-key>")
req.Header.Add("X-Api-Secret", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://execution.kairos.trade/exchanges/kalshi/enable-trading")
.header("X-Client-Id", "<api-key>")
.header("X-Api-Key", "<api-key>")
.header("X-Api-Secret", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"api_key_id\": \"<string>\",\n \"private_key_pem\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://execution.kairos.trade/exchanges/kalshi/enable-trading")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Client-Id"] = '<api-key>'
request["X-Api-Key"] = '<api-key>'
request["X-Api-Secret"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"api_key_id\": \"<string>\",\n \"private_key_pem\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"message": "<string>"
}{
"error": "Insufficient scope",
"code": "<string>"
}{
"error": "Unauthorized"
}{
"error": "Insufficient scope",
"code": "<string>"
}{
"error": "Insufficient scope",
"code": "<string>"
}
