CCXT

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.

Bitso is the largest exchange in Mexico and one of the larger venues in Latin America. Its public API is documented at bitso.com/api_info, and Bitso publishes exactly one client library of its own: bitso-java, an official Java wrapper for REST v3.

So the choice is narrower than it looks. If you write Java, you can use Bitso's own wrapper. In any other language you are either hand-rolling HTTP against a signed API or using CCXT. The question that decides it: do you want a Bitso-shaped client in one language, or a venue-shaped-agnostic client in seven?

TL;DR

  • Pick bitso-java if you are on the JVM, Bitso is your only venue, and you want types Bitso themselves defined (BitsoTicker, BitsoOrder, BigDecimal amounts) that track their docs one-for-one.
  • Pick CCXT if you are not on the JVM, or if Bitso is one of several venues. CCXT implements 24 unified capabilities for Bitso and exposes all 40 of its REST endpoints as implicit methods, from TypeScript, JavaScript, Python, PHP, C#/.NET, Go and Java.
  • Neither one streams Bitso. Bitso publishes a WebSocket API with trades, diff-orders and orders channels; CCXT implements no watch* methods for Bitso, and the official Java wrapper's README documents REST only. If you need a live Bitso book, you are writing that socket client yourself either way.

At a glance

CCXTbitso-java (official)
Exchanges covered104 (Bitso is one of them)Bitso only
LanguagesTypeScript, JavaScript, Python, PHP, C#/.NET, Go, Java — one APIJava
Unified market data + trading APIyes — same method names across every exchangeno — Bitso's own request/response shapes
Bitso capabilities implemented24 unified methods, 18 of them fetch*full REST v3 surface
Raw endpoint accessyes — 40 Bitso endpoints as implicit methodsyes, it is the whole product
WebSocketsno watch* methods for Bitsonot documented in the README
Built-in rate limiteryes, on by default (rateLimit 2000 ms)not documented
Unified error typesyes — 41 typed exceptions in one hierarchyBitso error codes
Testnet / sandboxsetSandboxMode(true) switches to Bitso's staging hostenvironment switching added in v4.1.0
Latest release readcontinuousv4.1.0, 11 July 2024
Popularity43.8k GitHub stars · 4.8M PyPI + 494k npm installs/month (one package, every venue)40 GitHub stars
LicenceMITMIT
SupportDiscord, Telegram, GitHub issues — usually same-dayGitHub issues

Figures verified September 2026 against CCXT v4.5.77, the bitsoex/bitso-java repository and its releases page, Bitso's published API documentation, and install counts from npm and PyPI.

The same job, written both ways

Fetch a ticker

import ccxt

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

The CCXT call returns a unified ticker structure — the same keys, types and units you get from Kraken or Binance. The Java wrapper returns Bitso's own objects, which is more literal and less portable.

Place a limit order

import ccxt

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

Note the symbol. Bitso books are btc_mxn; CCXT normalises that to 'BTC/MXN' and maps it back to the venue id for you, so the same strategy code addresses 'BTC/USDT' on the next exchange without a lookup table.

Where the differences actually bite

Six of seven languages have no official option

There is no first-party Bitso client for Python, JavaScript, Go, PHP or C#. The community filled part of the gap — mariorz/python-bitso is MIT-licensed and does cover the WebSocket channels — but it is one person's project, not a vendor commitment. CCXT gives you the same Bitso implementation in all seven of its targets, written once in TypeScript and transpiled:

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

Signing is fiddly enough to be worth not writing

Bitso authenticates with an Authorization: Bitso <key>:<nonce>:<signature> header, where the signature is HMAC-SHA256 over the nonce, the HTTP method, the full request path including the query string, and the JSON body when there is one. Get the concatenation order or the path prefix wrong and you get a 401 with no hint as to which part was wrong. CCXT builds that header in sign() and keeps it correct across every endpoint, including the ones with path parameters like orders/{oid} and order_trades/{oid}.

Rate limits you do not have to model

Bitso's documented limits are 60 requests per minute per IP for public endpoints and 300 requests per minute per account for private ones, with a one-minute lockout when you exceed them and longer blocks for repeat offences. CCXT ships a token-bucket throttler that is on by default, with rateLimit set to 2000 ms for Bitso. You write a loop; the library paces it.

Precision and string math

Bitso quotes MXN pairs where a single tick is a meaningful amount of money. CCXT loads Bitso's market 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/MXN', 0.0012345678)
price = exchange.price_to_precision('BTC/MXN', 1512345.6789)

One error hierarchy

CCXT maps Bitso's error codes onto a typed exception treeInsufficientFunds, InvalidOrder, OrderNotFound, RateLimitExceeded, AuthenticationError, NetworkError and 35 more, all descending from BaseError. You catch ccxt.InsufficientFunds once and it keeps working when you add a second venue, instead of matching on Bitso's 0201 and hoping the payload never changes.

Nothing is hidden — the implicit API

The 24 unified methods are not a ceiling. Every endpoint in Bitso's API is generated as a callable implicit method, with signing, nonce handling, rate limiting and error mapping applied:

# GET /v3/account_status
status = exchange.private_get_account_status()

# GET /v3/ledger/fundings
fundings = exchange.private_get_ledger_fundings()

Bitso-specific endpoints — mx_bank_codes, kyc_documents, funding_destination, the SPEI rails — are reachable without dropping to raw HTTP. Browse them all on the bitso implicit API page.

What bitso-java does better

An honest list:

  • It is Bitso's own code. The wrapper is published by the exchange, so its field names and enums are exactly the ones in Bitso's documentation. When you are debugging against their API reference, there is no translation step.
  • Java-native typed models. BitsoTicker, BitsoOrder.SIDE, BitsoOrder.TYPE and BigDecimal throughout give you compile-time safety over Bitso's actual payloads. CCXT's typed structures are deliberately unified — better for portability, less literal about Bitso.
  • Environment switching for JVM users. Release v4.1.0 (July 2024) added the ability to point the client at environments other than production, which is the shape JVM shops usually want for staging.
  • Smaller dependency for a single-venue Java service. If you trade only Bitso from a Java service, one MIT-licensed wrapper is a smaller install than all of CCXT.

If you are a JVM shop trading Bitso and only Bitso, bitso-java is a defensible choice — and CCXT's Java target is the alternative to weigh it against, not its Python one.

Migrating from the Bitso API to CCXT

What you are doingBitso REST v3CCXT
Symbolsbtc_mxn'BTC/MXN'
MarketsGET /v3/available_booksload_markets()
TickerGET /v3/tickerfetch_ticker()
Order bookGET /v3/order_bookfetch_order_book()
CandlesGET /v3/ohlcfetch_ohlcv()
Public tradesGET /v3/tradesfetch_trades()
New orderPOST /v3/orderscreate_order()
Cancel orderDELETE /v3/orders/{oid}cancel_order()
Cancel allDELETE /v3/orders/allcancel_all_orders()
Open ordersGET /v3/open_ordersfetch_open_orders()
BalanceGET /v3/balancefetch_balance()
My tradesGET /v3/user_tradesfetch_my_trades()
LedgerGET /v3/ledgerfetch_ledger()
Anything not listedthe raw endpointthe same endpoint as an implicit method

FAQ

Does Bitso have an official Python SDK? No. Bitso's GitHub organisation publishes one maintained client library, bitso-java, for the JVM. For Python, JavaScript, Go, PHP or C# your realistic options are CCXT or your own HTTP client; a community Python wrapper, mariorz/python-bitso, also exists under MIT.

Does CCXT support Bitso WebSockets? No. CCXT implements zero watch* methods for Bitso, so streaming is not available through CCXT Pro for this venue. Bitso does publish a WebSocket API with trades, diff-orders and orders channels — if you need it, you connect to it directly. Everything else in this comparison still applies to the REST side.

Can I test against Bitso without real money? CCXT wires setSandboxMode(true) to Bitso's staging host, and Bitso separately documents a sandbox server funded with Bitcoin and Ethereum testnet coins. Verify which environment your API keys were issued for before you rely on it.

Can I still call Bitso-specific endpoints through CCXT? Yes — all 40 of them, as implicit methods, with the Authorization: Bitso header, nonce and rate limiting applied.

Is CCXT free? Yes. MIT-licensed, including the WebSocket support for the exchanges that have it.

Next steps

On this page