Overview
On a market with Maker Protection, any order action that could take liquidity — that is, any order not marked post-only — is held for the market’s configured window before it reaches the matching engine. Post-only placements and all cancellations are never held.
The delay sits in the order gateway in front of the matching engine, not in the engine itself. Every client path passes through it, so the behaviour is the same whichever protocol you use. Because the hold happens before the request is sequenced into the engine, a held order takes its queue position at release, not at receipt.
The only way to avoid the delay is to submit the order as post-only. A limit order without post-only is held regardless of whether it would in fact have rested — the classification is by order type, not by outcome.
Which markets have it
ReadmakerProtectionMillis from the instruments endpoints. It is the authoritative, live source — the market list changes as the rollout progresses.
GET /instruments and GET /trading/instruments, and is omitted entirely when the market has no Maker Protection configured. Treat “absent” and “zero” as the same thing: no delay.
The ten most liquid linear perpetual markets are excluded at every phase, so that active taker flow in the majors is not slowed. Every perpetual listed after 15 September 2026 has Maker Protection applied from launch. Additions to the list are announced on status.kraken.com ahead of each maintenance window.
Phase 1 markets — 15 September 2026
Phase 1 markets — 15 September 2026
These 57 markets are covered at launch. This list is a point-in-time record; query
makerProtectionMillis for the current set.PF_2ZUSD · PF_ALCHUSD · PF_ANTHROPICXUSD · PF_ASTERUSD · PF_ASTRUSD · PF_ATOMUSD · PF_BELUSD · PF_BRENTOILUSD · PF_CHFUSD · PF_CKBUSD · PF_CTSIUSD · PF_CYBERUSD · PF_DEEPUSD · PF_DEGENUSD · PF_DYMUSD · PF_ENJUSD · PF_GALAUSD · PF_GRIFFAINUSD · PF_HMSTRUSD · PF_ICPUSD · PF_IDUSD · PF_IOSTUSD · PF_LCAPUSD · PF_LDOUSD · PF_LRCUSD · PF_METISUSD · PF_MINAUSD · PF_MTLUSD · PF_NATGASUSD · PF_NBISUSD · PF_NEIROUSD · PF_OPENAIXUSD · PF_OPUSD · PF_PENGUUSD · PF_PROMPTUSD · PF_SAMSUNGUSD · PF_SKHYUSD · PF_SNDKUSD · PF_SOONUSD · PF_SOXLUSD · PF_SOXSUSD · PF_TUSD · PF_US100USD · PF_VELOUSD · PF_VIRTUALUSD · PF_WIFUSD · PF_WTIOILUSD · PF_XAGUSD · PF_XAUUSD · PF_XCNUSD · PF_XCUUSD · PF_YFIUSD · PF_ZILUSD · PI_ETHUSD · PI_LTCUSD · PI_XBTUSD · PI_XRPUSDWhat is and isn’t delayed
An edit is classified against the order your account placed, not against what your order-status feed has caught up on. An edit sent immediately after a placement is therefore held on the same terms as one sent to a long-resting order, even though the target may not be visible to you yet. Only an edit naming an identifier your account has not placed — and that no resting non-post-only order answers to — is exempt.
Order lifecycle
Four properties are worth designing around:- Your order is validated at release, not at submission. The request is held untouched and only reaches the matching engine when the window expires, so margin, position limits, price collars and market status are all evaluated at that later moment. See What can happen while an order is held.
- The full window is always served. The hold is decided from market conditions at submission. If the liquidity that made your order aggressive disappears during the window, the order still waits out the delay before entering the book. Held orders are not re-evaluated.
- The queue is FIFO. With a fixed delay, holds are released in the order they were accepted. A later order cannot overtake an earlier one inside the queue.
- The contract is “at least N ms”. Orders you submit are released by a timer and land very close to the configured window. Orders fired by a trigger are different: they wait in the matching engine and are released by the next event it processes, so on a quiet market a stop or take-profit can be held noticeably longer than the configured window. Never assume the delay is exact, and never infer it by measuring latency — read
makerProtectionMillis, which can be changed at any time.
What can happen while an order is held
A held order is not yet in the book, and it is not guaranteed to get there. The window is an interval in which your order can be rejected by events that have nothing to do with your own trading:
The practical consequence: an order that returns a rejection roughly one window after you sent it has usually not been rejected on its own merits. Read the returned status rather than assuming the placement itself was malformed.
Self-trade prevention
A liquidity-taking order released from a hold always cancels the resting order of your own it would match, overriding the self-trade strategy configured on your account (GET / PUT /self-trade-strategy). It applies across the whole account tree — the maker may belong to your account, your master, a sibling or a sub-account.
This closes an evasion the hold would otherwise leave open: post-only orders are never held, so an account could drop one in front of its own held taker and have the default REJECT_TAKER strategy kill the release, recalling committed aggression for the price of one extra message.
Behaviour by protocol
There is noheld order state anywhere in the public API. Maker Protection surfaces as extra latency on aggressive placements, not as a new state to model.
- REST
- WebSocket
- FIX
The connection is simply held for the duration of the delay, and the response carries the final outcome —
placed, filled, cancelled or a rejection — exactly as it would without Maker Protection.Set your client-side request timeout comfortably above the market’s makerProtectionMillis. A timeout tighter than the window will abandon requests that are about to succeed. The window can never exceed 100 ms, so a single timeout budget covers every market.Cancelling a held order
You can cancel an order while it is held. Cancels are never delayed, so a cancel sent immediately after a placement can overtake it inside the window. A cancel cannot recall committed aggression. Cancelling inside the window does not withdraw the order: it removes the order’s right to rest, not its obligation to trade. The held request is rewritten to immediate-or-cancel and released at its original expiry, where it takes whatever liquidity it can and the remainder is discarded instead of joining the book. Address the cancel by order ID or by client order ID. For a held placement the client order ID is your only option — the engine has not assigned an order ID yet. A held amend is different: the order it targets is already resting, so it has an order ID you can use. What a cancel does inside the window depends on the shape of the request being held:
After release, timing is ordinary:
Edits cannot claim a held order. Only a cancel can — a single cancel, or your own cancel-all. When both a held placement and a held amend of the same order exist, amends are claimed first, and every matching amend is claimed, not just the first.
How a converted placement is reported
A conversion is not a new state and not a new status code. The cancel and the order are answered separately:
So a cancelled hold produces two responses: the cancel’s, and the order’s own — the latter about one window later. An
iocWouldNotExecute on an order you submitted as a plain limit order is the signature of this path.
How a withdrawn hold is reported
The claims that do withdraw an order — a cancel of a held post-only order, and an admin cancel-all — never reach the matching engine, so they are reported locally:
There is no dedicated “cancelled while held” value in the public enums. Distinguish this case by the cancel you sent, not by the code.
Cancelling while an edit is held
Amending a resting order so that it would cross the book is claimable too, and the outcome is the one instruction that reads least like a cancel. While the amend is held, the original order is still live in the book, unchanged, at its old price — the amendment has not reached the matching engine, so the order can still trade on its old terms during the window. A cancel of that order inside the window is absorbed: it is answered by the gateway and never forwarded, so the engine does not cancel the target. At release, the amendment is rewritten to reprice that same order to the price you committed to and to give up its right to rest. Same order ID, same client order ID, same order group. Both of your instructions therefore take effect — the amend crosses, and what it would have left behind does not sit on the book: A converted amend has exactly two outcomes. Either it trades and leaves nothing resting, or the order is gone:orderForEditNotFound is not the expected outcome of cancelling during a held amend. If you see it, the order had genuinely already left the book — it is not the signature of this race.REJECTED_AFTER_EXECUTION, so the fills that are already booked are visible rather than hidden behind an error.
Two amends of the same order can be held at once. A cancel claims both, because converting only one would let the other release as a plain edit and re-rest the order the cancel has just been acknowledged for.
Order groups cannot be cancelled while held
An order group whose new parent order would take liquidity is held, but it is not a claimable hold. A cancel addressed to the parent order ID during the window finds nothing, returnsORDER_NOT_FOUND, and the group still goes live when the window expires. You cannot stop the group inside the window; cancel it after it is live.
Reusing a client order ID inside the window
If you cancel an order and immediately replace it reusing the same client order ID, both can be in flight within one window. While that is true:- The replacement is addressable by order ID only. A cancel by client order ID still resolves to the first order, not the replacement.
- If the first order is somehow still live when the replacement is released, the engine rejects the replacement with
clientOrderIdAlreadyExist.
Cancel-all while orders are held
Your owncancelallorders claims every held placement and held amend in scope, on exactly the same terms as a single cancel: placements are converted to immediate-or-cancel, and amends are converted in place.
Because a held amend’s target is already resting at the engine, a sweep that claims one also carves that order out of the sweep: it is deliberately left in the book, and the converted amend removes it when it releases. So a cancelallorders on a Maker Protection market can return having left an order resting, by design.
Two consequences worth designing around:
- A carved-out bracket parent keeps its group’s triggers. They are not cancelled with the rest of the sweep, so the position the amend fills is not left without its take-profit and stop-loss.
- An order spared by one sweep stays spared. Once an amend has been converted, the order it targets is left alone by later cancel-alls too, until that amend releases and removes it.
Batch orders
A batch is not held as a single unit. The window starts at the first liquidity-taking instruction in the batch:- Instructions before the first aggressor are forwarded immediately.
- The first aggressor and everything after it wait out the window together.
- Cancels are forwarded immediately wherever they appear. A cancel placed after the order it targets claims that order’s hold within the same batch — converting it, exactly as a separate cancel would. A cancel placed before it cannot claim anything: at that point the placement does not exist yet, so the cancel resolves against whatever order you already had under that identifier.
Reference
Testing
Maker Protection has been enabled on the Phase 1 markets in the client UAT environment since 27 August 2026. Test your order handling there before the production date. Contact your account manager for UAT access. Worth exercising specifically, since each one has a non-obvious outcome:- Cancel during a hold. Confirm you handle the order still filling after a successful cancel, and that you do not retry the placement.
- Cancel during a held amend. Confirm you handle a successful cancel followed by the amend’s own fills or reject, rather than expecting
orderForEditNotFound. - Your own resting order in the way. Confirm you tolerate a maker of yours being cancelled with
CANCELLED_BY_SELF_TRADEeven withREJECT_TAKERset. - Batch instruction ordering, and client-side timeouts above the market’s
makerProtectionMillis.