diff --git a/services/reports/src/http/handlers.rs b/services/reports/src/http/handlers.rs
--- a/services/reports/src/http/handlers.rs
+++ b/services/reports/src/http/handlers.rs
@@ -1,4 +1,5 @@
 use actix_web::{get, post, web, HttpResponse};
+use http::header;
 use serde::Deserialize;
 
 use super::NotFoundHandler;
@@ -49,3 +50,23 @@
   let response = HttpResponse::Ok().json(report);
   Ok(response)
 }
+
+#[get("/{report_id}/redux-devtools.json")]
+async fn redux_devtools_import(
+  path: web::Path<String>,
+  service: ReportsService,
+) -> actix_web::Result<HttpResponse> {
+  let report_id = path.into_inner();
+  let devtools_json = service
+    .get_redux_devtools_import(report_id.clone().into())
+    .await?
+    .unwrap_or_404()?;
+
+  let response = HttpResponse::Ok()
+    .insert_header((
+      header::CONTENT_DISPOSITION,
+      format!("attachment; filename=report-{}.json", report_id),
+    ))
+    .json(devtools_json);
+  Ok(response)
+}
diff --git a/services/reports/src/http/mod.rs b/services/reports/src/http/mod.rs
--- a/services/reports/src/http/mod.rs
+++ b/services/reports/src/http/mod.rs
@@ -37,7 +37,8 @@
       .service(
         web::scope("/reports")
           .service(handlers::post_reports)
-          .service(handlers::get_single_report),
+          .service(handlers::get_single_report)
+          .service(handlers::redux_devtools_import),
       )
   })
   .bind(("0.0.0.0", CONFIG.http_port))?
diff --git a/services/reports/src/service.rs b/services/reports/src/service.rs
--- a/services/reports/src/service.rs
+++ b/services/reports/src/service.rs
@@ -5,12 +5,15 @@
   database,
 };
 use derive_more::{Display, Error, From};
-use std::future::{ready, Ready};
+use std::{
+  collections::HashMap,
+  future::{ready, Ready},
+};
 use tracing::error;
 
 use crate::{
   database::{client::DatabaseClient, item::ReportItem},
-  report_types::{ReportID, ReportInput, ReportOutput},
+  report_types::{ReportID, ReportInput, ReportOutput, ReportType},
 };
 
 #[derive(Debug, Display, Error, From)]
@@ -125,6 +128,22 @@
     };
     Ok(Some(output))
   }
+
+  pub async fn get_redux_devtools_import(
+    &self,
+    report_id: ReportID,
+  ) -> ServiceResult<Option<serde_json::Value>> {
+    let Some(report) = self.get_report(report_id).await? else {
+      return Ok(None);
+    };
+    if !matches!(report.report_type, ReportType::ErrorReport) {
+      return Err(ReportsServiceError::UnsupportedReportType);
+    };
+
+    let redux_devtools_payload = prepare_redux_devtools_import(report.content)
+      .map_err(ReportsServiceError::SerdeError)?;
+    Ok(Some(redux_devtools_payload))
+  }
 }
 
 impl FromRequest for ReportsService {
@@ -160,3 +179,29 @@
     ready(Ok(auth_service))
   }
 }
+
+/// Transforms report content JSON into format that can be
+/// imported into Redux DevTools.
+fn prepare_redux_devtools_import(
+  mut error_report: HashMap<String, serde_json::Value>,
+) -> Result<serde_json::Value, serde_json::Error> {
+  use serde_json::{json, map::Map, Value};
+
+  let nav_state = error_report.remove("navState");
+  let actions = error_report.remove("actions");
+  let mut preloaded_state = error_report
+    .remove("preloadedState")
+    .unwrap_or_else(|| Value::Object(Map::new()));
+
+  preloaded_state["navState"] = nav_state.into();
+  preloaded_state["frozen"] = true.into();
+  preloaded_state["_persist"]["rehydrated"] = false.into();
+
+  let preload_state_str = serde_json::to_string(&preloaded_state)?;
+  let payload_str = serde_json::to_string(&actions)?;
+
+  Ok(json!({
+    "preloadedState": preload_state_str,
+    "payload": payload_str,
+  }))
+}