CCXT

CCXT vs the XT.com API and pyxt

CCXT compared with XT.com's own connectors on signing schemes, the four API hosts, order-book streaming, language coverage and unified structures.

XT.com publishes REST and WebSocket APIs across four hosts, and points developers at three connectors: pyxt for Python, xt-open-api for JavaScript, and a Java library shipped as the xt4-java-demo repository. CCXT implements the same API as the xt exchange, behind method names shared with 103 other venues.

The question that decides between them: do you want a thin wrapper that mirrors XT's endpoint list, or one client that hides the fact that XT's spot and futures APIs are, in practice, two different APIs?

TL;DR

  • Pick XT's own connectors if XT is your only venue and you want method names that map one-for-one onto doc.xt.com, or if you are working from XT's per-language demo repositories as a signing reference.
  • Pick CCXT if you would rather not model four base hosts, two signing schemes, per-product symbol formats and a listen-key lifecycle yourself — and if a second exchange is anywhere in your plans.
  • Choosing CCXT does not hide anything. All 174 XT endpoints are generated as implicit methods, signed and rate-limited like the unified ones.

At a glance

CCXTXT's own connectors
Exchanges covered104 (XT is one of them)XT only
LanguagesTypeScript, JavaScript, Python, PHP, C#/.NET, Go, Java — one APIPython (pyxt), JavaScript (xt-open-api), Java (xt4-java-demo); demo repos in Go and C#
Packages to install1 (ccxt)1 per language, plus clone-and-run demo repos for Go, C# and Node.js
XT products in one clientspot, margin, USDT-M futures, COIN-M futuresseparate client class per product (pyxt.spot, pyxt.perp)
Unified market data + trading APIyes — 68 unified capabilities, 33 fetch* methodsno — XT's own request/response shapes
WebSocketsyes — 16 watch* / unWatch* methodsyes — SpotWebsocketStreamClient and futures equivalents
Raw endpoint accessyes — 174 XT endpoints as implicit methodsyes, it is the whole product
Built-in rate limiteryes, per-endpoint weights, on by default (rateLimit 100 ms)not a documented feature
Unified error typesyes — 41 typed exceptions in one hierarchyHTTP status plus XT rc/mc codes
Testnet / sandboxnot available for XT — set_sandbox_mode(True) raises NotSupportednone published
Popularity43.8k GitHub stars · 4.8M PyPI + 494k npm installs/month (one package, every venue)pyxt 3 GitHub stars · 231 PyPI installs/month; xt-open-api 48 npm installs/month; xtpub/api-doc 10 stars
LicenceMITpyxt MIT; xt-open-api ISC
SupportDiscord, Telegram, GitHub issues — usually same-dayGitHub issues, XT's API Telegram group

Figures verified September 2026 against CCXT v4.5.77, XT's published documentation repositories and connectors, and install counts from npm and PyPI.

The same job, written both ways

Fetch a ticker

import ccxt

exchange = ccxt.xt()
ticker = exchange.fetch_ticker('BTC/USDT')
print(ticker['last'], ticker['baseVolume'])

CCXT returns a unified ticker structure: the same keys, types and units you get from Binance, Kraken or Hyperliquid. pyxt returns XT's payload for you to parse.

The host is the other difference. Spot(host="https://sapi.xt.com") is spot; a futures ticker is Perp(host="https://fapi.xt.com") and an inverse one is https://dapi.xt.com. In CCXT the host follows from the symbol:

exchange.fetch_ticker('BTC/USDT')        # spot        -> sapi.xt.com
exchange.fetch_ticker('BTC/USDT:USDT')   # USDT-M swap -> fapi.xt.com

Coin-margined contracts settle in the base currency and carry that in the symbol suffix, and they route to dapi.xt.com. load_markets() tells you which contracts exist and under which unified symbol.

Place a limit order

import ccxt

exchange = ccxt.xt({'apiKey': '...', 'secret': '...'})
order = exchange.create_order('BTC/USDT', 'limit', 'buy', 0.001, 60000)
print(order['id'], order['status'])

Placing the same order on USDT-M futures means a different pyxt class, a different host and a different method signature. In CCXT it is the same method with a different symbol:

order = exchange.create_order('BTC/USDT:USDT', 'limit', 'buy', 0.001, 60000)

CCXT also rounds amount and price to the market's step and tick size before sending, using Precise string arithmetic, so a float that ends in 0.0012345678999 does not come back as a rejected order.

Stream an order book

import ccxt.pro
import asyncio

async def main():
    exchange = ccxt.pro.xt()
    while True:
        orderbook = await exchange.watch_order_book('BTC/USDT')
        print(orderbook['bids'][0], orderbook['asks'][0])

asyncio.run(main())

These two are not doing the same job. pyxt's example subscribes to a five-level snapshot stream and asks you to run the heartbeat thread yourself. CCXT's watch_order_book subscribes to XT's incremental depth stream by default and maintains a full merged book:

CCXTraw stream
Fetch the REST snapshot and align it with the delta streamdone for youyour code
Buffer deltas that arrive while the snapshot is in flight, then replay themdone for youyour code
Detect update-id gaps and re-syncdone for youyour code
Ping/pong keep-alive and reconnectdone for youyour code (heartbeat thread)
Re-subscribe after a dropdone for youyour code
Bounded caches for trades and candlesdone for youyour code

If you want the fixed-depth snapshot stream instead, it is a parameter: watch_order_book('BTC/USDT', params={'levels': 5}).

Where the differences actually bite

One client, four hosts and two signing schemes

XT's API is split across sapi.xt.com (spot), fapi.xt.com (USDT-M futures), dapi.xt.com (COIN-M futures) and api.xt.com (user centre). The signatures are not the same on both sides: spot and user requests sign a payload prefixed with xt-validate-algorithms, xt-validate-appkey, xt-validate-recvwindow and xt-validate-timestamp, joined to the method, path and body with # separators, and send matching headers. Futures requests sign a shorter prefix without the algorithm and recv-window fields. Both are HMAC-SHA256, and getting the delimiters wrong produces an authentication failure with no hint as to which part was wrong.

CCXT implements both schemes and picks the right one from the endpoint you called. You never see them.

Symbols and product selection

XT identifiers are lowercase and underscore-separated — btc_usdt, ltc_usdt — and the same string can mean a spot pair or a contract depending on which host you sent it to. CCXT uses unified symbols where the product is part of the symbol: 'BTC/USDT' for spot and 'BTC/USDT:USDT' for a USDT-M perpetual, with the settlement currency after the colon and a -YYMMDD suffix on dated futures. options.defaultType sets the default when a symbol is ambiguous.

Private streams and the listen key

XT's private WebSocket channels are not authenticated by signature. You fetch a listen key (spot) or an access token (futures) over REST, attach it to the subscription, and refresh it when the socket tells you it has expired. CCXT does this transparently: it requests the token, attaches it to watch_orders, watch_my_trades, watch_balance and watch_positions, and on an invalid_listen_key or token expire message it discards the cached token, fetches a new one and resubscribes.

Rate limits you do not have to model

XT publishes different limits per endpoint class and, on futures, an IP-level ceiling that locks the account for ten minutes when exceeded. CCXT encodes per-endpoint weights in the exchange definition and ships a token-bucket throttler that is on by default (enableRateLimit = True, rateLimit = 100 ms). You call methods in a loop; the library paces them.

One error hierarchy

CCXT maps XT's rc / mc response codes onto a typed exception treeInsufficientFunds, InvalidOrder, OrderNotFound, RateLimitExceeded, AuthenticationError, NetworkError and 35 more, all descending from BaseError. You write except ccxt.InsufficientFunds once and it keeps working on the next exchange.

No sandbox, on either side

CCXT reports sandbox: false for XT — set_sandbox_mode(True) raises NotSupported — because there is no testnet base URL to swap in. This is a property of the venue, and it is worth knowing before you plan a test strategy around it. The offline path is CCXT's static request and response fixtures, which assert the exact URL and body CCXT produces for XT without touching the network.

Nothing is hidden — the implicit API

Alongside the 68 unified capabilities, all 174 XT endpoints are generated as callable methods:

# any raw XT endpoint, camelCased from its path and API group
response = exchange.public_spot_get_ticker_24h({'symbol': 'btc_usdt'})

Signing, timestamping, rate-limit accounting and error mapping still apply, so copy-trading, loan, earn and broker endpoints that CCXT does not model as unified methods are still one call away. Browse them all on the xt implicit API page.

What XT's own connectors do better

An honest list:

  • They mirror XT's documentation exactly. get_tickers, get_depth, get_kline, order, cancel_order line up with the endpoint names on doc.xt.com. CCXT's unified names are a deliberate abstraction, which is one extra hop when you are debugging against the vendor docs.
  • The host is explicit. Spot(host="https://sapi.xt.com") and Perp(host="https://fapi.xt.com") make it impossible to be confused about which API you are hitting. CCXT decides for you, which is convenient until you want to be certain.
  • Per-language demo repositories are a signing reference. XT publishes working demos in Python, Java, Go, C# and Node.js under github.com/xt-com. If you are implementing XT's #-delimited signature yourself, or comparing byte-for-byte against a signature that is being rejected, those repos are the primary source.
  • New XT product lines are documented there first. XT's reference covers copy trading, margin, loan, earn, broker and other surfaces that CCXT does not model as unified methods. CCXT can call them through the implicit API on day one, but a unified wrapper may lag.

If XT is your only venue, you work primarily in Python, and you would rather read one vendor's docs than learn a unified abstraction, pyxt is a defensible choice.

Migrating from pyxt to CCXT

What you are doingpyxtCCXT
Symbols'btc_usdt''BTC/USDT' (spot), 'BTC/USDT:USDT' (USDT-M swap)
Product selectionpyxt.spot.Spot vs pyxt.perp.Perp, different hostone client, options.defaultType or the symbol
Marketsget_symbol_info()load_markets()
Tickerget_tickers()fetch_ticker() / fetch_tickers()
Order bookget_depth()fetch_order_book()
Candlesget_kline()fetch_ohlcv()
New orderorder()create_order()
Cancel ordercancel_order()cancel_order()
Open ordersspot order endpointsfetch_open_orders()
Balancebalance() / get_account_capital()fetch_balance()
Positionsperp account endpointsfetch_positions()
StreamsSpotWebsocketStreamClient callbacks + heartbeat threadwatch_* on ccxt.pro.xt
Anything not listednative methodthe same endpoint as an implicit method

Start with Install, then the Manual, then the xt unified API reference.

FAQ

Does CCXT support XT.com futures? Yes — spot, margin, USDT-M futures and COIN-M futures from one ccxt.xt instance. The product follows from the unified symbol ('BTC/USDT' spot, 'BTC/USDT:USDT' USDT-M swap, base-settled symbols for coin-margined contracts) or from options.defaultType, and CCXT routes to sapi, fapi or dapi accordingly.

Does XT.com have an official Python SDK? pyxt on PyPI describes itself as the official Python 3 connector for XT.com's HTTP APIs and is linked from XT's own API documentation. It is MIT-licensed, requires Python 3.9 or newer, and its most recent PyPI release is version 0.6.24 from November 2024. XT also publishes clone-and-run demo repositories in Python, Java, Go, C# and Node.js.

Is there an XT testnet I can use with CCXT? No. CCXT reports no sandbox for XT and set_sandbox_mode(True) raises NotSupported. Use CCXT's offline static request and response tests, and a small live account, instead.

Can I still call XT-specific endpoints from CCXT? Yes — all 174 of them, as implicit methods, with signing, rate limiting and error mapping applied.

Do I need CCXT Pro separately for WebSockets? No. CCXT Pro is included in the ccxt package. Use ccxt.pro.xt and call watch* methods — 16 of them, including unWatch* variants that unsubscribe cleanly.

Is CCXT free? Yes. MIT-licensed, including the WebSocket support.

Next steps

On this page