Bybit SDK
Unofficial Rust SDK for the Bybit exchange API.
Disclaimer
Stability & Versioning Policy
No stability or backward-compatibility guarantees are provided.
Every version change must be treated as a breaking change, including minor and patch releases.
Users are strongly advised to pin an exact version, for example:
patisson-bybit-sdk = "=0.3.0"
Maintenance Policy
This package is developed only in the author's free time.
Releases are best-effort and not planned in advance.
The scope of the package is intentionally limited to the most commonly used functionality.
Features
- REST API support
- Websocket API support
- Only async clients
- All categories: Spot, Linear, Inverse, Option
TLS
REST and WebSocket share one TLS backend, selected with a Cargo feature (enable exactly one):
rustls(default): rustls with aws-lc-rs and the operating system's root certificates; no OpenSSL needed.native-tls: the platform TLS library (OpenSSL on Linux, Schannel on Windows, Security.framework on macOS).
= { = "=0.3.0", = false, = ["native-tls"] }
Examples
See examples/ for runnable programs.
Get tickers
use ;
let cfg = for_env;
let client = new?;
// If category=option, symbol or baseCoin must be passed.
let params = new.with_symbol;
let response = client.get_tickers.await?;
println!;
Private endpoints, timeouts and rate limiting
use Duration;
use ;
let cfg = for_env
.credentials
.recv_window // Milliseconds.
.timeout
.rate_limiter;
let client = new?;
Calling a private endpoint on a client without credentials returns
Error::MissingCredentials.
REST requests honour the HTTP(S)_PROXY environment variables; set a proxy
explicitly with Config::proxy("http://127.0.0.1:8080").
Clock synchronization
Bybit rejects signed requests whose timestamp is more than recv_window behind
(or 1 s ahead of) its own clock (retCode 10002). Client::sync_time measures
the offset to the server clock and applies it to every signed request; call it
after creating the client and periodically in long-running programs. When a
signed request is rejected with 10002 anyway, the client re-synchronizes and
retries it once (Config::resync_time_on_timestamp_error, enabled by default).
Client::clock() shares the offset with WebSocket streams (see below).
Error has helpers for common decisions: api_code() (compare with the
constants in bybit::ret_code), is_retryable(), is_rate_limited(),
is_timestamp_error() and is_not_modified().
let offset_ms = client.sync_time.await?;
Subscribe to public channel 'ticker'
Topics subscribed with Handle::subscribe are restored automatically after
every reconnect.
use ;
let config = public;
let = new;
handle.subscribe.await?;
handle.connect.await?;
while let Some = events.recv.await
Subscribe to private channels
With credentials the driver sends auth on every (re)connect and subscribes
once it succeeded. Pass the REST client's clock so that auth uses the server
time measured by sync_time.
use ;
let config = private
.credentials
.server_clock;
let = new;
handle
.subscribe
.await?;
handle.connect.await?;
while let Some = events.recv.await
Order entry over WebSocket
ws::TradeClient places, amends and cancels orders over the order entry
stream (/v5/trade), matching replies to requests. It is not available on
demo trading (use testnet or mainnet). A reply only means Bybit accepted the
request; the order stream confirms the status. Requests in flight when the
connection drops fail with ws::Error::ConnectionLost and are not resent.
Not yet tested on a live account.
TradeClientis covered by tests against a local server that speaks the order entry protocol, but it has not been run against Bybit itself (mainnet or testnet). Try it with small, far-from-market post-only orders first (examples/ws-trade.rs) and please report any problem.
use ;
use dec;
let config = trade?
.credentials
.server_clock;
let = new?;
trade.connect.await?;
// Requests are accepted after ws::Event::Authenticated.
let mut order = new;
order.price = Some;
let reply = trade.place_order.await?;
println!;
Local account state
AccountState keeps open orders, positions and wallet balances from REST
snapshots and the private stream, ignoring stale updates. Reload the snapshots
after every authentication and after Event::Lagged:
use ;
let scope = new.linear.wallet;
let mut state = new;
while let Some = events.recv.await
See examples/account-state.rs for a complete program.
Migration from 0.2
0.3.0 has breaking changes:
- TLS features. REST and WebSocket now share one TLS backend.
rustlsis the default; 0.2 built WebSocket with native-tls. To keep the platform TLS library, usedefault-features = false, features = ["native-tls"]. Environment. Pick URLs withhttp::Config::for_env(env),ws::Config::public(env, category)andws::Config::private(env)instead ofBASE_URL_*+Path. TheBASE_URL_*constants are deprecated.- WebSocket subscriptions and auth. Use
Handle::subscribe/Handle::unsubscribeandws::Config::credentials: the driver authenticates and restores the subscriptions on every reconnect, so there is no need to resend them afterEvent::Connected.ws::Commandandws::Eventhave new variants (Authenticated,AuthFailed,SubscribeFailed,Lagged); add a_arm to exhaustive matches. - String parameters.
with_*setters andnew(..)constructors takeimpl Into<String>: pass"BTCUSDT"directly;"BTCUSDT".into()no longer infers a type. - Response models aligned with the live API.
get_mark_price_kline,get_index_price_klineandget_premium_index_price_klinereturnPriceKLine(rows of five values);Position::position_statusand the withdrawal fees and limits ofCoinChainareOption;DepositCoinConfig::block_confirm_numberis a number;OptionInstrumentsInfofollows the option instruments response. - Deprecated: the spot leveraged token methods (Bybit shut that API down on 2025-07-04).
New: ws::TradeClient (order entry over WebSocket), AccountState::load /
reload with AccountScope, automatic retry of timestamp errors (10002)
after sync_time, Error helpers and the ret_code constants, and
documentation for every public item.
License
This project is licensed under the MIT license.