Skip to content

Latest commit

 

History

4 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Bitculator Data API — Rust SDK

bitculator.com · API documentation · Get an API key crates.io — bitculator · docs.rs · GitHub

The official Rust SDK for the Bitculator Data API. Blocking reqwest + serde, generic typed responses, Rust 2021.

Keep your API key server-side. It is a Bearer token with the data-api ability and is not meant for client-side embedding.

Install

[dependencies]
bitculator = "1"
serde_json = "1" # for the generic Value type used below

Quick start

use bitculator::{Client, Params};
use serde_json::Value;

fn main() -> Result<(), bitculator::Error> {
    let client = Client::new(std::env::var("BITCULATOR_API_KEY").unwrap());

    // Single resource — the { "data": ... } envelope is unwrapped, then decoded
    // into whatever type you ask for (here, a generic JSON Value).
    let bitcoin: Value = client.coins().get("bitcoin", Params::new())?;
    println!("{}", bitcoin["price"]); // "63520.780763913"

    // ...or straight into your own struct.
    #[derive(serde::Deserialize)]
    struct Coin { symbol: String, price: String }
    let btc: Coin = client.coins().get("bitcoin", Params::new())?;
    println!("{} {}", btc.symbol, btc.price);
    Ok(())
}

Prices are decimal strings

Prices, rates, and supplies come back as strings (e.g. "63520.780763913") to preserve full precision. Decode them into a String (or a big-decimal type) — never an f64, which silently loses precision.

Parameters

Query parameters are built fluently; keys mirror the API's names (snake_case):

let params = Params::new()
    .set("per_page", 50)
    .set("sort", "-marketcap")
    .set("ids", vec!["bitcoin", "ethereum"]); // slices become CSV

Pagination

Paginated methods return Page<T>. Read one page, or auto-paginate:

// One page at a time.
let mut page: Page<Value> = client.exchanges().list(Params::new().set("per_page", 100))?;
loop {
    for exchange in &page.data { /* ... */ }
    match page.next_page()? {
        Some(next) => page = next,
        None => break,
    }
}

// Or auto-paginate across every page (each item is a Result).
let page: Page<Value> = client.coins().list(Params::new().set("sort", "-marketcap"))?;
for item in page.auto_paging() {
    let coin = item?;
    println!("{}", coin["symbol"]);
}

Errors

Everything returns Result<T, bitculator::Error>. HTTP failures are Error::Api(ApiError) carrying the { error: { code, message, details } } envelope.

match client.coins().list::<Value>(Params::new().set("per_page", 9999)) {
    Ok(page) => { /* ... */ }
    Err(bitculator::Error::Api(e)) if e.is_validation() => println!("{:?} {:?}", e.code, e.details),
    Err(bitculator::Error::Api(e)) if e.is_rate_limited() => println!("retry after {:?}", e.retry_after),
    Err(e) => eprintln!("{e}"),
}

ApiError predicates: is_auth (401) · is_permission (403) · is_not_found (404) · is_validation (422) · is_rate_limited (429) · is_server (5xx). Transport failures are Error::Timeout and Error::Connection.

Quota

Every response carries X-Quota-* headers, surfaced on the client after each call:

client.coins().list::<Value>(Params::new())?;
let q = client.quota(); // Option<Quota> { limit, remaining, reset, raw }

Configuration

let client = bitculator::Client::builder("your-api-key")
    .base_url("https://bitculator.com")           // default
    .timeout(std::time::Duration::from_secs(30))  // default
    .max_retries(2)                               // auto-retry 429/5xx/network; 0 to disable
    .build();

Using from async code

The client is blocking. Inside an async runtime (tokio, async-std), reqwest's blocking client panics if called directly — hand the call to a blocking thread instead:

let client = bitculator::Client::new(api_key); // Clone is cheap; move a clone in
let btc: serde_json::Value = tokio::task::spawn_blocking(move || {
    client.coins().get("bitcoin", bitculator::Params::new())
})
.await??;

(With async-std, use async_std::task::spawn_blocking the same way.)

Resources

coins · prices · markets · exchanges · wallets · global_market · sentiment · indicators · liquidations · conversion · calculators · editorial · alarms · webhooks · meta

Full endpoint reference: https://bitculator.com/en/documentation/api/v1.

License

MIT