---
title: "Rust SDK"
url: "https://bicho.fyi/docs/rust"
description: "Install the Bicho Rust crate to report errors from Tokio services and Tauri applications. Configure credentials, await delivery, and handle retries safely."
---

The `bicho` crate reports Rust errors and messages over OTLP/HTTP JSON. It requires Rust 1.89+ and a Tokio runtime for sending. Capture is explicit; it does not install panic hooks or automatically collect tracing spans, logs, or user identity.

## Install and configure

```
cargo add bicho
```

Use `otlp.endpoint` and `otlp.headers['X-Bicho-Key']` from [project registration](/docs/). Inside your application’s async Tokio code:

```
use bicho::{Client, Config};

let tracker = Client::new(
    Config::new("https://your-bicho-worker.example/v1/logs", "YOUR_PUBLIC_KEY")
        .service_name("my-app/rust")
        .environment("production")
        .release(env!("CARGO_PKG_VERSION")),
)?;

if let Err(delivery) = tracker.capture_message("Bicho setup check").await {
    eprintln!("Bicho delivery failed: {delivery}");
}
```

The example assumes an enclosing async function that can propagate client-configuration errors. Use your application’s Tokio runtime; the SDK does not start one. `Client` is cloneable and shareable across async tasks. Clones reuse the HTTP connection pool, while captured data belongs to each event rather than a global scope.

For a secret-enabled backend project, add `.secret("YOUR_INGEST_SECRET")` to the configuration using the generated `X-Bicho-Secret` value from secure application configuration. Never embed an admin token. Distributed desktop applications cannot keep an embedded ingest secret confidential; use public-key-only projects there.

The endpoint must end at the exact `/v1/logs` path. HTTPS is required except on loopback for local testing; URL credentials, query strings, fragments, and redirects are not supported.

## Capture errors and context

`capture_error(&error).await` accepts a Rust `std::error::Error` and records its type name, display message, and up to eight source messages. For trait objects, the recorded type can be the trait rather than the concrete error. Handle delivery failures separately so they do not replace the application’s original error.

For explicit exception types, tags, contexts, severity, or stack text, build an event:

```
use bicho::Event;

let event = Event::exception("SettingsError", "Could not load settings")
    .with_tag("operation", "load_settings");
let uid = tracker.send(&event).await?;
```

Rust errors do not generally carry a backtrace. Attach one captured at the failure site with `.with_stacktrace(...)` when available. The SDK does not invent a stack, perform native symbolication, or attach source-map debug IDs.

## Tauri applications

Create a client during setup, register it with `app.manage(tracker)`, and use `tauri::State<'_, bicho::Client>` in async commands. Tauri uses Tokio, so those commands do not need a separate runtime. Use the [JavaScript SDK](/docs/javascript/) for webview errors.

The [Tauri example](https://github.com/bicho-fyi/bicho-rust/tree/main/examples/tauri) demonstrates managed state and explicit reporting. It does not install panic hooks or intercept every command. Build an owned event before moving it and a cloned client into `tauri::async_runtime::spawn`; the application can exit before a spawned delivery completes.

## Delivery and retries

Awaiting capture waits for delivery or returns an error. There is no background queue or flush method. Await delivery before exiting; abrupt termination can lose in-flight requests.

Each request sends one event. Network failures and HTTP 429/502/503/504 responses allow at most two retries with the same serialized payload and occurrence UID. The overall deadline defaults to 15 seconds, with individual requests limited to five seconds. `Config::timeout(...)` accepts a `Duration` up to 60 seconds. `Retry-After` is honored within that deadline rather than retrying early.

HTTP 200 must contain a valid OTLP JSON acknowledgment. Populated partial success returns `Error::PartialSuccess` and is terminal. If explicitly retrying an ambiguous failure, reuse the same `Event` with `send(&event)`; another capture call creates a new occurrence.

A successful call returns the occurrence UID, not the server’s stored event lookup ID. Read stored evidence through [MCP](/docs/mcp/) or the [API](/docs/api/) to check delivery and captured fields.

## Limits and privacy

Events are limited to 60 KiB serialized. Messages and stack text stop at 16 KiB; contexts are bounded by depth, entry count, and string size. Tags cannot override protocol-owned attributes. Credential-like keys and common credential strings are filtered before sending, but this does not guarantee arbitrary prose or source code contains no private data.

There is no persistent offline queue or delivery guarantee. See [privacy](/docs/privacy/) and the [OTLP guide](/docs/otlp/) for collector behavior.

-   [Rust SDK source and full reference](https://github.com/bicho-fyi/bicho-rust)
-   [Rust package on crates.io](https://crates.io/crates/bicho)