diff --git a/Models/Models.csproj b/Models/Models.csproj
index 42326e5c3ec81e82a29317e741d328d2d68ef0b9..245b8c8d902f44288fb973cbc21b2653b5342dcf 100644
--- a/Models/Models.csproj
+++ b/Models/Models.csproj
@@ -7,4 +7,8 @@
         <RootNamespace>FitConnect.Models</RootNamespace>
     </PropertyGroup>
 
+    <ItemGroup>
+      <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
+    </ItemGroup>
+
 </Project>
diff --git a/Services/Models/Api/Metadata.cs b/Services/Models/Api/Metadata.cs
new file mode 100644
index 0000000000000000000000000000000000000000..adb00423acc5f7729507d4e42e6db8773aa5bd57
--- /dev/null
+++ b/Services/Models/Api/Metadata.cs
@@ -0,0 +1,1122 @@
+// <auto-generated />
+//
+// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:
+//
+//    using FitConnect;
+//
+//    var metadata = Metadata.FromJson(jsonString);
+
+namespace FitConnect.Models.Api.Metadata
+{
+    using System;
+    using System.Collections.Generic;
+
+    using System.Globalization;
+    using Newtonsoft.Json;
+    using Newtonsoft.Json.Converters;
+
+    public partial class Metadata
+    {
+        /// <summary>
+        /// Eine Struktur, um zusätzliche Informationen zu hinterlegen
+        /// </summary>
+        [JsonProperty("additionalReferenceInfo", NullValueHandling = NullValueHandling.Ignore)]
+        public AdditionalReferenceInfo AdditionalReferenceInfo { get; set; }
+
+        /// <summary>
+        /// Eine Liste aller Identifikationsnachweise der Einreichung.
+        /// </summary>
+        [JsonProperty("authenticationInformation", NullValueHandling = NullValueHandling.Ignore)]
+        public List<AuthenticationInformation> AuthenticationInformation { get; set; }
+
+        /// <summary>
+        /// Beschreibt die Struktur der zusätzlichen Inhalte der Einreichung, wie Anlagen oder
+        /// Fachdaten.
+        /// </summary>
+        [JsonProperty("contentStructure")]
+        public ContentStructure ContentStructure { get; set; }
+
+        /// <summary>
+        /// Dieses Objekt enthält die Informationen vom Bezahldienst.
+        /// </summary>
+        [JsonProperty("paymentInformation", NullValueHandling = NullValueHandling.Ignore)]
+        public PaymentInformation PaymentInformation { get; set; }
+
+        /// <summary>
+        /// 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.
+        /// </summary>
+        [JsonProperty("publicServiceType", NullValueHandling = NullValueHandling.Ignore)]
+        public Verwaltungsleistung PublicServiceType { get; set; }
+
+        [JsonProperty("replyChannel", NullValueHandling = NullValueHandling.Ignore)]
+        public ReplyChannel ReplyChannel { get; set; }
+    }
+
+    /// <summary>
+    /// Eine Struktur, um zusätzliche Informationen zu hinterlegen
+    /// </summary>
+    public partial class AdditionalReferenceInfo
+    {
+        /// <summary>
+        /// Das Datum der Antragstellung. Das Datum muss nicht zwingend identisch mit dem Datum der
+        /// Einreichung des Antrags über FIT-Connect sein.
+        /// </summary>
+        [JsonProperty("applicationDate", NullValueHandling = NullValueHandling.Ignore)]
+        public DateTimeOffset? ApplicationDate { get; set; }
+
+        /// <summary>
+        /// 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.
+        /// </summary>
+        [JsonProperty("senderReference", NullValueHandling = NullValueHandling.Ignore)]
+        public string SenderReference { get; set; }
+    }
+
+    /// <summary>
+    /// Eine Struktur, die einen Identifikationsnachweis beschreibt.
+    /// </summary>
+    public partial class AuthenticationInformation
+    {
+        /// <summary>
+        /// Der Nachweis wird als Base64Url-kodierte Zeichenkette angegeben.
+        /// </summary>
+        [JsonProperty("content")]
+        public string Content { get; set; }
+
+        /// <summary>
+        /// Definiert die Art des Identifikationsnachweises.
+        /// </summary>
+        [JsonProperty("type")]
+        public AuthenticationInformationType Type { get; set; }
+
+        /// <summary>
+        /// semver kompatible Versionsangabe des genutzten Nachweistyps.
+        /// </summary>
+        [JsonProperty("version")]
+        public string Version { get; set; }
+    }
+
+    /// <summary>
+    /// Beschreibt die Struktur der zusätzlichen Inhalte der Einreichung, wie Anlagen oder
+    /// Fachdaten.
+    /// </summary>
+    public partial class ContentStructure
+    {
+        [JsonProperty("attachments")]
+        public List<Attachment> Attachments { get; set; }
+
+        /// <summary>
+        /// Definiert das Schema und die Signatur(-art), die für die Fachdaten verwendet werden.
+        /// </summary>
+        [JsonProperty("data", NullValueHandling = NullValueHandling.Ignore)]
+        public Data Data { get; set; }
+    }
+
+    /// <summary>
+    /// Eine in der Einreichung enthaltene Anlage.
+    /// </summary>
+    public partial class Attachment
+    {
+        /// <summary>
+        /// Innerhalb einer Einreichung eindeutige Id der Anlage im Format einer UUIDv4.
+        /// </summary>
+        [JsonProperty("attachmentId")]
+        public Guid AttachmentId { get; set; }
+
+        /// <summary>
+        /// Optionale Beschreibung der Anlage
+        /// </summary>
+        [JsonProperty("description", NullValueHandling = NullValueHandling.Ignore)]
+        public string Description { get; set; }
+
+        /// <summary>
+        /// Ursprünglicher Dateiname bei Erzeugung oder Upload
+        /// </summary>
+        [JsonProperty("filename", NullValueHandling = NullValueHandling.Ignore)]
+        public string Filename { get; set; }
+
+        /// <summary>
+        /// 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).
+        /// </summary>
+        [JsonProperty("hash")]
+        public AttachmentHash Hash { get; set; }
+
+        /// <summary>
+        /// Internet Media Type gemäß RFC 2045, z. B. application/pdf.
+        /// </summary>
+        [JsonProperty("mimeType")]
+        public string MimeType { get; set; }
+
+        /// <summary>
+        /// 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
+        /// </summary>
+        [JsonProperty("purpose")]
+        public Purpose Purpose { get; set; }
+
+        [JsonProperty("signature", NullValueHandling = NullValueHandling.Ignore)]
+        public AttachmentSignature Signature { get; set; }
+    }
+
+    /// <summary>
+    /// 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).
+    /// </summary>
+    public partial class AttachmentHash
+    {
+        /// <summary>
+        /// Der Hex-kodierte Hashwert gemäß des angegebenen Algorithmus.
+        /// </summary>
+        [JsonProperty("content")]
+        public string Content { get; set; }
+
+        /// <summary>
+        /// Der verwendete Hash-Algorithmus. Derzeit ist nur `sha512` erlaubt.
+        /// </summary>
+        [JsonProperty("type")]
+        public HashType Type { get; set; }
+    }
+
+    /// <summary>
+    /// Beschreibt das Signaturformt und Profile
+    /// </summary>
+    public partial class AttachmentSignature
+    {
+        /// <summary>
+        /// 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.
+        /// </summary>
+        [JsonProperty("content", NullValueHandling = NullValueHandling.Ignore)]
+        public string Content { get; set; }
+
+        /// <summary>
+        /// 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.
+        /// </summary>
+        [JsonProperty("detachedSignature")]
+        public bool DetachedSignature { get; set; }
+
+        /// <summary>
+        /// 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
+        /// </summary>
+        [JsonProperty("eidasAdesProfile", NullValueHandling = NullValueHandling.Ignore)]
+        public EidasAdesProfile? EidasAdesProfile { get; set; }
+
+        /// <summary>
+        /// 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.
+        /// </summary>
+        [JsonProperty("signatureFormat")]
+        public SignatureFormat SignatureFormat { get; set; }
+    }
+
+    /// <summary>
+    /// Definiert das Schema und die Signatur(-art), die für die Fachdaten verwendet werden.
+    /// </summary>
+    public partial class Data
+    {
+        /// <summary>
+        /// 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).
+        /// </summary>
+        [JsonProperty("hash")]
+        public DataHash Hash { get; set; }
+
+        /// <summary>
+        /// Beschreibt das Signaturformt und Profile
+        /// </summary>
+        [JsonProperty("signature", NullValueHandling = NullValueHandling.Ignore)]
+        public DataSignature Signature { get; set; }
+
+        /// <summary>
+        /// Referenz auf ein Schema, das die Struktur der Fachdaten einer Einreichung beschreibt.
+        /// </summary>
+        [JsonProperty("submissionSchema")]
+        public Fachdatenschema SubmissionSchema { get; set; }
+    }
+
+    /// <summary>
+    /// 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).
+    /// </summary>
+    public partial class DataHash
+    {
+        /// <summary>
+        /// Der Hex-kodierte Hashwert gemäß des angegebenen Algorithmus.
+        /// </summary>
+        [JsonProperty("content")]
+        public string Content { get; set; }
+
+        /// <summary>
+        /// Der verwendete Hash-Algorithmus. Derzeit ist nur `sha512` erlaubt.
+        /// </summary>
+        [JsonProperty("type")]
+        public HashType Type { get; set; }
+    }
+
+    /// <summary>
+    /// Beschreibt das Signaturformt und Profile
+    /// </summary>
+    public partial class DataSignature
+    {
+        /// <summary>
+        /// 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.
+        /// </summary>
+        [JsonProperty("content", NullValueHandling = NullValueHandling.Ignore)]
+        public string Content { get; set; }
+
+        /// <summary>
+        /// 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.
+        /// </summary>
+        [JsonProperty("detachedSignature")]
+        public bool DetachedSignature { get; set; }
+
+        /// <summary>
+        /// 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
+        /// </summary>
+        [JsonProperty("eidasAdesProfile", NullValueHandling = NullValueHandling.Ignore)]
+        public EidasAdesProfile? EidasAdesProfile { get; set; }
+
+        /// <summary>
+        /// 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.
+        /// </summary>
+        [JsonProperty("signatureFormat")]
+        public SignatureFormat SignatureFormat { get; set; }
+    }
+
+    /// <summary>
+    /// Referenz auf ein Schema, das die Struktur der Fachdaten einer Einreichung beschreibt.
+    /// </summary>
+    public partial class Fachdatenschema
+    {
+        /// <summary>
+        /// Mimetype (z.B. application/json oder application/xml) des referenzierten Schemas (z.B.
+        /// XSD- oder JSON-Schema).
+        /// </summary>
+        [JsonProperty("mimeType")]
+        public MimeType MimeType { get; set; }
+
+        /// <summary>
+        /// 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.
+        /// </summary>
+        [JsonProperty("schemaUri")]
+        public Uri SchemaUri { get; set; }
+    }
+
+    /// <summary>
+    /// Dieses Objekt enthält die Informationen vom Bezahldienst.
+    /// </summary>
+    public partial class PaymentInformation
+    {
+        /// <summary>
+        /// Bruttobetrag
+        /// </summary>
+        [JsonProperty("grossAmount", NullValueHandling = NullValueHandling.Ignore)]
+        [JsonConverter(typeof(MinMaxValueCheckConverter))]
+        public double? GrossAmount { get; set; }
+
+        /// <summary>
+        /// Die vom Benutzer ausgewählte Zahlart. Das Feld ist nur bei einer erfolgreichen Zahlung
+        /// vorhanden / befüllt.
+        /// </summary>
+        [JsonProperty("paymentMethod")]
+        public PaymentMethod PaymentMethod { get; set; }
+
+        /// <summary>
+        /// Weitere Erläuterung zur gewählten Zahlart.
+        /// </summary>
+        [JsonProperty("paymentMethodDetail", NullValueHandling = NullValueHandling.Ignore)]
+        [JsonConverter(typeof(PurpleMinMaxLengthCheckConverter))]
+        public string PaymentMethodDetail { get; set; }
+
+        /// <summary>
+        /// - 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.
+        /// - BOOKED - der Nutzer hat die Bezahlung im Bezahldienst autorisiert.
+        /// - FAILED - der Vorgang wurde vom Bezahldienst aufgrund der Nutzereingaben abgebrochen.
+        /// - CANCELED - der Nutzer hat die Bezahlung im Bezahldienst abgebrochen.
+        /// </summary>
+        [JsonProperty("status")]
+        public Status Status { get; set; }
+
+        /// <summary>
+        /// Eine vom Bezahldienst vergebene Transaktions-Id.
+        /// </summary>
+        [JsonProperty("transactionId")]
+        [JsonConverter(typeof(PurpleMinMaxLengthCheckConverter))]
+        public string TransactionId { get; set; }
+
+        /// <summary>
+        /// Bezahlreferenz bzw. Verwendungszweck, wie z. B. ein Kassenzeichen.
+        /// </summary>
+        [JsonProperty("transactionReference")]
+        public string TransactionReference { get; set; }
+
+        /// <summary>
+        /// Zeitstempel der erfolgreichen Durchführung der Bezahlung.
+        /// </summary>
+        [JsonProperty("transactionTimestamp", NullValueHandling = NullValueHandling.Ignore)]
+        public DateTimeOffset? TransactionTimestamp { get; set; }
+
+        /// <summary>
+        /// Die Rest-URL der Payment Transaction für die Statusabfrage.
+        /// </summary>
+        [JsonProperty("transactionUrl", NullValueHandling = NullValueHandling.Ignore)]
+        public Uri TransactionUrl { get; set; }
+    }
+
+    /// <summary>
+    /// 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.
+    /// </summary>
+    public partial class Verwaltungsleistung
+    {
+        /// <summary>
+        /// (Kurz-)Beschreibung der Verwaltungsleistung
+        /// </summary>
+        [JsonProperty("description", NullValueHandling = NullValueHandling.Ignore)]
+        public string Description { get; set; }
+
+        /// <summary>
+        /// URN einer Leistung. Im Falle einer Leistung aus dem Leistungskatalog sollte hier
+        /// `urn:de:fim:leika:leistung:` vorangestellt werden.
+        /// </summary>
+        [JsonProperty("identifier")]
+        [JsonConverter(typeof(FluffyMinMaxLengthCheckConverter))]
+        public string Identifier { get; set; }
+
+        /// <summary>
+        /// Name/Bezeichnung der Verwaltungsleistung
+        /// </summary>
+        [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)]
+        public string Name { get; set; }
+    }
+
+    public partial class ReplyChannel
+    {
+        /// <summary>
+        /// Akkreditierte Anbieter siehe
+        /// https://www.bsi.bund.de/DE/Themen/Oeffentliche-Verwaltung/Moderner-Staat/De-Mail/Akkreditierte-DMDA/akkreditierte-dmda_node.html
+        /// </summary>
+        [JsonProperty("deMail", NullValueHandling = NullValueHandling.Ignore)]
+        public DeMail DeMail { get; set; }
+
+        /// <summary>
+        /// Siehe https://www.elster.de/elsterweb/infoseite/elstertransfer_hilfe_schnittstellen
+        /// </summary>
+        [JsonProperty("elster", NullValueHandling = NullValueHandling.Ignore)]
+        public Elster Elster { get; set; }
+
+        [JsonProperty("eMail", NullValueHandling = NullValueHandling.Ignore)]
+        public EMail EMail { get; set; }
+
+        /// <summary>
+        /// Postfachadresse in einem interoperablen Servicekonto (FINK.PFISK)
+        /// </summary>
+        [JsonProperty("fink", NullValueHandling = NullValueHandling.Ignore)]
+        public Fink Fink { get; set; }
+    }
+
+    /// <summary>
+    /// Akkreditierte Anbieter siehe
+    /// https://www.bsi.bund.de/DE/Themen/Oeffentliche-Verwaltung/Moderner-Staat/De-Mail/Akkreditierte-DMDA/akkreditierte-dmda_node.html
+    /// </summary>
+    public partial class DeMail
+    {
+        [JsonProperty("address")]
+        public string Address { get; set; }
+    }
+
+    public partial class EMail
+    {
+        [JsonProperty("address")]
+        public string Address { get; set; }
+
+        /// <summary>
+        /// Hilfe zur Erstellung gibt es in der Dokumentation unter
+        /// https://docs.fitko.de/fit-connect/details/pgp-export
+        /// </summary>
+        [JsonProperty("pgpPublicKey", NullValueHandling = NullValueHandling.Ignore)]
+        public string PgpPublicKey { get; set; }
+    }
+
+    /// <summary>
+    /// Siehe https://www.elster.de/elsterweb/infoseite/elstertransfer_hilfe_schnittstellen
+    /// </summary>
+    public partial class Elster
+    {
+        [JsonProperty("accountId")]
+        public string AccountId { get; set; }
+
+        [JsonProperty("geschaeftszeichen", NullValueHandling = NullValueHandling.Ignore)]
+        [JsonConverter(typeof(TentacledMinMaxLengthCheckConverter))]
+        public string Geschaeftszeichen { get; set; }
+
+        [JsonProperty("lieferTicket", NullValueHandling = NullValueHandling.Ignore)]
+        public string LieferTicket { get; set; }
+    }
+
+    /// <summary>
+    /// Postfachadresse in einem interoperablen Servicekonto (FINK.PFISK)
+    /// </summary>
+    public partial class Fink
+    {
+        /// <summary>
+        /// FINK Postfachadresse
+        /// </summary>
+        [JsonProperty("finkPostfachRef")]
+        [JsonConverter(typeof(StickyMinMaxLengthCheckConverter))]
+        public string FinkPostfachRef { get; set; }
+
+        /// <summary>
+        /// URL des Servicekontos, in dem das Ziel-Postfach liegt
+        /// </summary>
+        [JsonProperty("host", NullValueHandling = NullValueHandling.Ignore)]
+        public Uri Host { get; set; }
+    }
+
+    /// <summary>
+    /// Definiert die Art des Identifikationsnachweises.
+    /// </summary>
+    public enum AuthenticationInformationType { IdentificationReport };
+
+    /// <summary>
+    /// Der verwendete Hash-Algorithmus. Derzeit ist nur `sha512` erlaubt.
+    /// </summary>
+    public enum HashType { Sha512 };
+
+    /// <summary>
+    /// 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
+    /// </summary>
+    public enum Purpose { Attachment, Form, Report };
+
+    /// <summary>
+    /// 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
+    /// </summary>
+    public enum EidasAdesProfile { HttpUriEtsiOrgAdes191X2LevelBaselineBB, HttpUriEtsiOrgAdes191X2LevelBaselineBLt, HttpUriEtsiOrgAdes191X2LevelBaselineBLta, HttpUriEtsiOrgAdes191X2LevelBaselineBT };
+
+    /// <summary>
+    /// 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.
+    /// </summary>
+    public enum SignatureFormat { Asic, Cms, Json, Pdf, Xml };
+
+    /// <summary>
+    /// Mimetype (z.B. application/json oder application/xml) des referenzierten Schemas (z.B.
+    /// XSD- oder JSON-Schema).
+    /// </summary>
+    public enum MimeType { ApplicationJson, ApplicationXml };
+
+    /// <summary>
+    /// Die vom Benutzer ausgewählte Zahlart. Das Feld ist nur bei einer erfolgreichen Zahlung
+    /// vorhanden / befüllt.
+    /// </summary>
+    public enum PaymentMethod { Creditcard, Giropay, Invoice, Other, Paydirect, Paypal };
+
+    /// <summary>
+    /// - 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.
+    /// - BOOKED - der Nutzer hat die Bezahlung im Bezahldienst autorisiert.
+    /// - FAILED - der Vorgang wurde vom Bezahldienst aufgrund der Nutzereingaben abgebrochen.
+    /// - CANCELED - der Nutzer hat die Bezahlung im Bezahldienst abgebrochen.
+    /// </summary>
+    public enum Status { Booked, Canceled, Failed, Initial };
+
+    public partial class Metadata
+    {
+        public static Metadata FromJson(string json) => JsonConvert.DeserializeObject<Metadata>(json, FitConnect.Models.Api.Metadata.Converter.Settings);
+    }
+
+    public static class Serialize
+    {
+        public static string ToJson(this Metadata self) => JsonConvert.SerializeObject(self, FitConnect.Models.Api.Metadata.Converter.Settings);
+    }
+
+    internal static class Converter
+    {
+        public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
+        {
+            MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
+            DateParseHandling = DateParseHandling.None,
+            Converters =
+            {
+                AuthenticationInformationTypeConverter.Singleton,
+                HashTypeConverter.Singleton,
+                PurposeConverter.Singleton,
+                EidasAdesProfileConverter.Singleton,
+                SignatureFormatConverter.Singleton,
+                MimeTypeConverter.Singleton,
+                PaymentMethodConverter.Singleton,
+                StatusConverter.Singleton,
+                new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
+            },
+        };
+    }
+
+    internal class AuthenticationInformationTypeConverter : JsonConverter
+    {
+        public override bool CanConvert(Type t) => t == typeof(AuthenticationInformationType) || t == typeof(AuthenticationInformationType?);
+
+        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
+        {
+            if (reader.TokenType == JsonToken.Null) return null;
+            var value = serializer.Deserialize<string>(reader);
+            if (value == "identificationReport")
+            {
+                return AuthenticationInformationType.IdentificationReport;
+            }
+            throw new Exception("Cannot unmarshal type AuthenticationInformationType");
+        }
+
+        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
+        {
+            if (untypedValue == null)
+            {
+                serializer.Serialize(writer, null);
+                return;
+            }
+            var value = (AuthenticationInformationType)untypedValue;
+            if (value == AuthenticationInformationType.IdentificationReport)
+            {
+                serializer.Serialize(writer, "identificationReport");
+                return;
+            }
+            throw new Exception("Cannot marshal type AuthenticationInformationType");
+        }
+
+        public static readonly AuthenticationInformationTypeConverter Singleton = new AuthenticationInformationTypeConverter();
+    }
+
+    internal class HashTypeConverter : JsonConverter
+    {
+        public override bool CanConvert(Type t) => t == typeof(HashType) || t == typeof(HashType?);
+
+        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
+        {
+            if (reader.TokenType == JsonToken.Null) return null;
+            var value = serializer.Deserialize<string>(reader);
+            if (value == "sha512")
+            {
+                return HashType.Sha512;
+            }
+            throw new Exception("Cannot unmarshal type HashType");
+        }
+
+        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
+        {
+            if (untypedValue == null)
+            {
+                serializer.Serialize(writer, null);
+                return;
+            }
+            var value = (HashType)untypedValue;
+            if (value == HashType.Sha512)
+            {
+                serializer.Serialize(writer, "sha512");
+                return;
+            }
+            throw new Exception("Cannot marshal type HashType");
+        }
+
+        public static readonly HashTypeConverter Singleton = new HashTypeConverter();
+    }
+
+    internal class PurposeConverter : JsonConverter
+    {
+        public override bool CanConvert(Type t) => t == typeof(Purpose) || t == typeof(Purpose?);
+
+        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
+        {
+            if (reader.TokenType == JsonToken.Null) return null;
+            var value = serializer.Deserialize<string>(reader);
+            switch (value)
+            {
+                case "attachment":
+                    return Purpose.Attachment;
+                case "form":
+                    return Purpose.Form;
+                case "report":
+                    return Purpose.Report;
+            }
+            throw new Exception("Cannot unmarshal type Purpose");
+        }
+
+        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
+        {
+            if (untypedValue == null)
+            {
+                serializer.Serialize(writer, null);
+                return;
+            }
+            var value = (Purpose)untypedValue;
+            switch (value)
+            {
+                case Purpose.Attachment:
+                    serializer.Serialize(writer, "attachment");
+                    return;
+                case Purpose.Form:
+                    serializer.Serialize(writer, "form");
+                    return;
+                case Purpose.Report:
+                    serializer.Serialize(writer, "report");
+                    return;
+            }
+            throw new Exception("Cannot marshal type Purpose");
+        }
+
+        public static readonly PurposeConverter Singleton = new PurposeConverter();
+    }
+
+    internal class EidasAdesProfileConverter : JsonConverter
+    {
+        public override bool CanConvert(Type t) => t == typeof(EidasAdesProfile) || t == typeof(EidasAdesProfile?);
+
+        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
+        {
+            if (reader.TokenType == JsonToken.Null) return null;
+            var value = serializer.Deserialize<string>(reader);
+            switch (value)
+            {
+                case "http://uri.etsi.org/ades/191x2/level/baseline/B-B#":
+                    return EidasAdesProfile.HttpUriEtsiOrgAdes191X2LevelBaselineBB;
+                case "http://uri.etsi.org/ades/191x2/level/baseline/B-LT#":
+                    return EidasAdesProfile.HttpUriEtsiOrgAdes191X2LevelBaselineBLt;
+                case "http://uri.etsi.org/ades/191x2/level/baseline/B-LTA#":
+                    return EidasAdesProfile.HttpUriEtsiOrgAdes191X2LevelBaselineBLta;
+                case "http://uri.etsi.org/ades/191x2/level/baseline/B-T#":
+                    return EidasAdesProfile.HttpUriEtsiOrgAdes191X2LevelBaselineBT;
+            }
+            throw new Exception("Cannot unmarshal type EidasAdesProfile");
+        }
+
+        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
+        {
+            if (untypedValue == null)
+            {
+                serializer.Serialize(writer, null);
+                return;
+            }
+            var value = (EidasAdesProfile)untypedValue;
+            switch (value)
+            {
+                case EidasAdesProfile.HttpUriEtsiOrgAdes191X2LevelBaselineBB:
+                    serializer.Serialize(writer, "http://uri.etsi.org/ades/191x2/level/baseline/B-B#");
+                    return;
+                case EidasAdesProfile.HttpUriEtsiOrgAdes191X2LevelBaselineBLt:
+                    serializer.Serialize(writer, "http://uri.etsi.org/ades/191x2/level/baseline/B-LT#");
+                    return;
+                case EidasAdesProfile.HttpUriEtsiOrgAdes191X2LevelBaselineBLta:
+                    serializer.Serialize(writer, "http://uri.etsi.org/ades/191x2/level/baseline/B-LTA#");
+                    return;
+                case EidasAdesProfile.HttpUriEtsiOrgAdes191X2LevelBaselineBT:
+                    serializer.Serialize(writer, "http://uri.etsi.org/ades/191x2/level/baseline/B-T#");
+                    return;
+            }
+            throw new Exception("Cannot marshal type EidasAdesProfile");
+        }
+
+        public static readonly EidasAdesProfileConverter Singleton = new EidasAdesProfileConverter();
+    }
+
+    internal class SignatureFormatConverter : JsonConverter
+    {
+        public override bool CanConvert(Type t) => t == typeof(SignatureFormat) || t == typeof(SignatureFormat?);
+
+        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
+        {
+            if (reader.TokenType == JsonToken.Null) return null;
+            var value = serializer.Deserialize<string>(reader);
+            switch (value)
+            {
+                case "asic":
+                    return SignatureFormat.Asic;
+                case "cms":
+                    return SignatureFormat.Cms;
+                case "json":
+                    return SignatureFormat.Json;
+                case "pdf":
+                    return SignatureFormat.Pdf;
+                case "xml":
+                    return SignatureFormat.Xml;
+            }
+            throw new Exception("Cannot unmarshal type SignatureFormat");
+        }
+
+        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
+        {
+            if (untypedValue == null)
+            {
+                serializer.Serialize(writer, null);
+                return;
+            }
+            var value = (SignatureFormat)untypedValue;
+            switch (value)
+            {
+                case SignatureFormat.Asic:
+                    serializer.Serialize(writer, "asic");
+                    return;
+                case SignatureFormat.Cms:
+                    serializer.Serialize(writer, "cms");
+                    return;
+                case SignatureFormat.Json:
+                    serializer.Serialize(writer, "json");
+                    return;
+                case SignatureFormat.Pdf:
+                    serializer.Serialize(writer, "pdf");
+                    return;
+                case SignatureFormat.Xml:
+                    serializer.Serialize(writer, "xml");
+                    return;
+            }
+            throw new Exception("Cannot marshal type SignatureFormat");
+        }
+
+        public static readonly SignatureFormatConverter Singleton = new SignatureFormatConverter();
+    }
+
+    internal class MimeTypeConverter : JsonConverter
+    {
+        public override bool CanConvert(Type t) => t == typeof(MimeType) || t == typeof(MimeType?);
+
+        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
+        {
+            if (reader.TokenType == JsonToken.Null) return null;
+            var value = serializer.Deserialize<string>(reader);
+            switch (value)
+            {
+                case "application/json":
+                    return MimeType.ApplicationJson;
+                case "application/xml":
+                    return MimeType.ApplicationXml;
+            }
+            throw new Exception("Cannot unmarshal type MimeType");
+        }
+
+        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
+        {
+            if (untypedValue == null)
+            {
+                serializer.Serialize(writer, null);
+                return;
+            }
+            var value = (MimeType)untypedValue;
+            switch (value)
+            {
+                case MimeType.ApplicationJson:
+                    serializer.Serialize(writer, "application/json");
+                    return;
+                case MimeType.ApplicationXml:
+                    serializer.Serialize(writer, "application/xml");
+                    return;
+            }
+            throw new Exception("Cannot marshal type MimeType");
+        }
+
+        public static readonly MimeTypeConverter Singleton = new MimeTypeConverter();
+    }
+
+    internal class MinMaxValueCheckConverter : JsonConverter
+    {
+        public override bool CanConvert(Type t) => t == typeof(double) || t == typeof(double?);
+
+        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
+        {
+            if (reader.TokenType == JsonToken.Null) return null;
+            var value = serializer.Deserialize<double>(reader);
+            if (value >= 0.01)
+            {
+                return value;
+            }
+            throw new Exception("Cannot unmarshal type double");
+        }
+
+        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
+        {
+            if (untypedValue == null)
+            {
+                serializer.Serialize(writer, null);
+                return;
+            }
+            var value = (double)untypedValue;
+            if (value >= 0.01)
+            {
+                serializer.Serialize(writer, value);
+                return;
+            }
+            throw new Exception("Cannot marshal type double");
+        }
+
+        public static readonly MinMaxValueCheckConverter Singleton = new MinMaxValueCheckConverter();
+    }
+
+    internal class PaymentMethodConverter : JsonConverter
+    {
+        public override bool CanConvert(Type t) => t == typeof(PaymentMethod) || t == typeof(PaymentMethod?);
+
+        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
+        {
+            if (reader.TokenType == JsonToken.Null) return null;
+            var value = serializer.Deserialize<string>(reader);
+            switch (value)
+            {
+                case "CREDITCARD":
+                    return PaymentMethod.Creditcard;
+                case "GIROPAY":
+                    return PaymentMethod.Giropay;
+                case "INVOICE":
+                    return PaymentMethod.Invoice;
+                case "OTHER":
+                    return PaymentMethod.Other;
+                case "PAYDIRECT":
+                    return PaymentMethod.Paydirect;
+                case "PAYPAL":
+                    return PaymentMethod.Paypal;
+            }
+            throw new Exception("Cannot unmarshal type PaymentMethod");
+        }
+
+        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
+        {
+            if (untypedValue == null)
+            {
+                serializer.Serialize(writer, null);
+                return;
+            }
+            var value = (PaymentMethod)untypedValue;
+            switch (value)
+            {
+                case PaymentMethod.Creditcard:
+                    serializer.Serialize(writer, "CREDITCARD");
+                    return;
+                case PaymentMethod.Giropay:
+                    serializer.Serialize(writer, "GIROPAY");
+                    return;
+                case PaymentMethod.Invoice:
+                    serializer.Serialize(writer, "INVOICE");
+                    return;
+                case PaymentMethod.Other:
+                    serializer.Serialize(writer, "OTHER");
+                    return;
+                case PaymentMethod.Paydirect:
+                    serializer.Serialize(writer, "PAYDIRECT");
+                    return;
+                case PaymentMethod.Paypal:
+                    serializer.Serialize(writer, "PAYPAL");
+                    return;
+            }
+            throw new Exception("Cannot marshal type PaymentMethod");
+        }
+
+        public static readonly PaymentMethodConverter Singleton = new PaymentMethodConverter();
+    }
+
+    internal class PurpleMinMaxLengthCheckConverter : JsonConverter
+    {
+        public override bool CanConvert(Type t) => t == typeof(string);
+
+        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
+        {
+            var value = serializer.Deserialize<string>(reader);
+            if (value.Length >= 1 && value.Length <= 36)
+            {
+                return value;
+            }
+            throw new Exception("Cannot unmarshal type string");
+        }
+
+        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
+        {
+            var value = (string)untypedValue;
+            if (value.Length >= 1 && value.Length <= 36)
+            {
+                serializer.Serialize(writer, value);
+                return;
+            }
+            throw new Exception("Cannot marshal type string");
+        }
+
+        public static readonly PurpleMinMaxLengthCheckConverter Singleton = new PurpleMinMaxLengthCheckConverter();
+    }
+
+    internal class StatusConverter : JsonConverter
+    {
+        public override bool CanConvert(Type t) => t == typeof(Status) || t == typeof(Status?);
+
+        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
+        {
+            if (reader.TokenType == JsonToken.Null) return null;
+            var value = serializer.Deserialize<string>(reader);
+            switch (value)
+            {
+                case "BOOKED":
+                    return Status.Booked;
+                case "CANCELED":
+                    return Status.Canceled;
+                case "FAILED":
+                    return Status.Failed;
+                case "INITIAL":
+                    return Status.Initial;
+            }
+            throw new Exception("Cannot unmarshal type Status");
+        }
+
+        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
+        {
+            if (untypedValue == null)
+            {
+                serializer.Serialize(writer, null);
+                return;
+            }
+            var value = (Status)untypedValue;
+            switch (value)
+            {
+                case Status.Booked:
+                    serializer.Serialize(writer, "BOOKED");
+                    return;
+                case Status.Canceled:
+                    serializer.Serialize(writer, "CANCELED");
+                    return;
+                case Status.Failed:
+                    serializer.Serialize(writer, "FAILED");
+                    return;
+                case Status.Initial:
+                    serializer.Serialize(writer, "INITIAL");
+                    return;
+            }
+            throw new Exception("Cannot marshal type Status");
+        }
+
+        public static readonly StatusConverter Singleton = new StatusConverter();
+    }
+
+    internal class FluffyMinMaxLengthCheckConverter : JsonConverter
+    {
+        public override bool CanConvert(Type t) => t == typeof(string);
+
+        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
+        {
+            var value = serializer.Deserialize<string>(reader);
+            if (value.Length >= 7 && value.Length <= 255)
+            {
+                return value;
+            }
+            throw new Exception("Cannot unmarshal type string");
+        }
+
+        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
+        {
+            var value = (string)untypedValue;
+            if (value.Length >= 7 && value.Length <= 255)
+            {
+                serializer.Serialize(writer, value);
+                return;
+            }
+            throw new Exception("Cannot marshal type string");
+        }
+
+        public static readonly FluffyMinMaxLengthCheckConverter Singleton = new FluffyMinMaxLengthCheckConverter();
+    }
+
+    internal class TentacledMinMaxLengthCheckConverter : JsonConverter
+    {
+        public override bool CanConvert(Type t) => t == typeof(string);
+
+        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
+        {
+            var value = serializer.Deserialize<string>(reader);
+            if (value.Length <= 10)
+            {
+                return value;
+            }
+            throw new Exception("Cannot unmarshal type string");
+        }
+
+        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
+        {
+            var value = (string)untypedValue;
+            if (value.Length <= 10)
+            {
+                serializer.Serialize(writer, value);
+                return;
+            }
+            throw new Exception("Cannot marshal type string");
+        }
+
+        public static readonly TentacledMinMaxLengthCheckConverter Singleton = new TentacledMinMaxLengthCheckConverter();
+    }
+
+    internal class StickyMinMaxLengthCheckConverter : JsonConverter
+    {
+        public override bool CanConvert(Type t) => t == typeof(string);
+
+        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
+        {
+            var value = serializer.Deserialize<string>(reader);
+            if (value.Length <= 150)
+            {
+                return value;
+            }
+            throw new Exception("Cannot unmarshal type string");
+        }
+
+        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
+        {
+            var value = (string)untypedValue;
+            if (value.Length <= 150)
+            {
+                serializer.Serialize(writer, value);
+                return;
+            }
+            throw new Exception("Cannot marshal type string");
+        }
+
+        public static readonly StickyMinMaxLengthCheckConverter Singleton = new StickyMinMaxLengthCheckConverter();
+    }
+}
diff --git a/Services/Models/Api/SecurityEventToken.cs b/Services/Models/Api/SecurityEventToken.cs
new file mode 100644
index 0000000000000000000000000000000000000000..fccc4762f5ab79409b498649117f7fc057fd6979
--- /dev/null
+++ b/Services/Models/Api/SecurityEventToken.cs
@@ -0,0 +1,1122 @@
+// <auto-generated />
+//
+// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:
+//
+//    using FitConnect;
+//
+//    var metadata = Metadata.FromJson(jsonString);
+
+namespace FitConnect.Models.Api.Set
+{
+    using System;
+    using System.Collections.Generic;
+
+    using System.Globalization;
+    using Newtonsoft.Json;
+    using Newtonsoft.Json.Converters;
+
+    public partial class Metadata
+    {
+        /// <summary>
+        /// Eine Struktur, um zusätzliche Informationen zu hinterlegen
+        /// </summary>
+        [JsonProperty("additionalReferenceInfo", NullValueHandling = NullValueHandling.Ignore)]
+        public AdditionalReferenceInfo AdditionalReferenceInfo { get; set; }
+
+        /// <summary>
+        /// Eine Liste aller Identifikationsnachweise der Einreichung.
+        /// </summary>
+        [JsonProperty("authenticationInformation", NullValueHandling = NullValueHandling.Ignore)]
+        public List<AuthenticationInformation> AuthenticationInformation { get; set; }
+
+        /// <summary>
+        /// Beschreibt die Struktur der zusätzlichen Inhalte der Einreichung, wie Anlagen oder
+        /// Fachdaten.
+        /// </summary>
+        [JsonProperty("contentStructure")]
+        public ContentStructure ContentStructure { get; set; }
+
+        /// <summary>
+        /// Dieses Objekt enthält die Informationen vom Bezahldienst.
+        /// </summary>
+        [JsonProperty("paymentInformation", NullValueHandling = NullValueHandling.Ignore)]
+        public PaymentInformation PaymentInformation { get; set; }
+
+        /// <summary>
+        /// 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.
+        /// </summary>
+        [JsonProperty("publicServiceType", NullValueHandling = NullValueHandling.Ignore)]
+        public Verwaltungsleistung PublicServiceType { get; set; }
+
+        [JsonProperty("replyChannel", NullValueHandling = NullValueHandling.Ignore)]
+        public ReplyChannel ReplyChannel { get; set; }
+    }
+
+    /// <summary>
+    /// Eine Struktur, um zusätzliche Informationen zu hinterlegen
+    /// </summary>
+    public partial class AdditionalReferenceInfo
+    {
+        /// <summary>
+        /// Das Datum der Antragstellung. Das Datum muss nicht zwingend identisch mit dem Datum der
+        /// Einreichung des Antrags über FIT-Connect sein.
+        /// </summary>
+        [JsonProperty("applicationDate", NullValueHandling = NullValueHandling.Ignore)]
+        public DateTimeOffset? ApplicationDate { get; set; }
+
+        /// <summary>
+        /// 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.
+        /// </summary>
+        [JsonProperty("senderReference", NullValueHandling = NullValueHandling.Ignore)]
+        public string SenderReference { get; set; }
+    }
+
+    /// <summary>
+    /// Eine Struktur, die einen Identifikationsnachweis beschreibt.
+    /// </summary>
+    public partial class AuthenticationInformation
+    {
+        /// <summary>
+        /// Der Nachweis wird als Base64Url-kodierte Zeichenkette angegeben.
+        /// </summary>
+        [JsonProperty("content")]
+        public string Content { get; set; }
+
+        /// <summary>
+        /// Definiert die Art des Identifikationsnachweises.
+        /// </summary>
+        [JsonProperty("type")]
+        public AuthenticationInformationType Type { get; set; }
+
+        /// <summary>
+        /// semver kompatible Versionsangabe des genutzten Nachweistyps.
+        /// </summary>
+        [JsonProperty("version")]
+        public string Version { get; set; }
+    }
+
+    /// <summary>
+    /// Beschreibt die Struktur der zusätzlichen Inhalte der Einreichung, wie Anlagen oder
+    /// Fachdaten.
+    /// </summary>
+    public partial class ContentStructure
+    {
+        [JsonProperty("attachments")]
+        public List<Attachment> Attachments { get; set; }
+
+        /// <summary>
+        /// Definiert das Schema und die Signatur(-art), die für die Fachdaten verwendet werden.
+        /// </summary>
+        [JsonProperty("data", NullValueHandling = NullValueHandling.Ignore)]
+        public Data Data { get; set; }
+    }
+
+    /// <summary>
+    /// Eine in der Einreichung enthaltene Anlage.
+    /// </summary>
+    public partial class Attachment
+    {
+        /// <summary>
+        /// Innerhalb einer Einreichung eindeutige Id der Anlage im Format einer UUIDv4.
+        /// </summary>
+        [JsonProperty("attachmentId")]
+        public Guid AttachmentId { get; set; }
+
+        /// <summary>
+        /// Optionale Beschreibung der Anlage
+        /// </summary>
+        [JsonProperty("description", NullValueHandling = NullValueHandling.Ignore)]
+        public string Description { get; set; }
+
+        /// <summary>
+        /// Ursprünglicher Dateiname bei Erzeugung oder Upload
+        /// </summary>
+        [JsonProperty("filename", NullValueHandling = NullValueHandling.Ignore)]
+        public string Filename { get; set; }
+
+        /// <summary>
+        /// 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).
+        /// </summary>
+        [JsonProperty("hash")]
+        public AttachmentHash Hash { get; set; }
+
+        /// <summary>
+        /// Internet Media Type gemäß RFC 2045, z. B. application/pdf.
+        /// </summary>
+        [JsonProperty("mimeType")]
+        public string MimeType { get; set; }
+
+        /// <summary>
+        /// 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
+        /// </summary>
+        [JsonProperty("purpose")]
+        public Purpose Purpose { get; set; }
+
+        [JsonProperty("signature", NullValueHandling = NullValueHandling.Ignore)]
+        public AttachmentSignature Signature { get; set; }
+    }
+
+    /// <summary>
+    /// 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).
+    /// </summary>
+    public partial class AttachmentHash
+    {
+        /// <summary>
+        /// Der Hex-kodierte Hashwert gemäß des angegebenen Algorithmus.
+        /// </summary>
+        [JsonProperty("content")]
+        public string Content { get; set; }
+
+        /// <summary>
+        /// Der verwendete Hash-Algorithmus. Derzeit ist nur `sha512` erlaubt.
+        /// </summary>
+        [JsonProperty("type")]
+        public HashType Type { get; set; }
+    }
+
+    /// <summary>
+    /// Beschreibt das Signaturformt und Profile
+    /// </summary>
+    public partial class AttachmentSignature
+    {
+        /// <summary>
+        /// 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.
+        /// </summary>
+        [JsonProperty("content", NullValueHandling = NullValueHandling.Ignore)]
+        public string Content { get; set; }
+
+        /// <summary>
+        /// 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.
+        /// </summary>
+        [JsonProperty("detachedSignature")]
+        public bool DetachedSignature { get; set; }
+
+        /// <summary>
+        /// 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
+        /// </summary>
+        [JsonProperty("eidasAdesProfile", NullValueHandling = NullValueHandling.Ignore)]
+        public EidasAdesProfile? EidasAdesProfile { get; set; }
+
+        /// <summary>
+        /// 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.
+        /// </summary>
+        [JsonProperty("signatureFormat")]
+        public SignatureFormat SignatureFormat { get; set; }
+    }
+
+    /// <summary>
+    /// Definiert das Schema und die Signatur(-art), die für die Fachdaten verwendet werden.
+    /// </summary>
+    public partial class Data
+    {
+        /// <summary>
+        /// 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).
+        /// </summary>
+        [JsonProperty("hash")]
+        public DataHash Hash { get; set; }
+
+        /// <summary>
+        /// Beschreibt das Signaturformt und Profile
+        /// </summary>
+        [JsonProperty("signature", NullValueHandling = NullValueHandling.Ignore)]
+        public DataSignature Signature { get; set; }
+
+        /// <summary>
+        /// Referenz auf ein Schema, das die Struktur der Fachdaten einer Einreichung beschreibt.
+        /// </summary>
+        [JsonProperty("submissionSchema")]
+        public Fachdatenschema SubmissionSchema { get; set; }
+    }
+
+    /// <summary>
+    /// 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).
+    /// </summary>
+    public partial class DataHash
+    {
+        /// <summary>
+        /// Der Hex-kodierte Hashwert gemäß des angegebenen Algorithmus.
+        /// </summary>
+        [JsonProperty("content")]
+        public string Content { get; set; }
+
+        /// <summary>
+        /// Der verwendete Hash-Algorithmus. Derzeit ist nur `sha512` erlaubt.
+        /// </summary>
+        [JsonProperty("type")]
+        public HashType Type { get; set; }
+    }
+
+    /// <summary>
+    /// Beschreibt das Signaturformt und Profile
+    /// </summary>
+    public partial class DataSignature
+    {
+        /// <summary>
+        /// 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.
+        /// </summary>
+        [JsonProperty("content", NullValueHandling = NullValueHandling.Ignore)]
+        public string Content { get; set; }
+
+        /// <summary>
+        /// 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.
+        /// </summary>
+        [JsonProperty("detachedSignature")]
+        public bool DetachedSignature { get; set; }
+
+        /// <summary>
+        /// 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
+        /// </summary>
+        [JsonProperty("eidasAdesProfile", NullValueHandling = NullValueHandling.Ignore)]
+        public EidasAdesProfile? EidasAdesProfile { get; set; }
+
+        /// <summary>
+        /// 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.
+        /// </summary>
+        [JsonProperty("signatureFormat")]
+        public SignatureFormat SignatureFormat { get; set; }
+    }
+
+    /// <summary>
+    /// Referenz auf ein Schema, das die Struktur der Fachdaten einer Einreichung beschreibt.
+    /// </summary>
+    public partial class Fachdatenschema
+    {
+        /// <summary>
+        /// Mimetype (z.B. application/json oder application/xml) des referenzierten Schemas (z.B.
+        /// XSD- oder JSON-Schema).
+        /// </summary>
+        [JsonProperty("mimeType")]
+        public MimeType MimeType { get; set; }
+
+        /// <summary>
+        /// 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.
+        /// </summary>
+        [JsonProperty("schemaUri")]
+        public Uri SchemaUri { get; set; }
+    }
+
+    /// <summary>
+    /// Dieses Objekt enthält die Informationen vom Bezahldienst.
+    /// </summary>
+    public partial class PaymentInformation
+    {
+        /// <summary>
+        /// Bruttobetrag
+        /// </summary>
+        [JsonProperty("grossAmount", NullValueHandling = NullValueHandling.Ignore)]
+        [JsonConverter(typeof(MinMaxValueCheckConverter))]
+        public double? GrossAmount { get; set; }
+
+        /// <summary>
+        /// Die vom Benutzer ausgewählte Zahlart. Das Feld ist nur bei einer erfolgreichen Zahlung
+        /// vorhanden / befüllt.
+        /// </summary>
+        [JsonProperty("paymentMethod")]
+        public PaymentMethod PaymentMethod { get; set; }
+
+        /// <summary>
+        /// Weitere Erläuterung zur gewählten Zahlart.
+        /// </summary>
+        [JsonProperty("paymentMethodDetail", NullValueHandling = NullValueHandling.Ignore)]
+        [JsonConverter(typeof(PurpleMinMaxLengthCheckConverter))]
+        public string PaymentMethodDetail { get; set; }
+
+        /// <summary>
+        /// - 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.
+        /// - BOOKED - der Nutzer hat die Bezahlung im Bezahldienst autorisiert.
+        /// - FAILED - der Vorgang wurde vom Bezahldienst aufgrund der Nutzereingaben abgebrochen.
+        /// - CANCELED - der Nutzer hat die Bezahlung im Bezahldienst abgebrochen.
+        /// </summary>
+        [JsonProperty("status")]
+        public Status Status { get; set; }
+
+        /// <summary>
+        /// Eine vom Bezahldienst vergebene Transaktions-Id.
+        /// </summary>
+        [JsonProperty("transactionId")]
+        [JsonConverter(typeof(PurpleMinMaxLengthCheckConverter))]
+        public string TransactionId { get; set; }
+
+        /// <summary>
+        /// Bezahlreferenz bzw. Verwendungszweck, wie z. B. ein Kassenzeichen.
+        /// </summary>
+        [JsonProperty("transactionReference")]
+        public string TransactionReference { get; set; }
+
+        /// <summary>
+        /// Zeitstempel der erfolgreichen Durchführung der Bezahlung.
+        /// </summary>
+        [JsonProperty("transactionTimestamp", NullValueHandling = NullValueHandling.Ignore)]
+        public DateTimeOffset? TransactionTimestamp { get; set; }
+
+        /// <summary>
+        /// Die Rest-URL der Payment Transaction für die Statusabfrage.
+        /// </summary>
+        [JsonProperty("transactionUrl", NullValueHandling = NullValueHandling.Ignore)]
+        public Uri TransactionUrl { get; set; }
+    }
+
+    /// <summary>
+    /// 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.
+    /// </summary>
+    public partial class Verwaltungsleistung
+    {
+        /// <summary>
+        /// (Kurz-)Beschreibung der Verwaltungsleistung
+        /// </summary>
+        [JsonProperty("description", NullValueHandling = NullValueHandling.Ignore)]
+        public string Description { get; set; }
+
+        /// <summary>
+        /// URN einer Leistung. Im Falle einer Leistung aus dem Leistungskatalog sollte hier
+        /// `urn:de:fim:leika:leistung:` vorangestellt werden.
+        /// </summary>
+        [JsonProperty("identifier")]
+        [JsonConverter(typeof(FluffyMinMaxLengthCheckConverter))]
+        public string Identifier { get; set; }
+
+        /// <summary>
+        /// Name/Bezeichnung der Verwaltungsleistung
+        /// </summary>
+        [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)]
+        public string Name { get; set; }
+    }
+
+    public partial class ReplyChannel
+    {
+        /// <summary>
+        /// Akkreditierte Anbieter siehe
+        /// https://www.bsi.bund.de/DE/Themen/Oeffentliche-Verwaltung/Moderner-Staat/De-Mail/Akkreditierte-DMDA/akkreditierte-dmda_node.html
+        /// </summary>
+        [JsonProperty("deMail", NullValueHandling = NullValueHandling.Ignore)]
+        public DeMail DeMail { get; set; }
+
+        /// <summary>
+        /// Siehe https://www.elster.de/elsterweb/infoseite/elstertransfer_hilfe_schnittstellen
+        /// </summary>
+        [JsonProperty("elster", NullValueHandling = NullValueHandling.Ignore)]
+        public Elster Elster { get; set; }
+
+        [JsonProperty("eMail", NullValueHandling = NullValueHandling.Ignore)]
+        public EMail EMail { get; set; }
+
+        /// <summary>
+        /// Postfachadresse in einem interoperablen Servicekonto (FINK.PFISK)
+        /// </summary>
+        [JsonProperty("fink", NullValueHandling = NullValueHandling.Ignore)]
+        public Fink Fink { get; set; }
+    }
+
+    /// <summary>
+    /// Akkreditierte Anbieter siehe
+    /// https://www.bsi.bund.de/DE/Themen/Oeffentliche-Verwaltung/Moderner-Staat/De-Mail/Akkreditierte-DMDA/akkreditierte-dmda_node.html
+    /// </summary>
+    public partial class DeMail
+    {
+        [JsonProperty("address")]
+        public string Address { get; set; }
+    }
+
+    public partial class EMail
+    {
+        [JsonProperty("address")]
+        public string Address { get; set; }
+
+        /// <summary>
+        /// Hilfe zur Erstellung gibt es in der Dokumentation unter
+        /// https://docs.fitko.de/fit-connect/details/pgp-export
+        /// </summary>
+        [JsonProperty("pgpPublicKey", NullValueHandling = NullValueHandling.Ignore)]
+        public string PgpPublicKey { get; set; }
+    }
+
+    /// <summary>
+    /// Siehe https://www.elster.de/elsterweb/infoseite/elstertransfer_hilfe_schnittstellen
+    /// </summary>
+    public partial class Elster
+    {
+        [JsonProperty("accountId")]
+        public string AccountId { get; set; }
+
+        [JsonProperty("geschaeftszeichen", NullValueHandling = NullValueHandling.Ignore)]
+        [JsonConverter(typeof(TentacledMinMaxLengthCheckConverter))]
+        public string Geschaeftszeichen { get; set; }
+
+        [JsonProperty("lieferTicket", NullValueHandling = NullValueHandling.Ignore)]
+        public string LieferTicket { get; set; }
+    }
+
+    /// <summary>
+    /// Postfachadresse in einem interoperablen Servicekonto (FINK.PFISK)
+    /// </summary>
+    public partial class Fink
+    {
+        /// <summary>
+        /// FINK Postfachadresse
+        /// </summary>
+        [JsonProperty("finkPostfachRef")]
+        [JsonConverter(typeof(StickyMinMaxLengthCheckConverter))]
+        public string FinkPostfachRef { get; set; }
+
+        /// <summary>
+        /// URL des Servicekontos, in dem das Ziel-Postfach liegt
+        /// </summary>
+        [JsonProperty("host", NullValueHandling = NullValueHandling.Ignore)]
+        public Uri Host { get; set; }
+    }
+
+    /// <summary>
+    /// Definiert die Art des Identifikationsnachweises.
+    /// </summary>
+    public enum AuthenticationInformationType { IdentificationReport };
+
+    /// <summary>
+    /// Der verwendete Hash-Algorithmus. Derzeit ist nur `sha512` erlaubt.
+    /// </summary>
+    public enum HashType { Sha512 };
+
+    /// <summary>
+    /// 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
+    /// </summary>
+    public enum Purpose { Attachment, Form, Report };
+
+    /// <summary>
+    /// 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
+    /// </summary>
+    public enum EidasAdesProfile { HttpUriEtsiOrgAdes191X2LevelBaselineBB, HttpUriEtsiOrgAdes191X2LevelBaselineBLt, HttpUriEtsiOrgAdes191X2LevelBaselineBLta, HttpUriEtsiOrgAdes191X2LevelBaselineBT };
+
+    /// <summary>
+    /// 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.
+    /// </summary>
+    public enum SignatureFormat { Asic, Cms, Json, Pdf, Xml };
+
+    /// <summary>
+    /// Mimetype (z.B. application/json oder application/xml) des referenzierten Schemas (z.B.
+    /// XSD- oder JSON-Schema).
+    /// </summary>
+    public enum MimeType { ApplicationJson, ApplicationXml };
+
+    /// <summary>
+    /// Die vom Benutzer ausgewählte Zahlart. Das Feld ist nur bei einer erfolgreichen Zahlung
+    /// vorhanden / befüllt.
+    /// </summary>
+    public enum PaymentMethod { Creditcard, Giropay, Invoice, Other, Paydirect, Paypal };
+
+    /// <summary>
+    /// - 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.
+    /// - BOOKED - der Nutzer hat die Bezahlung im Bezahldienst autorisiert.
+    /// - FAILED - der Vorgang wurde vom Bezahldienst aufgrund der Nutzereingaben abgebrochen.
+    /// - CANCELED - der Nutzer hat die Bezahlung im Bezahldienst abgebrochen.
+    /// </summary>
+    public enum Status { Booked, Canceled, Failed, Initial };
+
+    public partial class Metadata
+    {
+        public static Metadata FromJson(string json) => JsonConvert.DeserializeObject<Metadata>(json, FitConnect.Models.Api.Set.Converter.Settings);
+    }
+
+    public static class Serialize
+    {
+        public static string ToJson(this Metadata self) => JsonConvert.SerializeObject(self, FitConnect.Models.Api.Set.Converter.Settings);
+    }
+
+    internal static class Converter
+    {
+        public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
+        {
+            MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
+            DateParseHandling = DateParseHandling.None,
+            Converters =
+            {
+                AuthenticationInformationTypeConverter.Singleton,
+                HashTypeConverter.Singleton,
+                PurposeConverter.Singleton,
+                EidasAdesProfileConverter.Singleton,
+                SignatureFormatConverter.Singleton,
+                MimeTypeConverter.Singleton,
+                PaymentMethodConverter.Singleton,
+                StatusConverter.Singleton,
+                new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
+            },
+        };
+    }
+
+    internal class AuthenticationInformationTypeConverter : JsonConverter
+    {
+        public override bool CanConvert(Type t) => t == typeof(AuthenticationInformationType) || t == typeof(AuthenticationInformationType?);
+
+        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
+        {
+            if (reader.TokenType == JsonToken.Null) return null;
+            var value = serializer.Deserialize<string>(reader);
+            if (value == "identificationReport")
+            {
+                return AuthenticationInformationType.IdentificationReport;
+            }
+            throw new Exception("Cannot unmarshal type AuthenticationInformationType");
+        }
+
+        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
+        {
+            if (untypedValue == null)
+            {
+                serializer.Serialize(writer, null);
+                return;
+            }
+            var value = (AuthenticationInformationType)untypedValue;
+            if (value == AuthenticationInformationType.IdentificationReport)
+            {
+                serializer.Serialize(writer, "identificationReport");
+                return;
+            }
+            throw new Exception("Cannot marshal type AuthenticationInformationType");
+        }
+
+        public static readonly AuthenticationInformationTypeConverter Singleton = new AuthenticationInformationTypeConverter();
+    }
+
+    internal class HashTypeConverter : JsonConverter
+    {
+        public override bool CanConvert(Type t) => t == typeof(HashType) || t == typeof(HashType?);
+
+        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
+        {
+            if (reader.TokenType == JsonToken.Null) return null;
+            var value = serializer.Deserialize<string>(reader);
+            if (value == "sha512")
+            {
+                return HashType.Sha512;
+            }
+            throw new Exception("Cannot unmarshal type HashType");
+        }
+
+        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
+        {
+            if (untypedValue == null)
+            {
+                serializer.Serialize(writer, null);
+                return;
+            }
+            var value = (HashType)untypedValue;
+            if (value == HashType.Sha512)
+            {
+                serializer.Serialize(writer, "sha512");
+                return;
+            }
+            throw new Exception("Cannot marshal type HashType");
+        }
+
+        public static readonly HashTypeConverter Singleton = new HashTypeConverter();
+    }
+
+    internal class PurposeConverter : JsonConverter
+    {
+        public override bool CanConvert(Type t) => t == typeof(Purpose) || t == typeof(Purpose?);
+
+        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
+        {
+            if (reader.TokenType == JsonToken.Null) return null;
+            var value = serializer.Deserialize<string>(reader);
+            switch (value)
+            {
+                case "attachment":
+                    return Purpose.Attachment;
+                case "form":
+                    return Purpose.Form;
+                case "report":
+                    return Purpose.Report;
+            }
+            throw new Exception("Cannot unmarshal type Purpose");
+        }
+
+        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
+        {
+            if (untypedValue == null)
+            {
+                serializer.Serialize(writer, null);
+                return;
+            }
+            var value = (Purpose)untypedValue;
+            switch (value)
+            {
+                case Purpose.Attachment:
+                    serializer.Serialize(writer, "attachment");
+                    return;
+                case Purpose.Form:
+                    serializer.Serialize(writer, "form");
+                    return;
+                case Purpose.Report:
+                    serializer.Serialize(writer, "report");
+                    return;
+            }
+            throw new Exception("Cannot marshal type Purpose");
+        }
+
+        public static readonly PurposeConverter Singleton = new PurposeConverter();
+    }
+
+    internal class EidasAdesProfileConverter : JsonConverter
+    {
+        public override bool CanConvert(Type t) => t == typeof(EidasAdesProfile) || t == typeof(EidasAdesProfile?);
+
+        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
+        {
+            if (reader.TokenType == JsonToken.Null) return null;
+            var value = serializer.Deserialize<string>(reader);
+            switch (value)
+            {
+                case "http://uri.etsi.org/ades/191x2/level/baseline/B-B#":
+                    return EidasAdesProfile.HttpUriEtsiOrgAdes191X2LevelBaselineBB;
+                case "http://uri.etsi.org/ades/191x2/level/baseline/B-LT#":
+                    return EidasAdesProfile.HttpUriEtsiOrgAdes191X2LevelBaselineBLt;
+                case "http://uri.etsi.org/ades/191x2/level/baseline/B-LTA#":
+                    return EidasAdesProfile.HttpUriEtsiOrgAdes191X2LevelBaselineBLta;
+                case "http://uri.etsi.org/ades/191x2/level/baseline/B-T#":
+                    return EidasAdesProfile.HttpUriEtsiOrgAdes191X2LevelBaselineBT;
+            }
+            throw new Exception("Cannot unmarshal type EidasAdesProfile");
+        }
+
+        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
+        {
+            if (untypedValue == null)
+            {
+                serializer.Serialize(writer, null);
+                return;
+            }
+            var value = (EidasAdesProfile)untypedValue;
+            switch (value)
+            {
+                case EidasAdesProfile.HttpUriEtsiOrgAdes191X2LevelBaselineBB:
+                    serializer.Serialize(writer, "http://uri.etsi.org/ades/191x2/level/baseline/B-B#");
+                    return;
+                case EidasAdesProfile.HttpUriEtsiOrgAdes191X2LevelBaselineBLt:
+                    serializer.Serialize(writer, "http://uri.etsi.org/ades/191x2/level/baseline/B-LT#");
+                    return;
+                case EidasAdesProfile.HttpUriEtsiOrgAdes191X2LevelBaselineBLta:
+                    serializer.Serialize(writer, "http://uri.etsi.org/ades/191x2/level/baseline/B-LTA#");
+                    return;
+                case EidasAdesProfile.HttpUriEtsiOrgAdes191X2LevelBaselineBT:
+                    serializer.Serialize(writer, "http://uri.etsi.org/ades/191x2/level/baseline/B-T#");
+                    return;
+            }
+            throw new Exception("Cannot marshal type EidasAdesProfile");
+        }
+
+        public static readonly EidasAdesProfileConverter Singleton = new EidasAdesProfileConverter();
+    }
+
+    internal class SignatureFormatConverter : JsonConverter
+    {
+        public override bool CanConvert(Type t) => t == typeof(SignatureFormat) || t == typeof(SignatureFormat?);
+
+        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
+        {
+            if (reader.TokenType == JsonToken.Null) return null;
+            var value = serializer.Deserialize<string>(reader);
+            switch (value)
+            {
+                case "asic":
+                    return SignatureFormat.Asic;
+                case "cms":
+                    return SignatureFormat.Cms;
+                case "json":
+                    return SignatureFormat.Json;
+                case "pdf":
+                    return SignatureFormat.Pdf;
+                case "xml":
+                    return SignatureFormat.Xml;
+            }
+            throw new Exception("Cannot unmarshal type SignatureFormat");
+        }
+
+        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
+        {
+            if (untypedValue == null)
+            {
+                serializer.Serialize(writer, null);
+                return;
+            }
+            var value = (SignatureFormat)untypedValue;
+            switch (value)
+            {
+                case SignatureFormat.Asic:
+                    serializer.Serialize(writer, "asic");
+                    return;
+                case SignatureFormat.Cms:
+                    serializer.Serialize(writer, "cms");
+                    return;
+                case SignatureFormat.Json:
+                    serializer.Serialize(writer, "json");
+                    return;
+                case SignatureFormat.Pdf:
+                    serializer.Serialize(writer, "pdf");
+                    return;
+                case SignatureFormat.Xml:
+                    serializer.Serialize(writer, "xml");
+                    return;
+            }
+            throw new Exception("Cannot marshal type SignatureFormat");
+        }
+
+        public static readonly SignatureFormatConverter Singleton = new SignatureFormatConverter();
+    }
+
+    internal class MimeTypeConverter : JsonConverter
+    {
+        public override bool CanConvert(Type t) => t == typeof(MimeType) || t == typeof(MimeType?);
+
+        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
+        {
+            if (reader.TokenType == JsonToken.Null) return null;
+            var value = serializer.Deserialize<string>(reader);
+            switch (value)
+            {
+                case "application/json":
+                    return MimeType.ApplicationJson;
+                case "application/xml":
+                    return MimeType.ApplicationXml;
+            }
+            throw new Exception("Cannot unmarshal type MimeType");
+        }
+
+        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
+        {
+            if (untypedValue == null)
+            {
+                serializer.Serialize(writer, null);
+                return;
+            }
+            var value = (MimeType)untypedValue;
+            switch (value)
+            {
+                case MimeType.ApplicationJson:
+                    serializer.Serialize(writer, "application/json");
+                    return;
+                case MimeType.ApplicationXml:
+                    serializer.Serialize(writer, "application/xml");
+                    return;
+            }
+            throw new Exception("Cannot marshal type MimeType");
+        }
+
+        public static readonly MimeTypeConverter Singleton = new MimeTypeConverter();
+    }
+
+    internal class MinMaxValueCheckConverter : JsonConverter
+    {
+        public override bool CanConvert(Type t) => t == typeof(double) || t == typeof(double?);
+
+        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
+        {
+            if (reader.TokenType == JsonToken.Null) return null;
+            var value = serializer.Deserialize<double>(reader);
+            if (value >= 0.01)
+            {
+                return value;
+            }
+            throw new Exception("Cannot unmarshal type double");
+        }
+
+        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
+        {
+            if (untypedValue == null)
+            {
+                serializer.Serialize(writer, null);
+                return;
+            }
+            var value = (double)untypedValue;
+            if (value >= 0.01)
+            {
+                serializer.Serialize(writer, value);
+                return;
+            }
+            throw new Exception("Cannot marshal type double");
+        }
+
+        public static readonly MinMaxValueCheckConverter Singleton = new MinMaxValueCheckConverter();
+    }
+
+    internal class PaymentMethodConverter : JsonConverter
+    {
+        public override bool CanConvert(Type t) => t == typeof(PaymentMethod) || t == typeof(PaymentMethod?);
+
+        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
+        {
+            if (reader.TokenType == JsonToken.Null) return null;
+            var value = serializer.Deserialize<string>(reader);
+            switch (value)
+            {
+                case "CREDITCARD":
+                    return PaymentMethod.Creditcard;
+                case "GIROPAY":
+                    return PaymentMethod.Giropay;
+                case "INVOICE":
+                    return PaymentMethod.Invoice;
+                case "OTHER":
+                    return PaymentMethod.Other;
+                case "PAYDIRECT":
+                    return PaymentMethod.Paydirect;
+                case "PAYPAL":
+                    return PaymentMethod.Paypal;
+            }
+            throw new Exception("Cannot unmarshal type PaymentMethod");
+        }
+
+        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
+        {
+            if (untypedValue == null)
+            {
+                serializer.Serialize(writer, null);
+                return;
+            }
+            var value = (PaymentMethod)untypedValue;
+            switch (value)
+            {
+                case PaymentMethod.Creditcard:
+                    serializer.Serialize(writer, "CREDITCARD");
+                    return;
+                case PaymentMethod.Giropay:
+                    serializer.Serialize(writer, "GIROPAY");
+                    return;
+                case PaymentMethod.Invoice:
+                    serializer.Serialize(writer, "INVOICE");
+                    return;
+                case PaymentMethod.Other:
+                    serializer.Serialize(writer, "OTHER");
+                    return;
+                case PaymentMethod.Paydirect:
+                    serializer.Serialize(writer, "PAYDIRECT");
+                    return;
+                case PaymentMethod.Paypal:
+                    serializer.Serialize(writer, "PAYPAL");
+                    return;
+            }
+            throw new Exception("Cannot marshal type PaymentMethod");
+        }
+
+        public static readonly PaymentMethodConverter Singleton = new PaymentMethodConverter();
+    }
+
+    internal class PurpleMinMaxLengthCheckConverter : JsonConverter
+    {
+        public override bool CanConvert(Type t) => t == typeof(string);
+
+        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
+        {
+            var value = serializer.Deserialize<string>(reader);
+            if (value.Length >= 1 && value.Length <= 36)
+            {
+                return value;
+            }
+            throw new Exception("Cannot unmarshal type string");
+        }
+
+        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
+        {
+            var value = (string)untypedValue;
+            if (value.Length >= 1 && value.Length <= 36)
+            {
+                serializer.Serialize(writer, value);
+                return;
+            }
+            throw new Exception("Cannot marshal type string");
+        }
+
+        public static readonly PurpleMinMaxLengthCheckConverter Singleton = new PurpleMinMaxLengthCheckConverter();
+    }
+
+    internal class StatusConverter : JsonConverter
+    {
+        public override bool CanConvert(Type t) => t == typeof(Status) || t == typeof(Status?);
+
+        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
+        {
+            if (reader.TokenType == JsonToken.Null) return null;
+            var value = serializer.Deserialize<string>(reader);
+            switch (value)
+            {
+                case "BOOKED":
+                    return Status.Booked;
+                case "CANCELED":
+                    return Status.Canceled;
+                case "FAILED":
+                    return Status.Failed;
+                case "INITIAL":
+                    return Status.Initial;
+            }
+            throw new Exception("Cannot unmarshal type Status");
+        }
+
+        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
+        {
+            if (untypedValue == null)
+            {
+                serializer.Serialize(writer, null);
+                return;
+            }
+            var value = (Status)untypedValue;
+            switch (value)
+            {
+                case Status.Booked:
+                    serializer.Serialize(writer, "BOOKED");
+                    return;
+                case Status.Canceled:
+                    serializer.Serialize(writer, "CANCELED");
+                    return;
+                case Status.Failed:
+                    serializer.Serialize(writer, "FAILED");
+                    return;
+                case Status.Initial:
+                    serializer.Serialize(writer, "INITIAL");
+                    return;
+            }
+            throw new Exception("Cannot marshal type Status");
+        }
+
+        public static readonly StatusConverter Singleton = new StatusConverter();
+    }
+
+    internal class FluffyMinMaxLengthCheckConverter : JsonConverter
+    {
+        public override bool CanConvert(Type t) => t == typeof(string);
+
+        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
+        {
+            var value = serializer.Deserialize<string>(reader);
+            if (value.Length >= 7 && value.Length <= 255)
+            {
+                return value;
+            }
+            throw new Exception("Cannot unmarshal type string");
+        }
+
+        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
+        {
+            var value = (string)untypedValue;
+            if (value.Length >= 7 && value.Length <= 255)
+            {
+                serializer.Serialize(writer, value);
+                return;
+            }
+            throw new Exception("Cannot marshal type string");
+        }
+
+        public static readonly FluffyMinMaxLengthCheckConverter Singleton = new FluffyMinMaxLengthCheckConverter();
+    }
+
+    internal class TentacledMinMaxLengthCheckConverter : JsonConverter
+    {
+        public override bool CanConvert(Type t) => t == typeof(string);
+
+        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
+        {
+            var value = serializer.Deserialize<string>(reader);
+            if (value.Length <= 10)
+            {
+                return value;
+            }
+            throw new Exception("Cannot unmarshal type string");
+        }
+
+        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
+        {
+            var value = (string)untypedValue;
+            if (value.Length <= 10)
+            {
+                serializer.Serialize(writer, value);
+                return;
+            }
+            throw new Exception("Cannot marshal type string");
+        }
+
+        public static readonly TentacledMinMaxLengthCheckConverter Singleton = new TentacledMinMaxLengthCheckConverter();
+    }
+
+    internal class StickyMinMaxLengthCheckConverter : JsonConverter
+    {
+        public override bool CanConvert(Type t) => t == typeof(string);
+
+        public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
+        {
+            var value = serializer.Deserialize<string>(reader);
+            if (value.Length <= 150)
+            {
+                return value;
+            }
+            throw new Exception("Cannot unmarshal type string");
+        }
+
+        public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
+        {
+            var value = (string)untypedValue;
+            if (value.Length <= 150)
+            {
+                serializer.Serialize(writer, value);
+                return;
+            }
+            throw new Exception("Cannot marshal type string");
+        }
+
+        public static readonly StickyMinMaxLengthCheckConverter Singleton = new StickyMinMaxLengthCheckConverter();
+    }
+}
diff --git a/Services/Services.csproj b/Services/Services.csproj
index 9532ca430385e7c6b1f9774a9064d4bcfebbb013..a7e0e4428d4d28e78ac79e675b28c5102e5ba1ad 100644
--- a/Services/Services.csproj
+++ b/Services/Services.csproj
@@ -8,12 +8,12 @@
     </PropertyGroup>
 
     <ItemGroup>
-        <ProjectReference Include="..\Models\Models.csproj"/>
-        <ProjectReference Include="..\RestService\RestService.csproj"/>
+        <ProjectReference Include="..\Models\Models.csproj" />
+        <ProjectReference Include="..\RestService\RestService.csproj" />
     </ItemGroup>
 
     <ItemGroup>
-        <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.1"/>
+        <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.1" />
     </ItemGroup>
 
 </Project>
diff --git a/working_notes.md b/working_notes.md
index 91b76b4a0db6dd3058c0fe7392d4bf4edd2a3c84..089b933e93f1064fa4bc9dc0825798d333bf6d8c 100644
--- a/working_notes.md
+++ b/working_notes.md
@@ -25,13 +25,24 @@
 
 ## Links
 
+### Documentation
+
 - [SDK-Konzept im Wiki](https://wiki.fit-connect.fitko.dev/de/Konzeption/Konzeption_SDK)
 - [inoffizielles Python-SDK](https://github.com/codedust/fitconnect-sdk-python)
 - [Project management](https://wiki.fit-connect.fitko.dev/de/PM_PUBLIC/Projektvorgehensmodell)
 - [Wiki SDK Description](https://wiki.fit-connect.fitko.dev/de/PM_PUBLIC/Epics/SDK_Initialisierung)
 - [Containing GitLab](https://git.fitko.de/)
 - [Board filtered for SDK](https://git.fitko.de/fit-connect/planning/-/boards/44?label_name%5B%5D=component%3A%3ASDK)
-- [Documentation](https://docs.fitko.de/fit-connect/docs/getting-started/first-steps/)
+- [FitConnect First Steps](https://docs.fitko.de/fit-connect/docs/getting-started/first-steps/)
 - [Security Event Token Requirements](https://wiki.fit-connect.fitko.dev/de/Konzeption/Security_Event_Token_Future)
 - [glossary](https://docs.fitko.de/fit-connect/docs/glossary/)
 
+### Helper
+- [Create C# class from JSON schema](https://app.quicktype.io/?l=csharp)
+
+## Values for testing
+
+| Topic              | Value          | Description                             |
+|:-------------------|:---------------|:----------------------------------------|
+| Leika Key          | 99099002067003 | Deutsche Staatsangehörigkeit beantragen |
+| Gemeinde Schlüssel | 09 3 72 126    | Furth im Wald                           |
\ No newline at end of file