Client
The SDK component responsible for event creation, integration management, and transport dispatch.
The Client is the SDK component responsible for building Sentry events from captured data and dispatching them to the Transport. It is configured once during Sentry.init() and manages the integration lifecycle.
The Client is stateless with respect to contextual data — it receives the Scope at capture time and merges scope data into the event. The Client does hold configuration (options) and owns its transport and integrations.
In the Hub & Scope model, the Client was bound to a Hub. In the current Scopes model, the Client is resolved via the scope chain.
Related specs:
- Configuration — client options, environment variables, debug mode, sampling
- Integrations — integration interface, lifecycle, and defaults
- Hooks — lifecycle hooks, before_send, before_breadcrumb
- Errors — error capture, exception interface, wire format
- Scopes — scope chain and client resolution
- Transport — envelope delivery
- Envelopes — wire format
- Attributes — attribute type system
Stateless: The Client does not hold contextual data (tags, breadcrumbs, user). All contextual data comes from scopes, which are passed to the Client at capture time.
Transport delegation: The Client builds the event; the Transport sends it. The Client MUST NOT implement network I/O directly — it delegates to its Transport (or TelemetryProcessor, if present).
NoOpClient: A Client that performs no operations. Present on the global scope before
Sentry.init()is called, ensuring thatgetClient()never returnsnull.Disabled SDK: The SDK is considered disabled when the Client has no transport, or when no DSN is configured. In this state, event processors,
configure_scopecallbacks, and breadcrumb recording SHOULD NOT be invoked.
Sentry.init(options) MUST create a Client, configure its transport, and set up integrations. The Client is then set on the global scope, replacing the NoOpClient.
Before Sentry.init() is called, a NoOpClient MUST be present on the global scope. (since 2.0.0)
SDKs MUST accept an empty DSN as valid configuration. If initialized with an empty or missing DSN, the SDK MUST NOT send any data over the network. Depending on the platform, the SDK MAY reduce its runtime footprint to a minimum.
Calling Sentry.init() multiple times is permitted for testing. Behavior in production beyond application startup is undefined.
The Client is considered active when it has a configured transport. When active, the Client processes captured events through the event pipeline.
| Method | Description |
|---|---|
close(timeout) | Flush the transport queue for up to timeout seconds. The Client SHOULD be disabled or disposed after close returns. |
flush(timeout) | Flush the transport queue for up to timeout seconds. The Client remains usable. |
Both methods MUST block for at most timeout seconds. If the transport includes a TelemetryProcessor, flushing MUST first forward all buffered items to the transport, then flush the transport itself.
A Client MUST always be available — getClient() MUST NOT return null.
Client resolution walks the scope chain:
- Check the current scope
- Check the isolation scope
- Check the global scope
- Fall back to NoOpClient (should not happen if
init()was called)
Users MAY bind a different Client to any scope via scope.setClient(client).
See Scopes: Client Resolution for details.
When captureEvent, captureException, or captureMessage is called, the Client processes the event through the following pipeline. The event MAY be discarded at any stage, stopping further processing.
- Disabled check: If the SDK is disabled (no transport / no DSN), discard immediately.
- Sampling: Apply the configured
sample_rate. Events MAY be randomly discarded. When discarded, the Client MUST record a client report with discard reasonsample_rate. - Scope application: Obtain the current, isolation, and global scopes. Merge scope data onto the event in the defined order. Invoke event processors in registration order. Any processor returning
nulldiscards the event (client report reason:event_processor). before_sendhook: Invoke the user-configured callback. Returningnulldiscards the event (client report reason:before_send). This hook MUST only apply to error events. For transactions, usebefore_send_transaction. For logs, usebefore_send_log. See Hooks for details.- Transport: Pass the event to the transport (or TelemetryProcessor). The transport MAY discard due to missing DSN, full queue, or rate limiting.
| Method | Description |
|---|---|
Client(options) / Client.from_config(options) | Construct a Client with the given options. |
| Method | Description |
|---|---|
capture_event(event, scope) | Merge event with scope data, run through event pipeline, dispatch to transport. |
capture_exception(exception, scope) | Convert exception to event, then capture. |
capture_message(message, level, scope) | Convert message to event, then capture. |
| Method | Description |
|---|---|
close(timeout) | Flush and disable. |
flush(timeout) | Flush without disabling. |
See Configuration for the full set of client options, environment variables, and sampling behavior.
| Version | Date | Summary |
|---|---|---|
2.2.0 | 2025-02-24 | Restructured into sub-specs for integrations, hooks, and configuration |
2.1.0 | 2024-09-23 | Added integration lifecycle (setupOnce, setup, afterAllSetup, preprocessEvent, processEvent) |
2.0.0 | 2024-02-14 | Breaking — Client decoupled from Hub; resolved via scope chain; NoOpClient before init |
1.1.0 | 2022-11-17 | Added session lifecycle (start_session, end_session) |
1.0.0 | 2020-05-04 | Initial spec — stateless event creator with capture_event, close, flush, transport delegation |
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) or suggesting an update ("yeah, this would be better").