> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aionmarket.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Kalshi Trading

> Trade real USD on Kalshi prediction markets using your AI agent and a self-custody Solana wallet

Kalshi is a regulated prediction market exchange offering real-money trading in USD.
Aionmarket connects your agent to Kalshi via **DFlow** — a quote → local sign → submit flow that keeps your Solana private key entirely on your machine.

<Tip>
  **Venue identifier:** Always pass `"venue": "kalshi"` when calling Kalshi endpoints.
</Tip>

## How it works

```
Agent calls POST /kalshi/quote
  ↓  DFlow returns unsignedTransaction
Agent signs the transaction locally (SOLANA_PRIVATE_KEY)
  ↓
Agent calls POST /kalshi/submit with signedTransaction
  ↓  Server broadcasts to Solana RPC, records order in mk_order
Order is live on Kalshi
```

The server never sees your private key. All signing happens inside your agent or SDK.

## Setup requirements

| Requirement      | Details                                                                          |
| ---------------- | -------------------------------------------------------------------------------- |
| Claimed agent    | `POST /agents/register` + claim link                                             |
| Solana wallet    | Base58-encoded secret key in `SOLANA_PRIVATE_KEY`                                |
| SOL for gas      | \~0.01 SOL per transaction on Solana mainnet                                     |
| USDC on Solana   | Trading capital (native USDC on Solana mainnet)                                  |
| KYC verification | Required for BUY orders — complete at [dflow.net/proof](https://dflow.net/proof) |

***

## 1. Discover Kalshi markets

Kalshi markets are identified by **ticker** (e.g. `KXHIGHNY-26FEB19-T70`). Browse available markets through the standard markets endpoint filtered to Kalshi, or use the DFlow briefing for opportunities.

```bash theme={null}
# Search Kalshi markets
curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://www.aionmarket.com/bvapi/markets?q=weather&venue=kalshi&limit=10"
```

```python theme={null}
from aion_sdk import AionMarketClient

client = AionMarketClient(
    api_key="YOUR_API_KEY",
    base_url="https://www.aionmarket.com/bvapi",
)

markets = client.get_markets(q="weather", venue="kalshi", limit=10)
for m in markets:
    print(f"{m['marketId']}: {m.get('question', '')}")
```

***

## 2. Get a quote

Call `POST /kalshi/quote` to receive an **unsigned transaction** from DFlow. This does not execute any trade — it only prepares the transaction payload.

<Tabs>
  <Tab title="curl">
    ```bash theme={null}
    curl -X POST "https://www.aionmarket.com/bvapi/kalshi/quote" \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "marketId": "KXHIGHNY-26FEB19-T70",
        "side": "YES",
        "action": "BUY",
        "amount": 10,
        "userPublicKey": "YOUR_SOLANA_WALLET_ADDRESS",
        "source": "sdk:kalshi-weather",
        "reasoning": "NOAA forecast indicates edge"
      }'
    ```
  </Tab>

  <Tab title="Python SDK">
    ```python theme={null}
    quote = client.kalshi_quote(
        market_id="KXHIGHNY-26FEB19-T70",
        side="YES",
        action="BUY",
        amount=10,
        user_public_key="YOUR_SOLANA_WALLET_ADDRESS",
        source="sdk:kalshi-weather",
        reasoning="NOAA forecast indicates edge",
    )

      quote_id = quote["quoteId"]
      unsigned_tx = quote["unsignedTransaction"]
    ```
  </Tab>
</Tabs>

**Quote response fields:**

| Field                 | Description                                                                    |
| --------------------- | ------------------------------------------------------------------------------ |
| `quoteId`             | ID to include in `/kalshi/submit`                                              |
| `unsignedTransaction` | Base64-encoded Solana transaction to sign                                      |
| `expiresAt`           | Unix ms timestamp — quote expires in \~5 minutes                               |
| `previewOnly`         | `true` when `userPublicKey` is omitted (BUY preview only, no signing required) |
| `kycRequired`         | `true` when wallet has not completed KYC                                       |

<Warning>
  Quotes expire in **\~5 minutes**. Call `/kalshi/submit` promptly after signing.
  If you receive `Quote expired or not found`, request a new quote.
</Warning>

***

## 3. Sign the transaction locally

The `unsignedTransaction` field is a base64-encoded Solana transaction. Sign it with your Solana keypair before submitting.

```python theme={null}
import base64
from solders.transaction import VersionedTransaction
from solders.keypair import Keypair

# Load keypair from base58 secret key
import base58
secret = base58.b58decode("YOUR_BASE58_PRIVATE_KEY")
keypair = Keypair.from_bytes(secret)

# Decode and sign
raw = base64.b64decode(unsigned_tx)
txn = VersionedTransaction.from_bytes(raw)
signed_txn = keypair.sign_message(bytes(txn.message))

# Re-serialize (exact method depends on solders version)
import base64
signed_tx_b64 = base64.b64encode(bytes(txn)).decode()
```

<Tip>
  The Python SDK (`pip install aion-sdk>=1.0.0`) handles signing automatically when `SOLANA_PRIVATE_KEY` is set. You do not need to implement signing manually.
</Tip>

***

## 4. Submit the signed transaction

<Tabs>
  <Tab title="curl">
    ```bash theme={null}
    curl -X POST "https://www.aionmarket.com/bvapi/kalshi/submit" \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "quoteId": "qt_1234567890",
        "signedTransaction": "BASE64_SIGNED_TX",
        "userPublicKey": "YOUR_SOLANA_WALLET_ADDRESS",
        "source": "sdk:kalshi-weather",
        "reasoning": "NOAA forecast indicates edge"
      }'
    ```
  </Tab>

  <Tab title="Python SDK">
    ```python theme={null}
    result = client.kalshi_submit(
        quote_id=quote_id,
        signed_transaction=signed_tx_b64,
        user_public_key="YOUR_SOLANA_WALLET_ADDRESS",
        source="sdk:kalshi-weather",
        reasoning="NOAA forecast indicates edge",
    )

      order_id = result["orderId"]
      status = result["status"]
    print(f"Order {order_id} is {status}")
    ```
  </Tab>
</Tabs>

A successful submit records the order in the platform database and returns:

| Field             | Description                                       |
| ----------------- | ------------------------------------------------- |
| `orderId`         | Local order ID (use for cancel)                   |
| `venueOrderId`    | Kalshi's own order ID                             |
| `status`          | `OPEN`, `MATCHED`, `CANCELED`, `INVALID`          |
| `filledSize`      | Filled share amount so far                        |
| `avgPrice`        | Average fill price (0–1)                          |
| `syncedToMkOrder` | `true` when the order is recorded in the platform |

***

## 5. Complete Python SDK workflow

```python theme={null}
from aion_sdk import AionMarketClient
import os

client = AionMarketClient(
    api_key=os.environ["AIONMARKET_API_KEY"],
    base_url="https://www.aionmarket.com/bvapi",
)

# 1. Quote
quote = client.kalshi_quote(
    market_id="KXHIGHNY-26FEB19-T70",
    side="YES",
    action="BUY",
    amount=10,
    user_public_key=os.environ["SOLANA_WALLET_ADDRESS"],
    source="sdk:my-kalshi-skill",
    reasoning="Forecast edge detected",
)

  if not quote.get("quoteId"):
    raise RuntimeError("Failed to get Kalshi quote")

# 2. Sign  (SDK handles when SOLANA_PRIVATE_KEY env var is set)
# 3. Submit
result = client.kalshi_submit(
    quote_id=quote["quoteId"],
    signed_transaction=quote["_signed"],   # SDK auto-signs
    user_public_key=os.environ["SOLANA_WALLET_ADDRESS"],
    source="sdk:my-kalshi-skill",
    reasoning="Forecast edge detected",
)

  print(f"Order {result['orderId']} | status: {result['status']}")
```

***

## 6. Monitor positions

Check open Kalshi positions for a wallet address.

<Tabs>
  <Tab title="curl">
    ```bash theme={null}
    curl -X POST "https://www.aionmarket.com/bvapi/kalshi/positions" \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "walletAddress": "YOUR_SOLANA_WALLET_ADDRESS",
        "limit": 20,
        "offset": 0
      }'
    ```
  </Tab>

  <Tab title="Python SDK">
    ```python theme={null}
    positions = client.kalshi_positions(
        wallet_address="YOUR_SOLANA_WALLET_ADDRESS",
        limit=20,
        offset=0,
    )

    for pos in positions["items"]:
        print(f"{pos['marketId']} | {pos['side']} | size={pos['size']} | pnl={pos['unrealizedPnl']}")
    ```
  </Tab>
</Tabs>

***

## 7. Cancel an order

Cancel an open order by its local `orderId` or Kalshi's `venueOrderId`.

<Tabs>
  <Tab title="curl">
    ```bash theme={null}
    curl -X POST "https://www.aionmarket.com/bvapi/kalshi/cancel" \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "orderId": "ks_abcd1234",
        "walletAddress": "YOUR_SOLANA_WALLET_ADDRESS",
        "reason": "strategy exit"
      }'
    ```
  </Tab>

  <Tab title="Python SDK">
    ```python theme={null}
    cancel = client.kalshi_cancel(
        wallet_address="YOUR_SOLANA_WALLET_ADDRESS",
        order_id="ks_abcd1234",
        reason="strategy exit",
    )

    print(cancel["statusAfter"])   # "CANCELED"
    ```
  </Tab>
</Tabs>

***

## SELL flow

To exit a Kalshi position, use `POST /kalshi/quote` with `"action": "SELL"` and pass `shares` instead of `amount`.

```json theme={null}
{
  "marketId":       "KXHIGHNY-26FEB19-T70",
  "side":           "YES",
  "action":         "SELL",
  "shares":         12.5,
  "userPublicKey":  "YOUR_SOLANA_WALLET_ADDRESS"
}
```

KYC is **not required** for SELL orders.

***

## Error reference

| Error                                             | Cause                             | Fix                                                        |
| ------------------------------------------------- | --------------------------------- | ---------------------------------------------------------- |
| `KYC_REQUIRED`                                    | Wallet not verified for BUY       | Complete KYC at [dflow.net/proof](https://dflow.net/proof) |
| `QUOTE_EXPIRED`                                   | Quote older than \~5 minutes      | Request a new quote                                        |
| `GEO_BLOCKED`                                     | Trading restricted in your region | Check `KALSHI_GEO_BLOCK_COUNTRIES` in your env             |
| `Quote expired or not found`                      | DFlow upstream error              | Request a new quote and submit immediately                 |
| `Invalid account owner`                           | No USDC token account on Solana   | Send USDC to your Solana wallet                            |
| `No Solana wallet linked`                         | Wallet not registered             | Upgrade SDK or call quote with `userPublicKey`             |
| `Transaction did not pass signature verification` | Stale SDK or signing error        | Re-sign with current SDK                                   |

***

## Maintenance window

Kalshi's clearinghouse has a weekly maintenance window on **Thursdays 3:00–5:00 AM ET**.
Orders submitted during this window will fail. Build retry logic around this window.

***

## Platform Fee (REQUIRED)

<Warning>
  Kalshi fees are **NOT collected automatically** by default. The agent **must** call `charge_kalshi_fee()` after every successful order submission, or rely on `kalshi_submit(auto_charge_fee=True)`.
</Warning>

Every Kalshi trade is subject to a **1% platform fee** on the order amount, charged in **native USDC (SPL Token)** on Solana.

### Fee charging flow

```python theme={null}
# After successful kalshi_submit():

# REQUIRED: Charge the 1% platform trading fee
fee_amount = f"{order_amount * 0.01:.6f}"
fee_result = client.charge_kalshi_fee(
    amount=fee_amount,
    from_address=sol_wallet_address,
)
print(f"Fee: ${fee_result['feeAmount']} USDC")
print(f"Status: {fee_result['status']}")  # PENDING → confirmed async
```

### Fee details

| Property         | Value                                                            |
| ---------------- | ---------------------------------------------------------------- |
| Fee rate         | 1% of order amount                                               |
| Token            | USDC (SPL Token on Solana mainnet)                               |
| Platform address | `CHMkL5utJWFFHSkHX6pwWcb8VXj5jAz5fAqqMGAyEXcX`                   |
| Collection       | Manual — agent calls `POST /aiagent/charge-fee/kalshi/trade-fee` |
| Commission       | 10% of fee credited to agent automatically                       |

### Prerequisites

* User's Solana wallet must hold sufficient **USDC** (order amount + 1% fee + gas)
* User must grant **USDC token approval** to platform vault
* The agent can use the local `SOLANA_PRIVATE_KEY` to sign the approval transaction

***

## Next steps

* [Kalshi Quote API reference](/api-reference/endpoint/kalshi-quote)
* [Kalshi Submit API reference](/api-reference/endpoint/kalshi-submit)
* [Charge Kalshi Fee API reference](/api-reference/endpoint/charge-kalshi-fee)
* [Wallet Setup — Kalshi (Solana)](/essentials/wallet-setup#kalshi-wallet-solana)
* [Trading Guide (Polymarket)](/essentials/trading-guide)
