---
title: "Feedback"
description: "Collecting qualitative user input with optional attachments, replay links, and error associations."
url: https://develop.sentry.dev/sdk/telemetry/feedbacks/
---

# Feedback

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`1.3.0`[(changelog)](https://develop.sentry.dev/sdk/telemetry/feedbacks.md#changelog)

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

User feedback allows Sentry to collect qualitative input directly from users — free-form comments describing what happened, optionally accompanied by contact information, linked errors, replay recordings, and file attachments. An SDK sends feedback as a `feedback` envelope item containing an event payload with a `feedback` context object.

Related specs:

* [Envelopes](https://develop.sentry.dev/sdk/foundations/transport/envelopes.md) — transport format
* [Event Payloads](https://develop.sentry.dev/sdk/foundations/transport/event-payloads.md) — base event attributes
* [User Report (Deprecated)](https://develop.sentry.dev/sdk/telemetry/user-reports.md) — deprecated predecessor

***

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

### [Feedback Events](https://develop.sentry.dev/sdk/telemetry/feedbacks.md#feedback-events)

A **feedback event** is an [event payload](https://develop.sentry.dev/sdk/foundations/transport/event-payloads.md) with a `feedback` context object. The feedback context carries user-provided data (message, contact info, URLs), while the event payload carries standard attributes (timestamp, event\_id, platform, user, tags, etc.).

### [Attachments](https://develop.sentry.dev/sdk/telemetry/feedbacks.md#attachments)

Files of any type (screenshots, logs, documents) can accompany a feedback event by sending them as [attachment items](https://develop.sentry.dev/sdk/telemetry/attachments.md) in the same envelope. Sentry uses the shared `event_id` to associate attachments with the feedback.

***

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

### [SDK Pipeline](https://develop.sentry.dev/sdk/telemetry/feedbacks.md#sdk-pipeline)

Stablespecified since

<!-- -->

1.0.0

A feedback captured by `capture_feedback` is processed through the SDK pipeline. The feedback event can be discarded at any stage, at which point no further processing happens.

SDKs **SHOULD** implement a `beforeSendFeedback` callback to allow users to modify or discard the feedback before it is sent. This callback **SHOULD** be similar to the existing [`beforeSend`](https://develop.sentry.dev/sdk/foundations/client/hooks.md#before-send-hook) callback used for error events. Feedback events **MUST NOT** go through the `beforeSend` hook.

SDKs **MUST** apply scope data to the feedback event, including tags, user, trace, and contexts. The scope's event processors **MUST** also be invoked.

SDKs **MUST** apply [rate limiting](https://develop.sentry.dev/sdk/foundations/transport/rate-limiting.md) to feedbacks in the same way as it is applied to events.

There is no sample rate for feedbacks — they are always sent. However, a feedback can be discarded at any pipeline stage (rate limiting, invalid message, etc.). SDKs **SHOULD** report dropped feedbacks through [client reports](https://develop.sentry.dev/sdk/telemetry/client-reports.md).

### [Session Replay Integration](https://develop.sentry.dev/sdk/telemetry/feedbacks.md#session-replay-integration)

Stablespecified since

<!-- -->

1.0.0

When sending feedback, SDKs **SHOULD** flush the current Session Replay, if running. This ensures a meaningful replay recording exists and can be included in the `replay_id` attribute of the feedback context.

### [Replay Sampling Timing for Feedback Widgets](https://develop.sentry.dev/sdk/telemetry/feedbacks.md#replay-sampling-timing-for-feedback-widgets)

Stablespecified since

<!-- -->

1.1.0

For feedback widgets specifically, when Session Replay's `onErrorSampleRate` is greater than 0, SDKs **MUST** sample and flush the replay when the widget **opens**, not when the user submits the feedback.

This timing is critical because:

* The replay buffer captures the user's session leading up to opening the feedback widget, providing context about what the user experienced before deciding to provide feedback.
* If sampling only occurs on submission, the buffer would primarily contain the user's interactions with the feedback form itself, which provides minimal debugging value.
* Early sampling ensures the complete user context is preserved regardless of whether the user ultimately submits the feedback.

### [Replay Sampling Timing for Manual API](https://develop.sentry.dev/sdk/telemetry/feedbacks.md#replay-sampling-timing-for-manual-api)

Stablespecified since

<!-- -->

1.2.0

When feedback is captured using the manual API (`capture_feedback`), SDKs **MUST** sample and flush the replay during the execution of the feedback capture API to ensure session context is preserved.

### [User-Facing Platforms](https://develop.sentry.dev/sdk/telemetry/feedbacks.md#user-facing-platforms)

Stablespecified since

<!-- -->

1.0.0

On user-facing platforms such as mobile, desktop, or browser, SDKs **SHOULD** provide first-class support for requesting user feedback when an error or crash occurs. See the user-facing docs for [Apple](https://docs.sentry.io/platforms/apple/enriching-events/user-feedback/) and [Java](https://docs.sentry.io/platforms/java/enriching-events/user-feedback/) for API examples.

On mobile and desktop, it is common to prompt the user for feedback after a crash happened on the previous run of the application. SDKs **SHOULD** implement the `onCrashedLastRun` callback on the options. This callback gets called shortly after the initialization of the SDK when the last program execution terminated with a crash. The SDK **SHOULD** execute the callback only once during the entire run of the program to avoid multiple callbacks if there are multiple crash events to send.

### [Backend Platforms](https://develop.sentry.dev/sdk/telemetry/feedbacks.md#backend-platforms)

Stablespecified since

<!-- -->

1.0.0

On backend platforms, SDKs **SHOULD** document how to use the [last event ID](https://develop.sentry.dev/sdk/foundations/state-management/scopes.md#event-id-retrieval) to prompt the user for feedback themselves.

***

## [Wire Format](https://develop.sentry.dev/sdk/telemetry/feedbacks.md#wire-format)

### [Feedback Payload](https://develop.sentry.dev/sdk/telemetry/feedbacks.md#feedback-payload)

Stablespecified since

<!-- -->

1.0.0

A feedback is sent as a `feedback` envelope item containing a JSON object. The object is an [event payload](https://develop.sentry.dev/sdk/foundations/transport/event-payloads.md) with an additional `feedback` context object.

#### [Envelope Item Constraints](https://develop.sentry.dev/sdk/telemetry/feedbacks.md#envelope-item-constraints)

* This Item **MAY** occur at most once per Envelope.
* This Item is mutually exclusive with `"transaction"` items.

#### [Envelope Headers](https://develop.sentry.dev/sdk/telemetry/feedbacks.md#envelope-headers)

* `event_id`

  **UUID String, required.** Corresponds to the `event_id` field of the event payload. **It is not equal to the `associated_event_id`** field in the feedback context. Clients are required to generate an event identifier ahead of time and set it at least in the Envelope headers. If the identifier mismatches between the Envelope and payload, the Envelope header takes precedence.

#### [Additional Item Headers](https://develop.sentry.dev/sdk/telemetry/feedbacks.md#additional-item-headers)

*None*

#### [Event Attributes](https://develop.sentry.dev/sdk/telemetry/feedbacks.md#event-attributes)

Below is a recap of the [required attributes](https://develop.sentry.dev/sdk/foundations/transport/event-payloads.md#required-attributes) for the event payload. For the full list of attributes, see [Event Payloads](https://develop.sentry.dev/sdk/foundations/transport/event-payloads.md).

| Field       | Type   | Required     | Since | Description                                      |
| ----------- | ------ | ------------ | ----- | ------------------------------------------------ |
| `event_id`  | String | **REQUIRED** | 1.0.0 | Hexadecimal string representing a UUID v4 value. |
| `timestamp` | Number | **REQUIRED** | 1.0.0 | UNIX timestamp of the current time (in seconds). |
| `platform`  | String | **REQUIRED** | 1.0.0 | Platform of the SDK.                             |

#### [Feedback Context Attributes](https://develop.sentry.dev/sdk/telemetry/feedbacks.md#feedback-context-attributes)

The `contexts.feedback` object carries user-provided feedback data:

| Field                 | Type   | Required     | Since | Description                                                                                                                                                                      |
| --------------------- | ------ | ------------ | ----- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `message`             | String | **REQUIRED** | 1.0.0 | Comments of the user, describing what happened and/or sharing feedback. Max length: **4096 characters**.                                                                         |
| `contact_email`       | String | **OPTIONAL** | 1.0.0 | Email of the user who submitted the feedback. If excluded, Sentry (not the SDK) attempts to fill this in from user context. Anonymous feedbacks (no name or email) are accepted. |
| `name`                | String | **OPTIONAL** | 1.0.0 | Name of the user who submitted the feedback. If excluded, Sentry (not the SDK) attempts to fill this in from user context.                                                       |
| `url`                 | String | **OPTIONAL** | 1.0.0 | URL of the webpage the user was on when submitting feedback. May be used for search or alerts.                                                                                   |
| `associated_event_id` | String | **OPTIONAL** | 1.0.0 | Identifier of an error event in the same project. Links a related error in the feedback UI.                                                                                      |
| `replay_id`           | String | **OPTIONAL** | 1.0.0 | Identifier of a related Session Replay in the same project. Sentry uses this to render a Replay clip in the feedback UI.                                                         |

### [File Attachments](https://develop.sentry.dev/sdk/telemetry/feedbacks.md#file-attachments)

Stablespecified since

<!-- -->

1.0.0

SDKs **MAY** attach files of any type to a feedback (screenshots, logs, documents, etc.) by sending them as [attachment items](https://develop.sentry.dev/sdk/telemetry/attachments.md), with `event_id` corresponding to the feedback item. SDKs **SHOULD** send attachment items in the same envelope as the feedback item. (since 1.3.0) Attachments are not limited to screenshots — any file type is supported.

***

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

### [Capture Feedback](https://develop.sentry.dev/sdk/telemetry/feedbacks.md#capture-feedback)

Stablespecified since

<!-- -->

1.0.0

SDKs **MUST** expose a top-level function to send a feedback:

```bash
captureFeedback(feedback) -> eventId
```

**Parameters:**

* `feedback` — Object containing at minimum `message`. Optionally includes `contact_email`, `name`, `url`, `associated_event_id`, and `replay_id`.

**Returns:** The `eventId` (string).

Naming **SHOULD** follow the SDK's language conventions:

* `captureFeedback` (JavaScript, Java)
* `capture_feedback` (Python, Ruby)
* `CaptureFeedback` (Go, .NET)

***

## [Examples](https://develop.sentry.dev/sdk/telemetry/feedbacks.md#examples)

### [Feedback Payload](https://develop.sentry.dev/sdk/telemetry/feedbacks.md#feedback-payload-1)

```json
{
  "event_id": "9ec79c33ec9942ab8353589fcb2e04dc",
  "timestamp": "2011-05-02T17:41:36Z",
  "platform": "javascript",
  "contexts": {
    "feedback": {
      "contact_email": "john@example.com",
      "name": "John Smith",
      "message": "I love session replay!",
      "url": "https://sentry.io/replays/",
      "associated_event_id": "32fd1995636d446385016e2747623e11",
      "replay_id": "82840977e85b4ed3bc27f7b5b25cec15"
    }
  }
}
```

### [Full Envelope with Attachments](https://develop.sentry.dev/sdk/telemetry/feedbacks.md#full-envelope-with-attachments)

```json
{"event_id":"9ec79c33ec9942ab8353589fcb2e04dc","sent_at":"2024-03-19T15:18:27.581Z","sdk":{"name":"sentry.javascript.react","version":"7.105.0"}}
{"type":"feedback"}
{
  "event_id": "9ec79c33ec9942ab8353589fcb2e04dc",
  "timestamp": "2011-05-02T17:41:36Z",
  "platform": "javascript",
  "contexts": {
    "organization": { "id": "0", "slug": "sentry" },
    "feedback": {
      "contact_email": "john@example.com",
      "name": "John Smith",
      "message": "I love session replay!",
      "url": "https://sentry.io/replays/",
      "associated_event_id": "32fd1995636d446385016e2747623e11",
      "replay_id": "82840977e85b4ed3bc27f7b5b25cec15"
    }
  },
  "level": "error",
  "environment": "prod",
  "release": "frontend@f00",
  "sdk": {
    "integrations": [
      "BrowserTracing",
      "BrowserProfiling",
      "Replay",
      "ReplayCanvas"
    ],
    "name": "sentry.javascript.react",
    "version": "7.105.0"
  },
  "tags": {
    "sentry_version": "24.4.0.dev0"
  },
  "user": {
    "ip_address": "127.0.0.1",
    "email": "john@example.com",
    "id": 1,
    "name": "John Smith"
  }
}
{"type":"attachment","length":1234,"filename":"screenshot.png"}
<binary screenshot data>
{"type":"attachment","length":567,"filename":"debug-logs.txt"}
<text file content>
```

### [Example Implementations](https://develop.sentry.dev/sdk/telemetry/feedbacks.md#example-implementations)

User Feedback class:

* [Objective-C](https://github.com/getsentry/sentry-cocoa/blob/9eedc425727f0daccca1bd2be6021f6c3d9c654c/Sources/Sentry/SentryUserFeedback.m)
* [Java](https://github.com/getsentry/sentry-java/blob/671f9e0b8b709ef18e8b0788c31df44f99d09d35/sentry/src/main/java/io/sentry/UserFeedback.java#L7)
* [C#](https://github.com/getsentry/sentry-dotnet/blob/6ddf8363170bffee74a8c3cbf44335797d39ca9c/src/Sentry/Protocol/UserFeedback.cs#L10)

Envelope item:

* [Objective-C](https://github.com/getsentry/sentry-cocoa/blob/fd3e46efe59324e894d5601a7b3028824a588dda/Sources/Sentry/SentryEnvelope.m#L145-L162)
* [Java](https://github.com/getsentry/sentry-java/blob/b2e8dd43ea2ef37201b215ec409655e49e3231c8/sentry/src/main/java/io/sentry/SentryEnvelopeItem.java#L131-L155)
* [C#](https://github.com/getsentry/sentry-dotnet/blob/3bc6c66a14e653982a6a25df033d68d8ad12c4af/src/Sentry/Protocol/Envelopes/EnvelopeItem.cs#L170-L178)

***

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

| Version | Date       | Summary                                                                                                                                                                                                 |
| ------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `1.3.0` | 2026-02-04 | Broadened attachments from screenshots-only to any file type, added attachment examples to envelope                                                                                                     |
| `1.2.0` | 2025-06-30 | Added manual API replay sampling timing requirement                                                                                                                                                     |
| `1.1.0` | 2025-06-19 | Added replay sampling timing requirement for feedback widgets                                                                                                                                           |
| `1.0.0` | 2025-04-15 | Initial spec — feedback protocol, envelope item constraints, context attributes, SDK pipeline, session replay integration, platform-specific guidance (onCrashedLastRun, user-facing/backend platforms) |
