OKX API error 51000 "Parameter error" and the posSide trap
Figures on this page are as of 2026-09. Fees, limits and margin tiers change — check the venue's own docs.
OKX error 51000 returns HTTP 400 with the message template "Parameter {param0} error". OKX substitutes the name of the offending parameter for
{param0}, so the response you actually receive names the field that was
rejected — and that name is most of the diagnosis.
51000 is generic by design: one code for any parameter that fails validation,
on any endpoint. That makes it frustrating if you log only the code and trivial
if you log the message. This page covers where to find the field name, the one
cause OKX itself documents — omitting posSide when the account is in
long/short mode — and a short list of checks for everything else.
What this error actually means
OKX’s V5 error-code table
lists 51000 as “Parameter {param0} error”, HTTP 400. Unlike the
authentication family, where each failure has its own narrow code (see
OKX API error 50111), there is no per-cause code
here. The information is in the substituted message, and the docs do not
publish a list of causes. The placeholder is the cause list.
Where to read it:
- The top-level
codeandmsgof the response. - Per-order
sCodeandsMsgon order endpoints. OKX’s general-information section says that when a response includessCode, “It is sCode and sMsg that represent the request result or error reason”. On a batch request, each order can fail for its own reason.
The most common reason 51000 feels opaque is a handler that logs
code=51000 and discards the rest. Log the raw response body for any non-zero
code. It contains no secrets and it ends this class of investigation in seconds.
The documented cause: posSide in long/short mode
This is the case OKX calls out explicitly, and the one most likely to hit derivatives code that used to work.
Position mode in one paragraph
OKX accounts have a position mode, posMode, with two values:
posMode | Help-centre name | Positions |
|---|---|---|
net_mode | One-way mode | One net position per contract; pos is signed (positive long, negative short) |
long_short_mode | Hedge mode | Separate long and short positions per contract, returned as separate records |
Long/short mode is “only applicable to FUTURES/SWAP”. In Futures mode and Multi-currency margin mode, futures and perpetual swaps support both position modes; in Portfolio margin mode, FUTURES and SWAP support net mode only.
What the place-order docs require
OKX’s place-order
documentation defines posSide as:
- Required in long/short mode, and must be
longorshort. - Defaulting to
netin net mode. - Only for FUTURES and SWAP — do not send it for SPOT or MARGIN.
And it states the consequence: omitting posSide for FUTURES or SWAP in
long/short mode returns error 51000.
Why it catches working code
Position mode is an account setting, not a property of the request. Code
written and tested against a net-mode account never sends posSide and never
needs to. Then someone switches the account to hedge mode in the app — for
manual trading, perhaps — and every automated futures or swap order starts
failing with 51000. Nothing in the code changed.
The reverse also bites: code copied from a hedge-mode example sends
posSide: long to a net-mode account. We did not find a documented statement of
what OKX does with a long/short value in net mode, so do not rely on it
being ignored.
The fix
Read the mode rather than assuming it. GET /api/v5/account/config returns
posMode; POST /api/v5/account/set-position-mode changes it. In outline:
config = GET /api/v5/account/config
if instType in (FUTURES, SWAP):
if config.posMode == "long_short_mode":
order.posSide = "long" or "short" # required
else:
# net_mode: posSide defaults to "net"; omit it or send "net"
else:
# SPOT / MARGIN: do not send posSide
Check it at startup and fail loudly if it is not the mode your code was written for. The same mode also changes how positions come back — one signed record versus two per contract — so position-reading and closing logic depend on it too. Exit logic in particular should not assume a position shape; the general case for making exits explicit is in what is a reduce-only order.
Other causes, in order of likelihood
OKX does not publish these as causes of 51000; they are the general shapes a
parameter failure takes, and the substituted field name tells you which one to
check.
1. A field sent where it does not belong
Parameters that only apply to some instrument types. posSide on a spot order
is the documented example of a field the docs say not to send; other
type-specific fields behave the same way. Check the field against the
endpoint’s parameter table for your instType.
2. A value from another venue’s vocabulary
Enum values, symbol formats and side names differ between exchanges. Code ported from another venue, or a unified symbol from a library passed straight through, can produce values OKX does not recognise. Compare the value to the allowed list on OKX’s endpoint page, character for character.
3. A conditionally required field
Some parameters are required only in combination with others — posSide
being required only in long/short mode is the pattern. If the field named in
the message is one you never send, look for the condition that made it
mandatory.
4. Serialisation
A number serialised in a form the API does not accept — scientific notation for a small quantity is the classic — or a type that differs from what the parameter table specifies. Log the exact body that went on the wire, not the object you built it from.
How to confirm which one you have
- Read the field name from
msgorsMsg. - Look it up on the endpoint’s page: is it required, for which instrument types, and what values does it take?
- If it is
posSide, callGET /api/v5/account/configand checkposMode— and whether the account is in Portfolio margin, which is net-only for futures and swaps. - Diff your request body against the docs’ example for the same endpoint.
- Fix, do not retry.
51000is a permanent refusal: the same request will fail the same way. See error handling patterns for trading APIs.
If a language model is building the orders, surface the field name to it rather than just “order failed” — but be deliberate about letting it correct and resubmit an order on its own. Parameter errors are among the failure modes covered in how LLM tool calls go wrong on orders.
FAQ
What does OKX error 51000 mean?
It means a request parameter failed validation. OKX returns HTTP 400 with the
message “Parameter {param0} error”, substituting the name of the rejected
parameter, so reading the full message tells you which field to fix. On order
endpoints, check the per-order sCode and sMsg as well.
Why do my OKX futures orders suddenly fail with 51000?
A common reason is that the account’s position mode changed to long/short
(hedge) mode. In that mode posSide is required for FUTURES and SWAP orders and
must be long or short; OKX documents that omitting it returns 51000. Read
posMode from GET /api/v5/account/config and set posSide accordingly.
Do I need to send posSide for OKX spot orders?
No. OKX’s place-order docs describe posSide as applicable only to FUTURES and
SWAP, and say not to send it for SPOT or MARGIN. In net mode it defaults to
net; in long/short mode it is required for futures and swaps.
Can OKX portfolio margin accounts use long/short position mode?
Not for futures and perpetual swaps. OKX’s docs state that in Portfolio margin mode, FUTURES and SWAP support net mode only. Futures mode and Multi-currency margin mode support both net and long/short mode for those instruments.