Skip to main content
The official Rust client is async-first and built on Tokio. The crate is published as ticksupply; rustdoc is hosted on docs.rs.

crates.io

Releases

docs.rs

API reference (rustdoc)

GitHub

Source & changelog

Install

[dependencies]
ticksupply = "0.1"
tokio      = { version = "1", features = ["macros", "rt-multi-thread"] }
Or via the CLI:
cargo add ticksupply
cargo add tokio --features macros,rt-multi-thread

Quick example

use ticksupply::Client;

#[tokio::main]
async fn main() -> ticksupply::Result<()> {
    // Reads TICKSUPPLY_API_KEY from the environment.
    let client = Client::new()?;

    for ex in client.exchanges().list().await? {
        println!("{}: {}", ex.code, ex.display_name);
    }

    let sub = client.subscriptions().create(123).send().await?;
    println!("Subscription: {}", sub.id);
    Ok(())
}

Features

  • Async-first — every call returns a Future; pairs with any Tokio runtime
  • Builder pattern — typed builders for every mutating endpoint with .send().await?
  • Cheap to cloneClient wraps an Arc, shares a connection pool, and is Send + Sync
  • Automatic retries — exponential backoff on transient errors and 5xx responses
  • Auto-pagination.stream() returns a Tokio Stream that walks every page
  • Typed errors — match on Error::NotFound, Error::RateLimited, etc.; every variant carries the request_id from X-Request-Id
  • Configurable transport — override timeout, retry count, base URL, or inject your own reqwest::Client for proxies / telemetry
  • Optional types — Cargo features for chrono (default), time, and rust_decimal
  • Fully documented#![warn(missing_docs)] is enforced; every public item has rustdoc on docs.rs

Configuration

Client::new() reads TICKSUPPLY_API_KEY from the environment. For more control, use the builder:
use std::time::Duration;
use ticksupply::Client;

let client = Client::builder()
    .api_key("key_xxx.secret")
    .timeout(Duration::from_secs(60))
    .max_retries(5)
    .user_agent("my-bot/1.2") // appended to "ticksupply-rust/<version>"
    .build()?;
SettingDefaultBuilder method
API key$TICKSUPPLY_API_KEY (required).api_key(...)
Base URLhttps://api.ticksupply.com/v1.base_url(...)
Timeout30 s.timeout(...)
Max retries3.max_retries(...)
User-Agentticksupply-rust/<version>.user_agent(...)
HTTP clientinternal reqwest::Client.http_client(...)

Wire types

The API uses string-encoded primitives to preserve precision across implementations. The crate exposes them as small wrapper types that hold the raw wire form losslessly and convert on demand:
TypeWire formTyped accessors
Nanosi64 nanoseconds, JSON string.as_i64(); .to_chrono() / .to_time() (under feature)
TimestampRFC 3339 string.as_str(); .to_chrono() / .to_time()Result<...>
Decimaldecimal string.as_str(); .to_f64() (lossy); .to_decimal() (lossless)
Nanos carries market-data timestamps (preserves nanosecond precision — f64 would silently round). Timestamp carries control-plane timestamps (creation times, activity spans) and round-trips any RFC 3339 variant the server sends. Decimal carries amounts where float precision matters (currently BillingUsage::export_gb_total).
use ticksupply::{Nanos, Timestamp, Decimal};

let n = Nanos::from_i64(1_704_067_200_000_000_000);
let dt = n.to_chrono(); // chrono::DateTime<Utc>, with the chrono feature

let t = Timestamp::from("2024-01-01T00:00:00Z");
let dt = t.to_chrono()?;

let d = Decimal::from("12.75");
let f = d.to_f64();              // Some(12.75) — lossy
let d2 = d.to_decimal();         // rust_decimal, with the rust_decimal feature
Request builders that take a timestamp accept anything that implements IntoTimestampi64, &str, String, Nanos, plus chrono::DateTime<Utc> (default feature) or time::OffsetDateTime (under time). So you can pass whatever your call site already uses:
client.exports().create(123, chrono::Utc::now() - chrono::Duration::hours(1), chrono::Utc::now())
    .send().await?;

client.exports().create(123, 1_704_067_200_000_000_000_i64, 1_704_070_800_000_000_000_i64)
    .send().await?;

Cargo features

Optional types are gated behind Cargo features so you only pay for what you use:
FeatureDefaultEffect
chronoyesIntoTimestamp accepts chrono::DateTime<Utc>; Timestamp deserializes into one
timenoSame, but for time::OffsetDateTime
rust_decimalnoDecimal wire values parse losslessly into rust_decimal::Decimal
Disable defaults if you only want raw i64 nanoseconds (Nanos) and string timestamps:
ticksupply = { version = "0.1", default-features = false }
Enable additional features as needed:
ticksupply = { version = "0.1", features = ["time", "rust_decimal"] }

Versioning & releases

The crate follows SemVer. Pin to a minor range ("0.1") to receive bug fixes; major bumps (0.2, 1.0) may include breaking API changes documented in CHANGELOG.md. Every published version has its own rustdoc snapshot at https://docs.rs/ticksupply/<version>.

Requirements

  • Rust 1.75 or newer (edition 2021)
  • A Tokio-compatible async runtime
  • rustls for TLS (no system OpenSSL dependency)
See the Rust examples page for complete usage examples, docs.rs/ticksupply for the rustdoc API reference, and the examples/ directory in the repo for runnable programs.
Last modified on April 26, 2026