Kalshi Order Groups and Trading Pauses: API Safety Switches for Bots

DeskBot — trading software and customer guides

Most Kalshi bot failures are not bad predictions. They are plumbing failures: a loop that re-sends the same order, a reconnect that doubles a position, or a resting order that survives a maintenance window and fills at a price that no longer makes sense. Kalshi's API has two built-in features aimed at exactly this, order groups and pause handling, and most hobby bots use neither of them.

This guide explains how both work, using Kalshi's own API documentation (checked October 27, 2026): the rolling 15-second contract limit, what "triggered" means, the Thursday maintenance window, cancel_order_on_pause, and the GET /exchange/status fields a bot should read before it trades. It covers mechanics, not trading tips.

What a Kalshi order group is

An order group is a container you create on the exchange with one number attached to it: a contracts limit. Every order you place with that group's ID counts toward the limit. Kalshi measures matched (filled) contracts over a rolling 15-second window. When fills inside the group hit the limit, the exchange does two things on its own side:

  • cancels every resting order in the group, and
  • rejects new orders in the group until you reset it.

That is the key property: the cutoff runs on Kalshi's servers, not in your code. If your bot is stuck in a retry loop or your laptop loses Wi-Fi mid-burst, the group still stops matching once the limit is reached. A check in your own code only works while your code is running correctly.

The fields

You create a group with POST /portfolio/order_groups/create. The documented request fields are:

  • contracts_limit: whole contracts, minimum 1. Or contracts_limit_fp, the same value as a fixed-point string such as "10.00" (0.01 granularity). If you send both, they must match.
  • subaccount: 0 for the primary account, 1-63 for subaccounts (see Kalshi subaccounts explained).
  • exchange_index: the exchange shard, default 0.

The response returns an order_group_id. You then pass that ID as order_group_id on each order. Kalshi's guide gives a limit range of 1 to 1,000,000 contracts, and the API reference allows up to 100,000 order groups per user at a time.

The actions

Action Endpoint (REST) What happens
Create POST /portfolio/order_groups/create Group is active: orders can be placed and fills count toward the limit.
Trigger PUT /portfolio/order_groups/{id}/trigger Manual kill switch: cancels all orders in the group whether or not the limit was reached.
Reset Reset Order Group Clears the triggered state and sets the rolling counter back to zero. The group becomes active again.
Update limit Update Order Group Limit Changes the limit. Setting it below the current rolling volume triggers the group immediately.
Delete Delete Order Group Removes the group for good and cancels its resting orders.

Order groups exist on the FIX protocol too, and there is a WebSocket channel for order group updates, so a bot can learn that a group triggered without polling for it.

A worked example: sizing the limit

Say a bot trades Kalshi's 15-minute Bitcoin market and normally sends one order of 5 contracts at a time, at most a few times per 15-minute window. A sensible group setup:

  • Normal burst: 5 contracts. Even two quick orders in a row match 10 contracts inside 15 seconds.
  • Limit: 15 contracts. That leaves headroom for a legitimate double entry and stops a runaway loop on roughly its third or fourth order.
  • Worst case at a $0.56 price: 15 contracts × $0.56 = $8.40 of cost matched before the exchange stops the group, plus fees. Without a group, a bug that loops for 60 seconds at one order per second could try to buy 300 contracts (about $168 at the same price) if the book has that much depth and your balance allows it.

Two cautions. First, the limit covers matched contracts in a rolling 15-second window. It is not a daily cap or a dollar cap. A slow bug that sends one order every 20 seconds never trips a 15-contract group, so you still need a daily loss limit (see why every Kalshi bot needs a daily loss limit). Second, the docs do not say whether one large fill can push the total past the limit before the trigger. Assume the worst case is "limit plus one order" and size orders so that number is still acceptable.

One group per what?

A group is just an ID, so you decide what it represents. Common patterns:

  • One group per strategy. A runaway in one strategy cannot block the others.
  • One group per market window (for example per 15-minute BTC window), deleted after the window settles.
  • One group per subaccount, combined with a restricted API key, so each bot has both a capital boundary and a speed boundary.

A triggered group should page you, not auto-reset. If your code resets the group every time it triggers, you have rebuilt the bug the group was supposed to catch.

Trading pauses and the Thursday maintenance window

The second half of this is time. Kalshi documents a scheduled maintenance window every Thursday from 3:00 to 5:00 AM ET. During it, a trading pause is in effect, and clients should expect their sessions to disconnect and plan to reconnect after 5:00 AM ET. Rarely, heavier maintenance needs a full exchange pause.

Place / amend Cancel When
Trading pause No Yes Thursdays 3:00-5:00 AM ET, or when Kalshi detects an issue
Exchange pause No No Rare: scheduled heavy maintenance or an outage

The part that surprises people: resting orders stay on the book through both kinds of pause by default and come back to life when trading resumes. An order you placed at 2:58 AM on a Thursday, priced for the market as it was then, can fill at 5:00 AM against a market that has moved.

cancel_order_on_pause

The fix is a per-order flag. On Kalshi's create-order request, cancel_order_on_pause: true tells the exchange to cancel that order automatically when a trading or exchange pause begins. The default is false. On FIX, the same setting is tag 21006 on New Order Single.

For a bot trading 15-minute markets, a resting limit order priced off the last few minutes of an index has no reason to survive a pause, so setting this flag is usually the right default. A long-dated order on a weekly or monthly market is a different decision.

Read the exchange status before you trade

GET /exchange/status needs no authentication and returns:

  • exchange_active: false if the core exchange is not taking any state changes at all (maintenance).
  • trading_active: true when trading is currently permitted. Kalshi notes it can pause trading at any time if it detects an issue.
  • exchange_estimated_resume_time: an estimate for the current maintenance window. The docs warn it is not guaranteed and may be extended.
  • exchange_index_statuses: the same flags per exchange shard. The top-level fields describe shard 0.

A simple rule set for a bot:

  1. Before each entry decision, check that trading_active is true (cache it for a few seconds; see Kalshi API rate limits for why you should not poll everything).
  2. If it flips to false, stop generating new orders. If it is a trading pause, you can still cancel resting ones.
  3. After it flips back, do not resume blindly. Re-read positions and resting orders first (see balance, positions and fills), because your local state may be stale after a disconnect.
  4. Expect the Thursday window. A bot that treats a 3:00 AM disconnect as a crash and restarts in a loop is a common source of noise and duplicated orders.

How the pieces fit together

Order groups and pause handling guard against different failures:

Risk Guard Where it runs
Runaway order loop Order group contracts limit Kalshi
You need to stop everything now Trigger the order group Kalshi
Stale order fills after a pause cancel_order_on_pause Kalshi
Bot trades into a pause or outage GET /exchange/status check Your bot
Slow bleed over a day Daily loss limit Your bot
Bot touches more money than intended Subaccount + restricted key Kalshi

None of these makes a strategy profitable. They limit how much a mistake can cost, which matters most in fast markets where a bug can place dozens of orders before you notice. Fees still apply to every fill; see Kalshi fees and break-even win rate.

Test it on the demo exchange first

Triggering, resetting and pause behaviour are much easier to test on Kalshi's demo environment than in production. Create a group with a limit of 2, send three 1-contract orders against a market with depth, and confirm that the third is rejected and the group reports as triggered. The setup is in Kalshi demo environment and API, and request signing is covered in Kalshi API keys and authentication.

What is a Kalshi order group?

A server-side container for orders with a contracts limit measured over a rolling 15-second window. When matched contracts in the group hit the limit, Kalshi cancels the group's resting orders and rejects new ones until you reset it.

Is the order group limit a daily limit?

No. It only counts fills in the last 15 seconds. Use it to stop bursts and loops, and use a separate daily loss limit for slow losses.

How do I attach an order to an order group?

Create the group, take the returned order_group_id, and pass it as the order_group_id field on each create-order request.

Can I use an order group as a kill switch?

Yes. PUT /portfolio/order_groups/{order_group_id}/trigger cancels every order in the group immediately, whether or not the limit was reached.

When is Kalshi maintenance?

Kalshi documents scheduled maintenance every Thursday from 3:00 to 5:00 AM ET, with a trading pause in effect. You can cancel orders during a trading pause but cannot place or amend them.

Do my Kalshi orders get cancelled during maintenance?

Not by default. Resting orders stay on the book through pauses unless you set cancel_order_on_pause to true when you create them.

How can a bot tell if Kalshi trading is paused?

Call GET /exchange/status (no authentication needed) and read trading_active and exchange_active. Per-shard status is in exchange_index_statuses.

What happens when a Kalshi order group is triggered?

All resting orders in the group are canceled, and new orders in the group are rejected until the group is reset. A reset clears the triggered state and the rolling volume counter and returns the group to active.

What can trigger an order group besides hitting the limit?

Three things trigger a group: the rolling 15-second volume goes over the contracts limit; you issue a manual Trigger action, which cancels all orders in the group whether or not the limit was reached; or you update the limit to a value below the current rolling volume.

What limits can I set, and how many order groups can I have?

The contracts limit can be anywhere from 1 to 1,000,000 contracts. The server generates the group ID and returns it when you create the group. An account can have up to 100,000 order groups at a time.

What is the difference between resetting and deleting an order group?

Reset keeps the group: it clears the triggered state and the rolling volume counter so orders can be placed again. Delete removes the group entirely and cancels all resting orders in it.

Trading can lose money. Nothing here is a guarantee of profits, returns or win rates. DeskBot is not affiliated with Kalshi. API details are from Kalshi's public documentation as of October 28, 2026 and may change; check docs.kalshi.com before relying on them.

Current product information: Kalshi · Robinhood · Setup and support. Check the relevant product page for current downloads, pricing, renewal and cancellation terms. Desktop and mobile products have separate availability and offers.

Educational content, not financial advice. Trading can lose money. DeskBot does not guarantee profits, returns, win rates or income and is not affiliated with or endorsed by the named exchanges or brokers.