The SDK reads its credentials from the environment and starts on the first call. init() overrides that: it accepts credentials in code, pays setup cost up front, and registers identity getters.
Environment variables
In-code config
init() kwargs override env vars.
init() is optional if you only use bento.track_ai. The first call lazy-initializes from env vars. Call init() explicitly to pay setup cost up front (cold-start sensitive workloads), pass credentials from code, or register identity getters (the next section). For integrations, call bento.init() before bento.instrument() so the getters are registered before the first captured call.
Identity getters
init() accepts user_id, session_id, and tags kwargs. Bento invokes them on every span, whether captured by an integration or emitted by bento.track_ai, and writes the result to gen_ai.user.id, gen_ai.conversation.id, and langfuse.tags.
Each kwarg accepts three forms:
A getter that raises is swallowed by the SDK and the field is dropped for that span. Telemetry must never break the host app.
See Integrations → Identity at init for the three common bridges (framework state, ContextVar, auth library), and Identity helpers for late-binding (update_current_trace, propagate_attributes).
Lifecycle
Calling init() twice with conflicting credentials raises BentoAuthError("already_initialized"). Call shutdown() first to rotate.
Errors
The SDK raises BentoAuthError with a typed code for fail-fast cases.
Resolution helpers
For tools that need the resolved config without standing up a tracer:
Returns a frozen BentoConfig(api_key, base_url) dataclass. Same resolution order as init().