diff --git a/Sources/ElixxirDAppsSDK/Models/NodeRegistrationReport.swift b/Sources/ElixxirDAppsSDK/Models/NodeRegistrationReport.swift
new file mode 100644
index 0000000000000000000000000000000000000000..135e77af9475e775433928231e6651e9ee4f0658
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/Models/NodeRegistrationReport.swift
@@ -0,0 +1,36 @@
+import Foundation
+
+public struct NodeRegistrationReport: Equatable {
+  public init(
+    registered: Int,
+    total: Int
+  ) {
+    self.registered = registered
+    self.total = total
+  }
+
+  public var registered: Int
+  public var total: Int
+}
+
+extension NodeRegistrationReport {
+  public var ratio: Double {
+    guard total != 0 else { return 0 }
+    return Double(registered) / Double(total)
+  }
+}
+
+extension NodeRegistrationReport: Codable {
+  enum CodingKeys: String, CodingKey {
+    case registered = "NumberOfNodesRegistered"
+    case total = "NumberOfNodes"
+  }
+
+  public static func decode(_ data: Data) throws -> Self {
+    try JSONDecoder().decode(Self.self, from: data)
+  }
+
+  public func encode() throws -> Data {
+    try JSONEncoder().encode(self)
+  }
+}
diff --git a/Tests/ElixxirDAppsSDKTests/Models/NodeRegistrationReportTests.swift b/Tests/ElixxirDAppsSDKTests/Models/NodeRegistrationReportTests.swift
new file mode 100644
index 0000000000000000000000000000000000000000..8411aa5b3fa5288b786c8196feb03e1322eb4ac2
--- /dev/null
+++ b/Tests/ElixxirDAppsSDKTests/Models/NodeRegistrationReportTests.swift
@@ -0,0 +1,46 @@
+import CustomDump
+import XCTest
+@testable import ElixxirDAppsSDK
+
+final class NodeRegistrationReportTests: XCTestCase {
+  func testCoding() throws {
+    let registered: Int = 128
+    let total: Int = 2048
+    let jsonString = """
+    {
+      "NumberOfNodesRegistered": \(registered),
+      "NumberOfNodes": \(total)
+    }
+    """
+    let jsonData = jsonString.data(using: .utf8)!
+    let model = try NodeRegistrationReport.decode(jsonData)
+
+    XCTAssertNoDifference(model, NodeRegistrationReport(
+      registered: registered,
+      total: total
+    ))
+
+    let encodedModel = try model.encode()
+    let decodedModel = try NodeRegistrationReport.decode(encodedModel)
+
+    XCTAssertNoDifference(decodedModel, model)
+  }
+
+  func testRatio() {
+    let model = NodeRegistrationReport(
+      registered: 128,
+      total: 2048
+    )
+
+    XCTAssertEqual(model.ratio, 0.0625)
+  }
+
+  func testRatioWhenNoNodes() {
+    let model = NodeRegistrationReport(
+      registered: 128,
+      total: 0
+    )
+
+    XCTAssertEqual(model.ratio, 0)
+  }
+}