diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/Requests/ImmutableData/CardMasterRequest.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/Requests/ImmutableData/CardMasterRequest.cs
new file mode 100644
index 00000000..e9584d26
--- /dev/null
+++ b/SVSim.EmulatedEntrypoint/Models/Dtos/Requests/ImmutableData/CardMasterRequest.cs
@@ -0,0 +1,18 @@
+using MessagePack;
+using System.Text.Json.Serialization;
+using SVSim.EmulatedEntrypoint.Models.Dtos.Requests;
+
+namespace SVSim.EmulatedEntrypoint.Models.Dtos.Requests.ImmutableData;
+
+///
+/// Wire body for POST /immutable_data/card_master. Client populates from
+/// GetCardMasterTask.CardMasterTaskParam (Wizard/GetCardMasterTask.cs:14). For Tier 1
+/// the hash is bound only for completeness — the controller serves the static blob regardless.
+///
+[MessagePackObject]
+public class CardMasterRequest : BaseRequest
+{
+ [JsonPropertyName("card_master_hash")]
+ [Key("card_master_hash")]
+ public string? CardMasterHash { get; set; }
+}
diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/Responses/ImmutableData/CardMasterResponse.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/Responses/ImmutableData/CardMasterResponse.cs
new file mode 100644
index 00000000..c23b2a2b
--- /dev/null
+++ b/SVSim.EmulatedEntrypoint/Models/Dtos/Responses/ImmutableData/CardMasterResponse.cs
@@ -0,0 +1,17 @@
+using MessagePack;
+using System.Text.Json.Serialization;
+
+namespace SVSim.EmulatedEntrypoint.Models.Dtos.Responses.ImmutableData;
+
+///
+/// Wire response shape. Client decodes card_master via:
+/// Convert.FromBase64String → GZipStream.UncompressBuffer → UTF-8 decode →
+/// JsonMapper.ToObject, yielding a dict { "1": "<csv>", "2"?: "<csv>" }.
+///
+[MessagePackObject]
+public class CardMasterResponse
+{
+ [JsonPropertyName("card_master")]
+ [Key("card_master")]
+ public string CardMaster { get; set; } = "";
+}