diff --git a/develop-docs/sdk/expected-features/data-handling.mdx b/develop-docs/sdk/expected-features/data-handling.mdx
index d7422ebdda3d21..26d5a03d8d0057 100644
--- a/develop-docs/sdk/expected-features/data-handling.mdx
+++ b/develop-docs/sdk/expected-features/data-handling.mdx
@@ -111,45 +111,3 @@ This helps Relay to know what kind of data it receives and this helps with scrub
Additionally all semantic conventions of OpenTelemetry for database spans should be set in the `span.data` if applicable:
https://opentelemetry.io/docs/reference/specification/trace/semantic_conventions/database/
-
-### Breadcrumbs
-
-If the `message` in a breadcrumb contains an URL it should be formatted the same way as in `http` spans (see above).
-If query strings are present in the URL or fragments (Browser SDKs only) are present in the URI, both should also be set in the data attribute like with `http` spans.
-
-```js
-Sentry.addBreadcrumb({
- type: "http",
- category: "xhr",
- data: {
- method: "POST",
- url: "https://example.com/api/users/create.php",
- "http.query": "username=ada&password=123&newsletter=0",
- "http.fragment": "#foo",
- },
-});
-```
-
-Additionally all semantic conventions of OpenTelemetry for database spans should be set in the `data` if applicable:
-https://opentelemetry.io/docs/reference/specification/trace/semantic_conventions/database/
-
-## Variable Size
-
-Fields in the event payload that allow user-specified or dynamic values are restricted in size. This applies to most meta data fields, such as variables in a stack trace, as well as contexts, tags and extra data:
-
-- Event IDs are limited to 36 characters and must be valid UUIDs.
-- Flag keys are limited to 32 characters.
-- Flag values are limited to 200 characters.
-- Tag keys are limited to 200 characters.
-- Tag values are limited to 200 characters.
-- Culprits are limited to 200 characters.
-- Context objects are limited to 8kB.
-- Individual extra data items are limited to 16kB. Total extra data is limited to 256kb.
-- Messages are limited to 8192 characters.
-- HTTP data (the body) is limited to 8kB. Always trim HTTP data before attaching it to the event.
-- Stack traces are limited to 50 frames. If more are sent, data will be removed from the middle of the stack.
-- Input messages in AI integrations recorded in the span attribute `gen_ai.request.messages` are limited to 20kB per span. Messages are trimmed and truncated if they exceed the limit, retaining the most recent messages.
-
-Additionally, size limits apply to all store requests for the total size of the request, event payload, and attachments. Sentry rejects all requests exceeding these limits. Please refer the following resources for the exact size limits:
-
-- Envelope Endpoint Size Limits
diff --git a/develop-docs/sdk/expected-features/index.mdx b/develop-docs/sdk/expected-features/index.mdx
index 0b9da5b24637a6..dc5ea0e02f248d 100644
--- a/develop-docs/sdk/expected-features/index.mdx
+++ b/develop-docs/sdk/expected-features/index.mdx
@@ -9,36 +9,12 @@ sidebar_order: 5
including the Scopes and Client specs.
-## Background Sending
-
-Events should be transmitted in a background thread or similar system. This queue must be flushed when the
-application shuts down with a specific timeout. This feature is typically user facing and explained
-as part of [shutdown and draining](https://docs.sentry.io/platforms/javascript/configuration/draining/).
-
-
## Uncaught Exception Handler
Ability for the SDK to be set as a hook to record any uncaught exceptions. At the language level this is typically a global hook provided by the language itself. For framework integrations this might be part of middleware or some other system.
This behavior is typically provided by a default integration that can be disabled.
-## Automatic Context Data
-
-Automatic addition of useful attributes such as `flags` or `tags` or `extra` or specific `contexts`. Typically means the SDK hooks into a framework so that it can set attributes that are known to be useful for most users. Please check [Data Handling](/sdk/expected-features/data-handling) for considerations.
-
-## Rate Limiting
-
-Respect Sentry's HTTP 429 `Retry-After` header, or, if the SDK supports multiple payload types (e.g. errors and transactions), the `X-Sentry-Rate-Limits` header. Outgoing SDK requests should be dropped during the backoff period.
-
-See Rate Limiting for details.
-
-
-## Backpressure Management
-
-Backend SDKs (typically used in server applications) should have backpressure management logic that dynamically downsamples transactions when the throughput in the system is too high.
-
-See Backpressure Management for details.
-
## In-App frames
Stack parsing can tell which frames should be identified as part of the user's application (as opposed to part of the language, a library, or a framework), either automatically or by user configuration at startup, often declared as a package/module prefix.
@@ -57,65 +33,6 @@ This functionality should be gated behind the `includeLocalVariables` option, wh
Turn compiled or obfuscated code/method names in stack traces back into the original. Desymbolication always requires Sentry backend support. Not necessary for many languages.
-## Retrieve Last Event ID
-
-Ability to get the ID of the last event sent. Event IDs are useful for correlation, logging, customers rolling their own feedback forms, etc.
-
-## List Loaded Libraries
-
-Include a list of loaded libraries (and versions) when sending an event.
-
-## Buffer to Disk
-
-This feature is also known as 'Offline Caching'.
-
-Write events to disk before attempting to send, so that they can be retried in the event of a temporary network failure. Needs to implement a cap on the number of stored events. This is mostly useful on mobile and desktop(e.g: laptop) apps, where stable connectivity is often not available.
-
-### Dealing With Network Failures
-
-When SDKs receive an `HTTP 2xx` status code response from Sentry, they **MUST** consider it as a successful send.
-
-If Sentry returns an `HTTP 4xx` or `HTTP 5xx` status code, SDKs **MUST** discard the envelope and record a [client report](/sdk/telemetry/client-reports/#network-failure-recording) as specified in the client reports spec.
-
-For an [`HTTP 413 Content Too Large`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/413) response, SDKs:
-
-* **MUST** discard the envelope and record a [client report](/sdk/telemetry/client-reports/#network-failure-recording).
-* **MUST NOT** retry sending the envelope.
-* **SHOULD** log an error, informing users that the envelope was discarded due to size limits.
-* **MAY** add information from the response body to the logged error. If doing so, SDKs **MUST** be aware that Relay can change or remove information in the response body for an `HTTP 413` at any time without notice.
-
-For an [`HTTP 429 Too Many Requests`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429) response, SDKs:
-
-- **MUST** respect the [rate limiting rules](/sdk/expected-features/rate-limiting/), such as correctly parsing the retry-header.
-- **MUST** discard the envelope, but **MUST NOT** record a [client report](/sdk/telemetry/client-reports/#network-failure-recording), because the upstream already does this.
-- **MUST NOT** retry sending the envelope.
-
-SDKs **MAY** retry sending the envelope when a network error occurs, such as:
-
-* Connection timeout
-* DSN resolution failure
-* Connection reset by peer
-
-When other failures occur, like those caused by processing the file in the SDK itself, SDKs **MUST** discard the envelope and record a [client report](/sdk/telemetry/client-reports/#network-failure-recording) with the discard reason `internal_sdk_error`. Otherwise, the SDK might end up in an endless retry loop.
-
-See the [Client Reports — Network Failure Recording](/sdk/telemetry/client-reports/#network-failure-recording) spec for the full set of client report recording requirements for each HTTP status code.
-
-
-#### Additional capabilities
-
-Consider having the SDK retry sending events once the device is back online, when such notification exists in the platform.
-
-Once the device is back online, the SDK is likely going to empty its disk queue in a quick burst of requests. This can trigger different abuse filters in Sentry. To account for that, it's considered to add a small delay between cached event captures. A recommended value is 100 milliseconds.
-
-If the SDK is being [rate-limited](/sdk/expected-features/rate-limiting/), which causes the SDK to drop any event that reaches its HTTP transport, consider stop consuming the disk cache until the `Retry-After` timeout is reached or the app restarts.
-
-#### Example implementations
-
-- [C#](https://github.com/getsentry/sentry-dotnet/blob/main/src/Sentry/Internal/Http/CachingTransport.cs)
-- [Java](https://github.com/getsentry/sentry-java/blob/main/sentry/src/main/java/io/sentry/cache/EnvelopeCache.java)
-- [Objective-C](https://github.com/getsentry/sentry-cocoa/blob/master/Sources/Sentry/SentryHttpTransport.m)
-- [TypeScript](https://github.com/getsentry/sentry-electron/blob/master/src/main/transports/electron-offline-net.ts)
-
## Start-Up Crash Detection
We recommend implementing this feature for mobile and desktop SDKs.
@@ -152,25 +69,3 @@ ones. We can always add these values later.
#### Example implementations
- [Java](https://github.com/getsentry/sentry-java/pull/2277)
- [Objective-C](https://github.com/getsentry/sentry-cocoa/pull/2220)
-
-## HTTP Proxy
-
-Ability to use an HTTP proxy. Often easy to implement using the existing HTTP client. This should be picked up from the system config if possible or explicit config in the client options.
-
-## Attaching Request Body in Server SDKs
-
-Ability for the SDK to attach request body to events and triggered during the execution of request.
-
-User should be able to set a configuration option `maxRequestBodySize` to instruct SDK how big requests bodies should be attached.
-SDK controls what is an actual size in bytes for each option:
-
-- `none`
-- `small` - `1000` bytes
-- `medium` - `10000` bytes (default)
-- `always`
-
-## Log context
-
-Some logging frameworks provide an option to set logging context. In Java this is called MDC (Mapped Diagnostic Context).
-
-Users should be able to set a list of logging context entries in a configuration option `contextTags` to tell the SDK to convert the entries to Sentry tags.
diff --git a/develop-docs/sdk/foundations/client/configuration/index.mdx b/develop-docs/sdk/foundations/client/configuration/index.mdx
index d1dc8d1b6acab1..b8ceed777ac614 100644
--- a/develop-docs/sdk/foundations/client/configuration/index.mdx
+++ b/develop-docs/sdk/foundations/client/configuration/index.mdx
@@ -53,6 +53,8 @@ Core options that all SDKs **MUST** or **SHOULD** support:
| `traces_sample_rate` | `float [0,1]` | Trace/transaction sample rate. |
| `traces_sampler` | `callback` | Dynamic per-transaction sample rate. |
| `trace_propagation_targets` | `array` | URL patterns for outgoing trace header injection. |
+| `context_tags` | `array` | List of logging context keys to convert to Sentry tags. See [Log Context](#log-context). |
+| `max_request_body_size` | `string` | Controls how large request bodies may be before the SDK skips attaching them. Server SDKs only. See [Request Body Size](#request-body-size). |
@@ -176,6 +178,37 @@ ignore_transactions = ['GET /api/health','/api/v1/*']
+
+
+### Request Body Size
+
+Server SDKs **SHOULD** support attaching the incoming HTTP request body to events. The `max_request_body_size` option controls the maximum body size the SDK will attach. The SDK defines the actual byte thresholds for each setting:
+
+| Value | Max Size |
+|---|---|
+| `none` | Never attach the body |
+| `small` | 1,000 bytes |
+| `medium` | 10,000 bytes (default) |
+| `always` | No limit |
+
+
+
+
+
+### Log Context
+
+Some logging frameworks provide an option to set logging context. In Java this is called MDC (Mapped Diagnostic Context).
+
+SDKs that integrate with platform logging frameworks **SHOULD** support a `context_tags` configuration option. This option accepts a list of logging context keys whose values the SDK converts to Sentry tags on captured events.
+
+```python
+sentry_sdk.init(
+ context_tags=["request_id", "tenant"],
+)
+```
+
+
+
---
## Changelog
diff --git a/develop-docs/sdk/foundations/client/integrations/index.mdx b/develop-docs/sdk/foundations/client/integrations/index.mdx
index d3c6bf0717fa26..76ed6ee94c3133 100644
--- a/develop-docs/sdk/foundations/client/integrations/index.mdx
+++ b/develop-docs/sdk/foundations/client/integrations/index.mdx
@@ -29,6 +29,7 @@ Related specs:
- [HTTP Client Integration](/sdk/foundations/client/integrations/http-client) — HTTP client instrumentation guidelines
- [GraphQL Integration](/sdk/foundations/client/integrations/graphql) — GraphQL client instrumentation guidelines
- [Feature Flags Integration](/sdk/foundations/client/integrations/feature-flags) — feature flag tracking guidelines
+- [Modules Integration](/sdk/foundations/client/integrations/modules) — loaded library and version reporting
---
diff --git a/develop-docs/sdk/foundations/client/integrations/modules.mdx b/develop-docs/sdk/foundations/client/integrations/modules.mdx
new file mode 100644
index 00000000000000..e81733ba7196e0
--- /dev/null
+++ b/develop-docs/sdk/foundations/client/integrations/modules.mdx
@@ -0,0 +1,107 @@
+---
+title: Modules
+description: Integration for attaching loaded libraries and their versions to events, populating the event modules field.
+spec_id: sdk/foundations/client/integrations/modules
+spec_version: 1.0.0
+spec_status: stable
+spec_depends_on:
+ - id: sdk/foundations/client/integrations
+ version: ">=1.0.0"
+spec_changelog:
+ - version: 1.0.0
+ date: 2026-03-04
+ summary: Initial spec, extracted from expected features
+sidebar_order: 4
+---
+
+
+
+
+
+## Overview
+
+The Modules integration attaches a list of loaded libraries (packages, modules) and their versions to events. This populates the [`modules` field](/sdk/foundations/transport/event-payloads/#optional-attributes) on the event payload, which Sentry displays in the event detail view to help users identify dependency-related issues.
+
+This integration **SHOULD** be a default integration.
+
+---
+
+## Behavior
+
+
+
+### Event Enrichment
+
+The integration **MUST** use the `processEvent` lifecycle hook to attach module information to events.
+
+The integration **MUST** populate `event.modules` as a map of module name to version string:
+
+```json
+{
+ "modules": {
+ "flask": "2.3.1",
+ "requests": "2.31.0",
+ "sqlalchemy": "2.0.19"
+ }
+}
+```
+
+The integration **SHOULD** cache the module list, since installed packages rarely change during a process lifetime.
+
+
+
+
+
+### Module Sources
+
+How modules are discovered is platform-specific. SDKs **SHOULD** use the most reliable mechanism available on their platform. Common strategies include:
+
+- **Package manager metadata** — reading installed package registries (e.g., `pkg_resources` or `importlib.metadata` in Python, `package.json` dependencies in Node.js)
+- **Runtime module cache** — inspecting loaded modules from the runtime (e.g., `require.cache` in Node.js CJS)
+- **Build-time injection** — embedding module information at build time when runtime discovery is unavailable or incomplete (e.g., bundled environments)
+
+SDKs **MAY** combine multiple sources to produce the most complete list. When the same module appears in multiple sources, the more specific version (e.g., from a lockfile or runtime cache) **SHOULD** take precedence.
+
+
+
+
+
+### Event Type Filtering
+
+SDKs **MAY** skip attaching modules to certain event types (e.g., transactions) where the information is less useful, to reduce payload size.
+
+
+
+---
+
+## Examples
+
+### JavaScript (Node.js)
+
+```javascript
+// modulesIntegration is a default integration in @sentry/node
+Sentry.init({
+ dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
+});
+
+// Modules are automatically attached to error events.
+// The integration reads from package.json and require.cache (CJS).
+```
+
+### Python
+
+```python
+import sentry_sdk
+
+# ModulesIntegration is a default integration
+sentry_sdk.init(dsn="https://examplePublicKey@o0.ingest.sentry.io/0")
+
+# Modules are automatically attached to error events.
+# The integration reads from importlib.metadata / pkg_resources.
+```
+
+---
+
+## Changelog
+
+
diff --git a/develop-docs/sdk/foundations/processing/telemetry-processor/index.mdx b/develop-docs/sdk/foundations/processing/telemetry-processor/index.mdx
index 875063216d3c92..a19dbc3762067e 100644
--- a/develop-docs/sdk/foundations/processing/telemetry-processor/index.mdx
+++ b/develop-docs/sdk/foundations/processing/telemetry-processor/index.mdx
@@ -154,7 +154,7 @@ Here are the common requirements for all platforms:
2. The telemetry scheduler **SHOULD** attach the client reports to the envelopes it forwards to the transport.
3. When the telemetry queue overflows and drops envelopes, it **MUST** record the client report.
-To be defined: How exactly does the telemetry scheduler interact with the transport to correctly remove items from the telemetry queue based on the received HTTP info and how to adhere to the [dealing with network failure](/sdk/expected-features/#dealing-with-network-failures) requirements.
+To be defined: How exactly does the telemetry scheduler interact with the transport to correctly remove items from the telemetry queue based on the received HTTP info and how to adhere to the [dealing with network failure](/sdk/foundations/transport/offline-caching/#dealing-with-network-failures) requirements.
## Client Reports
diff --git a/develop-docs/sdk/foundations/state-management/hub-and-scope/index.mdx b/develop-docs/sdk/foundations/state-management/hub-and-scope/index.mdx
index 0e2a56ef30874f..5aeda29ef04137 100644
--- a/develop-docs/sdk/foundations/state-management/hub-and-scope/index.mdx
+++ b/develop-docs/sdk/foundations/state-management/hub-and-scope/index.mdx
@@ -61,6 +61,8 @@ The decision to remove the Hub from all Sentry SDKs was confirmed on 2024-05-03
- **Disabled SDK**: The SDK is considered disabled when the client has no transport. In this state, callbacks like `configure_scope` and event processors **SHOULD NOT** be invoked, and breadcrumbs **SHOULD NOT** be recorded.
+- **Automatic Context Data**: SDKs and their integrations automatically populate scopes with useful contextual data such as tags, contexts, and extras. This typically happens by hooking into a framework (e.g., a web framework middleware setting request-related context on the scope). See [Data Handling](/sdk/expected-features/data-handling) for considerations around sensitive data.
+
---
## Behavior
diff --git a/develop-docs/sdk/foundations/state-management/scopes/index.mdx b/develop-docs/sdk/foundations/state-management/scopes/index.mdx
index aa4228d4af5b46..5bdadf1bebbc9f 100644
--- a/develop-docs/sdk/foundations/state-management/scopes/index.mdx
+++ b/develop-docs/sdk/foundations/state-management/scopes/index.mdx
@@ -94,6 +94,10 @@ When a scope is forked, the new scope receives a copy of all data from the paren
This replaces the manual hub-cloning pattern from the old model. Users no longer need to manage scope isolation — it happens automatically when spans are created or `withScope()` is called.
+### Automatic Context Data
+
+SDKs and their integrations automatically populate scopes with useful contextual data such as tags, contexts, and attributes. This typically happens by hooking into a framework (e.g., a web framework middleware setting request-related context on the isolation scope). This automatic enrichment is a key benefit of scopes — users get useful data on events without manual instrumentation. See [Data Handling](/sdk/expected-features/data-handling) for considerations around sensitive data.
+
### Scope Chain
Clients are resolved by walking the scope chain: current scope -> isolation scope -> global scope. If no client is found, a NoOpClient is used (see [Client Resolution](#client-resolution)).
@@ -341,6 +345,12 @@ Capture functions operate on the **current scope**:
| `Sentry.captureMessage(message)` | 1.0.0 | Capture a message on the current scope. |
| `Sentry.captureEvent(event)` | 1.0.0 | Capture a raw event on the current scope. |
+### Event ID Retrieval
+
+| Function | Since | Description |
+|---|---|---|
+| `Sentry.lastEventId()` | 1.0.0 | Return the ID of the last event sent from the isolation scope. Useful for correlation, logging, and custom user feedback forms. |
+
### Scope Data Methods
These methods are available on any scope instance (see [Behavior: Scope Data Methods](#scope-data-methods) for requirements):
@@ -354,6 +364,8 @@ These methods are available on any scope instance (see [Behavior: Scope Data Met
| `set_level(level)` | 1.0.0 | Override event severity level. |
| `set_fingerprint(fingerprint[])` | 1.0.0 | Set grouping fingerprint. |
| `add_event_processor(fn)` | 1.0.0 | Register an event processor callback. |
+| `set_last_event_id(id)` | 1.0.0 | Store the ID of the last event sent. Typically set on the isolation scope by the SDK after sending an event. |
+| `last_event_id()` | 1.0.0 | Return the ID of the last event sent. Typically read from the isolation scope. |
| `clear()` | 1.0.0 | Reset scope to defaults, keeping event processors. |
---
diff --git a/develop-docs/sdk/foundations/transport/event-payloads/breadcrumbs.mdx b/develop-docs/sdk/foundations/transport/event-payloads/breadcrumbs.mdx
index 8860d30021115d..97408ff1ce4209 100644
--- a/develop-docs/sdk/foundations/transport/event-payloads/breadcrumbs.mdx
+++ b/develop-docs/sdk/foundations/transport/event-payloads/breadcrumbs.mdx
@@ -291,3 +291,25 @@ _Internally, we display breadcrumbs of type `default` that contain category `ui.
"timestamp": 1598613151.875368
}
```
+
+## Structuring Data for Scrubbing
+
+For better data scrubbing on the server side, SDKs should save breadcrumb data in a structured way when possible. See [RFC-0038](https://github.com/getsentry/rfcs/blob/main/text/0038-scrubbing-sensitive-data.md) for background.
+
+If the `message` in a breadcrumb contains a URL, it should be formatted the same way as in `http` spans: `HTTP_METHOD scheme://host/path`. If query strings are present in the URL or fragments (Browser SDKs only) are present in the URI, both should be set in the `data` attribute rather than included in the URL.
+
+```js
+Sentry.addBreadcrumb({
+ type: "http",
+ category: "xhr",
+ data: {
+ method: "POST",
+ url: "https://example.com/api/users/create.php",
+ "http.query": "username=ada&password=123&newsletter=0",
+ "http.fragment": "#foo",
+ },
+});
+```
+
+Additionally, all semantic conventions of OpenTelemetry for database spans should be set in the `data` if applicable:
+https://opentelemetry.io/docs/reference/specification/trace/semantic_conventions/database/
diff --git a/develop-docs/sdk/foundations/transport/event-payloads/index.mdx b/develop-docs/sdk/foundations/transport/event-payloads/index.mdx
index 9a3b94f5312519..ab4f1628fb7566 100644
--- a/develop-docs/sdk/foundations/transport/event-payloads/index.mdx
+++ b/develop-docs/sdk/foundations/transport/event-payloads/index.mdx
@@ -287,6 +287,23 @@ Fingerprints](https://docs.sentry.io/data-management/event-grouping/).
Event ingestion imposes limits on the size of events.
See [Envelope Size Limits](/sdk/foundations/transport/envelopes/#size-limits) for further details.
+### Variable Size
+
+Fields in the event payload that allow user-specified or dynamic values are restricted in size. This applies to most meta data fields, such as variables in a stack trace, as well as contexts, tags and extra data:
+
+- Event IDs are limited to 36 characters and must be valid UUIDs.
+- Flag keys are limited to 32 characters.
+- Flag values are limited to 200 characters.
+- Tag keys are limited to 200 characters.
+- Tag values are limited to 200 characters.
+- Culprits are limited to 200 characters.
+- Context objects are limited to 8kB.
+- Individual extra data items are limited to 16kB. Total extra data is limited to 256kb.
+- Messages are limited to 8192 characters.
+- HTTP data (the body) is limited to 8kB. Always trim HTTP data before attaching it to the event.
+- Stack traces are limited to 50 frames. If more are sent, data will be removed from the middle of the stack.
+- Input messages in AI integrations recorded in the span attribute `gen_ai.request.messages` are limited to 20kB per span. Messages are trimmed and truncated if they exceed the limit, retaining the most recent messages.
+
## Core Interfaces
All values in the event payload that are not basic attributes are data
diff --git a/develop-docs/sdk/foundations/transport/index.mdx b/develop-docs/sdk/foundations/transport/index.mdx
index a284f6ada3e7aa..a95939e0b52dd3 100644
--- a/develop-docs/sdk/foundations/transport/index.mdx
+++ b/develop-docs/sdk/foundations/transport/index.mdx
@@ -4,7 +4,26 @@ description: How SDKs send data to Sentry - envelope format, authentication, com
sidebar_order: 20
---
-The transport layer handles all communication between an SDK and the Sentry server. SDKs serialize data into [envelopes](envelopes/), [authenticate](authentication/) requests using DSN-derived credentials, optionally [compress](compression/) payloads, and respect [rate limits](rate-limiting/) communicated via response headers.
+The transport layer handles all communication between an SDK and the Sentry server. SDKs serialize data into [envelopes](envelopes/), [authenticate](authentication/) requests using DSN-derived credentials, optionally [compress](compression/) payloads, respect [rate limits](rate-limiting/) communicated via response headers, and optionally [buffer envelopes to disk](offline-caching/) for retry on network failure.
+
+## Background Sending
+
+Envelopes **SHOULD** be transmitted in a background thread or equivalent asynchronous mechanism so that sending does not block the application. The send queue **MUST** be flushed when the application shuts down, with a configurable timeout. This is typically exposed to users as [shutdown and draining](https://docs.sentry.io/platforms/javascript/configuration/draining/).
+
+## HTTP Proxy
+
+SDKs **SHOULD** support routing requests through an HTTP proxy. The proxy **SHOULD** be configurable via a `proxy` option in `Sentry.init()` and **SHOULD** also be picked up from the system environment when not explicitly configured.
+
+SDKs **SHOULD** respect the following environment variables, in order of precedence:
+
+1. `options.proxy` — explicit SDK configuration (highest priority)
+2. `https_proxy` — for HTTPS requests to Sentry
+3. `http_proxy` — fallback for all requests
+4. `no_proxy` — comma-separated list of hostnames that bypass the proxy
+
+When a proxy is configured, the SDK **MUST** use it for all outgoing requests to Sentry. When `no_proxy` matches the Sentry hostname, the proxy **MUST** be bypassed.
+
+SDKs **MAY** support proxy authentication (username/password) and custom CA certificates for secure proxy connections.
## Reading the Response
diff --git a/develop-docs/sdk/foundations/transport/offline-caching.mdx b/develop-docs/sdk/foundations/transport/offline-caching.mdx
new file mode 100644
index 00000000000000..94e062ddf6d4ea
--- /dev/null
+++ b/develop-docs/sdk/foundations/transport/offline-caching.mdx
@@ -0,0 +1,65 @@
+---
+title: Offline Caching
+description: How SDKs buffer envelopes to disk for retry when network connectivity is unavailable, and how to handle network failure responses.
+sidebar_order: 5
+---
+
+
+ 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.
+
+
+## Overview
+
+Also known as "Buffer to Disk". SDKs write envelopes to disk before attempting to send, so that they can be retried in the event of a temporary network failure. SDKs **MUST** implement a cap on the number of stored envelopes. This feature is mostly useful on mobile and desktop apps, where stable connectivity is often not available.
+
+## Dealing With Network Failures
+
+When SDKs receive an `HTTP 2xx` status code response from Sentry, they **MUST** consider it as a successful send.
+
+If Sentry returns an `HTTP 4xx` or `HTTP 5xx` status code, SDKs **MUST** discard the envelope and record a [client report](/sdk/telemetry/client-reports/#network-failure-recording) as specified in the client reports spec.
+
+### HTTP 413 Content Too Large
+
+For an [`HTTP 413 Content Too Large`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/413) response, SDKs:
+
+* **MUST** discard the envelope and record a [client report](/sdk/telemetry/client-reports/#network-failure-recording).
+* **MUST NOT** retry sending the envelope.
+* **SHOULD** log an error, informing users that the envelope was discarded due to size limits.
+* **MAY** add information from the response body to the logged error. If doing so, SDKs **MUST** be aware that Relay can change or remove information in the response body for an `HTTP 413` at any time without notice.
+
+### HTTP 429 Too Many Requests
+
+For an [`HTTP 429 Too Many Requests`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429) response, SDKs:
+
+- **MUST** respect the [rate limiting rules](/sdk/expected-features/rate-limiting/), such as correctly parsing the retry-header.
+- **MUST** discard the envelope, but **MUST NOT** record a [client report](/sdk/telemetry/client-reports/#network-failure-recording), because the upstream already does this.
+- **MUST NOT** retry sending the envelope.
+
+### Network Errors
+
+SDKs **MAY** retry sending the envelope when a network error occurs, such as:
+
+* Connection timeout
+* DSN resolution failure
+* Connection reset by peer
+
+When other failures occur, like those caused by processing the file in the SDK itself, SDKs **MUST** discard the envelope and record a [client report](/sdk/telemetry/client-reports/#network-failure-recording) with the discard reason `internal_sdk_error`. Otherwise, the SDK might end up in an endless retry loop.
+
+See the [Client Reports — Network Failure Recording](/sdk/telemetry/client-reports/#network-failure-recording) spec for the full set of client report recording requirements for each HTTP status code.
+
+## Additional Capabilities
+
+SDKs **SHOULD** retry sending envelopes once the device is back online, when such notification exists in the platform.
+
+Once the device is back online, the SDK is likely going to empty its disk queue in a quick burst of requests. This can trigger abuse filters in Sentry. To account for that, SDKs **SHOULD** add a small delay between cached envelope sends. A recommended value is 100 milliseconds.
+
+If the SDK is being [rate-limited](/sdk/expected-features/rate-limiting/), which causes the SDK to drop any envelope that reaches its HTTP transport, SDKs **SHOULD** stop consuming the disk cache until the `Retry-After` timeout is reached or the app restarts.
+
+## Example Implementations
+
+- [C#](https://github.com/getsentry/sentry-dotnet/blob/main/src/Sentry/Internal/Http/CachingTransport.cs)
+- [Java](https://github.com/getsentry/sentry-java/blob/main/sentry/src/main/java/io/sentry/cache/EnvelopeCache.java)
+- [Objective-C](https://github.com/getsentry/sentry-cocoa/blob/master/Sources/Sentry/SentryHttpTransport.m)
+- [TypeScript](https://github.com/getsentry/sentry-electron/blob/master/src/main/transports/electron-offline-net.ts)
diff --git a/develop-docs/sdk/telemetry/feedbacks.mdx b/develop-docs/sdk/telemetry/feedbacks.mdx
index 8832cde1044add..66f28290c2e1f9 100644
--- a/develop-docs/sdk/telemetry/feedbacks.mdx
+++ b/develop-docs/sdk/telemetry/feedbacks.mdx
@@ -111,7 +111,7 @@ On mobile and desktop, it is common to prompt the user for feedback after a cras
### Backend Platforms
-On backend platforms, SDKs **SHOULD** document how to use the [last event ID](/sdk/expected-features/#retrieve-last-event-id) to prompt the user for feedback themselves.
+On backend platforms, SDKs **SHOULD** document how to use the [last event ID](/sdk/foundations/state-management/scopes/#event-id-retrieval) to prompt the user for feedback themselves.
diff --git a/docs/concepts/data-management/size-limits.mdx b/docs/concepts/data-management/size-limits.mdx
index ee9f173fcc5804..104792e6eb208a 100644
--- a/docs/concepts/data-management/size-limits.mdx
+++ b/docs/concepts/data-management/size-limits.mdx
@@ -27,4 +27,4 @@ Sentry's exact size limits may change over time. For more information, please re
- [Envelope Size Limits](https://develop.sentry.dev/sdk/data-model/envelopes/#size-limits)
- [Minidump Size Limits](/platforms/native/guides/minidumps/#size-limits)
-- [Variable Size Limits](https://develop.sentry.dev/sdk/expected-features/data-handling/#variable-size)
+- [Variable Size Limits](https://develop.sentry.dev/sdk/foundations/transport/event-payloads/#variable-size)
diff --git a/docs/platforms/python/configuration/options.mdx b/docs/platforms/python/configuration/options.mdx
index 9ed296b70b552c..a378a736d04cf0 100644
--- a/docs/platforms/python/configuration/options.mdx
+++ b/docs/platforms/python/configuration/options.mdx
@@ -174,7 +174,7 @@ This parameter controls whether integrations should capture HTTP request bodies.
- `medium`: Medium and small requests will be captured (typically 10KB).
- `always`: The SDK will always capture the request body as long as Sentry can make sense of it.
-Please note that the Sentry server [limits HTTP request body size](https://develop.sentry.dev/sdk/expected-features/data-handling/#variable-size). The server always enforces its size limit, regardless of how you configure this option.
+Please note that the Sentry server [limits HTTP request body size](https://develop.sentry.dev/sdk/foundations/transport/event-payloads/#variable-size). The server always enforces its size limit, regardless of how you configure this option.
@@ -380,7 +380,7 @@ If `trace_propagation_targets` is not provided, trace data is attached to every
-If set to `True`, the SDK will only continue a trace if the `org_id` of the incoming trace found in the
+If set to `True`, the SDK will only continue a trace if the `org_id` of the incoming trace found in the
`baggage` header matches the `org_id` of the current Sentry client and only if BOTH are present.
If set to `False`, consistency of `org_id` will only be enforced if both are present. If either are missing, the trace will be continued.