diff --git a/src/components/sidebar.tsx b/src/components/sidebar.tsx
index 2e8857a8fa..bceb40abb3 100644
--- a/src/components/sidebar.tsx
+++ b/src/components/sidebar.tsx
@@ -94,6 +94,9 @@ export default () => {
n.name === 'dynamic-sampling').children} />
+
+ User Feedback Architecture
+
diff --git a/src/docs/feedback-architecture.mdx b/src/docs/feedback-architecture.mdx
new file mode 100644
index 0000000000..d4ed6d4ab2
--- /dev/null
+++ b/src/docs/feedback-architecture.mdx
@@ -0,0 +1,197 @@
+---
+title: User Feedback Architecture
+---
+
+**The goal of this doc is to give engineers an in-depth understanding of User Feedback's backend.**
+It will:
+1. describe the relevant ingestion pipelines, data models, and functions.
+2. explain the difference between “feedback”, “user reports”, and “crash reports”, and why we built and need to support each.
+
+## Creation sources
+When broken down, there are **5** ways to create feedback in our system 😵💫.
+(But 4 of them, related to user reports, are quite similar!) A good reference is the
+`FeedbackCreationSource(Enum)` in [create_feedback.py](https://github.com/getsentry/sentry/blob/2b642e149c79b251e1c2f4339fc73d656347d74e/src/sentry/feedback/usecases/create_feedback.py#L33-L33).
+The 4 ways _clients_ can create feedback are:
+
+`NEW_FEEDBACK_ENVELOPE`: [The new format](https://develop.sentry.dev/sdk/envelopes/#full-examples) created by the Replay team when adding
+the [User Feedback Widget](https://docs.sentry.io/product/user-feedback/#user-feedback-widget)
+to the JavaScript SDK. It allows adding more information, for example tags,
+release, url, etc.
+
+`USER_REPORT_ENVELOPE`: [The older format](https://develop.sentry.dev/sdk/envelopes/#user-feedback) with name/email/comments, that requires
+`event_id` to link a Sentry error event.
+
+`USER_REPORT_DJANGO_ENDPOINT`: [The Web API](https://docs.sentry.io/api/projects/submit-user-feedback/)
+
+`CRASH_REPORT_EMBED_FORM`: The [crash report modal](https://docs.sentry.io/product/user-feedback/#crash-report-modal)
+
+## How feedback is stored
+On the backend, each feedback submission in Sentry's UI is **an un-grouped issue occurrence**,
+saved via the [issues platform](https://develop.sentry.dev/issue-platform/).
+The entrypoint is [**`create_feedback_issue()`**](https://github.com/getsentry/sentry/blob/2b642e149c79b251e1c2f4339fc73d656347d74e/src/sentry/feedback/usecases/create_feedback.py#L184-L184),
+which
+1. filters feedback with empty or spam messages. Note **anonymous feedbacks are not filtered** (missing name and/or email).
+2. sends to issues pipeline in a standardized format. To make sure it is never grouped, we use a random UUID for the fingerprint.
+
+---
+
+## Feedback events
+
+The new and preferred way to send feedback from the SDK is in an [event envelope](https://develop.sentry.dev/sdk/envelopes/#full-examples).
+The format is the same as error events, except the `type` header = `"feedback"`. While
+user reports have an associated event, **new feedback _is_ an event**. This
+offers 2 improvements:
+
+1. Users can submit generic feedback without an error occurring. We're allowing users to catch things that Sentry can’t!
+2. Rather than waiting for the associated error to be ingested asynchronously, we immediately get access to context like the environment, platform, replay, user, tags...
+
+The user's submission is wrapped in a context object:
+
+```Python/Javascript
+event[”contexts”][”feedback”] = {
+ "name": ,
+ "contact_email": ,
+ "message": ,
+ "url": ,
+ "source":
+}
+
+// all fields are technically optional, but recommended
+// the widget can be configured to require a non-empty email and/or name
+```
+
+- This doc refers to the payload format (`event` in the pseudo-code above) as a “**feedback event”**.
+- The feedback [widget](https://docs.sentry.io/platforms/javascript/user-feedback/#user-feedback-widget), which is installed by default, sends these envelopes.
+- API: for SDK v8.0.0+, we use the `sendFeedback` function.
+
+
+### Ingest diagram
+
+
+[diagram source](https://mermaid.live/edit#pako:eNptkc1qwzAQhF9F7MmGmN59KJSmx_ZQ91IsYxR5YwvbkqqfgEny7l05NW0hOg3a0erb2TNI0yGU0DthB_ax55rREdbWnyY69mTtpKQIyuiGFcUju3BAfcLJWORwYe84iYVrHlaxOo6tNNrHGV1WK92jD8URsTsIORZ4Qh18k6cXv76t8VfEiJ4JzyRO6BYWhB_TL9KhCNhubVrlfcTU425hbWf-UHD44TBSRudQS_QcbhTmP4WmNHwwDuvsbZN5c8dIuC9pmCoQwpwgvY4HUWccqiQenim3cTDRU055Azugl7NQHWV9TiFzCAPOVCxJTqofAgeur2QUMZhq0RLK4CLuINqOhtwrQTuat0vsFLG93pa37vD6DRJvo7g)
+
+In Relay v24.5.1, we migrated feedback to its own kafka topic + consumer,
+`ingest-feedback-events`. This decouples risk and ownership from errors
+(`ingest-events`).
+
+
+### Attachments
+
+We only use attachments for the widget’s screenshot feature, which allows users
+to submit **at most 1 screenshot per feedback**. Attachments are another [item type](https://develop.sentry.dev/sdk/envelopes/#attachment)
+in an envelope.
+- SDK v8.0.0+, Relay v24.5.1+: Sends the feedback and attachment items in the same envelope.
+- SDK < v8, all Relay versions: Sends a separate envelope for each item.
+
+**The feedback pipeline does not process attachments**. Relay routes them to
+a separate topic and storage, and the UI makes a separate request for them.
+
+---
+
+## User reports
+
+The deprecated way of sending feedback is as a **user report**. This is a simple typed dict:
+
+```Python/Javascript
+user_report = {
+ "event_id": ,
+ "email": ,
+ "name": ,
+ "comments": ,
+}
+```
+
+
+### Ingest diagram
+
+[diagram source](https://mermaid.live/edit#pako:eNp9VNtq3DAQ_ZVBEHAgy77vQ6EkDfShF7KhUKzFaOXZtYgtqbpsCUn-vaOxvWmT3frF4-HozJkzIz8J7VoUK7EPyndwfyOtTDFvx8812hQeS0qmgN6F1KBtvTM21VIsc8Sw2CG2W6UfpNiMQB1U7JoJPrhW9YS9Lkm44yT8MPh7ghMdvf6uuctWJ-NsrG_nCBYQsgVjIeAOQ8AwlYrqgE1RMVYrSaAndmZokmuO0iZdqBIek42JMeNJHlgsPsCzFJ9vAQ9kAfjgNMaIrRTPZ9jfZpnjbMlj2xcXgPaAvfMI3njsjWWA8r7-6XKAj973Rqviw2bWNZ8oau6wVzwhDhihSIc3uqqN3WNMC5WS0t1AjcTNJZOPAAa_t3BWNc4ZlG2BRwojIk7yZjHfv63vi5A3-3GG_NTJ9wvzX2VsYgTfq7RzYSjZkz4ziWs0LVAeMFS0hZMhTutMrJZmSmvIlrzi-JilSxGTC1hXX-fwcnMCSG18KiuypvuhBl4Pm7eqrtbltbym2T10jrrg02MDpafJLm4yLrNvST87e2oVvYtpHzDWFZk2xVKMerjcLOVXxmDIG95aFs2K_qUUV4LUD8q0dO2fpAWQInU4EHZFYW_2XZJC2hcCqpzc-tFqsUoh45UYhd4YRXd1EKud6iNlsTVU68v4I-H_ycsfwTWaqg)
+
+
+### Shimming to feedback
+
+Before it was extended to generic feedback, the [`UserReport` model](https://github.com/getsentry/sentry/blob/2b642e149c79b251e1c2f4339fc73d656347d74e/src/sentry/models/userreport.py#L9-L9)
+was first used for crash reports. Therefore an associated event ID is required, and
+we use it to set environment and group before saving the model to **Postgres**.
+Only then can we shim the report to a **feedback event** and pass it to `create_feedback_issue()`.
+
+If the event hasn’t reached eventstore (Snuba) by the time of ingest, we still
+save the report, but leave the environment + group empty and skip feedback creation.
+
+To ensure the skipped reports eventually get fixed and shimmed, we
+added a post process job to the errors pipeline: [`link_event_to_user_report()`](https://github.com/getsentry/sentry/blob/2b642e149c79b251e1c2f4339fc73d656347d74e/src/sentry/tasks/post_process.py#L1387-L1387).
+This is the 5th, automated way of creating feedback.
+
+Simplified diagram:
+
+[diagram source](https://mermaid.live/edit#pako:eNpdULtuwzAM_BWBUwIkzm4UXZq1QIF0MwNDlllLTfSoKAUokvx7ZasZWi06kMfj8a6g_EjQwhRl0OJ9j06Ux9rYPvn-g2gcpDqJ7fZZ3BCapkG4CXZ5kN3qMH-7l7NRJ-0z0_qIDtPSfAx8ZYqGWNCFXOLkI83zIfSffqirKu4QKEYfWQTPSYToFTGLmQVH8fRXbZfDKBPxIlXoUyTuVghvvxihOqnSi5X_B9XdsAFL0UozlgSucw0habLFZFvg2Uw6IaC7F6LMyR--nYI2xUwbqB72Rpbk7KNIoyk3vtZIl2TvP_9DeX4)
+
+
+
+### Envelopes
+
+User reports are also sent to Relay in [envelope format](https://develop.sentry.dev/sdk/envelopes/#user-feedback).
+**This item type is misleadingly called “user feedback” in some of our docs, but the
+item header will read `"user_report"`.**
+
+The SDK function that sends these is `captureUserFeedback`.
+
+
+### Django endpoint
+
+Before our envelope ingest service existed, older SDKs directly POST the report
+to Sentry, with
+`/api/0/projects/{organization_id_or_slug}/{project_id_or_slug}/user-feedback/`.
+
+See [https://docs.sentry.io/api/projects/submit-user-feedback/](https://docs.sentry.io/api/projects/submit-user-feedback/).
+
+
+### Crash reports
+
+The **crash report modal** pops up when Sentry detects an error on the current
+page, prompting users to describe what happened. On the backend, crash report
+data is the same as user reports.
+
+You can install it as an [SDK integration](https://docs.sentry.io/platforms/javascript/user-feedback/#crash-report-modal).
+
+We implement it as a Django view:
+* URL: `/api/embed/error-page/`
+* Python Class: `error_page_embed.ErrorPageEmbedView`
+
+Crash reports are also shimmed to feedback. The pipeline is the same as the
+`/user-feedback` endpoint.
+
+---
+
+## Sentry UI
+
+
+[diagram source](https://mermaid.live/edit#pako:eNp9Uj1vwjAQ_SvWTUECsWdgKaViqFQVmDhUmeRILBI7tc8DAv577YRAG6F68fn53b37OkNmcoIUCiubUqznqEU4zu87YMXGyoJcB8fTGMeFJbdNED5utkg2juwnNcayGyGMdg--034vt8kqXtOXSmXH0nhHPYV03hmokR-ypNmeIoSsnPPkvgKxMUrzFmHaQQi7pwwxmczEBeHtdY1wEV4FlwVRvpfZUWyWIpkebq_RPYRtc_8jEpK0k57ZEvuSBuSB3u23lV3GzMScWKrKRe2ZiJ0Si2dh_y_jHvZX3zqzn0jv8O3JqtieyzDTtsdxEE-oA3UYQ022lioPy3GOQghcUk0IaTArVZSMgPoaiNKzWZ10BilbT2PwTS6Z5kqGYdaQHmTlAkq5Csv03q1bu3XXH4El2dU)
+
+You can view the user reports related to a specific issue at the "User Feedback"
+tab of Issue Details. This excludes "new" feedback (anything sent from the widget).
+
+---
+
+## Email alerts
+
+Email alerts are triggered in feedback’s post process pipeline. (Unrelated to
+the post process diagram above.) We apply some feedback-specific
+filters, **skipping emails if:**
+
+1. The feedback is [marked as spam](https://docs.sentry.io/product/user-feedback/#spam-detection-for-user-feedback) AND the `organizations.user-feedback-spam-filter-actions` feature flag is enabled.
+2. The source is NOT a new feedback envelope / the widget, AND the “Crash Report Notifications” setting is disabled.
+ - in UI: Settings > Projects > (project slug) > User Feedback > “Enable Crash Report Notifications”
+ - project option in code: `sentry:feedback_user_report_notifications`
+ - default = true/enabled
+
+---
+
+## Feature flags for self-hosted
+To disable all UI features and/or ingestion, set these to false:
+* `organizations:user-feedback-ui`
+* `organizations:feedback-visible`
+* `organizations:user-feedback-ingest`
+
+To disable auto spam filters, set these to false:
+* `organizations:user-feedback-spam-filter-ingest`
+* `organizations:user-feedback-spam-filter-actions`