---
title: "Client"
description: "The SDK component responsible for event creation, integration management, and transport dispatch."
url: https://develop.sentry.dev/sdk/foundations/client/
---

# Client

This document uses key words such as "MUST", "SHOULD", and "MAY" as defined in

<!-- -->

[RFC 2119](https://www.ietf.org/rfc/rfc2119.txt) to indicate requirement levels.

Statusstable

Version`2.2.0`[(changelog)](https://develop.sentry.dev/sdk/foundations/client.md#changelog)

## [Overview](https://develop.sentry.dev/sdk/foundations/client.md#overview)

The Client is the SDK component responsible for building Sentry events from captured data and dispatching them to the [Transport](https://develop.sentry.dev/sdk/foundations/transport.md). It is configured once during `Sentry.init()` and manages the [integration](https://develop.sentry.dev/sdk/foundations/client/integrations.md) lifecycle.

The Client is **stateless** with respect to contextual data — it receives the [Scope](https://develop.sentry.dev/sdk/foundations/state-management/scopes.md) 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](https://develop.sentry.dev/sdk/foundations/state-management/hub-and-scope.md) model, the Client was bound to a Hub. In the current [Scopes](https://develop.sentry.dev/sdk/foundations/state-management/scopes.md) model, the Client is resolved via the scope chain.

Related specs:

* [Configuration](https://develop.sentry.dev/sdk/foundations/client/configuration.md) — client options, environment variables, debug mode, sampling
* [Integrations](https://develop.sentry.dev/sdk/foundations/client/integrations.md) — integration interface, lifecycle, and defaults
* [Hooks](https://develop.sentry.dev/sdk/foundations/client/hooks.md) — lifecycle hooks, before\_send, before\_breadcrumb
* [Errors](https://develop.sentry.dev/sdk/telemetry/errors.md) — error capture, exception interface, wire format
* [Scopes](https://develop.sentry.dev/sdk/foundations/state-management/scopes.md) — scope chain and client resolution
* [Transport](https://develop.sentry.dev/sdk/foundations/transport.md) — envelope delivery
* [Envelopes](https://develop.sentry.dev/sdk/foundations/transport/envelopes.md) — wire format
* [Attributes](https://develop.sentry.dev/sdk/foundations/state-management/scopes/attributes.md) — attribute type system

***

## [Concepts](https://develop.sentry.dev/sdk/foundations/client.md#concepts)

* **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](https://develop.sentry.dev/sdk/foundations/processing/telemetry-processor.md), if present).

* **NoOpClient**: A Client that performs no operations. Present on the global scope before `Sentry.init()` is called, ensuring that `getClient()` never returns `null`.

* **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_scope` callbacks, and breadcrumb recording **SHOULD NOT** be invoked.

***

## [Behavior](https://develop.sentry.dev/sdk/foundations/client.md#behavior)

### [Client Lifecycle](https://develop.sentry.dev/sdk/foundations/client.md#client-lifecycle)

Stablespecified since

<!-- -->

1.0.0

#### [Initialization](https://develop.sentry.dev/sdk/foundations/client.md#initialization)

`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.

#### [Active State](https://develop.sentry.dev/sdk/foundations/client.md#active-state)

The Client is considered **active** when it has a configured transport. When active, the Client processes captured events through the [event pipeline](https://develop.sentry.dev/sdk/foundations/client.md#event-pipeline).

#### [Shutdown](https://develop.sentry.dev/sdk/foundations/client.md#shutdown)

| 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](https://develop.sentry.dev/sdk/foundations/processing/telemetry-processor.md), flushing **MUST** first forward all buffered items to the transport, then flush the transport itself.

### [Client Resolution](https://develop.sentry.dev/sdk/foundations/client.md#client-resolution)

Stablespecified since

<!-- -->

2.0.0

A Client **MUST** always be available — `getClient()` **MUST NOT** return `null`.

Client resolution walks the scope chain:

1. Check the current scope
2. Check the isolation scope
3. Check the global scope
4. 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](https://develop.sentry.dev/sdk/foundations/state-management/scopes.md#client-resolution) for details.

### [Event Pipeline](https://develop.sentry.dev/sdk/foundations/client.md#event-pipeline)

Stablespecified since

<!-- -->

1.0.0

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.

1. **Disabled check**: If the SDK is disabled (no transport / no DSN), discard immediately.
2. **Sampling**: Apply the configured `sample_rate`. Events **MAY** be randomly discarded. When discarded, the Client **MUST** record a [client report](https://develop.sentry.dev/sdk/telemetry/client-reports.md) with discard reason `sample_rate`.
3. **Scope application**: Obtain the current, isolation, and global scopes. Merge scope data onto the event in the [defined order](https://develop.sentry.dev/sdk/foundations/state-management/scopes.md#applying-scope-data-to-events). Invoke event processors in registration order. Any processor returning `null` discards the event (client report reason: `event_processor`).
4. **`before_send` hook**: Invoke the user-configured callback. Returning `null` discards the event (client report reason: `before_send`). This hook **MUST** only apply to error events. For transactions, use `before_send_transaction`. For logs, use `before_send_log`. See [Hooks](https://develop.sentry.dev/sdk/foundations/client/hooks.md) for details.
5. **Transport**: Pass the event to the transport (or TelemetryProcessor). The transport **MAY** discard due to missing DSN, full queue, or [rate limiting](https://develop.sentry.dev/sdk/foundations/transport/rate-limiting.md).

***

## [Public API](https://develop.sentry.dev/sdk/foundations/client.md#public-api)

### [Client Construction](https://develop.sentry.dev/sdk/foundations/client.md#client-construction)

| Method                                            | Description                                |
| ------------------------------------------------- | ------------------------------------------ |
| `Client(options)` / `Client.from_config(options)` | Construct a Client with the given options. |

### [Capture Methods](https://develop.sentry.dev/sdk/foundations/client.md#capture-methods)

| 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.                                         |

### [Lifecycle](https://develop.sentry.dev/sdk/foundations/client.md#lifecycle)

| Method           | Description              |
| ---------------- | ------------------------ |
| `close(timeout)` | Flush and disable.       |
| `flush(timeout)` | Flush without disabling. |

See [Configuration](https://develop.sentry.dev/sdk/foundations/client/configuration.md) for the full set of client options, environment variables, and sampling behavior.

***

## [Changelog](https://develop.sentry.dev/sdk/foundations/client.md#changelog)

| 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 |

## Pages in this section

- [Configuration](https://develop.sentry.dev/sdk/foundations/client/configuration.md)
- [Hooks](https://develop.sentry.dev/sdk/foundations/client/hooks.md)
- [Integrations](https://develop.sentry.dev/sdk/foundations/client/integrations.md)
