Troubleshooting · OKX Webhook

OKX Error 54094
Cool-off period now extends to REST/WebSocket, webhooks rejected server-side

2026-07-31·9 min read

You pointed a TradingView alert at OKX, and one day the webhook started coming back with nothing but a 54094. Your API key hasn't expired, the IP allowlist hasn't changed, and you're nowhere near the rate limit — but OKX cool-off period API rejection is, as of 2026-07-07, expected behaviour by design, not something you misconfigured. This post walks the OKX "Notice on Upgrade to the Futures Cool-off Period" and the OKX API v5 changelog against your webhook payload, field by field, so you know exactly which orders get rejected, which don't, and whether existing users need to worry.

This post isn't a verdict on whether OKX designed the mechanism well — cool-off is a retail-protection feature and we're not going to argue against it. It also isn't a "how to get around it" guide, because the rule is enforced server-side and no client-side trick can bypass it. Scope is narrow: what 54094 means, why your webhook hits it, and what you can change in your flow.

The short version
Three things, in order of importance: first, only "open / increase" orders that are not reduce-only come back as 54094 — your reduce-only close orders are always allowed through; second, strategy orders and copy-trading orders are rejected regardless of whether they open or close — stricter than a plain REST order — so any bot placing orders through OKX's built-in strategy engine is fully blocked; third, if you configured a cool-off period before the 2026-07-07 upgrade, you keep the old behaviour, which only restricts web/app manual orders and leaves the API untouched, until you actively reset the cool-off period yourself.

What It Looks Like: HTTP 200 but the Order Never Landed

The most confusing thing about this error is that its HTTP status code is 200 — not 4xx, not 5xx. Your HTTP client will tell you "request succeeded," but the JSON body OKX returned has an sCode (per-order status code) of 54094, with a message copied straight from the official changelog:

text
Order rejected. The cool-off period is active for the current instId.

What it actually means: this was never an order. OKX received your request, verified the signature, ran risk checks, and then rejected it at the order-placement layer because the cool-off period is active — so the entire HTTP request lifecycle counts as "successful," but the trade you thought you placed never reached the matching engine. If your webhook consumer only looks at the HTTP status code and treats 200 as success, you get the classic "response is 200 but positions never moved" scenario. This kind of error doesn't make noise. It fails silently — and it will stay silent until you reconcile the account and find out yourself.

Is this OKX-specific behaviour?
Yes. Binance, Bybit, and Bitget currently have no official notice extending "cool-off" to their REST APIs — their cool-off features (where they exist at all) usually just grey out the order button in the UI. OKX is the first exchange we've verified that pulls this into server-side API rejection logic. For a cross-exchange view of webhook support, see Which exchanges actually support TradingView webhook signals?

Why This Happens: The Rule Lives in the API Layer, Not Your Code

OKX posted the notice on 2026-07-03, brought it into effect on 2026-07-07, and started phased rollout in specific regions from 2026-07-16, extending what used to be a web/app-only cool-off period to "REST API, WebSocket, third-party authorization (including Broker OAuth, Agent Trade Kit, etc.), trading bots" (from the second paragraph of the notice). Which means: once you actively enable cool-off on your OKX account, open/increase orders arriving via any channel during that window are server-side rejected.

Where does the official notice stop? The notice states in plain text that "any orders to open or increase positions submitted through the above channels will be rejected. Orders to reduce or close positions are not affected." — open/increase rejected, reduce/close allowed. Strategy orders and copy trading get their own line: "Strategy orders and copy trading orders will be rejected regardless of whether they are for opening or closing positions." — rejected regardless of open or close. Everything else in this post is us mapping those two sentences to fields in your webhook payload; the specifics are inferred, not additional official wording.

The error code 54094 itself was added in the 2026-07-07 API changelog, and the changelog's Cool-off period order rejection section states "While a user's cool-off period is active, non reduce-only orders on SWAP and FUTURES instruments covered by the cool-off are rejected server-side." — which also pins down the instrument scope: SWAP (perpetuals) and FUTURES (dated futures). Spot and options are not listed in the original text.

Which Orders Get Rejected, Which Don't

This table cross-references both the notice and the changelog — the first column is the order channel, the next three are common scenarios. Use it to map your deployment path by path and see which routes get blocked by 54094.

Order channel / typeOpen / increaseReduce-only closeStrategy orders (including TP/SL algo)
Web / app manualRejected (unchanged behaviour)AllowedRejected
REST API (TradingView webhook → your server → OKX)Rejected with 54094AllowedRejected
WebSocket order placementRejected with 54094AllowedRejected
Broker OAuth / Agent Trade Kit (third-party authorization)Rejected with 54094AllowedRejected
OKX built-in Trading BotRejected with 54094AllowedRejected
Copy TradingRejected (regardless of open/close)Rejected (regardless of open/close)Rejected (regardless of open/close)

Scope affected by the OKX cool-off upgrade. Sources: OKX Help Center Notice on Upgrade to the Futures Cool-off Period (published 2026-07-03) plus the Cool-off period order rejection section in the OKX API v5 changelog dated 2026-07-07. Instruments: SWAP and FUTURES; spot and options are outside the original scope. Verified July 2026.

Why are strategy orders stricter than plain orders?
A plain REST order only blocks open/increase and lets reduce-only through — there's an explicit escape hatch. Strategy orders (conditional orders, take-profit / stop-loss, trailing stops — anything placed exchange-side that waits for a trigger) are "rejected regardless of open or close" — the notice uses "regardless of whether they are for opening or closing positions". Practical consequence: if you rely on OKX-side TP/SL algo orders, once cool-off is on you can't just fail to open new positions — you also can't use OKX-side protection orders to close old ones. During cool-off, your stops have to come from a client-side price watcher that fires reduce-only market orders on trigger.

How the TVSBot / TradingView Webhook Payload Maps to This

The TVSBot webhook payload schema has a field called reduce_only, type bool, default false. Whether that field is boolean true is what tells OKX to treat this as a reduce-only close and let it through — the difference between true and false is huge:

Payload shapeWhat happens during OKX cool-off
action=buy / sell, no reduce_only set{ "action": "buy", "symbol": "BTC-USDT-SWAP" }Rejected with 54094 — because reduce_only defaults to false
action=close (TVSBot rewrites this into reduce_only){ "action": "close", "symbol": "BTC-USDT-SWAP" }Allowed — TVSBot's order service always forces reduce_only=true for action=close
action=buy / sell, payload explicitly sets reduce_only=true{ "action": "sell", "reduce_only": true }Allowed — the payload declares it as a reduce-only close
action=buy / sell, payload sets reduce_only=false{ "action": "buy", "reduce_only": false }Rejected with 54094 — an explicit open/increase order

What this means for a Pine Script strategy author: if your webhook fires from a strategy.entry()-triggered alert, it's an open/increase by nature and cool-off blocks it. Alerts from strategy.close() or strategy.exit() can pass through, but only if your payload template sets action to "close" (or explicitly writes reduce_only: true). The qty_type trap article has a full field-by-field payload reference — worth reading alongside this one.

Check your own payload template
Open a live alert you're currently running in TradingView and look at the JSON in the Message box. If reduce_only isn't there as a key, it's going out as false (the TVSBot-side default) — and during cool-off every such alert will be rejected by OKX. Nothing will warn you about this ahead of time; either you fix it now, or the next time you enter cool-off you'll find out from your account reconciliation.

Three Ways to Fix It — Pick One

Once you're seeing 54094, you have three choices: cancel the cool-off, wait it out, or refactor your flow around reduce-only closes. There is no fourth option — this is server-side rejection at OKX and no client-side change matters.

FixWhen it fitsConstraints
Cancel the cool-offYou didn't actually want it — set it by mistake or for a testIf you set it under the new version (post-2026-07-07), you can turn it off. If you set it under the old version, the notice explicitly says current cool-off period cannot be terminated early — you wait it out
Wait for it to expireYou set the cool-off deliberately, to protect yourselfDuring the window, all open/increase orders come back as 54094 unless you switch them to reduce-only
Switch to a "client-side position state machine" + reduce-only closesThe strategy runs long enough that hitting 54094 manually every time isn't sustainableDevelopment cost, and you can no longer lean on OKX-side strategy orders (TP/SL) for protection — you have to track price client-side and fire reduce-only market orders to close, similar to the pattern in the failover-design post

Three fixes for 54094. In practice most TVSBot users take the third route — rewrite payloads to explicitly carry action=close or reduce_only=true so the close path stays open, and accept that opening has to wait or that cool-off has to come off. Verified July 2026.

Do Existing Users Get Grandfathered?

Yes, conditionally. The third paragraph of the official notice reads "Users who configured the cool-off period before this upgrade will remain on the existing service, which only restricts orders placed via the web and app. These users will not be subject to the expanded restrictions introduced in this upgrade." — anyone who had a cool-off configured before 2026-07-07 stays on the old behaviour (web/app only) until the current cool-off window ends.

There is a switching point coming up, though: if you want the new, full protection, the notice recommends "we recommend re-enabling the cool-off period after your current one expires" — reset the cool-off once the old one expires, and the new rules apply. So the moment you next re-enable your cool-off, "I had cool-off configured previously and my API just kept working" flips automatically to the new regime. If you want cool-off to keep leaving your API alone, don't re-enable it.

How long will this grandfather promise hold?
The official text doesn't give an end date. This is a current transitional commitment, not a permanent guarantee — similar transitional clauses at other exchanges have historically quietly disappeared within six to twelve months. Before you rely on it, check the OKX notice page yourself to confirm the wording is still there. This paragraph is our inference, not something OKX put in writing.

Diagnostic Order When You See 54094

This checklist is meant to be run top-to-bottom the moment you see 54094 — you don't need to memorise it, just stop at whichever step catches your case. The first three confirm it's really this mechanism; the last three tell you how to respond.

  • Read the HTTP body, not just the status code. OKX returns HTTP 200 + sCode: "54094" for this error, so any consumer that only checks the HTTP status will miss it entirely. Your webhook consumer must parse the JSON body and inspect sCode.
  • Confirm your OKX account actually has an active cool-off period. Go to Account > Trading > Cool-off Period in the OKX web console and see whether status is Active and how much time is left. If it's Inactive, 54094 isn't coming from this — check sub-account settings or Broker OAuth scopes instead.
  • Confirm the instrument is SWAP or FUTURES. The changelog only names those two categories. If your instId is BTC-USDT (spot) or options, a 54094 is likely something else — go back to the OKX API sCode reference and look up the latest definition for that code.
  • Check whether this order is reduce-only. Look at reduce_only in the payload — is it present, is it true? For TVSBot, setting action to "close" counts too — the order service will translate it into reduce_only=true automatically.
  • Check whether it's a strategy or copy-trading order. Orders going through OKX's built-in strategy engine, or a sub-account set up for copy trading, are rejected during cool-off regardless of open or close. Either switch to your own REST order placement, or wait for cool-off to end.
  • Decide: kill the cool-off or refactor the flow. Old-version cool-offs can't be ended early — the notice is explicit — so wait. New-version cool-offs can be turned off. The long-term fix is to split your strategy logic into "opens might get blocked by cool-off, closes always go through reduce-only," so that the next time this happens the whole pipeline doesn't stall.

The Honest Section: We Can't Get Around This Either

Any automated trading system running on OKX — including our own TVSBot — has to obey this rule. It's enforced server-side by OKX, not client-side; no SaaS, broker, or bot service can bypass it for you. For example, TVSBot doesn't pre-check cool-off before placing an order (OKX doesn't expose a query API for it), and when a rejection comes back we keep the raw 54094 message on the order record so you can see in the dashboard exactly why it didn't go through — but that only solves "you find out faster," not "the order actually went out." Cool-off exists to make you cool off; any service claiming to "automatically bypass cool-off" is working against the design intent, we don't do that, and you shouldn't use a third-party service that does either.

Common Questions

I never turned on a cool-off period myself — why am I still getting 54094?
The OKX notice only says "rejections fire when cool-off is active" — it doesn't address the case where a user has never configured one at all. If you're certain you've never clicked anything on the Cool-off Period page, go check the status first — it's possible the master account set one on your sub-account, or the Broker OAuth / Agent Trade Kit authorisation flow included it. Verified July 2026, and the official documentation doesn't yet lay out every path by which a cool-off can be set on your behalf; in practice you just walk through the dashboard row by row.
Does spot get blocked by 54094?
No. The API changelog is explicit: "non reduce-only orders on SWAP and FUTURES instruments covered by the cool-off are rejected server-side" — only SWAP (perpetuals) and FUTURES (dated futures). Spot and options fall outside that sentence. That's the state at the time this was verified; if OKX later extends cool-off to more instrument types it wouldn't be surprising — cool-off is a protection feature, and expanding it is the natural direction.
Does TVSBot's dry-run mode hit 54094?
No, because dry-run doesn't call the real order API — it only simulates payload parsing, risk checks, and quantity computation locally, and never reaches the OKX server. The only way to verify behaviour during cool-off is to actually send a non-reduce-only open order to the demo environment (demo trading) or use a small real-money test. Whether OKX demo behaves identically to production for cool-off is something we haven't tested; this article won't call it.
During cool-off, can I add OKX-side TP / SL algo orders?
No. Those fall under the notice's "Strategy Order" category, and the wording is "regardless of whether they are for opening or closing positions" — whether it's a stop protecting a new open or a strategy order to close an existing position, during cool-off both are rejected. TP/SL you set before cool-off started are unaffected; OKX only blocks "new/modify," not the firing of existing ones. So set your protection orders before you enter cool-off.
Since existing users are grandfathered, should I set a cool-off now to lock myself into the old behaviour?
Not recommended. Doing that costs you a real cool-off window in exchange for the expectation that you'll keep the old behaviour — but that expectation is a transitional commitment, with no end date and no promise of permanence (see the inference in the "how long will this grandfather promise hold" box above). And during the cool-off, your own manual orders are blocked too. The pragmatic move is to rewrite payloads to explicitly mark reduce_only close paths — regardless of old vs new regime, regardless of what OKX does later, your close orders will keep going through.
Will Binance / Bybit / Bitget follow?
No official notices. These kinds of API-layer behaviour changes usually appear quietly in the changelog with an effective date pushed forward by a week or two — verified July 2026, and none of the Binance / Bybit / Bitget API changelogs show any pre-announcement or hint of a similar mechanism. That doesn't mean it'll stay that way — it's just the current observable state. If you want to track this, subscribing to each exchange's API changelog RSS is the low-effort option.

Get started

Ready to ship what you just learned?

Pipe TradingView signals into OKX for automated order placement — TVSBot is non-custodial, uses your own API key, exposes fine-grained reduce_only control in the payload, supports dry-run before you go live, and preserves every raw error message on the order record so when 54094 shows up you can see immediately whether it's cool-off or something else.

Get started for free