CCXT

CCXT vs the BTSE API and the official BTSE Python SDK

BTSE's official SDK is Python-only and installs from source. CCXT covers 59 BTSE capabilities in seven languages, but ships no BTSE WebSocket support.

BTSE runs spot and perpetual-futures markets and documents both a REST and a WebSocket API at btsecom.github.io/docs. There are two realistic ways to integrate it: BTSE's own Python SDK, btsecom/btse-sdk, or CCXT, which speaks BTSE natively behind an API shared with 103 other venues.

The deciding question here is unusually clear, because the two sides do not overlap completely: do you need live streams, and are you writing Python?

TL;DR

  • Pick the official BTSE SDK if you are in Python, BTSE is your only venue, and you need WebSocket data. CCXT implements zero watch* methods for BTSE — the vendor SDK is the only one of the two that streams.
  • Pick CCXT if you want 59 unified capabilities (30 of them fetch*), all 128 BTSE endpoints as implicit methods, and the same code in TypeScript, JavaScript, Python, PHP, C#/.NET, Go or Java.
  • The two are not mutually exclusive. Nothing stops you polling REST through CCXT and running a small vendor-SDK process for the private WebSocket feed. The REST surface is where portability pays; a single venue's socket is where it pays least.

At a glance

CCXTOfficial BTSE Python SDK
Exchanges covered104 (BTSE is one of them)BTSE only
LanguagesTypeScript, JavaScript, Python, PHP, C#/.NET, Go, Java — one APIPython
Distributionpip install ccxt, npm install ccxt, NuGet, Go modules, Mavennot on PyPI — git clone then pip install -e .
BTSE products in one clientspot and futures from one ccxt.btse instanceBTSESpotClient and BTSEFuturesClient
Unified market data + trading APIyes — same method names across every exchangeno — BTSE's own payloads, with typed enums
BTSE capabilities implemented59 unified methods, 30 of them fetch*REST for spot and futures, plus WebSocket
WebSocketsno — 0 watch* methods for BTSEyes — order-book cache and private streams
Raw endpoint accessyes — 128 BTSE endpoints as implicit methodsyes, it is the whole product
Built-in rate limiteryes, per-endpoint costs, on by defaultnot documented
Unified error typesyes — 41 typed exceptions in one hierarchyHTTP status plus BTSE error codes
Testnet / sandboxexchange.set_sandbox_mode(True)testnet=True on the client
Popularity43.8k GitHub stars · 4.7M PyPI + 494k npm installs/month (one package, every venue)0 GitHub stars; not published to PyPI
LicenceMITMIT
SupportDiscord, Telegram, GitHub issues — usually same-dayGitHub issues, BTSE support

Figures verified September 2026 against CCXT v4.5.77, the btsecom GitHub organisation, BTSE's published API documentation, and install counts from npm and PyPI.

The same job, written both ways

Fetch a price

import ccxt

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

CCXT returns a unified ticker structure — last, bid, ask, high, low, volumes, a millisecond timestamp, the same keys on every venue. The SDK's price() returns BTSE's own payload for BTSE's own market id.

Place a limit order

import ccxt

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

Moving that order to perpetual futures means a different client class in the SDK (BTSEFuturesClient, symbol BTC-PERP). In CCXT it is a different unified symbol on the same instance:

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

Where the differences actually bite

CCXT does not stream BTSE — be clear about that first

BTSE documents WebSocket feeds at wss://ws.btse.com/ws/spot, with a separate order-book feed at wss://ws.btse.com/ws/oss/spot and testnet equivalents on testws.btse.io. CCXT implements none of them: there is no ccxt.pro.btse, and exchange.has['ws'] is false. Live data through CCXT means polling fetch_order_book, fetch_trades or fetch_tickers on a timer.

This is the one axis where the vendor SDK is straightforwardly ahead, and it is worth deciding on before anything else on this page.

Seven languages, one API

The official SDK is Python. BTSE also publishes btsecom/api-sample, which carries example connectors in Python, Node.js and C# plus a Postman collection — but those are samples, not a library you take a dependency on.

CCXT is written once in TypeScript and transpiled to JavaScript, Python, PHP, C#/.NET, Go and Java, with identical method names and return structures in all of them.

import ccxt from 'ccxt';
const exchange = new ccxt.btse ();
const ticker = await exchange.fetchTicker ('BTC/USDT');

Portability is the whole point

Adding a second exchange to a vendor-SDK integration means a second payload shape, a second symbol convention, a second auth scheme and a second error taxonomy — then a translation layer of your own. That translation layer is what CCXT already is:

for exchange_id in ['btse', 'binance', 'bybit', 'okx']:
    exchange = getattr(ccxt, exchange_id)()
    print(exchange_id, exchange.fetch_ticker('BTC/USDT')['last'])

Rate limits you do not have to model

BTSE's documentation sets different ceilings per endpoint class: 15 requests per second per API key for query endpoints (30 per user), and 75 per second for order endpoints, with tiered blocking of 1 second, 5 minutes and 15 minutes and a Retry-After header on 429.

CCXT encodes that shape directly. The base rateLimit is 1000 / 75 ms — a 75-request-per-second budget — and each endpoint carries a cost against it: 1 for order placement and cancellation, 3 for the public-api/market/v1 data endpoints, 5 for most spot and futures queries, 15 for wallet calls. The throttler is on by default, so a loop of fetch_ohlcv calls paces itself.

Precision, rounding and string math

BTSE markets are loaded in TICK_SIZE mode, so CCXT knows each market's price tick and amount step and applies them for you through amount_to_precision and price_to_precision, backed by the Precise string-arithmetic class — no float drift turning into a rejected order.

amount = exchange.amount_to_precision('BTC/USDT', 0.0012345678)
price = exchange.price_to_precision('BTC/USDT', 61234.56789)

One error hierarchy

CCXT maps BTSE's error codes onto a typed exception treeInsufficientFunds, InvalidOrder, OrderNotFound, RateLimitExceeded, AuthenticationError, InvalidNonce, ExchangeNotAvailable and 34 more, all descending from BaseError. You catch ccxt.InsufficientFunds once, and it keeps working on the next venue.

Testnet without a second code path

exchange = ccxt.btse({'apiKey': '...', 'secret': '...'})
exchange.set_sandbox_mode(True)   # swaps in https://testapi.btse.io

One flag swaps the REST base URL to BTSE's testnet host. No constants to juggle.

Nothing is hidden — the implicit API

The 59 unified methods are not a ceiling. Every endpoint in BTSE's api block is generated as a callable implicit method, with the request-api / request-nonce / request-sign HMAC-SHA384 headers, rate-limit accounting and error mapping applied:

# GET /spot/api/v3.3/invest/products
products = exchange.private_get_spot_api_v3_3_invest_products()

# GET /public-api/otc/v1/markets
otc = exchange.public_get_public_api_otc_v1_markets()

That covers the Earn, OTC, convert and sub-account routes CCXT does not model as unified methods. Browse all 128 on the btse implicit API page.

What the official BTSE SDK does better

An honest list, and the first item is the big one:

  • It streams and CCXT does not. btse-sdk ships WebSocket support with a built-in order-book cache that handles snapshot/delta merging for you, plus authenticated private streams for fills and order notifications. CCXT has no watch* method for BTSE at all. If live data is the requirement, this decides it.
  • One-to-one with BTSE's own documentation. OrderSide, OrderType and the client method names mirror BTSE's API reference exactly, so debugging against the vendor docs is a single hop rather than two.
  • Products CCXT does not unify. CCXT's BTSE integration has no unified withdraw, transfer, fetchDepositAddress or createDepositAddress. Those endpoints exist and are reachable as implicit methods, but the SDK and the official samples treat wallet, convert, transfer, OTC and Earn as first-class.
  • Official multi-language samples. btsecom/api-sample covers spot v3.3, futures v2.3, OTC, wallet and streaming in Python, Node.js and C#, with a Postman collection kept alongside — a useful reference even if you end up on CCXT.

If you are writing Python, trade only BTSE, and need the WebSocket feeds, the official SDK is the better fit today.

Migrating from the BTSE API to CCXT

What you are doingBTSE RESTCCXT
SymbolsBTC-USDT, BTC-PERP-USDT'BTC/USDT', 'BTC/USDT:USDT'
MarketsGET /public-api/market/v1/marketsload_markets()
TickerGET /public-api/market/v1/ticker/24hrfetch_ticker() / fetch_tickers()
Order bookGET /public-api/market/v1/orderbookfetch_order_book()
CandlesGET /public-api/market/v1/klinesfetch_ohlcv()
Public tradesGET /public-api/market/v1/tradesfetch_trades()
New orderPOST /spot/api/v4/trade/orderscreate_order()
Amend orderPUT /spot/api/v4/trade/ordersedit_order()
Cancel orderDELETE /spot/api/v4/trade/orderscancel_order()
Cancel everythingDELETE /spot/api/v4/trade/orders/allcancel_all_orders()
Dead-man switchPOST /spot/api/v4/trade/orders/cancel_all_aftercancel_all_orders_after()
Open ordersGET /spot/api/v4/trade/ordersfetch_open_orders()
BalanceGET /public-api/wallet/v1/user/assetsfetch_balance()
PositionsGET /futures/api/v3/trade/positionsfetch_positions()
LeveragePOST /futures/api/v3/trade/leverageset_leverage()
My tradesGET /spot/api/v4/trade/trade_historyfetch_my_trades()
Funding rateGET /public-api/market/v1/recentFundingHistoryfetch_funding_rate()
Streamswss://ws.btse.com/ws/spotnot implemented — poll, or use the vendor SDK
Anything not listedthe raw endpointthe same endpoint as an implicit method

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

FAQ

Does CCXT support BTSE WebSockets? No. CCXT implements zero watch* methods for BTSE, so there is no ccxt.pro.btse. BTSE itself publishes WebSocket feeds and its own Python SDK consumes them; through CCXT, live data means polling fetch_order_book or fetch_trades on a timer.

Does BTSE have an official SDK? Yes — btsecom/btse-sdk, a Python SDK for spot and futures with WebSocket support, MIT-licensed. It is not published to PyPI: you clone the repository and pip install -e .. BTSE also maintains btsecom/api-sample with Python, Node.js and C# examples.

Does CCXT cover BTSE futures as well as spot? Yes, from one ccxt.btse instance. Spot markets are 'BTC/USDT', perpetuals are 'BTC/USDT:USDT', and positions, leverage, margin mode, position mode, funding rates, open interest and leverage tiers are all unified methods.

Can I test against BTSE's testnet through CCXT? Yes. exchange.set_sandbox_mode(True) swaps the REST base URL to https://testapi.btse.io, which is what BTSE's documentation gives as the testnet host.

Can I still call BTSE-specific endpoints through CCXT? Yes — all 128 of them, as implicit methods, with HMAC-SHA384 signing and rate limiting applied. Choosing CCXT does not cut you off from the OTC, Earn, convert or sub-account routes.

Is CCXT free? Yes. MIT-licensed, with no paid tier.

Next steps

On this page