CCXT vs the Blockchain.com Exchange API
Blockchain.com's official client is an archived OpenAPI-generated repo with no WebSocket support. Compared with CCXT on maintenance, streaming and errors.
Blockchain.com Exchange documents a REST API at api.blockchain.com/v3 and a WebSocket feed at wss://ws.blockchain.info/mercury-gateway/v1/ws. Its official client library is blockchain/lib-exchange-client — a repository of clients autogenerated from the OpenAPI specification, covering thirteen language targets.
Two facts about that repository decide most of this comparison. It was archived on 22 January 2026 and is now read-only. And the generated clients cover the REST API only — there is no WebSocket client in them, while the market data most people want from this venue arrives over the socket.
So the question is: do you want generated REST bindings frozen at their last build, or a maintained client that also streams?
TL;DR
- Pick lib-exchange-client if you need REST-only bindings in a language CCXT does not target — Rust, Kotlin, Haskell, Clojure, Elm and C are all in that repository — and you are comfortable vendoring an archived, generated client.
- Pick CCXT if you want the venue maintained: 34 unified capabilities, 19 of them
fetch*, sixwatch*streaming methods, and all 24 Blockchain.com endpoints as implicit methods, in TypeScript, JavaScript, Python, PHP, C#/.NET, Go and Java. - Streaming is the sharpest divide. Blockchain.com's WebSocket feed uses FIX field naming and is not covered by the generated clients at all; CCXT exposes it as
watch_order_book,watch_trades,watch_ticker,watch_ohlcv,watch_ordersandwatch_balance.
At a glance
| CCXT | lib-exchange-client (official) | |
|---|---|---|
| Exchanges covered | 104 (Blockchain.com is one of them) | Blockchain.com Exchange only |
| Languages | TypeScript, JavaScript, Python, PHP, C#/.NET, Go, Java — one API | 13 generated targets: Android, C, Clojure, C#, Elm, Go, Haskell, JavaScript, Kotlin, PHP, Python, Rust, TypeScript/Axios |
| Repository status | actively maintained | archived 22 January 2026, read-only |
| How it is built | hand-written unified implementation | autogenerated from the OpenAPI specification |
| Unified market data + trading API | yes — same method names across every exchange | no — Blockchain.com's own models |
| Capabilities implemented | 34 unified methods, 19 of them fetch* | the REST surface in the spec |
| Raw endpoint access | yes — 24 Blockchain.com endpoints as implicit methods | yes, it is the whole product |
| WebSockets | yes — 6 watch* methods | none — REST only |
| Built-in rate limiter | yes, on by default (rateLimit 500 ms) | not provided |
| Unified error types | yes — 41 typed exceptions in one hierarchy | ApiException plus HTTP status |
| Testnet / sandbox | not applicable | none documented by Blockchain.com |
| Popularity | 43.8k GitHub stars · 4.8M PyPI + 494k npm installs/month (one package, every venue) | 212 GitHub stars; Python package published to no index, JVM artifact com.blockchain:exchange-rest-api:1.0.0 on Maven Central |
| Licence | MIT | see repository |
| Support | Discord, Telegram, GitHub issues — usually same-day | archived repository; Blockchain.com support |
Figures verified September 2026 against CCXT v4.5.77, the blockchain/lib-exchange-client repository and its Python client README, and Blockchain.com's published API documentation.
The same job, written both ways
Fetch a ticker
import ccxt
exchange = ccxt.blockchaincom()
ticker = exchange.fetch_ticker('BTC/USD')
print(ticker['last'], ticker['baseVolume'])Two things stand out. The generated package is named openapi-client — the generator's default, never customised — and its README still instructs you to install it from git+https://github.com/GIT_USER_ID/GIT_REPO_ID.git, the generator's placeholder. In practice you vendor the directory. CCXT is pip install ccxt.
Place a limit order
import ccxt
exchange = ccxt.blockchaincom({'apiKey': '...', 'secret': '...'})
order = exchange.create_order('BTC/USD', 'limit', 'buy', 0.001, 60000)
print(order['id'], order['status'])Blockchain.com authenticates with a single X-API-Token header, so signing is not the pain point here — the pain point is that everything is a generated model you construct field by field, and the generated classes are frozen at the last build of an archived repository.
Stream an order book
import ccxt.pro
import asyncio
async def main():
exchange = ccxt.pro.blockchaincom()
while True:
orderbook = await exchange.watch_order_book('BTC/USD')
print(orderbook['bids'][0], orderbook['asks'][0])
asyncio.run(main())There is no official-SDK column here because the generated clients do not cover WebSockets at all. Blockchain.com's socket uses FIX field naming and sends a snapshot followed by updates per channel; turning that into a usable book is your code:
| CCXT | raw stream | |
|---|---|---|
Send the required Origin header on connect | done for you | your code |
| Apply the snapshot, then merge subsequent updates | done for you | your code |
| Reconnect, re-subscribe and re-seed after a drop | done for you | your code |
| Authenticate the socket for order and balance channels | done for you | your code |
| Bounded caches for trades and candles | done for you | your code |
CCXT's watch_order_book returns the same structure as fetch_order_book, so a polling loop becomes a stream by changing one word.
Where the differences actually bite
Generated versus maintained
Generated clients are a reasonable way to publish bindings in thirteen languages at once. The tradeoff is that they track the specification, not the exchange: whatever the OpenAPI file said at generation time is what you get, and the repository has been read-only since January 2026. CCXT's Blockchain.com implementation is hand-written, tested against live responses, and fixed in a version bump when the venue changes something.
Six streaming methods versus none
CCXT implements watch_ticker, watch_trades, watch_order_book, watch_ohlcv, watch_orders and watch_balance for Blockchain.com, over the same prices, ticker, trades, l2, trading and balances channels the venue publishes, with authentication for the private ones handled by the library. The official clients have no WebSocket support to compare against.
One error hierarchy
The generated Python client raises ApiException for anything the server rejects; the meaning is in the status code and the body. CCXT maps Blockchain.com's failures onto a typed exception tree — InsufficientFunds, InvalidOrder, OrderNotFound, RateLimitExceeded, AuthenticationError, NetworkError and 35 more, all descending from BaseError — so except ccxt.InsufficientFunds keeps working when you add a second venue.
Rate limits you do not have to model
The generated clients contain no throttling. CCXT ships a token-bucket rate limiter that is on by default, with rateLimit set to 500 ms for Blockchain.com, so a backfill loop paces itself instead of relying on you to remember.
Precision and string math
CCXT loads Blockchain.com's symbol metadata and gives you amount_to_precision, price_to_precision and cost_to_precision, backed by the Precise string-arithmetic class, so quantities never drift through float rounding into a rejected order:
amount = exchange.amount_to_precision('BTC/USD', 0.0012345678)
price = exchange.price_to_precision('BTC/USD', 61234.56789)L2 and L3 books, unified
Blockchain.com publishes both an aggregated l2/{symbol} book and a full-depth l3/{symbol} book. CCXT exposes them as fetch_l2_order_book and fetch_l3_order_book returning the same order book structure you get from every other exchange, rather than two venue-specific models.
Nothing is hidden — the implicit API
Alongside the 34 unified capabilities, all 24 Blockchain.com endpoints are generated as callable implicit methods, with the X-API-Token header, rate limiting and error mapping applied:
# GET /v3/exchange/whitelist
whitelist = exchange.private_get_whitelist()
# GET /v3/exchange/fees
fees = exchange.private_get_fees()Browse them all on the blockchaincom implicit API page.
What lib-exchange-client does better
An honest list, because these are real:
- Thirteen language targets, including six CCXT does not have. Rust, Kotlin, Haskell, Clojure, Elm and C bindings exist in that repository. If your service is written in one of those, the generated client is the only ready-made option and CCXT is not a substitute.
- A published JVM artifact.
com.blockchain:exchange-rest-api:1.0.0is on Maven Central, so a JVM project can depend on it by coordinate rather than vendoring source. - Models map one-to-one onto the OpenAPI specification.
BaseOrder,OrderSummary,OrderBook,TimeInForceand the rest are literally the spec's schemas. When you are reading Blockchain.com's API reference, there is no translation step; CCXT's unified structures are a deliberate abstraction over it. - One source of truth. Because every client is generated from the same file, the thirteen targets cannot drift from each other in the way thirteen hand-written wrappers would.
If you work in Rust, Kotlin or Haskell against Blockchain.com's REST API and do not need streaming, the generated client is the right starting point — with the caveat that you are maintaining a fork of an archived repository.
Migrating from lib-exchange-client to CCXT
| What you are doing | lib-exchange-client | CCXT |
|---|---|---|
| Symbols | 'BTC-USD' | 'BTC/USD' |
| Markets | UnauthenticatedApi.get_symbols() | load_markets() |
| Ticker | UnauthenticatedApi.get_ticker_by_symbol() | fetch_ticker() / fetch_tickers() |
| L2 book | UnauthenticatedApi.get_l2_order_book() | fetch_l2_order_book() |
| L3 book | UnauthenticatedApi.get_l3_order_book() | fetch_l3_order_book() |
| New order | TradingApi.create_order() | create_order() |
| Cancel order | TradingApi.delete_order() | cancel_order() |
| Cancel all | TradingApi.delete_all_orders() | cancel_all_orders() |
| Orders | TradingApi.get_orders() | fetch_open_orders() / fetch_closed_orders() |
| Fills | TradingApi.get_fills() | fetch_my_trades() |
| Fees | TradingApi.get_fees() | fetch_trading_fees() |
| Balance | PaymentsApi.get_accounts() | fetch_balance() |
| Deposits | PaymentsApi.get_deposits() | fetch_deposits() |
| Streams | not supported | watch_* on ccxt.pro.blockchaincom |
| Anything not listed | the raw endpoint | the same endpoint as an implicit method |
FAQ
Does Blockchain.com have an official API client? Yes, blockchain/lib-exchange-client — thirteen clients autogenerated from the OpenAPI specification. The repository was archived on 22 January 2026 and is read-only, and the generated clients cover REST only.
Does CCXT support Blockchain.com WebSockets?
Yes — six watch* methods via ccxt.pro.blockchaincom: watch_ticker, watch_trades, watch_order_book, watch_ohlcv, watch_orders and watch_balance. Socket authentication, reconnect and re-subscribe are handled by the library.
How does Blockchain.com authenticate API requests?
With a single X-API-Token header carrying an API key created in your exchange account settings; the key must be confirmed by email before it works. There is no request signing, so the main integration cost is elsewhere — pagination, error handling, rate limiting and the socket.
Is there a Blockchain.com Exchange testnet? Blockchain.com's published API documentation does not describe a sandbox or testnet environment. Test with small live orders on a low-balance account.
Can I still call Blockchain.com-specific endpoints through CCXT? Yes — all 24 of them, as implicit methods, including the withdrawal whitelist routes, with authentication and rate limiting applied.
Is CCXT free? Yes. MIT-licensed, including the WebSocket support.
Next steps
- Install CCXT in your language
- Manual — the unified API, structures and conventions
- blockchaincom unified API reference
- blockchaincom implicit API — every raw endpoint
- CCXT Pro manual — WebSocket methods
- More comparisons
CCXT vs the Bitso API
Bitso's only maintained connector is a Java REST wrapper. Compare it with CCXT on languages, coverage, signing, rate limits, sandbox and raw endpoint access.
CCXT vs the BloFin API and official SDK
BloFin's official SDK is Python-only and installs from source. Compared with CCXT on languages, streaming, demo trading, rate limits and raw endpoints.