diff --git a/Sources/ElixxirDAppsSDK/Models/SingleUseResponseReport.swift b/Sources/ElixxirDAppsSDK/Models/SingleUseResponseReport.swift
new file mode 100644
index 0000000000000000000000000000000000000000..0aea471e2c7421c3b622f96065932dac221b1750
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/Models/SingleUseResponseReport.swift
@@ -0,0 +1,59 @@
+import Foundation
+
+public struct SingleUseResponseReport: Equatable {
+  public init(
+    rounds: [Int],
+    payload: Data,
+    receptionId: ReceptionId,
+    error: String?
+  ) {
+    self.rounds = rounds
+    self.payload = payload
+    self.receptionId = receptionId
+    self.error = error
+  }
+
+  public var rounds: [Int]
+  public var payload: Data
+  public var receptionId: ReceptionId
+  public var error: String?
+}
+
+extension SingleUseResponseReport {
+  public struct ReceptionId: Equatable {
+    public init(
+      ephId: [Int],
+      source: Data
+    ) {
+      self.ephId = ephId
+      self.source = source
+    }
+
+    public var ephId: [Int]
+    public var source: Data
+  }
+}
+
+extension SingleUseResponseReport: Codable {
+  enum CodingKeys: String, CodingKey {
+    case rounds = "Rounds"
+    case payload = "Payload"
+    case receptionId = "ReceptionID"
+    case error = "Err"
+  }
+
+  public static func decode(_ data: Data) throws -> Self {
+    try JSONDecoder().decode(Self.self, from: data)
+  }
+
+  public func encode() throws -> Data {
+    try JSONEncoder().encode(self)
+  }
+}
+
+extension SingleUseResponseReport.ReceptionId: Codable {
+  enum CodingKeys: String, CodingKey {
+    case ephId = "EphId"
+    case source = "Source"
+  }
+}
diff --git a/Tests/ElixxirDAppsSDKTests/Models/SingleUseResponseReportTests.swift b/Tests/ElixxirDAppsSDKTests/Models/SingleUseResponseReportTests.swift
new file mode 100644
index 0000000000000000000000000000000000000000..223582b948f34a1c8f18de5c8464a33d67602fb0
--- /dev/null
+++ b/Tests/ElixxirDAppsSDKTests/Models/SingleUseResponseReportTests.swift
@@ -0,0 +1,71 @@
+import CustomDump
+import XCTest
+@testable import ElixxirDAppsSDK
+
+final class SingleUseResponseReportTests: XCTestCase {
+  func testCoding() throws {
+    let rounds: [Int] = [1, 5, 9]
+    let payloadB64 = "rSuPD35ELWwm5KTR9ViKIz/r1YGRgXIl5792SF8o8piZzN6sT4Liq4rUU/nfOPvQEjbfWNh/NYxdJ72VctDnWw=="
+    let receptionIdEphId: [Int] = [0, 0, 0, 0, 0, 0, 3, 89]
+    let receptionIdSourceB64 = "emV6aW1hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD"
+    let jsonString = """
+    {
+      "Rounds": [\(rounds.map { "\($0)" }.joined(separator: ", "))],
+      "Payload": "\(payloadB64)",
+      "ReceptionID": {
+        "EphId": [\(receptionIdEphId.map { "\($0)" }.joined(separator: ", "))],
+        "Source": "\(receptionIdSourceB64)"
+      },
+      "Err": null
+    }
+    """
+    let jsonData = jsonString.data(using: .utf8)!
+    let report = try SingleUseResponseReport.decode(jsonData)
+
+    XCTAssertNoDifference(report, SingleUseResponseReport(
+      rounds: rounds,
+      payload: Data(base64Encoded: payloadB64)!,
+      receptionId: .init(
+        ephId: receptionIdEphId,
+        source: Data(base64Encoded: receptionIdSourceB64)!
+      ),
+      error: nil
+    ))
+
+    let encodedReport = try report.encode()
+    let decodedReport = try SingleUseResponseReport.decode(encodedReport)
+
+    XCTAssertNoDifference(decodedReport, report)
+  }
+
+  func testDecodingReportWithError() throws {
+    let rounds: [Int] = [1, 5, 9]
+    let payloadB64 = "rSuPD35ELWwm5KTR9ViKIz/r1YGRgXIl5792SF8o8piZzN6sT4Liq4rUU/nfOPvQEjbfWNh/NYxdJ72VctDnWw=="
+    let receptionIdEphId: [Int] = [0, 0, 0, 0, 0, 0, 3, 89]
+    let receptionIdSourceB64 = "emV6aW1hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD"
+    let error = "something went wrong"
+    let jsonString = """
+    {
+      "Rounds": [\(rounds.map { "\($0)" }.joined(separator: ", "))],
+      "Payload": "\(payloadB64)",
+      "ReceptionID": {
+        "EphId": [\(receptionIdEphId.map { "\($0)" }.joined(separator: ", "))],
+        "Source": "\(receptionIdSourceB64)"
+      },
+      "Err": "\(error)"
+    }
+    """
+    let jsonData = jsonString.data(using: .utf8)!
+    let report = try SingleUseResponseReport.decode(jsonData)
+
+    XCTAssertNoDifference(report, SingleUseResponseReport(
+      rounds: rounds,
+      payload: Data(base64Encoded: payloadB64)!,
+      receptionId: .init(
+        ephId: receptionIdEphId,
+        source: Data(base64Encoded: receptionIdSourceB64)!
+      ),
+      error: error
+    ))
+  }
+}