CCXT vs native exchange SDKs: what the abstraction hides
Figures on this page are as of 2026-09. Fees, limits and margin tiers change — check the venue's own docs.
The choice between CCXT and an exchange’s own SDK is hard because both are right for different parts of the same program. CCXT gives you one interface and one error hierarchy across venues. A native SDK speaks the venue’s own vocabulary — what you need for the parts that do not generalise, which tend to decide whether an order does what you meant.
This page compares the two for Binance, Bybit, OKX and Hyperliquid, for developers who already know CCXT (if not, start with getting started with CCXT). It does not declare either the better choice.
Short answer
- You trade on several venues and want one error-handling path → CCXT. Its split between “the exchange refused” and “the outcome is unknown” is the most useful thing it gives you.
- Your strategy depends on account or position modes → learn the native model whichever client you use. Hedge-mode fields, margin modes and account levels differ per venue and are account state, not order options.
- You need every behaviour traceable to the venue’s own docs → a native SDK is the shorter path. CCXT’s mappings are source code, not a contract.
- The venue’s official SDK does not exist in your language → check the lists below first; some venues list only Python.
What they have in common
- Both sign requests for you, so neither leaves you writing HMAC or EIP-712 code by hand.
- Both are code you trust with credentials; “official” and “popular” are different properties, as below.
- Neither makes an order retry safe. That is a venue property, not a library one.
Where they actually differ
Who publishes it
| Venue | Official SDKs, per the venue |
|---|---|
| Binance | Modular connectors: Python (binance-sdk-spot, binance-sdk-derivatives-trading-usds-futures, …), JavaScript (@binance/spot, …), Java, Go, Rust, PHP, Ruby. The older standalone futures connectors are marked deprecated |
| Bybit | pybit (Python), plus Go, Rust, Ruby, JavaScript, PHP, Java and .NET repos. The npm package bybit-api is labelled Community |
| OKX | python-okx, linked from the V5 docs; we did not find other languages linked there |
| Hyperliquid | One Python SDK; the Rust and TypeScript SDKs are labelled community-written. The docs note CCXT “also maintains integrations” |
CCXT is maintained by its own project, not by these venues — and so is some of
what people call “the native SDK”: Bybit labels the npm bybit-api package
community code. Check the venue’s list before assuming a package is
official.
Authentication details you still own
A library signs for you, but it cannot supply credentials it does not know exist. Each venue has at least one:
- OKX requires a third credential, the passphrase, and switches demo
trading on REST with the header
x-simulated-trading: 1. See the OKX API passphrase. - Bybit names four environments — mainnet, testnet, mainnet-demo, testnet-demo — and a key works only against the one it was created in.
- Binance Spot Testnet and Spot Demo Mode are separate environments whose keys do not cross.
- Hyperliquid has no API key. An agent wallet signs, but account queries must use the master address or they come back empty. See what an agent wallet is.
Whichever client you choose, these decide whether authentication works.
Errors: one hierarchy vs native codes
CCXT’s top-level split is the reason to use it:
ExchangeError— the exchange understood the request and refused it. Retrying unchanged fails again.OperationFailed— network, timeout, rate limit, maintenance. The request may or may not have been processed.RateLimitExceededsits here, underNetworkError.
CCXT maps each venue’s codes into that tree. Its source maps OKX 50111–50115
to AuthenticationError, Bybit 10001 to BadRequest and Bybit 110007 to
InsufficientFunds.
What a class name cannot carry is which of several native conditions you hit. Some examples where the native detail matters:
| Venue | What the native code tells you that a class may not |
|---|---|
| Bybit | 10003 means an invalid key or environment mismatch over REST, but too many sessions on WebSocket order entry |
| Bybit | 110004 and 110045 both read “Wallet balance is insufficient” |
| OKX | 51008 arrives only with sub-codes such as 51008_1000 (balance) or 51008_1001 (margin) |
| Binance | -2010 is generic; the cause is in msg, e.g. “Account has insufficient balance for requested action.” |
| Hyperliquid | Errors are strings, returned per order inside an HTTP 200 response |
With a native SDK you face these directly, and you also face each venue’s
envelope: Binance’s HTTP status is meaningful, Bybit reports retCode under
HTTP 200, OKX puts per-item results in sCode/sMsg. With CCXT, log the native
code and message next to the class. See
CCXT’s common errors and
auth errors across exchanges.
Account modes
Account-level state sits outside any single order call, unified or not:
- Binance USDⓈ-M:
dualSidePositionswitches one-way/hedge for every symbol, and after CM migration flips USDⓈ-M and COIN-M together. Blocked by open orders (-4067) or positions (-4068). - Bybit: under the Unified Trading Account the margin mode —
ISOLATED_MARGIN,REGULAR_MARGINorPORTFOLIO_MARGIN— applies to the whole account, and cross and portfolio liquidation are assessed per account. - OKX:
acctLvselects Spot, Futures, Multi-currency or Portfolio margin. Spot mode cannot trade perpetuals; portfolio margin allows net mode only; the first switch into a mode must be made on the web or app.
A correct-looking order can fail, or carry more risk than intended, because of one of these. Read them at startup with whichever client you use, and refuse to trade if they differ from what the strategy assumes. See what a unified trading account is.
Position parameters
| Venue | Field on the order | Values |
|---|---|---|
| Binance USDⓈ-M | positionSide | BOTH (one-way); LONG/SHORT (hedge, required) |
| Bybit | positionIdx | 0 (one-way); 1 buy / 2 sell (hedge, required) |
| OKX | posSide | net; long/short (required in long/short mode, FUTURES/SWAP only) |
Three vocabularies for one idea, each with its own failure — -4061 on
Binance, 51000 on OKX when posSide is missing. Binance also rejects
reduceOnly in hedge mode. Our Hyperliquid sources do not cover a position
mode, so it is left out of this table.
A unified createOrder has to translate a hedge-mode intent into one of these.
How CCXT does that for a given venue is defined in that exchange’s class in
CCXT’s source; we have not verified the mapping, so check it for the venue you
use. With a native SDK you pass the venue’s own field and read the venue’s own
docs. See hedge mode.
Retries and client order IDs
Neither layer makes a retry safe. On Binance, newClientOrderId is unique only
among open orders — a reused ID is accepted once the first order has
filled, exactly the ambiguous-timeout case. CCXT’s DuplicateOrderId can only
fire when the venue rejects a duplicate. We have verified this for Binance only.
With either client, reconcile open orders and positions before resending. See
why retrying a failed order is not safe.
Rate limits and coverage
The venues meter different things — Binance request weight per IP, Bybit per
account per endpoint, OKX per instrument for trading, Hyperliquid an allowance
earned from trading volume. CCXT unifies the exception, not the budget. It
exposes exchange.rateLimit and a per-venue capability map, exchange.has, at
runtime; read both rather than assuming. See
rate-limit models compared.
Which to pick
| Your situation | Lean toward | Why |
|---|---|---|
| Several venues, simple spot or one-way orders | CCXT | One interface and one error tree cover the common path |
| One venue, heavy use of hedge mode or account modes | Native SDK | You work in the venue’s own fields and docs |
| You need to cite the venue’s docs for every behaviour | Native SDK | CCXT mappings are source code and can change between versions |
| Your language has no official SDK for the venue | CCXT or raw HTTP, after checking | Some venues list only Python; confirm CCXT covers your language and venue |
| You want retry safety | Neither on its own | Reconcile against the venue before resending |
Can you use both
Yes: CCXT for market data, balances and plain orders across venues, and the native SDK or raw calls where you depend on something venue-specific. Keep one credential store and one reconciliation path so the clients cannot disagree about what the account holds.
FAQ
Is CCXT an official SDK for Binance, Bybit or OKX?
CCXT is maintained by its own project, not by the exchanges. Binance, Bybit and
OKX each list their own SDKs — Binance’s modular connectors, Bybit’s pybit
and other language repos, OKX’s python-okx. Hyperliquid’s docs name one
official Python SDK and note that CCXT also maintains integrations.
Does CCXT hide the exchange’s error codes?
It maps them into a unified exception hierarchy, which tells you the kind of
problem — refused, or outcome unknown. The class alone may not tell you which
native condition you hit; Bybit’s 10003, for instance, means different things
over REST and WebSocket order entry. Log the native code and message alongside
the CCXT class.
Can I rely on CCXT to handle hedge mode for me?
Treat hedge mode as account state you must verify yourself. Binance uses
positionSide, Bybit positionIdx and OKX posSide, and each venue sets the
mode at account or symbol level. How CCXT translates these for a given venue is
in that exchange’s class in its source; check it before relying on it.
Is the npm package bybit-api Bybit’s official Node SDK?
No. Bybit’s own API guide labels the npm package bybit-api as Community. The
official list includes pybit for Python and repositories for Go, Rust, Ruby,
JavaScript, PHP, Java and .NET.