diff --git a/api/pom.xml b/api/pom.xml
index f1720e292779a455a2a74708fa65012de4b098ef..efa2b4ef25e21ccf1798aeb4217ff9addc408bef 100644
--- a/api/pom.xml
+++ b/api/pom.xml
@@ -25,6 +25,11 @@
             <groupId>org.zalando</groupId>
             <artifactId>problem</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-annotations</artifactId>
+        </dependency>
     </dependencies>
 
+
 </project>
\ No newline at end of file
diff --git a/api/src/main/java/fitconnect/api/data/Attachment.java b/api/src/main/java/fitconnect/api/data/Attachment.java
deleted file mode 100644
index 7954f6e7b930ec5fb2b41281dfc4bea49fa252ad..0000000000000000000000000000000000000000
--- a/api/src/main/java/fitconnect/api/data/Attachment.java
+++ /dev/null
@@ -1,3 +0,0 @@
-package fitconnect.api.data;
-
-public record Attachment() { }
diff --git a/api/src/main/java/fitconnect/api/data/Data.java b/api/src/main/java/fitconnect/api/data/Data.java
deleted file mode 100644
index 0e65148af94752d02f66e77483823424b0abb2b3..0000000000000000000000000000000000000000
--- a/api/src/main/java/fitconnect/api/data/Data.java
+++ /dev/null
@@ -1,3 +0,0 @@
-package fitconnect.api.data;
-
-public record Data() { }
diff --git a/api/src/main/java/fitconnect/api/data/Metadata.java b/api/src/main/java/fitconnect/api/data/Metadata.java
deleted file mode 100644
index 0ce04e32d9427ecfd2551dcda5c4bba03f1317d5..0000000000000000000000000000000000000000
--- a/api/src/main/java/fitconnect/api/data/Metadata.java
+++ /dev/null
@@ -1,3 +0,0 @@
-package fitconnect.api.data;
-
-public record Metadata() { }
diff --git a/api/src/main/java/fitconnect/api/domain/metadata/AdditionalReferenceInfo.java b/api/src/main/java/fitconnect/api/domain/metadata/AdditionalReferenceInfo.java
new file mode 100644
index 0000000000000000000000000000000000000000..b55e7df9eb812b101dcb59da588878e2d94eb65b
--- /dev/null
+++ b/api/src/main/java/fitconnect/api/domain/metadata/AdditionalReferenceInfo.java
@@ -0,0 +1,30 @@
+package fitconnect.api.domain.metadata;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+
+import java.util.Map;
+
+/**
+ * Eine Struktur, um zusätzliche Informationen zu hinterlegen
+ */
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+        "senderReference",
+        "applicationDate"
+})
+public record AdditionalReferenceInfo(
+
+        @JsonProperty("senderReference")
+        String senderReference,
+
+        @JsonProperty("applicationDate")
+        String applicationDate,
+
+        @JsonIgnore
+        Map<String, Object> additionalProperties
+) { }
+
diff --git a/api/src/main/java/fitconnect/api/domain/metadata/AuthenticationInformation.java b/api/src/main/java/fitconnect/api/domain/metadata/AuthenticationInformation.java
new file mode 100644
index 0000000000000000000000000000000000000000..e20ceb3e3287d5c1e076a53c3e1bf5b40ab6598a
--- /dev/null
+++ b/api/src/main/java/fitconnect/api/domain/metadata/AuthenticationInformation.java
@@ -0,0 +1,4 @@
+package fitconnect.api.domain.metadata;
+
+public record AuthenticationInformation() {
+}
diff --git a/api/src/main/java/fitconnect/api/domain/metadata/ContentStructure.java b/api/src/main/java/fitconnect/api/domain/metadata/ContentStructure.java
new file mode 100644
index 0000000000000000000000000000000000000000..a25a9f89eaafbf0d8fd86a6cccf8c38e3cc39efa
--- /dev/null
+++ b/api/src/main/java/fitconnect/api/domain/metadata/ContentStructure.java
@@ -0,0 +1,31 @@
+package fitconnect.api.domain.metadata;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import fitconnect.api.domain.metadata.attachment.Attachment;
+import fitconnect.api.domain.metadata.data.Data;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Beschreibt die Struktur der zusätzlichen Inhalte der Einreichung, wie Anlagen oder Fachdaten.
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+        "data",
+        "attachments"
+})
+public record ContentStructure(
+
+        @JsonProperty("data")
+        Data data,
+
+        @JsonProperty("attachments")
+        List<Attachment> attachments,
+
+        @JsonIgnore
+        Map<String, Object> additionalProperties
+) { }
diff --git a/api/src/main/java/fitconnect/api/domain/metadata/Metadata.java b/api/src/main/java/fitconnect/api/domain/metadata/Metadata.java
new file mode 100644
index 0000000000000000000000000000000000000000..889f0c4656d5f64fe673ab43fb06bcce4b88fd15
--- /dev/null
+++ b/api/src/main/java/fitconnect/api/domain/metadata/Metadata.java
@@ -0,0 +1,42 @@
+package fitconnect.api.domain.metadata;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+
+import java.util.List;
+import java.util.Map;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+        "contentStructure",
+        "publicServiceType",
+        "authenticationInformation",
+        "paymentInformation",
+        "replyChannel",
+        "additionalReferenceInfo"
+})
+public record Metadata(
+        @JsonProperty("contentStructure")
+        ContentStructure contentStructure,
+
+        @JsonProperty("publicServiceType")
+        PublicServiceType publicServiceType,
+
+        @JsonProperty("authenticationInformation")
+        List<AuthenticationInformation> authenticationInformation,
+
+        @JsonProperty("paymentInformation")
+        PaymentInformation paymentInformation,
+
+        @JsonProperty("replyChannel")
+        ReplyChannel replyChannel,
+
+        @JsonProperty("additionalReferenceInfo")
+        AdditionalReferenceInfo additionalReferenceInfo,
+
+        @JsonIgnore
+        Map<String, Object> additionalProperties
+) { }
+
diff --git a/api/src/main/java/fitconnect/api/domain/metadata/PaymentInformation.java b/api/src/main/java/fitconnect/api/domain/metadata/PaymentInformation.java
new file mode 100644
index 0000000000000000000000000000000000000000..3e78e452ad3d6dee3beab22c2314d126023dda83
--- /dev/null
+++ b/api/src/main/java/fitconnect/api/domain/metadata/PaymentInformation.java
@@ -0,0 +1,4 @@
+package fitconnect.api.domain.metadata;
+
+public record PaymentInformation() {
+}
diff --git a/api/src/main/java/fitconnect/api/domain/metadata/PublicServiceType.java b/api/src/main/java/fitconnect/api/domain/metadata/PublicServiceType.java
new file mode 100644
index 0000000000000000000000000000000000000000..d91252768f810e7e3b3f5d989002a2f6f3582f66
--- /dev/null
+++ b/api/src/main/java/fitconnect/api/domain/metadata/PublicServiceType.java
@@ -0,0 +1,37 @@
+package fitconnect.api.domain.metadata;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+
+import java.util.Map;
+
+/**
+ * Verwaltungsleistung
+ * <p>
+ * Beschreibung der Art der Verwaltungsleistung. Eine Verwaltungsleistung sollte immer mit einer LeiKa-Id beschrieben werden.
+ * <p>
+ * Ist für die gegebene Verwaltungsleistung keine LeiKa-Id vorhanden, kann die Verwaltungsleistung übergangsweise über die Angabe einer anderen eindeutigen Schema-URN beschrieben werden.
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+        "name",
+        "description",
+        "identifier"
+})
+public record PublicServiceType(
+
+        @JsonProperty("name")
+        String name,
+
+        @JsonProperty("description")
+        String description,
+
+        @JsonProperty("identifier")
+        String identifier,
+
+        @JsonIgnore
+        Map<String, Object> additionalProperties
+) { }
+
diff --git a/api/src/main/java/fitconnect/api/domain/metadata/ReplyChannel.java b/api/src/main/java/fitconnect/api/domain/metadata/ReplyChannel.java
new file mode 100644
index 0000000000000000000000000000000000000000..9384433d09e0f1eff3c480f8d0f170efeaa6b1dc
--- /dev/null
+++ b/api/src/main/java/fitconnect/api/domain/metadata/ReplyChannel.java
@@ -0,0 +1,4 @@
+package fitconnect.api.domain.metadata;
+
+public record ReplyChannel() {
+}
diff --git a/api/src/main/java/fitconnect/api/domain/metadata/attachment/Attachment.java b/api/src/main/java/fitconnect/api/domain/metadata/attachment/Attachment.java
new file mode 100644
index 0000000000000000000000000000000000000000..a78b0be1e42d4b365e7aa32048b33d554a5951c0
--- /dev/null
+++ b/api/src/main/java/fitconnect/api/domain/metadata/attachment/Attachment.java
@@ -0,0 +1,53 @@
+package fitconnect.api.domain.metadata.attachment;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import fitconnect.api.domain.metadata.attachment.signature.Hash__1;
+import fitconnect.api.domain.metadata.attachment.signature.Signature__1;
+
+import java.util.Map;
+import java.util.UUID;
+
+
+/**
+ * Eine in der Einreichung enthaltene Anlage.
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+        "hash",
+        "signature",
+        "purpose",
+        "filename",
+        "description",
+        "mimeType",
+        "attachmentId"
+})
+public record Attachment(
+
+        @JsonProperty("hash")
+        Hash__1 hash,
+
+        @JsonProperty("signature")
+        Signature__1 signature,
+
+        @JsonProperty("purpose")
+        Purpose purpose,
+
+        @JsonProperty("filename")
+        String filename,
+
+        @JsonProperty("description")
+        String description,
+
+        @JsonProperty("mimeType")
+        String mimeType,
+
+        @JsonProperty("attachmentId")
+        UUID attachmentId,
+        @JsonIgnore
+        Map<String, Object> additionalProperties
+) { }
+
+
diff --git a/api/src/main/java/fitconnect/api/domain/metadata/attachment/Purpose.java b/api/src/main/java/fitconnect/api/domain/metadata/attachment/Purpose.java
new file mode 100644
index 0000000000000000000000000000000000000000..5505532561a231e694701c3b0a64f2cdd857ee35
--- /dev/null
+++ b/api/src/main/java/fitconnect/api/domain/metadata/attachment/Purpose.java
@@ -0,0 +1,52 @@
+package fitconnect.api.domain.metadata.attachment;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonValue;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Zweck/Art der Anlage
+ * - form: Automatisch generierte PDF-Repräsentation des vollständigen Antragsformulars
+ * - attachment: Anlage, die von einem Bürger hochgeladen wurde
+ * - report: Vom Onlinedienst, nachträglich erzeugte Unterlage
+ */
+public enum Purpose {
+
+    FORM("form"),
+    ATTACHMENT("attachment"),
+    REPORT("report");
+    private final String value;
+    private final static Map<String, Purpose> CONSTANTS = new HashMap<>();
+
+    static {
+        for (Purpose c : values()) {
+            CONSTANTS.put(c.value, c);
+        }
+    }
+
+    Purpose(String value) {
+        this.value = value;
+    }
+
+    @Override
+    public String toString() {
+        return this.value;
+    }
+
+    @JsonValue
+    public String value() {
+        return this.value;
+    }
+
+    @JsonCreator
+    public static Purpose fromValue(String value) {
+        Purpose constant = CONSTANTS.get(value);
+        if (constant == null) {
+            throw new IllegalArgumentException(value);
+        } else {
+            return constant;
+        }
+    }
+}
diff --git a/api/src/main/java/fitconnect/api/domain/metadata/attachment/signature/EidasAdesProfile.java b/api/src/main/java/fitconnect/api/domain/metadata/attachment/signature/EidasAdesProfile.java
new file mode 100644
index 0000000000000000000000000000000000000000..c601b49bd25c537624ae9d258676a9961bbd0554
--- /dev/null
+++ b/api/src/main/java/fitconnect/api/domain/metadata/attachment/signature/EidasAdesProfile.java
@@ -0,0 +1,54 @@
+package fitconnect.api.domain.metadata.attachment.signature;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonValue;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Referenziert ein eindeutiges Profil einer AdES (advanced electronic signature/seal) gemäß eIDAS-Verordnung über eine URI gemäß [ETSI TS 119 192](https://www.etsi.org/deliver/etsi_ts/119100_119199/119192/01.01.01_60/ts_119192v010101p.pdf).
+ *
+ * Für die Details zur Verwendung und Validierung von Profilen siehe auch https://ec.europa.eu/cefdigital/DSS/webapp-demo/doc/dss-documentation.html#_signatures_profile_simplification
+ *
+ */
+public enum EidasAdesProfile {
+
+    HTTP_URI_ETSI_ORG_ADES_191_X_2_LEVEL_BASELINE_B_B("http://uri.etsi.org/ades/191x2/level/baseline/B-B#"),
+    HTTP_URI_ETSI_ORG_ADES_191_X_2_LEVEL_BASELINE_B_T("http://uri.etsi.org/ades/191x2/level/baseline/B-T#"),
+    HTTP_URI_ETSI_ORG_ADES_191_X_2_LEVEL_BASELINE_B_LT("http://uri.etsi.org/ades/191x2/level/baseline/B-LT#"),
+    HTTP_URI_ETSI_ORG_ADES_191_X_2_LEVEL_BASELINE_B_LTA("http://uri.etsi.org/ades/191x2/level/baseline/B-LTA#");
+    private final String value;
+    private final static Map<String, EidasAdesProfile> CONSTANTS = new HashMap<String, EidasAdesProfile>();
+
+    static {
+        for (EidasAdesProfile c: values()) {
+            CONSTANTS.put(c.value, c);
+        }
+    }
+
+    EidasAdesProfile(String value) {
+        this.value = value;
+    }
+
+    @Override
+    public String toString() {
+        return this.value;
+    }
+
+    @JsonValue
+    public String value() {
+        return this.value;
+    }
+
+    @JsonCreator
+    public static EidasAdesProfile fromValue(String value) {
+        EidasAdesProfile constant = CONSTANTS.get(value);
+        if (constant == null) {
+            throw new IllegalArgumentException(value);
+        } else {
+            return constant;
+        }
+    }
+
+}
diff --git a/api/src/main/java/fitconnect/api/domain/metadata/attachment/signature/Hash__1.java b/api/src/main/java/fitconnect/api/domain/metadata/attachment/signature/Hash__1.java
new file mode 100644
index 0000000000000000000000000000000000000000..8792354745bb9c905ea308675ec2471860738a7b
--- /dev/null
+++ b/api/src/main/java/fitconnect/api/domain/metadata/attachment/signature/Hash__1.java
@@ -0,0 +1,33 @@
+package fitconnect.api.domain.metadata.attachment.signature;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+
+import java.util.Map;
+
+
+/**
+ * Hashwert
+ * <p>
+ * Der Hashwert der unverschlüsselten Anlage.
+ * Die Angabe des Hashwertes dient der Integritätssicherung des Gesamtantrags und schützt vor einem Austausch der Anlage durch Systeme zwischen Sender und Subscriber (z.B. dem Zustelldienst).
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+        "type",
+        "content"
+})
+public record Hash__1(
+
+        @JsonProperty("type")
+        Type type,
+
+        @JsonProperty("content")
+        String content,
+
+        @JsonIgnore
+        Map<String, Object> additionalProperties
+) { }
+
diff --git a/api/src/main/java/fitconnect/api/domain/metadata/attachment/signature/SignatureFormat.java b/api/src/main/java/fitconnect/api/domain/metadata/attachment/signature/SignatureFormat.java
new file mode 100644
index 0000000000000000000000000000000000000000..9df5dd4ee9ae991cae390246458bf72c7d5d5fa4
--- /dev/null
+++ b/api/src/main/java/fitconnect/api/domain/metadata/attachment/signature/SignatureFormat.java
@@ -0,0 +1,53 @@
+package fitconnect.api.domain.metadata.attachment.signature;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonValue;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Beschreibt, welches Signaturformat die genutzte Signatur / das genutzte Siegel nutzt. Aktuell wird die Hinterlegung folgender Signaturformate unterstützt: CMS = Cryptographic Message Syntax, Asic = Associated Signature Containers, PDF = PDF Signatur, XML = XML-Signature, JSON = JSON Web Signature.
+ *
+ */
+public enum SignatureFormat {
+
+    CMS("cms"),
+    XML("xml"),
+    PDF("pdf"),
+    ASIC("asic"),
+    JSON("json");
+    private final String value;
+    private final static Map<String, SignatureFormat> CONSTANTS = new HashMap<>();
+
+    static {
+        for (SignatureFormat c: values()) {
+            CONSTANTS.put(c.value, c);
+        }
+    }
+
+    SignatureFormat(String value) {
+        this.value = value;
+    }
+
+    @Override
+    public String toString() {
+        return this.value;
+    }
+
+    @JsonValue
+    public String value() {
+        return this.value;
+    }
+
+    @JsonCreator
+    public static SignatureFormat fromValue(String value) {
+        SignatureFormat constant = CONSTANTS.get(value);
+        if (constant == null) {
+            throw new IllegalArgumentException(value);
+        } else {
+            return constant;
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/api/src/main/java/fitconnect/api/domain/metadata/attachment/signature/Signature__1.java b/api/src/main/java/fitconnect/api/domain/metadata/attachment/signature/Signature__1.java
new file mode 100644
index 0000000000000000000000000000000000000000..e35b63a102fb06baea712b7854583c09a0086035
--- /dev/null
+++ b/api/src/main/java/fitconnect/api/domain/metadata/attachment/signature/Signature__1.java
@@ -0,0 +1,39 @@
+package fitconnect.api.domain.metadata.attachment.signature;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+
+import java.util.Map;
+
+
+/**
+ * Beschreibt das Signaturformt und Profile
+ *
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+        "signatureFormat",
+        "eidasAdesProfile",
+        "detachedSignature",
+        "content"
+})
+public record Signature__1(
+
+        @JsonProperty("signatureFormat")
+        SignatureFormat signatureFormat,
+
+        @JsonProperty("eidasAdesProfile")
+        EidasAdesProfile eidasAdesProfile,
+
+        @JsonProperty("detachedSignature")
+        Boolean detachedSignature,
+
+        @JsonProperty("content")
+        String content,
+
+        @JsonIgnore
+         Map<String, Object> additionalProperties
+) { }
+
diff --git a/api/src/main/java/fitconnect/api/domain/metadata/attachment/signature/Type.java b/api/src/main/java/fitconnect/api/domain/metadata/attachment/signature/Type.java
new file mode 100644
index 0000000000000000000000000000000000000000..e14d3aa86e80a82973a1f66c412902efeeef71ac
--- /dev/null
+++ b/api/src/main/java/fitconnect/api/domain/metadata/attachment/signature/Type.java
@@ -0,0 +1,49 @@
+package fitconnect.api.domain.metadata.attachment.signature;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonValue;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Der verwendete Hash-Algorithmus. Derzeit ist nur `sha512` erlaubt.
+ *
+ */
+public enum Type {
+
+    SHA_512("sha512");
+    private final String value;
+    private final static Map<String, Type> CONSTANTS = new HashMap<>();
+
+    static {
+        for (Type c: values()) {
+            CONSTANTS.put(c.value, c);
+        }
+    }
+
+    Type(String value) {
+        this.value = value;
+    }
+
+    @Override
+    public String toString() {
+        return this.value;
+    }
+
+    @JsonValue
+    public String value() {
+        return this.value;
+    }
+
+    @JsonCreator
+    public static Type fromValue(String value) {
+        Type constant = CONSTANTS.get(value);
+        if (constant == null) {
+            throw new IllegalArgumentException(value);
+        } else {
+            return constant;
+        }
+    }
+
+}
diff --git a/api/src/main/java/fitconnect/api/domain/metadata/data/Data.java b/api/src/main/java/fitconnect/api/domain/metadata/data/Data.java
new file mode 100644
index 0000000000000000000000000000000000000000..d43ef300c8ca9158a68943f921c55f1d045d3798
--- /dev/null
+++ b/api/src/main/java/fitconnect/api/domain/metadata/data/Data.java
@@ -0,0 +1,34 @@
+package fitconnect.api.domain.metadata.data;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+
+import java.util.Map;
+
+/**
+ * Definiert das Schema und die Signatur(-art), die für die Fachdaten verwendet werden.
+ *
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+        "signature",
+        "hash",
+        "submissionSchema"
+})
+public record Data(
+
+        @JsonProperty("signature")
+        Signature signature,
+
+        @JsonProperty("hash")
+        Hash hash,
+
+        @JsonProperty("submissionSchema")
+        SubmissionSchema submissionSchema,
+
+        @JsonIgnore
+        Map<String, Object> additionalProperties
+) { }
+
diff --git a/api/src/main/java/fitconnect/api/domain/metadata/data/EidasAdesProfile.java b/api/src/main/java/fitconnect/api/domain/metadata/data/EidasAdesProfile.java
new file mode 100644
index 0000000000000000000000000000000000000000..0fd71a987508c907262c061cba264c1a0b66d41e
--- /dev/null
+++ b/api/src/main/java/fitconnect/api/domain/metadata/data/EidasAdesProfile.java
@@ -0,0 +1,55 @@
+package fitconnect.api.domain.metadata.data;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonValue;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Referenziert ein eindeutiges Profil einer AdES (advanced electronic signature/seal) gemäß eIDAS-Verordnung über eine URI gemäß [ETSI TS 119 192](https://www.etsi.org/deliver/etsi_ts/119100_119199/119192/01.01.01_60/ts_119192v010101p.pdf).
+ *
+ * Für die Details zur Verwendung und Validierung von Profilen siehe auch https://ec.europa.eu/cefdigital/DSS/webapp-demo/doc/dss-documentation.html#_signatures_profile_simplification
+ *
+ */
+public enum EidasAdesProfile {
+
+    HTTP_URI_ETSI_ORG_ADES_191_X_2_LEVEL_BASELINE_B_B("http://uri.etsi.org/ades/191x2/level/baseline/B-B#"),
+    HTTP_URI_ETSI_ORG_ADES_191_X_2_LEVEL_BASELINE_B_T("http://uri.etsi.org/ades/191x2/level/baseline/B-T#"),
+    HTTP_URI_ETSI_ORG_ADES_191_X_2_LEVEL_BASELINE_B_LT("http://uri.etsi.org/ades/191x2/level/baseline/B-LT#"),
+    HTTP_URI_ETSI_ORG_ADES_191_X_2_LEVEL_BASELINE_B_LTA("http://uri.etsi.org/ades/191x2/level/baseline/B-LTA#");
+    private final String value;
+    private final static Map<String, EidasAdesProfile> CONSTANTS = new HashMap<>();
+
+    static {
+        for (EidasAdesProfile c: values()) {
+            CONSTANTS.put(c.value, c);
+        }
+    }
+
+    EidasAdesProfile(String value) {
+        this.value = value;
+    }
+
+    @Override
+    public String toString() {
+        return this.value;
+    }
+
+    @JsonValue
+    public String value() {
+        return this.value;
+    }
+
+    @JsonCreator
+    public static EidasAdesProfile fromValue(String value) {
+        EidasAdesProfile constant = CONSTANTS.get(value);
+        if (constant == null) {
+            throw new IllegalArgumentException(value);
+        } else {
+            return constant;
+        }
+    }
+
+}
+
diff --git a/api/src/main/java/fitconnect/api/domain/metadata/data/Hash.java b/api/src/main/java/fitconnect/api/domain/metadata/data/Hash.java
new file mode 100644
index 0000000000000000000000000000000000000000..7000552245dcc8c67209e8f51191ede5efaf1efe
--- /dev/null
+++ b/api/src/main/java/fitconnect/api/domain/metadata/data/Hash.java
@@ -0,0 +1,32 @@
+package fitconnect.api.domain.metadata.data;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+
+import java.util.Map;
+
+
+/**
+ * Hashwert
+ * <p>
+ * Der Hashwert der unverschlüsselten Fachdaten. Die Angabe des Hashwertes dient der Integritätssicherung des Gesamtantrags und schützt vor einem Austausch der Fachdaten durch Systeme zwischen Sender und Subscriber (z.B. dem Zustelldienst).
+ *
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+        "type",
+        "content"
+})
+public record Hash(
+
+        @JsonProperty("type")
+        Type type,
+
+        @JsonProperty("content")
+        String content,
+
+        @JsonIgnore
+        Map<String, Object> additionalProperties
+){ }
diff --git a/api/src/main/java/fitconnect/api/domain/metadata/data/MimeType.java b/api/src/main/java/fitconnect/api/domain/metadata/data/MimeType.java
new file mode 100644
index 0000000000000000000000000000000000000000..6c3aa73762450abae72be7d288e144c13c48d1e6
--- /dev/null
+++ b/api/src/main/java/fitconnect/api/domain/metadata/data/MimeType.java
@@ -0,0 +1,50 @@
+package fitconnect.api.domain.metadata.data;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonValue;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Mimetype (z.B. application/json oder application/xml) des referenzierten Schemas (z.B. XSD- oder JSON-Schema).
+ *
+ */
+public enum MimeType {
+
+    APPLICATION_JSON("application/json"),
+    APPLICATION_XML("application/xml");
+    private final String value;
+    private final static Map<String, MimeType> CONSTANTS = new HashMap<>();
+
+    static {
+        for (MimeType c: values()) {
+            CONSTANTS.put(c.value, c);
+        }
+    }
+
+    MimeType(String value) {
+        this.value = value;
+    }
+
+    @Override
+    public String toString() {
+        return this.value;
+    }
+
+    @JsonValue
+    public String value() {
+        return this.value;
+    }
+
+    @JsonCreator
+    public static MimeType fromValue(String value) {
+        MimeType constant = CONSTANTS.get(value);
+        if (constant == null) {
+            throw new IllegalArgumentException(value);
+        } else {
+            return constant;
+        }
+    }
+
+}
diff --git a/api/src/main/java/fitconnect/api/domain/metadata/data/Signature.java b/api/src/main/java/fitconnect/api/domain/metadata/data/Signature.java
new file mode 100644
index 0000000000000000000000000000000000000000..8a7fe7278819a88baa340ee71e6828cd04b9a925
--- /dev/null
+++ b/api/src/main/java/fitconnect/api/domain/metadata/data/Signature.java
@@ -0,0 +1,37 @@
+package fitconnect.api.domain.metadata.data;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+
+import java.util.Map;
+
+/**
+ * Beschreibt das Signaturformt und Profile
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+        "signatureFormat",
+        "eidasAdesProfile",
+        "detachedSignature",
+        "content"
+})
+public record Signature(
+
+        @JsonProperty("signatureFormat")
+        SignatureFormat signatureFormat,
+
+        @JsonProperty("eidasAdesProfile")
+        EidasAdesProfile eidasAdesProfile,
+
+        @JsonProperty("detachedSignature")
+        Boolean detachedSignature,
+
+        @JsonProperty("content")
+        String content,
+        @JsonIgnore
+        Map<String, Object> additionalProperties
+
+) { }
+
diff --git a/api/src/main/java/fitconnect/api/domain/metadata/data/SignatureFormat.java b/api/src/main/java/fitconnect/api/domain/metadata/data/SignatureFormat.java
new file mode 100644
index 0000000000000000000000000000000000000000..87053dd923abbc9c032957100e032a6a283f2ac5
--- /dev/null
+++ b/api/src/main/java/fitconnect/api/domain/metadata/data/SignatureFormat.java
@@ -0,0 +1,53 @@
+package fitconnect.api.domain.metadata.data;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonValue;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Beschreibt, welches Signaturformat die genutzte Signatur / das genutzte Siegel nutzt. Aktuell wird die Hinterlegung folgender Signaturformate unterstützt: CMS = Cryptographic Message Syntax, Asic = Associated Signature Containers, PDF = PDF Signatur, XML = XML-Signature, JSON = JSON Web Signature.
+ *
+ */
+public enum SignatureFormat {
+
+    CMS("cms"),
+    XML("xml"),
+    PDF("pdf"),
+    ASIC("asic"),
+    JSON("json");
+    private final String value;
+    private final static Map<String, SignatureFormat> CONSTANTS = new HashMap<>();
+
+    static {
+        for (SignatureFormat c: values()) {
+            CONSTANTS.put(c.value, c);
+        }
+    }
+
+    SignatureFormat(String value) {
+        this.value = value;
+    }
+
+    @Override
+    public String toString() {
+        return this.value;
+    }
+
+    @JsonValue
+    public String value() {
+        return this.value;
+    }
+
+    @JsonCreator
+    public static SignatureFormat fromValue(String value) {
+        SignatureFormat constant = CONSTANTS.get(value);
+        if (constant == null) {
+            throw new IllegalArgumentException(value);
+        } else {
+            return constant;
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/api/src/main/java/fitconnect/api/domain/metadata/data/SubmissionSchema.java b/api/src/main/java/fitconnect/api/domain/metadata/data/SubmissionSchema.java
new file mode 100644
index 0000000000000000000000000000000000000000..b62f222e07f256030ba035a17a7a22d7cf37afd2
--- /dev/null
+++ b/api/src/main/java/fitconnect/api/domain/metadata/data/SubmissionSchema.java
@@ -0,0 +1,33 @@
+package fitconnect.api.domain.metadata.data;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+
+import java.net.URI;
+import java.util.Map;
+
+
+/**
+ * Fachdatenschema
+ * <p>
+ * Referenz auf ein Schema, das die Struktur der Fachdaten einer Einreichung beschreibt.
+ *
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+        "schemaUri",
+        "mimeType"
+})
+public record SubmissionSchema(
+
+        @JsonProperty("schemaUri")
+        URI schemaUri,
+
+        @JsonProperty("mimeType")
+        MimeType mimeType,
+
+        @JsonIgnore
+        Map<String, Object> additionalProperties
+) { }
diff --git a/api/src/main/java/fitconnect/api/domain/metadata/data/Type.java b/api/src/main/java/fitconnect/api/domain/metadata/data/Type.java
new file mode 100644
index 0000000000000000000000000000000000000000..b6f5c1b686189042d6a708d1488128501eb2b651
--- /dev/null
+++ b/api/src/main/java/fitconnect/api/domain/metadata/data/Type.java
@@ -0,0 +1,49 @@
+package fitconnect.api.domain.metadata.data;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonValue;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Der verwendete Hash-Algorithmus. Derzeit ist nur `sha512` erlaubt.
+ *
+ */
+public enum Type {
+
+    SHA_512("sha512");
+    private final String value;
+    private final static Map<String, Type> CONSTANTS = new HashMap<>();
+
+    static {
+        for (Type c: values()) {
+            CONSTANTS.put(c.value, c);
+        }
+    }
+
+    Type(String value) {
+        this.value = value;
+    }
+
+    @Override
+    public String toString() {
+        return this.value;
+    }
+
+    @JsonValue
+    public String value() {
+        return this.value;
+    }
+
+    @JsonCreator
+    public static Type fromValue(String value) {
+        Type constant = CONSTANTS.get(value);
+        if (constant == null) {
+            throw new IllegalArgumentException(value);
+        } else {
+            return constant;
+        }
+    }
+
+}
diff --git a/api/src/main/java/fitconnect/api/metadata/MetadataService.java b/api/src/main/java/fitconnect/api/metadata/MetadataService.java
new file mode 100644
index 0000000000000000000000000000000000000000..e9d674575c767d7e038856084d835fe7a00cd2ff
--- /dev/null
+++ b/api/src/main/java/fitconnect/api/metadata/MetadataService.java
@@ -0,0 +1,8 @@
+package fitconnect.api.metadata;
+
+import fitconnect.api.domain.metadata.Metadata;
+
+public interface MetadataService {
+
+    Metadata createMetadata();
+}
diff --git a/api/src/main/resources/schemas/metadata.schema.json b/api/src/main/resources/schemas/metadata.schema.json
new file mode 100644
index 0000000000000000000000000000000000000000..997aeb08a5fe08d460c0e9efc23f4229931d5b97
--- /dev/null
+++ b/api/src/main/resources/schemas/metadata.schema.json
@@ -0,0 +1 @@
+{"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://schema.fitko.de/fit-connect/metadata/1.0.0/metadata.schema.json","type":"object","title":"Metadaten","description":"","required":["contentStructure"],"properties":{"contentStructure":{"description":"Beschreibt die Struktur der zusätzlichen Inhalte der Einreichung, wie Anlagen oder Fachdaten.","type":"object","required":["attachments"],"properties":{"data":{"description":"Definiert das Schema und die Signatur(-art), die für die Fachdaten verwendet werden.","type":"object","required":["hash","submissionSchema"],"properties":{"signature":{"type":"object","description":"Beschreibt das Signaturformt und Profile","examples":[],"properties":{"signatureFormat":{"type":"string","description":"Beschreibt, welches Signaturformat die genutzte Signatur / das genutzte Siegel nutzt. Aktuell wird die Hinterlegung folgender Signaturformate unterstützt: CMS = Cryptographic Message Syntax, Asic = Associated Signature Containers, PDF = PDF Signatur, XML = XML-Signature, JSON = JSON Web Signature. ","enum":["cms","xml","pdf","asic","json"]},"eidasAdesProfile":{"type":"string","description":"Referenziert ein eindeutiges Profil einer AdES (advanced electronic signature/seal) gemäß eIDAS-Verordnung über eine URI gemäß [ETSI TS 119 192](https://www.etsi.org/deliver/etsi_ts/119100_119199/119192/01.01.01_60/ts_119192v010101p.pdf).\n\nFür die Details zur Verwendung und Validierung von Profilen siehe auch https://ec.europa.eu/cefdigital/DSS/webapp-demo/doc/dss-documentation.html#_signatures_profile_simplification","enum":["http://uri.etsi.org/ades/191x2/level/baseline/B-B#","http://uri.etsi.org/ades/191x2/level/baseline/B-T#","http://uri.etsi.org/ades/191x2/level/baseline/B-LT#","http://uri.etsi.org/ades/191x2/level/baseline/B-LTA#"]},"detachedSignature":{"type":"boolean","description":"Beschreibt, ob die Signatur als seperate (detached) Signatur (`true`) oder als Teil des Fachdatensatzes bzw. der Anlage  (`false`) übertragen wird. Wenn der Wert `true` ist, dann wird die Signatur Base64- oder Base64Url-kodiert im Feld `content` übertragen."},"content":{"type":"string","description":"Hier wird die Signatur im Falle einer Detached-Signatur als Base64- oder Base64Url-kodierte Zeichenkette hinterlegt. Eine Base64Url-Kodierung kommt nur bei Einsatz von JSON Web Signatures (JWS / JAdES) zum Einsatz.","pattern":"^[a-zA-Z0-9+/=]+|[a-zA-Z0-9_-]+$"}},"required":["signatureFormat","detachedSignature"]},"hash":{"title":"Hashwert","description":"Der Hashwert der unverschlüsselten Fachdaten. Die Angabe des Hashwertes dient der Integritätssicherung des Gesamtantrags und schützt vor einem Austausch der Fachdaten durch Systeme zwischen Sender und Subscriber (z.B. dem Zustelldienst).","type":"object","required":["type","content"],"properties":{"type":{"type":"string","description":"Der verwendete Hash-Algorithmus. Derzeit ist nur `sha512` erlaubt.","enum":["sha512"]},"content":{"type":"string","description":"Der Hex-kodierte Hashwert gemäß des angegebenen Algorithmus.","pattern":"^[a-f0-9]{128}$"}}},"submissionSchema":{"title":"Fachdatenschema","description":"Referenz auf ein Schema, das die Struktur der Fachdaten einer Einreichung beschreibt.","type":"object","required":["schemaUri","mimeType"],"properties":{"schemaUri":{"type":"string","format":"uri","description":"URI des Fachschemas. Wird hier eine URL verwendet, sollte das Schema unter der angegebenen URL abrufbar sein. Eine Verfügbarkeit des Schemas unter der angegebenen URL darf jedoch nicht vorausgesetzt werden."},"mimeType":{"type":"string","description":"Mimetype (z.B. application/json oder application/xml) des referenzierten Schemas (z.B. XSD- oder JSON-Schema).","enum":["application/json","application/xml"]}}}}},"attachments":{"type":"array","items":{"type":"object","description":"Eine in der Einreichung enthaltene Anlage.","required":["hash","purpose","mimeType","attachmentId"],"properties":{"hash":{"title":"Hashwert","description":"Der Hashwert der unverschlüsselten Anlage. Die Angabe des Hashwertes dient der Integritätssicherung des Gesamtantrags und schützt vor einem Austausch der Anlage durch Systeme zwischen Sender und Subscriber (z.B. dem Zustelldienst).","type":"object","required":["type","content"],"properties":{"type":{"type":"string","description":"Der verwendete Hash-Algorithmus. Derzeit ist nur `sha512` erlaubt.","enum":["sha512"]},"content":{"type":"string","description":"Der Hex-kodierte Hashwert gemäß des angegebenen Algorithmus.","pattern":"^[a-f0-9]{128}$"}}},"signature":{"$ref":"#/properties/contentStructure/properties/data/properties/signature"},"purpose":{"description":"Zweck/Art der Anlage\n- form: Automatisch generierte PDF-Repräsentation des vollständigen Antragsformulars\n- attachment: Anlage, die von einem Bürger hochgeladen wurde\n- report: Vom Onlinedienst, nachträglich erzeugte Unterlage","type":"string","enum":["form","attachment","report"]},"filename":{"type":"string","description":"Ursprünglicher Dateiname bei Erzeugung oder Upload"},"description":{"type":"string","description":"Optionale Beschreibung der Anlage"},"mimeType":{"type":"string","title":"MIME Type","description":"Internet Media Type gemäß RFC 2045, z. B. application/pdf.","examples":["application/xml"],"pattern":"^[-\\w.]+/[-\\w.+]+$"},"attachmentId":{"type":"string","description":"Innerhalb einer Einreichung eindeutige Id der Anlage im Format einer UUIDv4.","format":"uuid","minLength":32,"maxLength":36}}}}}},"publicServiceType":{"type":"object","title":"Verwaltungsleistung","description":"Beschreibung der Art der Verwaltungsleistung. Eine Verwaltungsleistung sollte immer mit einer LeiKa-Id beschrieben werden. Ist für die gegebene Verwaltungsleistung keine LeiKa-Id vorhanden, kann die Verwaltungsleistung übergangsweise über die Angabe einer anderen eindeutigen Schema-URN beschrieben werden.","properties":{"name":{"type":"string","description":"Name/Bezeichnung der Verwaltungsleistung"},"description":{"type":"string","description":"(Kurz-)Beschreibung der Verwaltungsleistung"},"identifier":{"title":"Leistungs-Identifikator","description":"URN einer Leistung. Im Falle einer Leistung aus dem Leistungskatalog sollte hier `urn:de:fim:leika:leistung:` vorangestellt werden.\n","type":"string","minLength":7,"maxLength":255,"pattern":"^urn:[a-z0-9][a-z0-9-]{0,31}:[a-z0-9()+,.:=@;$_!*'%/?#-]+$"}},"required":["identifier"]},"authenticationInformation":{"description":"Eine Liste aller Identifikationsnachweise der Einreichung.","type":"array","minItems":1,"items":{"type":"object","description":"Eine Struktur, die einen Identifikationsnachweis beschreibt.","properties":{"type":{"description":"Definiert die Art des Identifikationsnachweises.","type":"string","enum":["identificationReport"]},"version":{"type":"string","pattern":"^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)$","description":"semver kompatible Versionsangabe des genutzten Nachweistyps."},"content":{"type":"string","description":"Der Nachweis wird als Base64Url-kodierte Zeichenkette angegeben.","pattern":"^[a-zA-Z0-9_\\-.]+$"}},"required":["type","version","content"]}},"paymentInformation":{"description":"Dieses Objekt enthält die Informationen vom Bezahldienst.","type":"object","required":["transactionReference","transactionId","paymentMethod","status"],"properties":{"transactionUrl":{"type":"string","format":"uri","minLength":1,"examples":["https://payment.bundesland.zzzz/api/v1/paymenttransaction/12002312/MELD-ANT-FORM-4711/9xxd-432x-6543-xfd6-gfdx-fd27"],"description":"Die Rest-URL der Payment Transaction für die Statusabfrage."},"transactionId":{"type":"string","minLength":1,"maxLength":36,"pattern":"^[\\w\\d-]+$","examples":["9xxd-432x-6543-xfd6-gfdx-fd27"],"description":"Eine vom Bezahldienst vergebene Transaktions-Id."},"transactionReference":{"type":"string","description":"Bezahlreferenz bzw. Verwendungszweck, wie z. B. ein Kassenzeichen."},"transactionTimestamp":{"type":"string","format":"date-time","description":"Zeitstempel der erfolgreichen Durchführung der Bezahlung."},"paymentMethod":{"type":"string","enum":["GIROPAY","PAYDIRECT","CREDITCARD","PAYPAL","INVOICE","OTHER"],"examples":["CREDITCARD"],"description":"Die vom Benutzer ausgewählte Zahlart. Das Feld ist nur bei einer erfolgreichen Zahlung vorhanden / befüllt."},"paymentMethodDetail":{"type":"string","minLength":1,"maxLength":36,"pattern":"^[\\w\\d-]+$","examples":["Visa"],"description":"Weitere Erläuterung zur gewählten Zahlart."},"status":{"type":"string","enum":["INITIAL","BOOKED","FAILED","CANCELED"],"description":"- INITIAL - der Einreichung hat einen Payment-Request ausgelöst und eine Payment-Transaction wurde angelegt. Der Nutzer hat aber im Bezahldienst noch keine Wirkung erzeugt.\n- BOOKED - der Nutzer hat die Bezahlung im Bezahldienst autorisiert.\n- FAILED - der Vorgang wurde vom Bezahldienst aufgrund der Nutzereingaben abgebrochen.\n- CANCELED - der Nutzer hat die Bezahlung im Bezahldienst abgebrochen."},"grossAmount":{"type":"number","minimum":0.01,"multipleOf":0.01,"description":"Bruttobetrag"}}},"replyChannel":{"type":"object","minProperties":1,"maxProperties":1,"properties":{"eMail":{"type":"object","properties":{"address":{"type":"string","format":"email"},"pgpPublicKey":{"type":"string","description":"Hilfe zur Erstellung gibt es in der Dokumentation unter https://docs.fitko.de/fit-connect/details/pgp-export","pattern":"^-----BEGIN PGP PUBLIC KEY BLOCK-----\\n\\n"}},"required":["address"]},"deMail":{"type":"object","description":"Akkreditierte Anbieter siehe https://www.bsi.bund.de/DE/Themen/Oeffentliche-Verwaltung/Moderner-Staat/De-Mail/Akkreditierte-DMDA/akkreditierte-dmda_node.html","properties":{"address":{"type":"string","format":"email"}},"required":["address"]},"fink":{"type":"object","description":"Postfachadresse in einem interoperablen Servicekonto (FINK.PFISK)","properties":{"finkPostfachRef":{"type":"string","description":"FINK Postfachadresse","examples":["hh/by/12345"],"maxLength":150,"pattern":"^[-._a-z0-9~/]*$"},"host":{"type":"string","description":"URL des Servicekontos, in dem das Ziel-Postfach liegt","format":"uri","examples":["https://servicekonto1.example.com/"]}},"required":["finkPostfachRef"]},"elster":{"type":"object","description":"Siehe https://www.elster.de/elsterweb/infoseite/elstertransfer_hilfe_schnittstellen","properties":{"accountId":{"type":"string","pattern":"^\\d{10}$"},"lieferTicket":{"type":"string"},"geschaeftszeichen":{"type":"string","maxLength":10}},"required":["accountId"]}}},"additionalReferenceInfo":{"type":"object","description":"Eine Struktur, um zusätzliche Informationen zu hinterlegen","properties":{"senderReference":{"type":"string","description":"Eine Referenz zum Vorgang im sendenden System, um bei Problemen und Rückfragen außerhalb von FIT-Connect den Vorgang im dortigen System schneller zu identifizieren."},"applicationDate":{"type":"string","format":"date","description":"Das Datum der Antragstellung. Das Datum muss nicht zwingend identisch mit dem Datum der Einreichung des Antrags über FIT-Connect sein."}}}}}
\ No newline at end of file
diff --git a/impl/pom.xml b/impl/pom.xml
index 183f8537e447a7ae877ed875daaa7093cc2c0039..4d1c6f1102f0006f1cf7ed86ea7906469547a68b 100644
--- a/impl/pom.xml
+++ b/impl/pom.xml
@@ -31,4 +31,6 @@
         </dependency>
     </dependencies>
 
+
+
 </project>
\ No newline at end of file
diff --git a/impl/src/main/java/fitconnect/impl/SubmissionSender.java b/impl/src/main/java/fitconnect/impl/SubmissionSender.java
index 36278545d876d0090f7ab99492dd9f39225efcda..7bdcde0f639912dae211f0310cebe38a4b994a0b 100644
--- a/impl/src/main/java/fitconnect/impl/SubmissionSender.java
+++ b/impl/src/main/java/fitconnect/impl/SubmissionSender.java
@@ -4,6 +4,8 @@ import com.nimbusds.jose.jwk.RSAKey;
 import fitconnect.api.auth.OAuthService;
 import fitconnect.api.auth.OAuthToken;
 import fitconnect.api.crypto.EncryptionService;
+import fitconnect.api.domain.metadata.Metadata;
+import fitconnect.api.metadata.MetadataService;
 import fitconnect.api.problems.EncryptionProblem;
 
 import java.util.Optional;
@@ -11,7 +13,7 @@ import java.util.Optional;
 /**
  * A technical system that creates a submission via the FIT-Co Submission API.
  */
-public class SubmissionSender implements OAuthService, EncryptionService {
+public class SubmissionSender implements OAuthService, EncryptionService, MetadataService {
 
     private final OAuthService authService;
     private final EncryptionService encryptionService;
@@ -35,4 +37,9 @@ public class SubmissionSender implements OAuthService, EncryptionService {
     public String encryptBytes(RSAKey publicKey, byte[] unencryptedAttachment) throws EncryptionProblem {
         return encryptionService.encryptBytes(publicKey, unencryptedAttachment);
     }
+
+    @Override
+    public Metadata createMetadata() {
+        throw new UnsupportedOperationException("not yet implemented");
+    }
 }
diff --git a/impl/src/main/java/fitconnect/impl/crypto/MetadataVerifier.java b/impl/src/main/java/fitconnect/impl/crypto/MetadataVerifier.java
new file mode 100644
index 0000000000000000000000000000000000000000..804b822e764d61d26a90a06ab6636ec81dfd7ee5
--- /dev/null
+++ b/impl/src/main/java/fitconnect/impl/crypto/MetadataVerifier.java
@@ -0,0 +1,49 @@
+package fitconnect.impl.crypto;
+
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
+
+public class MetadataVerifier {
+
+    private static final String DEFAULT_ALGORITHM = "SHA-512"; // Currently, only SHA-512 is supported.
+
+    private final MessageDigest hasher;
+
+    public MetadataVerifier() {
+        try {
+            this.hasher = MessageDigest.getInstance(DEFAULT_ALGORITHM);
+        } catch (NoSuchAlgorithmException e) {
+            //TODO use Problem Exception Type
+            throw new RuntimeException(e);
+        }
+    }
+
+    public byte[] createHash(byte[] data) {
+        this.hasher.reset();
+        return this.hasher.digest(data);
+    }
+
+    public boolean verify(byte[] originalHash, byte[] data) {
+        byte[] newHash = createHash(data);
+        return compareHashes(originalHash, newHash);
+    }
+
+    public static String toHexString(byte[] hash) {
+        return String.format("%0128x", new BigInteger(1, hash));
+    }
+
+    public byte[] fromHexString(String hexString) {
+        byte[] byteArray = new BigInteger(hexString, 16).toByteArray();
+        return Arrays.copyOfRange(byteArray, 1, byteArray.length);
+    }
+
+    private boolean compareHashes(byte[] originalHash, byte[] comparisonHash) {
+        int diff = originalHash.length ^ comparisonHash.length;
+        for (int i = 0; i < originalHash.length && i < comparisonHash.length; i++) {
+            diff |= originalHash[i] ^ comparisonHash[i];
+        }
+        return diff == 0;
+    }
+}
diff --git a/impl/src/test/java/fitconnect/impl/crypto/MetadataVerifierTest.java b/impl/src/test/java/fitconnect/impl/crypto/MetadataVerifierTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..70dd51d9e145bd63b3255bbc5b13a30770b48ff0
--- /dev/null
+++ b/impl/src/test/java/fitconnect/impl/crypto/MetadataVerifierTest.java
@@ -0,0 +1,31 @@
+package fitconnect.impl.crypto;
+
+import org.junit.jupiter.api.Test;
+
+import java.io.IOException;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class MetadataVerifierTest {
+
+    MetadataVerifier underTest = new MetadataVerifier();
+
+    @Test
+    public void testMessageDigestForDataAndAttachments() throws IOException {
+
+            // Given (sender creates hash of (Fachdaten) or attachments (Anhänge))
+            byte[] exampleFileContent = getExampleFileContent("/example.pdf");
+            byte[] data = exampleFileContent;
+            byte[] hashFromSender = underTest.createHash(data);
+
+            // When (subscriber verifies hash of data or attachments)
+            byte[] dataFromSender = exampleFileContent;
+            boolean verificationResult = underTest.verify(hashFromSender, dataFromSender);
+            assertTrue(verificationResult);
+    }
+
+    private byte[] getExampleFileContent(final String path) throws IOException {
+        return MetadataVerifier.class.getResourceAsStream(path).readAllBytes();
+    }
+
+}
\ No newline at end of file
diff --git a/impl/src/test/resources/example.pdf b/impl/src/test/resources/example.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..92aa8424e344f57d9206aa85becd6198255a44b9
Binary files /dev/null and b/impl/src/test/resources/example.pdf differ
diff --git a/pom.xml b/pom.xml
index 5caf81cb56aaa3ce9109031200c7f05f97cb087a..93289ee62500b2561fbd1ae80154197a4633d260 100644
--- a/pom.xml
+++ b/pom.xml
@@ -52,6 +52,12 @@
                 <artifactId>jackson-databind</artifactId>
                 <version>2.12.3</version>
             </dependency>
+            <dependency>
+                <groupId>com.fasterxml.jackson.core</groupId>
+                <artifactId>jackson-annotations</artifactId>
+                <version>2.13.3</version>
+                <scope>compile</scope>
+            </dependency>
             <dependency>
                 <groupId>com.google.guava</groupId>
                 <artifactId>guava</artifactId>