CryptoClients.Net provides unified access to cryptocurrency trading APIs in C#.
It combines:
- direct access to exchange-specific REST and WebSocket clients
- shared cross-exchange interfaces from CryptoExchange.Net
- dynamic multi-exchange requests and subscriptions
- client-side helpers such as rate limiting, order books, trackers, and user client management
The library currently supports 28 exchanges and additional platform integrations such as CoinGecko and Polymarket.
- Full access to exchange-specific APIs through
ExchangeRestClientandExchangeSocketClient - Shared exchange-agnostic interfaces for spot and futures functionality
- Request data from a single exchange or many exchanges in one call
- Subscribe to one or many data streams on multiple exchanges through a single API
- Strongly typed models and enum mappings
- Automatic WebSocket (re)connection management
- Client-side rate limiting
- Client-side order book support, including
(I)CrossExchangeBookfor aggregated books across exchanges - Multi-user client management
- Support for multiple API environments
- Dynamic credential management
Performance is a core focus. For a benchmark comparing CryptoClients.Net performance to CCXT, see docs/crypto-clients-net-benchmark.md.
var client = new ExchangeRestClient();
var symbol = new SharedSymbol(TradingMode.Spot, "ETH", "USDT");
var results = await client.GetSpotTickerAsync(
new GetTickerRequest(symbol),
["Binance", "Bybit", "HyperLiquid", "OKX"]);
foreach (var result in results)
{
if (!result.Success)
Console.WriteLine($"{result.Exchange} error: {result.Error}");
else
Console.WriteLine($"{result.Exchange} price: {result.Data.LastPrice}");
}
For more examples, see the documentation or the full demo application:
https://github.com/JKorf/CryptoManager.Net
dotnet add package CryptoClients.Net
CryptoClients.Net is also available on GitHub Packages.
Add the following NuGet source:
https://nuget.pkg.github.com/JKorf/index.json
Latest releases are available here:
https://github.com/JKorf/CryptoClients.Net/releases
There are two main entry points:
ExchangeRestClientfor REST APIsExchangeSocketClientfor WebSocket APIs
You can also use exchange-specific clients directly, such as BinanceRestClient or KucoinSocketClient.
// Load options from configuration
builder.Services.AddCryptoClients(builder.Configuration.GetSection("CryptoClients"));
// Or configure in code
builder.Services.AddCryptoClients(options =>
{
options.OutputOriginalData = true;
});
// Inject later
public class TradingBot
{
public TradingBot(IExchangeRestClient restClient, IExchangeSocketClient socketClient)
{
}
}
IExchangeRestClient restClient = new ExchangeRestClient();
IExchangeSocketClient socketClient = new ExchangeSocketClient();
IBinanceRestClient binanceRestClient = new BinanceRestClient();
IKucoinSocketClient kucoinSocketClient = new KucoinSocketClient();
Clients can be configured globally, per exchange, or both.
builder.Services.AddCryptoClients(globalOptions =>
{
globalOptions.OutputOriginalData = true;
globalOptions.ApiCredentials = new ExchangeCredentials
{
Binance = new BinanceCredentials("BinanceKey", "BinanceSecret"),
Kucoin = new KucoinCredentials("KucoinKey", "KucoinSecret", "KucoinPassphrase"),
OKX = new OKXCredentials("OKXKey", "OKXSecret", "OKXPassphrase")
};
},
bybitRestOptions: bybitOptions =>
{
bybitOptions.Environment = Bybit.Net.BybitEnvironment.Eu;
bybitOptions.ApiCredentials = new BybitCredentials("BybitKey", "BybitSecret");
});
Environment selection can also be configured through GlobalExchangeOptions.ApiEnvironments.
More configuration details are available in the documentation:
https://cryptoexchange.jkorf.dev/crypto-clients/options
Use the exchange libraries directly when full exchange-specific functionality is needed.
var kucoinClient = new KucoinRestClient();
var binanceClient = new BinanceRestClient();
var binanceTicker = await binanceClient.SpotApi.ExchangeData.GetTickerAsync("ETHUSDT");
var kucoinTicker = await kucoinClient.SpotApi.ExchangeData.GetTickerAsync("ETH-USDT");
Use ExchangeRestClient or ExchangeSocketClient as a single entry point.
var client = new ExchangeRestClient();
var binanceTicker = await client.Binance.SpotApi.ExchangeData.GetTickerAsync("ETHUSDT");
var kucoinTicker = await client.Kucoin.SpotApi.ExchangeData.GetTickerAsync("ETH-USDT");
Use shared interfaces for exchange-agnostic logic.
async Task<HttpResult<SharedSpotTicker>> GetTickerAsync(ISpotTickerRestClient client, SharedSymbol symbol)
=> await client.GetSpotTickerAsync(new GetTickerRequest(symbol));
var client = new ExchangeRestClient();
var symbol = new SharedSymbol(TradingMode.Spot, "ETH", "USDT");
var binanceResult = await GetTickerAsync(client.Binance.SpotApi.SharedClient, symbol);
var kucoinResult = await GetTickerAsync(client.Kucoin.SpotApi.SharedClient, symbol);
Request the same data from multiple exchanges in one call.
var client = new ExchangeRestClient();
var symbol = new SharedSymbol(TradingMode.Spot, "ETH", "USDT");
var tickers = await client.GetSpotTickerAsync(
new GetTickerRequest(symbol),
[Exchange.Binance, Exchange.Kucoin, Exchange.OKX]);
The socket client also supports single-exchange and multi-exchange subscriptions.
var socketClient = new ExchangeSocketClient();
var symbol = new SharedSymbol(TradingMode.Spot, "ETH", "USDT");
var subscriptions = await socketClient.SubscribeToTickerUpdatesAsync(
new SubscribeTickerRequest(symbol),
data => Console.WriteLine($"{data.Data.Symbol} {data.Data.LastPrice}"),
[Exchange.Binance, Exchange.OKX]);
Use IExchangeOrderBookFactory.CreateCrossExchange to create an (I)CrossExchangeBook which aggregates locally synced order books for the same symbol across multiple exchanges into a single book.
var symbol = new SharedSymbol(TradingMode.Spot, "ETH", "USDT");
var book = orderBookFactory.CreateCrossExchange(
symbol,
exchanges: [Exchange.Binance, Exchange.Bybit, Exchange.OKX]);
await book.StartAsync();
Use ExchangeUserClientProvider when working with multiple users and isolated client instances.
var provider = new ExchangeUserClientProvider();
var user1Credentials = new ExchangeCredentials
{
Binance = new BinanceCredentials("key", "secret")
};
var user2Credentials = new ExchangeCredentials
{
Binance = new BinanceCredentials("key", "secret")
};
var restClientUser1 = provider.GetRestClient("user-1", user1Credentials);
var restClientUser2 = provider.GetRestClient("user-2", user2Credentials);
var socketClientUser1 = provider.GetSocketClient("user-1");
The package targets:
.NET Standard 2.0.NET Standard 2.1.NET 8.0.NET 9.0.NET 10.0
Compatibility includes:
| .NET implementation | Version support |
|---|---|
| .NET Core | 2.0 and higher |
| .NET Framework | 4.6.1 and higher |
| Mono | 5.4 and higher |
| Xamarin.iOS | 10.14 and higher |
| Xamarin.Android | 8.0 and higher |
| UWP | 10.0.16299 and higher |
| Unity | 2018.1 and higher |
Binance, BingX, Bitfinex, Bitget, BitMart, BitMEX, Bitstamp, BloFin, Bybit, Coinbase, CoinEx, CoinW, Crypto.com, DeepCoin, GateIo, HTX, Kraken, Kucoin, Mexc, OKX, Toobit, Upbit, Weex, WhiteBit, XT
Aster, HyperLiquid
CoinGecko, Polymarket
| Exchange | Type | Referral Link | Referral Fee Discount | |
|---|---|---|---|---|
| Aster | DEX | Link | 4% | |
| Binance | CEX | Link | 20% | |
| BingX | CEX | Link | 20% | |
| Bitfinex | CEX | - | - | |
| Bitget | CEX | Link | 20% | |
| BitMart | CEX | Link | 30% | |
| BitMEX | CEX | Link | 30% | |
| Bitstamp | CEX | - | - | |
| BloFin | CEX | - | - | |
| Bybit | CEX | Link | - | |
| Coinbase | CEX | Link | - | |
| CoinEx | CEX | Link | 20% | |
| CoinW | CEX | Link | - | |
| CoinGecko | - | - | - | |
| Crypto.com | CEX | Link | - | |
| DeepCoin | CEX | Link | - | |
| Gate.io | CEX | Link | 20% | |
| HTX | CEX | Link | 30% | |
| HyperLiquid | DEX | Link | 4% | |
| Kraken | CEX | - | - | |
| Kucoin | CEX | Link | - | |
| Mexc | CEX | - | - | |
| OKX | CEX | Link | 20% | |
| Toobit | CEX | Link | - | |
| Upbit | CEX | - | - | |
| Weex | CEX | - | - | |
| WhiteBit | CEX | Link | - | |
| XT | CEX | Link | 25% |
Use:
Exchanges.Allfor supported exchangesPlatforms.Allfor supported exchanges and additional platforms
The following minimal API exposes a cross-exchange ticker endpoint:
using CryptoClients.Net.Interfaces;
using CryptoExchange.Net.Objects;
using CryptoExchange.Net.SharedApis;
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCryptoClients();
var app = builder.Build();
app.MapGet("Ticker/{exchange}/{baseAsset}/{quoteAsset}",
async ([FromServices] IExchangeRestClient client, string exchange, string baseAsset, string quoteAsset) =>
{
var spotClient = client.GetSpotTickerClient(exchange)!;
var result = await spotClient.GetSpotTickerAsync(
new GetTickerRequest(new SharedSymbol(TradingMode.Spot, baseAsset, quoteAsset)));
return result.Data;
});
app.Run();
Example requests:
GET /Ticker/Kraken/ETH/BTCGET /Ticker/Kucoin/BTC/USDT
- Documentation: https://cryptoexchange.jkorf.dev/crypto-clients
- Benchmark results: docs/crypto-clients-net-benchmark.md
- Configuration options: https://cryptoexchange.jkorf.dev/crypto-clients/options
- Example configuration: https://github.com/JKorf/CryptoClients.Net/tree/main/Examples/example-config.json
- Examples: https://github.com/JKorf/CryptoClients.Net/tree/main/Examples
- Base library examples: https://github.com/JKorf/CryptoExchange.Net/tree/master/Examples
- Demo application: https://github.com/JKorf/CryptoManager.Net
CryptoClients.Net includes AI-oriented documentation and examples for code generation tools:
| File | Purpose |
|---|---|
AGENTS.md |
Assistant skill with core CryptoClients.Net patterns, pitfalls, and examples |
llms.txt |
Short LLM index with links to docs, examples, and critical usage rules |
llms-full.txt |
Detailed LLM context with aggregate REST, WebSocket, direct-client, credential, order book, and tracker guidance |
docs/ai-api-map.md |
Table-style intent-to-method map for aggregate/shared APIs, direct exchange access, sockets, credentials, order books, and trackers |
Examples/ai-friendly |
Compilable single-file examples for common aggregate REST, WebSocket, direct-client, order book, tracker, and error handling workflows |
See cryptoexchange-skills-hub for installable skills.
Join the Discord server for questions and discussion:
https://discord.gg/MSpeEtSY8t
BTC: bc1q277a5n54s2l2mzlu778ef7lpkwhjhyvghuv8qf
ETH: 0xcb1b63aCF9fef2755eBf4a0506250074496Ad5b7
USDT (TRX): TKigKeJPXZYyMVDgMyXxMf17MWYia92Rjd
https://github.com/sponsors/JKorf
-
Version 5.1.0 - 10 Jul 2026
- Updated library versions
-
Version 5.0.2 - 04 Jul 2026
- Updated Kucoin library version to fix issue in websocket user subscriptions
- Updated Lighter library version to fix issue with signing libraries not getting copied correctly
-
Version 5.0.1 - 03 Jul 2026
- Updated client library versions, fixing signing issues in Binance and Mexc implementation
- Fixed Lighter implementation missing library references, added Lighter IFundingRateRestClient implementation
-
Version 5.0.0 - 30 Jun 2026
- Updated client library versions
- Added support for Lighter DEX with JKorf.Lighter.Net v1.0.0
- Result types:
- ExchangeWebResult/ExchangeResult types are replaced by HttpResult and WebSocketResult with the same logic
- WebSocketResult now returns additional info for websocket operations
- Updated result types to record type
- Removed implicit result type conversion to bool,
if (result)no longer works, instead useif (result.Success) - Fixed result object nullability hinting, for example Data might be null if Success isn't checked for true
- Clients:
- Added ToString overrides on base API types
- Added Exchange property on BaseApiClient
- Added ApiCredentials property on Api clients
- Updated ILogger source from client name to topic specific client name
- Removed logging from client creation
- Fixed issue in SocketApiClient.GetSocketConnection causing requests to always wait the full max 10 seconds when there was a reconnecting socket
- Shared APIs:
- Added missing dedicated option types
- Added Discover method on ISharedClient interface, returning info on supported capabilities and operations
- Added ResetStaticExchangeParameters method on ExchangeParameters
- Added Status property to SharedWithdrawal model
- Added TradingModes property to SharedBalance model
- Updated Shared ExchangeParameters parameter names to be case insensitive
- Updated code comments
- Removed TradingMode from the response model, only maintained on models where it makes sense
- Removed IListenKey support, listen keys now rely on internal management
- Added async streaming on UserDataTracker items with StreamUpdatesAsync
- Added cancellation token support to UserDataTracker starting
- Added SupportedEnvironments property to PlatformInfo
- Added Clear() method on UserClientProvider to clear all cached clients
- Various small performance improvements
- Fixed websocket connection attempts counting towards rate limit even when server could not be reached
- Removed previously deprecated SetApiCredentials method from ExchangeRestClient and ExchangeSocketClient