Quickstart
Initialize the Rust SDK and capture your first attributed LLM cost inside a Tokio async application.
Initialize dexcost, start a task, record a call, and end the task — that is all it takes to land a fully attributed cost record.
Initialize
Call dexcost::init once at application startup with a Config value, then call dexcost::close on shutdown to stop the background pusher:
use dexcost::{Config, init, close};
#[tokio::main]
async fn main() {
init(Config {
api_key: Some("dx_live_your_key_here".into()), // or set DEXCOST_API_KEY env var
..Config::default()
}).unwrap();
// ... rest of your application
close();
}init is safe to call multiple times — only the first call takes effect. Omit api_key (or leave it None) to run in local-only mode, where events are written to the on-disk SQLite buffer but not pushed to the Control Layer.
Your first tracked call
Start a task with start_task, record an LLM call, then end the task:
use dexcost::{Config, TaskOptions, TaskStatus, init, start_task, flush, close};
use rust_decimal::Decimal;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
init(Config::default())?;
// Start a task with customer and project attribution.
let mut task = start_task(
"resolve_ticket",
TaskOptions {
customer_id: Some("acme-corp".into()),
project_id: Some("support".into()),
..Default::default()
},
)
.await?;
// Record an LLM call — cost is auto-computed from bundled pricing data.
task.record_llm_call(
"openai", // provider
"gpt-4o", // model
1_000, // input tokens
500, // output tokens
None, // cost_usd: None → auto-priced
None, // cached_tokens
Some(250), // latency_ms
)
.await?;
// Record a non-LLM service cost with exact-precision Decimal.
task.record_cost(
"google_maps",
Decimal::new(5, 3), // $0.005
None,
None,
)
.await?;
// End the task — aggregates LLM + external costs into total_cost_usd.
task.end(TaskStatus::Success).await?;
println!("Total cost: {} USD", task.task().total_cost_usd);
flush().await?;
close();
Ok(())
}start_task returns a TrackedTask. record_llm_call looks up the model in the bundled pricing engine and records the computed cost; pass a non-zero cost_usd to override auto-pricing with an exact value. task.end writes the final task status and timestamps to the local buffer. flush pushes any buffered events immediately (a no-op when no API key is configured).
Run it locally
Pass environment: Some("development".into()) to Config to enable dev mode. In dev mode, every recorded event is printed to stdout and no data is sent to the cloud — useful for local development and debugging:
use dexcost::{Config, TaskOptions, TaskStatus, init, start_task, close};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
init(Config {
environment: Some("development".into()),
..Config::default()
})?;
let mut task = start_task(
"resolve_ticket",
TaskOptions {
customer_id: Some("acme-corp".into()),
..Default::default()
},
)
.await?;
task.record_llm_call("openai", "gpt-4o", 1_000, 500, None, None, None)
.await?;
task.end(TaskStatus::Success).await?;
close();
Ok(())
}You can also set the DEXCOST_ENV=development environment variable instead of passing the field to Config.
Next steps
- Instrumentation — wrapper client usage for
TrackedOpenAI,TrackedAnthropic, andTrackedGemini; explicit recording withrecord_llm_call; retry tracking; and HTTP cost capture. - Configuration — all
Configfields, environment variables, buffer location, flush tuning, and privacy options.