Skip to main content
This guide walks you through installing CryptoClients.Net, making your first REST request, and subscribing to a live WebSocket stream.

Prerequisites

  • .NET 8.0 or later (or .NET Standard 2.0+ for older targets)
  • A .NET project (console, web API, or otherwise)
1

Install the package

Add CryptoClients.Net to your project via the .NET CLI:
dotnet add package CryptoClients.Net
Or using the Package Manager Console in Visual Studio:
Install-Package CryptoClients.Net
2

Create a client

There are two main entry points — ExchangeRestClient for REST APIs and ExchangeSocketClient for WebSocket streams. You can construct them directly or register them via dependency injection.
using CryptoClients.Net;

IExchangeRestClient restClient = new ExchangeRestClient();
IExchangeSocketClient socketClient = new ExchangeSocketClient();
Use dependency injection in ASP.NET Core applications so the framework manages client lifetimes. Use direct construction in console apps or scripts.
3

Make your first REST request

Request a spot ticker from a single exchange using the unified shared interface:
using CryptoClients.Net;
using CryptoExchange.Net.SharedApis;

var client = new ExchangeRestClient();
var symbol = new SharedSymbol(TradingMode.Spot, "ETH", "USDT");

var result = await client.GetSpotTickerAsync(Exchange.Binance, new GetTickerRequest(symbol));

if (result.Success)
    Console.WriteLine($"Binance ETH/USDT: {result.Data.LastPrice}");
else
    Console.WriteLine($"Error: {result.Error}");
The SharedSymbol type lets you specify a trading pair in a normalized format that works across all exchanges — no need to know each exchange’s symbol convention.
4

Request data from multiple exchanges at once

One of the key features of CryptoClients.Net is the ability to query multiple exchanges with a single call. All requests run in parallel and results are returned together:
using CryptoClients.Net;
using CryptoExchange.Net.SharedApis;

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}");
}
You can also use GetSpotTickerAsyncEnumerable to process results as they arrive instead of waiting for all exchanges to respond:
await foreach (var result in client.GetSpotTickerAsyncEnumerable(new GetTickerRequest(symbol)))
    Console.WriteLine($"{result.Exchange}: {result.Data?.LastPrice}");
To query all supported exchanges, omit the exchange list entirely — the client will send requests to every exchange that supports the requested endpoint.
5

Subscribe to WebSocket streams

Use ExchangeSocketClient to subscribe to live data. Subscriptions are automatically managed — connections are kept alive and reconnected if they drop.
using CryptoClients.Net;
using CryptoExchange.Net.SharedApis;

var socketClient = new ExchangeSocketClient();
var symbol = new SharedSymbol(TradingMode.Spot, "ETH", "USDT");

var subscriptions = await socketClient.SubscribeToTickerUpdatesAsync(
    new SubscribeTickerRequest(symbol),
    data => Console.WriteLine($"{data.Exchange} {data.Data.Symbol}: {data.Data.LastPrice}"),
    [Exchange.Binance, Exchange.OKX]);

foreach (var sub in subscriptions)
{
    if (!sub.Success)
        Console.WriteLine($"{sub.Exchange} subscription failed: {sub.Error}");
}

Console.ReadLine(); // Keep the process alive to receive updates
This subscribes to ticker updates on Binance and OKX simultaneously. The same callback receives updates from both exchanges, each tagged with the exchange name in data.Exchange.

Using dependency injection in ASP.NET Core

The AddCryptoClients extension method registers all clients with the DI container. You can configure options inline or load them from appsettings.json:
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddCryptoClients(options =>
{
    options.OutputOriginalData = true;
});

var app = builder.Build();
app.Run();
Once registered, inject IExchangeRestClient or IExchangeSocketClient into any service:
app.MapGet("ticker/{exchange}/{base}/{quote}",
    async (IExchangeRestClient client, string exchange, string @base, string quote) =>
    {
        var spotClient = client.GetSpotTickerClient(exchange);
        if (spotClient == null)
            return Results.Problem("Exchange not found");

        var result = await spotClient.GetSpotTickerAsync(
            new GetTickerRequest(new SharedSymbol(TradingMode.Spot, @base, quote)));

        return result.Success
            ? Results.Ok(result.Data.LastPrice)
            : Results.Problem(result.Error!.ToString());
    });

Exchange-specific clients

When you need access to exchange-specific endpoints that aren’t part of the shared interface, use the typed clients exposed directly on ExchangeRestClient:
var client = new ExchangeRestClient();

// Exchange-specific APIs are accessible as typed properties
var binanceTicker = await client.Binance.SpotApi.ExchangeData.GetTickerAsync("ETHUSDT");
var kucoinTicker = await client.Kucoin.SpotApi.ExchangeData.GetTickerAsync("ETH-USDT");
You can also construct exchange clients directly if you only need one exchange:
using Binance.Net.Clients;
using Kucoin.Net.Clients;

var binanceClient = new BinanceRestClient();
var kucoinSocketClient = new KucoinSocketClient();

Next steps

Installation

See all installation options including GitHub Packages and framework compatibility

REST client

Learn how the ExchangeRestClient works in depth

Shared interfaces

Write exchange-agnostic logic using common interfaces

Configuration

Configure credentials, rate limiting, environments, and more

Build docs developers (and LLMs) love