Skip to main content

posthog_rs/
lib.rs

1//! Official Rust SDK for PostHog.
2//!
3//! Use [`client`] to construct a [`Client`], [`Event`] to capture analytics
4//! events, and [`Client::evaluate_flags`] with [`EvaluateFlagsOptions`] for
5//! feature flag evaluation.
6//!
7//! See the [PostHog Rust SDK documentation](https://posthog.com/docs/libraries/rust)
8//! for installation, configuration, and more examples.
9//!
10//! # Getting started
11//!
12//! Add `posthog-rs` to your `Cargo.toml`, then initialize a client with your
13//! project API key.
14//!
15//! ```no_run
16//! use posthog_rs::{client, EvaluateFlagsOptions, Event};
17//!
18//! #[cfg(feature = "async-client")]
19//! #[tokio::main]
20//! async fn main() -> Result<(), posthog_rs::Error> {
21//!     let api_key = std::env::var("POSTHOG_API_KEY")
22//!         .expect("set POSTHOG_API_KEY to your PostHog project API key");
23//!
24//!     let posthog = client(api_key.as_str()).await;
25//!     let distinct_id = "user-123";
26//!
27//!     // Capture an analytics event.
28//!     let mut event = Event::new("signed_up", distinct_id);
29//!     event.insert_prop("plan", "pro")?;
30//!     posthog.capture(event);
31//!
32//!     // Evaluate feature flags once, then read from the snapshot.
33//!     let flags = posthog
34//!         .evaluate_flags(distinct_id, EvaluateFlagsOptions::default())
35//!         .await?;
36//!
37//!     if flags.is_enabled("new-onboarding") {
38//!         let mut event = Event::new("onboarding_step_completed", distinct_id);
39//!         event.with_flags(&flags.only_accessed());
40//!         posthog.capture(event);
41//!     }
42//!
43//!     Ok(())
44//! }
45//!
46//! #[cfg(not(feature = "async-client"))]
47//! fn main() -> Result<(), posthog_rs::Error> {
48//!     let api_key = std::env::var("POSTHOG_API_KEY")
49//!         .expect("set POSTHOG_API_KEY to your PostHog project API key");
50//!
51//!     let posthog = client(api_key.as_str());
52//!     let distinct_id = "user-123";
53//!
54//!     // Capture an analytics event.
55//!     let mut event = Event::new("signed_up", distinct_id);
56//!     event.insert_prop("plan", "pro")?;
57//!     posthog.capture(event);
58//!
59//!     // Evaluate feature flags once, then read from the snapshot.
60//!     let flags = posthog.evaluate_flags(distinct_id, EvaluateFlagsOptions::default())?;
61//!
62//!     if flags.is_enabled("new-onboarding") {
63//!         let mut event = Event::new("onboarding_step_completed", distinct_id);
64//!         event.with_flags(&flags.only_accessed());
65//!         posthog.capture(event);
66//!     }
67//!
68//!     Ok(())
69//! }
70//! ```
71//!
72//! # Capture is fire-and-forget
73//!
74//! [`Client::capture`] and [`Client::capture_batch`] are the primary API: they
75//! hand the event to a background worker that batches, sends, and retries it,
76//! and return immediately. Delivery failures are not surfaced to the caller —
77//! register [`ClientOptionsBuilder::on_error`] to observe them. This is the
78//! right choice for essentially all analytics.
79//!
80//! ## Immediate delivery (advanced)
81//!
82//! [`Client::capture_immediate`] and [`Client::capture_batch_immediate`] send
83//! inline and return a [`CaptureSummary`] once the request reaches a terminal
84//! outcome (or an [`Error`] if the retry budget is spent). They bypass the
85//! background worker and do not fire `on_error` — the returned value is the
86//! signal. Reach for them only when the caller must know a batch persisted
87//! before advancing its own durable state (for example, a server-side importer
88//! committing an upstream offset); prefer fire-and-forget everywhere else.
89mod client;
90mod compression;
91mod constants;
92mod endpoints;
93mod error;
94#[cfg(feature = "error-tracking")]
95mod error_tracking;
96mod event;
97#[cfg(feature = "capture-v1")]
98mod event_v1;
99mod feature_flag_evaluations;
100mod feature_flags;
101mod global;
102mod local_evaluation;
103
104// Public interface - any change to this is breaking!
105// Client
106pub use client::client;
107pub use client::BeforeSendHook;
108pub use client::CaptureCompression;
109pub use client::CaptureSummary;
110pub use client::Client;
111pub use client::ClientOptions;
112pub use client::ClientOptionsBuilder;
113pub use client::ClientOptionsBuilderError;
114pub use client::{CaptureFailure, FlagsFailure, LocalEvaluationFailure, PostHogError};
115
116// Endpoints
117pub use endpoints::{
118    Endpoint, EndpointManager, DEFAULT_HOST, EU_INGESTION_ENDPOINT, US_INGESTION_ENDPOINT,
119};
120
121// Error
122pub use error::Error;
123
124// Error Tracking
125#[cfg(feature = "error-tracking")]
126pub use error_tracking::{
127    CaptureExceptionOptions, ErrorTrackingOptions, ErrorTrackingOptionsBuilder,
128    ErrorTrackingOptionsBuilderError,
129};
130
131// Event
132pub use event::Event;
133
134// V1 Capture types
135#[cfg(feature = "capture-v1")]
136pub use event_v1::{CaptureResponse, EventResult, EventStatus, V1ErrorResponse};
137
138// Feature Flags
139pub use feature_flag_evaluations::{EvaluateFlagsOptions, FeatureFlagEvaluations};
140pub use feature_flags::{
141    match_feature_flag, match_feature_flag_with_context, match_property_with_context,
142    CohortDefinition, EvaluationContext, FeatureFlag, FeatureFlagCondition, FeatureFlagFilters,
143    FeatureFlagsResponse, FlagDetail, FlagMetadata, FlagReason, FlagValue, InconclusiveMatchError,
144    MultivariateFilter, MultivariateVariant, Property,
145};
146
147// Local Evaluation
148pub use local_evaluation::{
149    Cohort, FlagCache, FlagPoller, LocalEvaluationConfig, LocalEvaluationResponse, LocalEvaluator,
150};
151
152#[cfg(feature = "async-client")]
153pub use local_evaluation::AsyncFlagPoller;
154
155// We expose global convenience functions (capture/flush/shutdown) that use a
156// global client. flush/shutdown matter because the global singleton lives in a
157// `static`, whose `Drop` never runs — they must be called to drain on exit.
158pub use global::capture;
159#[cfg(feature = "error-tracking")]
160pub use global::capture_exception;
161#[cfg(feature = "error-tracking")]
162pub use global::capture_exception_with;
163pub use global::disable as disable_global;
164pub use global::flush;
165pub use global::init_global_client as init_global;
166pub use global::is_disabled as global_is_disabled;
167pub use global::shutdown;