diff --git a/E2ETests/E2ETests.csproj b/E2ETests/E2ETests.csproj
index 5c22f888dff9e67e999ba2f5716fec2c0fedc16f..b78e88522ad81a1269c8f66db483d2d240b8be2b 100644
--- a/E2ETests/E2ETests.csproj
+++ b/E2ETests/E2ETests.csproj
@@ -8,15 +8,16 @@
     </PropertyGroup>
 
     <ItemGroup>
-        <PackageReference Include="FluentAssertions" Version="6.7.0" />
-        <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
-        <PackageReference Include="NUnit" Version="3.13.2" />
-        <PackageReference Include="NUnit3TestAdapter" Version="4.0.0" />
-        <PackageReference Include="coverlet.collector" Version="3.1.0" />
+        <PackageReference Include="FluentAssertions" Version="6.7.0"/>
+        <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0"/>
+        <PackageReference Include="NUnit" Version="3.13.2"/>
+        <PackageReference Include="NUnit3TestAdapter" Version="4.0.0"/>
+        <PackageReference Include="coverlet.collector" Version="3.1.0"/>
     </ItemGroup>
 
     <ItemGroup>
-      <ProjectReference Include="..\FitConnect\FitConnect.csproj" />
+        <ProjectReference Include="..\FitConnect\FitConnect.csproj"/>
+        <ProjectReference Include="..\Services\Services.csproj"/>
     </ItemGroup>
 
 </Project>
diff --git a/E2ETests/OAuthServiceTest.cs b/E2ETests/OAuthServiceTest.cs
new file mode 100644
index 0000000000000000000000000000000000000000..bb7bdc5e37e0e3b8c438c96f1f45917558a39afa
--- /dev/null
+++ b/E2ETests/OAuthServiceTest.cs
@@ -0,0 +1,64 @@
+using System;
+using System.IO;
+using FitConnect;
+using FitConnect.Services;
+using FluentAssertions;
+using Newtonsoft.Json;
+using NUnit.Framework;
+
+namespace E2ETests;
+
+public class OAuthServiceTest {
+    private string _clientId;
+    private string _clientSecret;
+    private OAuthService _oAuthService = null!;
+
+    [OneTimeSetUp]
+    public void OneTimeSetup() {
+        // relative to the project execution directory
+        const string secretFile = "../../../http-client.private.env.json";
+
+        if (!File.Exists(secretFile)) {
+            // If the secret file is not found, create it with the default values
+            // The file will be pretty in C#11, when """ is introduced
+            File.WriteAllText(secretFile, @"
+{
+    ""sender"": {
+        ""id"": ""00000000-0000-0000-0000-000000000000"",
+        ""secret"": ""0000000000000000000000000000000000000000000"",
+        ""scope"": ""send:region:DE""
+    }
+}");
+            throw new Exception("Please fill the secret.json file with your sender credentials");
+        }
+
+        var jsonContent = File.ReadAllText(secretFile);
+        var secret = JsonConvert.DeserializeObject<dynamic>(jsonContent);
+        _clientId = secret.sender.id;
+        _clientSecret = secret.sender.secret;
+    }
+
+
+    [SetUp]
+    public void SetUp() {
+        var endpoints = FitConnectEndpoints.Create(FitConnectEndpoints.EndpointType.Development);
+        _oAuthService = new OAuthService(endpoints.TokenUrl);
+    }
+
+    [Test]
+    public void GetAccessToken_ExpiresInShouldBe1800_WithoutScope() {
+        var token = _oAuthService.GetTokenAsync(_clientId, _clientSecret).Result;
+        token.Should().NotBeNull();
+        token!.ExpiresIn.Should().Be(1800);
+        token.Scope.Should().Be("send:region:DE");
+    }
+
+    [Test]
+    public void GetAccessToken_ScopeShouldMatch_WithScope() {
+        var token = _oAuthService.GetTokenAsync(_clientId, _clientSecret, "send:region:DE01010")
+            .Result;
+        token.Should().NotBeNull();
+        token!.ExpiresIn.Should().Be(1800);
+        token.Scope.Should().Be("send:region:DE01010");
+    }
+}
diff --git a/E2ETests/SenderTest.cs b/E2ETests/SenderTest.cs
index d912585e6239ce4d272bdb141b1c409fe3c27f74..21d5c64cf1bbc98150100b1eb53dce7f52f009c9 100644
--- a/E2ETests/SenderTest.cs
+++ b/E2ETests/SenderTest.cs
@@ -12,6 +12,10 @@ public class SenderTest {
     private string _clientSecret = "";
     private Sender _sender;
 
+    /// <summary>
+    ///     Setup creates json file for credentials if not found
+    /// </summary>
+    /// <exception cref="Exception"></exception>
     [OneTimeSetUp]
     public void OneTimeSetup() {
         // relative to the project execution directory
@@ -48,20 +52,4 @@ public class SenderTest {
         _clientId.Should().NotBe("00000000-0000-0000-0000-000000000000");
         _clientSecret.Should().NotBe("0000000000000000000000000000000000000000000");
     }
-
-    [Test]
-    public void GetAccessToken() {
-        var token = _sender.GetTokenAsync(_clientId, _clientSecret).Result;
-        token.Should().NotBeNull();
-        token!.ExpiresIn.Should().Be(1800);
-        token.Scope.Should().Be("send:region:DE");
-    }
-
-    [Test]
-    public void GetAccessTokenWithScope() {
-        var token = _sender.GetTokenAsync(_clientId, _clientSecret, "send:region:DE01010").Result;
-        token.Should().NotBeNull();
-        token!.ExpiresIn.Should().Be(1800);
-        token.Scope.Should().Be("send:region:DE01010");
-    }
 }
diff --git a/EncryptionTests/Certificates/certificate.cer b/EncryptionTests/Certificates/certificate.cer
new file mode 100644
index 0000000000000000000000000000000000000000..73f0387ee1b1ff8bdc9fe430d24b328c0e860b85
--- /dev/null
+++ b/EncryptionTests/Certificates/certificate.cer
@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIIEyjCCArKgAwIBAgIIMIw7HOs7698wDQYJKoZIhvcNAQELBQAwJTEWMBQGA1UEAxMNZml0Y29u
+bmVjdC5kZTELMAkGA1UEBhMCREUwHhcNMjIwNjA4MTEwNzQ3WhcNMjcwNjA4MTEwNzUyWjAlMRYw
+FAYDVQQDEw1maXRjb25uZWN0LmRlMQswCQYDVQQGEwJERTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
+ADCCAgoCggIBAJxxbIieIEY9Vvql4R6ED5HqtGMjoJZ2xiwF5Zv/DuLseAZEUR7QuBvPG8CLcYOE
+JArXcAS5smLfG2LiNerMgDnrLGvBl3qrYOEq0kRIqGkSr5JM2V/bk2UgMToOJGQDBMh6IbU707Xp
+u1gHe2wuNxbJE4kALZV8zJX9fE2bc87o3URsw4yv3EnCpR3TskPI2uazNxKWVWjgpZ5yB6PQMbG0
+R7e0qGdEeIo5PpaxdkzbJUN4LwnEdZCKbXt3bMqr7wUJ4lXrqCUhO1Y57iR5YoNBTkKgJHV9fbcy
+EHs6IZAhxQCCyuczby5UDS4VzXvnqpxxnvI/rv12nc2WPPctvmA3AyHOH7hTugg7UZ75UKFFHqfU
+TeY6lWkifUpTpWVZ3Krm0+3Ja/VZzufPSybifTR9v5JMxQdwaqp9E53Cqh1csqciLVazDOjU6Lhn
+fjLr4GwSri1FveXDqpq/jJhkTbuDL1fAEs+eDauD3vNxb0Bverpb5/7rOcAKTH0GEzZhSHV23fyP
+DpKmpi5h0py42SdbBAZat8C1StMQ7m3UxuDdoMg+zRS5d12d6s0ZFf2xwFCjDVNVN6y7BkSGuA2l
+2/I5ojXhK/Wm+DAcKT/osZznyNq4OlHL2ck6LOSSgFCJFrdkpku++gROx2xjUIFQjryUkcPZ6y0l
+PLXAHJUEGO97AgMBAAEwDQYJKoZIhvcNAQELBQADggIBADXJ6LP4HdnUiFCgQR8PoY+fR8XCnYx8
+FdVB9v9xdsBhE1/B1c8z6kUInQdq2NfsRjyfgA1wIdPElP+b1bu/TKS/GpWrsPHUXDRv67qT13cB
+rw8I6rHTDdnF00pEU4mabI32EqGnEAwu8DGlKnDbnh/dY7IQjYK40/ZutcqzybzvBiNFoYu7rKXg
+7CThPwc92fnPfFcDJJMU9YlA5C6MaLSxDj0e3z1rl+ew9pab8gclnbzgxGOqFMNPhNRHx0SvFrCF
+dPzva9mYDATHgR66hJAo/hov8qJnz6/7xkQgFPy4jHwBk2ubM2SN8+UEyklm7u3v8X6mpvdE7/gC
+qWJYJjcpzz7QEBmvJ9yYIALNo8E9UyZNfYgE/hEyBpEccNk7z6y/yHNThcojwbfmYjztl5Ed4uHY
+i1ycf5LYcSAxtzD6V5CuIVzmPNkSgB1m8Wu/+5Sy2/uQGIKNK/X6E9f1GjTDBv5KzxOoongc4yri
+VinYgmrpoF6Uh6G423IGT6/+SpyQa5oegpSbKKDcSAQKK/fCJQbck03WTbpgKDhc0KDLB2C07yiI
+RNgSDRO+eg8BTFjxE3uPVwY8AP+QxK2+Xn5ozuT7aedeS41MQYeeatd6StNy809DvIMb44ZUA6JU
+/n8Ok8eHWVY+aShfomcLyH7+EeL9e2LTSp0geUdmsnNI
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/EncryptionTests/Certificates/certificate.pfx b/EncryptionTests/Certificates/certificate.pfx
new file mode 100644
index 0000000000000000000000000000000000000000..ec4092f2c68e0c8865fe9333be770dd09fb5c6f9
Binary files /dev/null and b/EncryptionTests/Certificates/certificate.pfx differ
diff --git a/SenderTest/SenderTest.csproj b/EncryptionTests/EncryptionTests.csproj
similarity index 66%
rename from SenderTest/SenderTest.csproj
rename to EncryptionTests/EncryptionTests.csproj
index def8c00370d4ec3573756904bfa33de12b0ef921..edababf841e8930e50e54f1d0a183f4ce4299bb5 100644
--- a/SenderTest/SenderTest.csproj
+++ b/EncryptionTests/EncryptionTests.csproj
@@ -5,20 +5,26 @@
         <Nullable>enable</Nullable>
 
         <IsPackable>false</IsPackable>
+
+        <RootNamespace>SenderTest</RootNamespace>
     </PropertyGroup>
 
     <ItemGroup>
-        <PackageReference Include="FluentAssertions" Version="6.7.0" />
-        <PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
-        <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="6.0.0" />
-        <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
-        <PackageReference Include="NUnit" Version="3.13.2" />
-        <PackageReference Include="NUnit3TestAdapter" Version="4.0.0" />
-        <PackageReference Include="coverlet.collector" Version="3.1.0" />
+        <PackageReference Include="FluentAssertions" Version="6.7.0"/>
+        <PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0"/>
+        <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="6.0.0"/>
+        <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0"/>
+        <PackageReference Include="NUnit" Version="3.13.2"/>
+        <PackageReference Include="NUnit3TestAdapter" Version="4.0.0"/>
+        <PackageReference Include="coverlet.collector" Version="3.1.0"/>
+    </ItemGroup>
+
+    <ItemGroup>
+        <ProjectReference Include="..\FitConnect\FitConnect.csproj"/>
     </ItemGroup>
 
     <ItemGroup>
-      <ProjectReference Include="..\FitConnect\FitConnect.csproj" />
+        <Folder Include="Certificates"/>
     </ItemGroup>
 
 </Project>
diff --git a/EncryptionTests/JweTest.cs b/EncryptionTests/JweTest.cs
new file mode 100644
index 0000000000000000000000000000000000000000..fbde038538a0600c3f80dbe58dd7941c5ec7c57f
--- /dev/null
+++ b/EncryptionTests/JweTest.cs
@@ -0,0 +1,28 @@
+using FitConnect;
+using Microsoft.Extensions.Logging;
+using NUnit.Framework;
+
+namespace SenderTest;
+
+public class JweTest {
+    private ILogger<JweTest> _logger;
+    private Sender _sender;
+
+
+    [SetUp]
+    public void SetUp() {
+        _logger = LoggerFactory.Create(cfg => cfg.AddConsole())
+            .CreateLogger<JweTest>();
+
+        _sender = new Sender(_logger,
+            FitConnectEndpoints.Create(FitConnectEndpoints.EndpointType.Development));
+    }
+
+    [Test]
+    public void TestJwe() {
+        var jwe = _sender.Encryption.GetTestToken();
+        Assert.IsNotNull(jwe);
+
+        _logger.LogInformation(jwe);
+    }
+}
diff --git a/EncryptionTests/SenderEncryptionWithImportedCertificateTest.cs b/EncryptionTests/SenderEncryptionWithImportedCertificateTest.cs
new file mode 100644
index 0000000000000000000000000000000000000000..9b63f0e53381eb68f66a60ba7c42235c01ebb0d0
--- /dev/null
+++ b/EncryptionTests/SenderEncryptionWithImportedCertificateTest.cs
@@ -0,0 +1,43 @@
+using System.Security.Cryptography.X509Certificates;
+using FitConnect;
+using Microsoft.Extensions.Logging;
+using NUnit.Framework;
+
+namespace SenderTest;
+
+public class SenderEncryptionWithImportedCertificateTest {
+    private ILogger _logger = null!;
+    private Sender _sender = null!;
+
+    [OneTimeSetUp]
+    public void OneTimeSetUp() {
+        // Import certificate
+    }
+
+    [SetUp]
+    public void SetUp() {
+        // Create a new Sender
+        var fileName = "../../../Certificates/certificate.cer";
+        var cert = new X509Certificate2(fileName);
+        _logger = LoggerFactory.Create(cfg => cfg.AddConsole())
+            .CreateLogger<SenderEncryptionWithSelfSignedCertificateTest>();
+
+        _sender = new Sender(_logger,
+            FitConnectEndpoints.Create(FitConnectEndpoints.EndpointType.Development), cert);
+    }
+
+    [TearDown]
+    public void TearDown() {
+        // Dispose the Sender
+    }
+
+    [OneTimeTearDown]
+    public void OneTimeTearDown() {
+        // Delete certificate
+    }
+
+    [Test]
+    public void TestEncryption() {
+        // Encrypt a message
+    }
+}
diff --git a/EncryptionTests/SenderEncryptionWithSelfSignedCertificateTest.cs b/EncryptionTests/SenderEncryptionWithSelfSignedCertificateTest.cs
new file mode 100644
index 0000000000000000000000000000000000000000..abe9bd3ed4c81e058365827e6eaacc5720074c85
--- /dev/null
+++ b/EncryptionTests/SenderEncryptionWithSelfSignedCertificateTest.cs
@@ -0,0 +1,73 @@
+using System;
+using System.IO;
+using System.Security.Cryptography.X509Certificates;
+using System.Text;
+using FitConnect;
+using FitConnect.Security;
+using FluentAssertions;
+using Microsoft.Extensions.Logging;
+using NUnit.Framework;
+
+namespace SenderTest;
+
+public class SenderEncryptionWithSelfSignedCertificateTest {
+    private const string ToEncrypt = "This is a test message";
+    private static byte[]? cypher;
+    private X509Certificate2 _certificate = null!;
+    private ILogger<SenderEncryptionWithSelfSignedCertificateTest> _logger = null!;
+    private Sender _sender = null!;
+
+
+    /*
+     * Encryption test must be changed for production to only allow extern signed certificates
+     * and forbid self-signed certificates.
+     */
+
+    [OneTimeSetUp]
+    public void OneTimeSetup() {
+        _certificate = RsaEncryption.CreateSelfSignedCertificate("./");
+    }
+
+    [OneTimeTearDown]
+    public void OneTimeTearDown() {
+        _certificate.Dispose();
+        // File.Copy("./certificate.pfx", "../../../Certificates/certificate.pfx", true);
+        // File.Copy("./certificate.cer", "../../../Certificates/certificate.cer", true);
+        File.Delete("./certificate.pfx");
+        File.Delete("./certificate.cer");
+    }
+
+    [SetUp]
+    public void Setup() {
+        _logger = LoggerFactory.Create(cfg => cfg.AddConsole())
+            .CreateLogger<SenderEncryptionWithSelfSignedCertificateTest>();
+        _sender = new Sender(_logger,
+            FitConnectEndpoints.Create(FitConnectEndpoints.EndpointType.Development));
+
+        var certificate = new X509Certificate2("./certificate.pfx");
+        _sender.Encryption.ImportCertificate(certificate);
+    }
+
+
+    [Test]
+    [Order(10)]
+    public void CryptWithOutPublicKeyImport() {
+        cypher = _sender.Encryption.EncryptData(Encoding.UTF8.GetBytes(ToEncrypt));
+
+        _logger.LogInformation("Cypher: {}", Convert.ToBase64String(cypher));
+    }
+
+    [Test]
+    [Order(20)]
+    public void Decrypt_ResultShouldMatchToEncrypt() {
+        var result = _sender.Encryption.DecryptDataAsync(cypher!);
+        Encoding.UTF8.GetString(result).Should().Be(ToEncrypt);
+    }
+
+
+    [Test]
+    public void ExportPrivateKey() {
+        var privateKey = _sender.Encryption.ExportPrivateKey();
+        _logger.LogInformation("Private key: {}", Convert.ToBase64String(privateKey));
+    }
+}
diff --git a/EncryptionTests/SenderEncryptionWithoutCertificateTest.cs b/EncryptionTests/SenderEncryptionWithoutCertificateTest.cs
new file mode 100644
index 0000000000000000000000000000000000000000..61207eb94cb5ec94aa791f358c8fe5c01e0cb5c8
--- /dev/null
+++ b/EncryptionTests/SenderEncryptionWithoutCertificateTest.cs
@@ -0,0 +1,54 @@
+using System;
+using System.Text;
+using FitConnect;
+using FluentAssertions;
+using Microsoft.Extensions.Logging;
+using NUnit.Framework;
+
+namespace SenderTest;
+
+public class SenderEncryptionWithoutCertificateTest {
+    private const string ToEncrypt = "Hello World";
+    private string _cypherText = null!;
+    private ILogger<SenderEncryptionWithoutCertificateTest> _logger = null!;
+    private Sender _sender = null!;
+
+    /*
+     * Encryption test must be changed for production to only allow extern signed certificates
+     * and forbid self-signed certificates.
+     */
+
+    [OneTimeSetUp]
+    public void OneTimeSetUp() {
+        _logger = LoggerFactory.Create(cfg => cfg.AddConsole())
+            .CreateLogger<SenderEncryptionWithoutCertificateTest>();
+        _sender = new Sender(_logger,
+            FitConnectEndpoints.Create(FitConnectEndpoints.EndpointType.Development));
+    }
+
+
+    [Test]
+    [Order(10)]
+    public void EncryptData_ShouldNotThrowAnyException() {
+        var cypher = _sender.Encryption.EncryptData(Encoding.UTF8.GetBytes(ToEncrypt));
+
+        _cypherText = Convert.ToBase64String(cypher);
+        _logger.LogInformation("Cypher: {}", _cypherText);
+    }
+
+
+    [Test]
+    [Order(20)]
+    public void DecryptData_ShouldMatchToEncrypt() {
+        var cypher = Convert.FromBase64String(_cypherText);
+        var plain = _sender.Encryption.DecryptDataAsync(cypher);
+
+        Encoding.UTF8.GetString(plain).Should().Be(ToEncrypt);
+    }
+
+    [Test]
+    public void ExportPrivateKey_ShouldNotThrowAnyException() {
+        var privateKey = _sender.Encryption.ExportPrivateKey();
+        _logger.LogInformation("Private key: {}", Convert.ToBase64String(privateKey));
+    }
+}
diff --git a/EncryptionTests/SubscriberEncryptionWithImportedCertificateTest.cs b/EncryptionTests/SubscriberEncryptionWithImportedCertificateTest.cs
new file mode 100644
index 0000000000000000000000000000000000000000..9adf848c95063f1905b41000a957d2bf2c603199
--- /dev/null
+++ b/EncryptionTests/SubscriberEncryptionWithImportedCertificateTest.cs
@@ -0,0 +1,43 @@
+using System.Security.Cryptography.X509Certificates;
+using FitConnect;
+using Microsoft.Extensions.Logging;
+using NUnit.Framework;
+
+namespace SenderTest;
+
+public class SubscriberEncryptionWithImportedCertificateTest {
+    private ILogger _logger = null!;
+    private Subscriber _subscriber = null!;
+
+    [OneTimeSetUp]
+    public void OneTimeSetUp() {
+        // Import certificate
+    }
+
+    [SetUp]
+    public void SetUp() {
+        // Create a new Sender
+        var fileName = "../../../Certificates/certificate.pfx";
+        var cert = new X509Certificate2(fileName);
+        _logger = LoggerFactory.Create(cfg => cfg.AddConsole())
+            .CreateLogger<SenderEncryptionWithSelfSignedCertificateTest>();
+
+        _subscriber = new Subscriber(_logger,
+            FitConnectEndpoints.Create(FitConnectEndpoints.EndpointType.Development), cert);
+    }
+
+    [TearDown]
+    public void TearDown() {
+        // Dispose the Sender
+    }
+
+    [OneTimeTearDown]
+    public void OneTimeTearDown() {
+        // Delete certificate
+    }
+
+    [Test]
+    public void TestEncryption() {
+        // Encrypt a message
+    }
+}
diff --git a/FitConnect.sln b/FitConnect.sln
index 8c1a251e18c5c52a00665405ae50d9e84d1cb20d..1b039a682ba57d7971d14a95f46c0281516890c6 100644
--- a/FitConnect.sln
+++ b/FitConnect.sln
@@ -8,7 +8,13 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InitializationTests", "Init
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "E2ETests", "E2ETests\E2ETests.csproj", "{27115A99-2AE8-42BC-9495-BE2DCEDDF1E8}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SenderTest", "SenderTest\SenderTest.csproj", "{68F1EC39-B234-4422-9AA8-E55CFA15025D}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EncryptionTests", "EncryptionTests\EncryptionTests.csproj", "{68F1EC39-B234-4422-9AA8-E55CFA15025D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Services", "Services\Services.csproj", "{1BB06AF4-492C-4041-A947-FE65F7A48698}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RestService", "RestService\RestService.csproj", "{51743B56-6147-43FF-8513-EE38A3E7B188}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Models", "Models\Models.csproj", "{98C78243-6ABD-492D-ACA8-23B3BF17FBDA}"
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -32,6 +38,18 @@ Global
 		{68F1EC39-B234-4422-9AA8-E55CFA15025D}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{68F1EC39-B234-4422-9AA8-E55CFA15025D}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{68F1EC39-B234-4422-9AA8-E55CFA15025D}.Release|Any CPU.Build.0 = Release|Any CPU
+		{1BB06AF4-492C-4041-A947-FE65F7A48698}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{1BB06AF4-492C-4041-A947-FE65F7A48698}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{1BB06AF4-492C-4041-A947-FE65F7A48698}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{1BB06AF4-492C-4041-A947-FE65F7A48698}.Release|Any CPU.Build.0 = Release|Any CPU
+		{51743B56-6147-43FF-8513-EE38A3E7B188}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{51743B56-6147-43FF-8513-EE38A3E7B188}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{51743B56-6147-43FF-8513-EE38A3E7B188}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{51743B56-6147-43FF-8513-EE38A3E7B188}.Release|Any CPU.Build.0 = Release|Any CPU
+		{98C78243-6ABD-492D-ACA8-23B3BF17FBDA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{98C78243-6ABD-492D-ACA8-23B3BF17FBDA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{98C78243-6ABD-492D-ACA8-23B3BF17FBDA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{98C78243-6ABD-492D-ACA8-23B3BF17FBDA}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(NestedProjects) = preSolution
 		{73CE5625-4C13-458E-B524-0DAA850F4041} = {D382641C-B027-411A-814C-C8C20A9505F3}
diff --git a/FitConnect/BaseClasses/FunctionalBaseClass.cs b/FitConnect/BaseClasses/FunctionalBaseClass.cs
new file mode 100644
index 0000000000000000000000000000000000000000..18ab99ad865e147cd64488553a13491f6c5feab7
--- /dev/null
+++ b/FitConnect/BaseClasses/FunctionalBaseClass.cs
@@ -0,0 +1,44 @@
+using System.Security.Cryptography.X509Certificates;
+using FitConnect.Models;
+using FitConnect.RestService;
+using FitConnect.Security;
+using FitConnect.Services;
+using Microsoft.Extensions.Logging;
+
+namespace FitConnect.BaseClasses;
+
+public abstract class FunctionalBaseClass {
+    public readonly IEncryption Encryption;
+    protected readonly ILogger? Logger;
+    protected readonly FitConnectApiService ApiService;
+
+    /// <summary>
+    ///     Constructor for the FunctionalBaseClass
+    /// </summary>
+    /// <param name="logger">ILogger implementation</param>
+    /// <param name="endpoints">FitConnect endpoints</param>
+    /// <param name="certificate">The Encryption certificate</param>
+    /// <example>
+    ///     new Sender(logger, FitConnectEndpoints.Create(FitConnectEndpoints.EndpointType.Development))
+    /// </example>
+    protected FunctionalBaseClass(ILogger? logger, FitConnectEndpoints? endpoints,
+        X509Certificate2? certificate) {
+        Endpoints = endpoints ??
+                    FitConnectEndpoints.Create(FitConnectEndpoints.EndpointType.Development);
+
+        Logger = logger;
+        Encryption = new RsaEncryption(logger, certificate);
+        ApiService = new FitConnectApiService(Endpoints, logger);
+    }
+
+    public FitConnectEndpoints Endpoints { get; }
+
+
+    /// <summary>
+    ///     Receive the SET data
+    /// </summary>
+    /// <returns></returns>
+    public Task<SecurityEventToken> GetSetDataAsync() {
+        throw new NotImplementedException();
+    }
+}
diff --git a/FitConnect/Client.cs b/FitConnect/Client.cs
new file mode 100644
index 0000000000000000000000000000000000000000..0008dc93dde33da376dc4c6fd36da4f7eecb6081
--- /dev/null
+++ b/FitConnect/Client.cs
@@ -0,0 +1,117 @@
+using System.Security.Cryptography.X509Certificates;
+using FitConnect.Models;
+using FitConnect.Services;
+using FitConnect.Services.Models;
+using Microsoft.Extensions.Logging;
+
+namespace FitConnect;
+
+/// <summary>
+///     The FitConnect API Client
+/// </summary>
+// ReSharper disable once UnusedType.Global
+public class Client {
+    private readonly string _clientId;
+    private readonly string _clientSecret;
+    private readonly Sender _sender;
+    private readonly Subscriber _subscriber;
+
+
+
+    public Client(FitConnectEndpoints endpoints,
+        string clientId, string clientSecret,
+        X509Certificate2? certificate = null,
+        ILogger? logger = null) {
+        _clientId = clientId;
+        _clientSecret = clientSecret;
+        _sender = new Sender(logger, endpoints, certificate);
+        _subscriber = new Subscriber(logger, endpoints, certificate);
+        //_service = new FitConnectApiService(endpoints, logger);
+    }
+
+
+    /// <summary>
+    /// Get destination for submission.
+    /// <para>Leika-Key and one of the area specifier has to be set.</para>
+    /// </summary>
+    /// <param name="leiaKey">Mandatory</param>
+    /// <param name="ags"></param>
+    /// <param name="ars"></param>
+    /// <param name="areaId"></param>
+    /// <returns></returns>
+    public async Task<string> GetDestinationIdAsync(string leiaKey, string? ags, string? ars,
+        string? areaId) {
+        if (string.IsNullOrEmpty(leiaKey)) {
+            throw new ArgumentException("leiaKey is mandatory");
+        }
+
+        if (string.IsNullOrEmpty(ags) && 
+            string.IsNullOrEmpty(ars) && 
+            string.IsNullOrEmpty(areaId)) {
+            throw new ArgumentException("One of the area specifier has to be set");
+        }
+        
+        return await _sender.GetDestinationIdAsync(leiaKey, ags, ars, areaId);
+    }
+
+    /// <summary>
+    ///     Sending a submission to the FitConnect API<br/>
+    /// <para>The submission is prepared for sending to the FitConnect API.</para>
+    /// </summary>
+    /// <param name="submission">The submission to send</param>
+    /// <returns>success</returns>
+    // ReSharper disable once MemberCanBePrivate.Global
+    public async Task<bool> SendSubmissionAsync(Submission submission) {
+        // Einreichung anlegen und ankündigen
+        var createSubmissionDto = _sender.CreateSubmissionDto(submission);
+
+        // Anlagen verschlüsseln
+        var encryptedAttachments = submission.Attachments
+            .Select(a => _sender.EncryptAttachment(a)).ToList();
+
+        // Anlagen hochladen
+        await _sender.UploadAttachmentsAsync(encryptedAttachments);
+
+        // Metadaten befüllen und verschlüsseln
+        var metaData = await _sender.CreateMetadataAsync("", new byte[] { });
+
+        // Fachdaten verschlüsseln
+        var encryptedData = _sender.EncryptDataAsync(submission.Data);
+
+        // Fachdaten & Metadaten hochladen und Einreichung absenden
+        await _sender.SubmitSubmissionAsync(submission);
+
+        return true;
+    }
+
+    /// <summary>
+    ///     Gets all submissions from the FitConnect API
+    /// </summary>
+    /// <returns>List of the available submissions</returns>
+    // ReSharper disable once MemberCanBePrivate.Global
+    public async Task<List<Submission>> GetSubmissionsAsync(string destinationId, int offset = 0,
+        int limit = 100) {
+        // var pickUpList =
+        //     await _service.SubmissionService.ListSubmissions(destinationId, offset, limit);
+        // return pickUpList.Submissions.Select(dto => (Submission)dto).ToList();
+        throw new NotImplementedException();
+    }
+
+    /// <summary>
+    ///     Sending a submission to the FitConnect API
+    /// </summary>
+    /// <param name="submission">The submission to send</param>
+    /// <returns>success</returns>
+    public bool SendSubmission(Submission submission) {
+        return SendSubmissionAsync(submission).Result;
+    }
+
+    /// <summary>
+    ///     Gets all submissions from the FitConnect API
+    /// </summary>
+    /// <returns>List of the available submissions</returns>
+    public List<Submission> GetSubmissions(string destinationId, int offset = 0,
+        int limit = 100) {
+        return GetSubmissionsAsync(destinationId, offset, limit).Result;
+    }
+}
diff --git a/FitConnect/EncryptionBaseClass.cs b/FitConnect/EncryptionBaseClass.cs
deleted file mode 100644
index 60581a49e6f26ffb84ec973fd94ac35412c52de8..0000000000000000000000000000000000000000
--- a/FitConnect/EncryptionBaseClass.cs
+++ /dev/null
@@ -1,101 +0,0 @@
-using System.Security.Cryptography;
-using System.Security.Cryptography.X509Certificates;
-using Microsoft.Extensions.Logging;
-
-namespace FitConnect;
-
-public class EncryptionBaseClass {
-    private readonly ILogger? _logger;
-    private readonly RSA _rsa;
-    private RSA? _publicKey;
-    private RSA? _privateKey;
-
-    protected EncryptionBaseClass(ILogger? logger) {
-        _logger = logger;
-        _rsa = RSA.Create(2048);
-    }
-
-
-    /// <summary>
-    /// 
-    /// </summary>
-    /// <param name="cert"></param>
-    /// <returns></returns>
-    private bool CheckCertificate(X509Certificate2 cert) =>
-        cert.HasPrivateKey; //  && cert.Verify();
-
-
-    public void ImportCertificate(X509Certificate2 cert) {
-        if (!CheckCertificate(cert)) {
-            throw new Exception("Invalid certificate");
-        }
-
-        _publicKey = cert.GetRSAPublicKey();
-        // _publicKey = RSA.Create(2048);
-        // _publicKey.ImportRSAPublicKey(cert.GetPublicKey(), out int _);
-
-        if ((_publicKey?.KeySize ?? 0) == 0)
-            throw new Exception("Invalid certificate, no public key");
-
-        _logger.LogInformation("Public key imported {}",
-            Convert.ToBase64String(_publicKey.ExportRSAPrivateKey()));
-
-        if (cert.HasPrivateKey) {
-            _privateKey = cert.GetRSAPrivateKey();
-        }
-
-        if (_privateKey != null)
-            _logger.LogInformation("Certificate with private key imported");
-        else
-            _logger.LogInformation("Certificate has no private key");
-    }
-
-    /// <summary>
-    /// Import a public key from a PEM file
-    /// </summary>
-    /// <param name="certificatePath"></param>
-    /// <param name="password">Password for the certificate</param>
-    /// <exception cref="ArgumentException"></exception>
-    /// <exception cref="Exception"></exception>
-    public void ImportCertificate(string certificatePath, string password) {
-        _logger.LogInformation("Importing certificate {CertPath}", certificatePath);
-        var cert =
-            new X509Certificate2(certificatePath, password, X509KeyStorageFlags.MachineKeySet);
-
-        if (!CheckCertificate(cert)) {
-            throw new ArgumentException("Certificate is not valid");
-        }
-
-        var parameters = cert.PublicKey.GetRSAPublicKey()?.ExportParameters(true);
-        if (parameters == null) {
-            throw new Exception("Could not get public key from certificate");
-        }
-
-        _rsa.ImportParameters(parameters.Value);
-    }
-
-    public byte[] DecryptDataAsync(byte[] data) {
-        return (_privateKey ?? _rsa).Decrypt(data, RSAEncryptionPadding.OaepSHA256);
-    }
-
-    public byte[] ExportPublicKey() {
-        return _rsa.ExportRSAPublicKey();
-    }
-
-    public byte[] ExportPrivateKey() {
-        return _rsa.ExportRSAPrivateKey();
-    }
-
-    public byte[] EncryptData(byte[] data) {
-        return (_publicKey ?? _rsa).Encrypt(data, RSAEncryptionPadding.OaepSHA256);
-    }
-
-    public byte[] EncryptData(byte[] data, byte[] publicKey) {
-        _logger?.LogInformation(
-            "Encrypting data with public key: {}",
-            Convert.ToBase64String(_rsa.ExportRSAPublicKey()));
-
-        _rsa.ImportRSAPublicKey(publicKey, out var read);
-        return _rsa.Encrypt(data, RSAEncryptionPadding.OaepSHA256);
-    }
-}
diff --git a/FitConnect/FitConnect.csproj b/FitConnect/FitConnect.csproj
index 69367e6234325f21201583ed8e29f60558966ca8..30c89efb000c08f73948a96e07ca5647cf6c4103 100644
--- a/FitConnect/FitConnect.csproj
+++ b/FitConnect/FitConnect.csproj
@@ -11,18 +11,24 @@
     </PropertyGroup>
 
     <ItemGroup>
-      <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.1" />
-      <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
-      <PackageReference Include="Newtonsoft.Json.Schema" Version="3.0.14" />
+        <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.1" />
+        <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
+        <PackageReference Include="Newtonsoft.Json.Schema" Version="3.0.14" />
+        <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.19.0" />
     </ItemGroup>
 
     <ItemGroup>
-      <None Remove="metadata.schema.json" />
-      <EmbeddedResource Include="metadata.schema.json" />
+        <None Remove="metadata.schema.json" />
+        <EmbeddedResource Include="metadata.schema.json" />
     </ItemGroup>
 
     <ItemGroup>
-      <Folder Include="Interfaces" />
+        <Folder Include="Interfaces" />
+    </ItemGroup>
+
+    <ItemGroup>
+        <ProjectReference Include="..\Models\Models.csproj" />
+        <ProjectReference Include="..\Services\Services.csproj" />
     </ItemGroup>
 
 </Project>
diff --git a/FitConnect/FunctionalBaseClass.cs b/FitConnect/FunctionalBaseClass.cs
deleted file mode 100644
index 844b2fe928b0703b19f3eeb3e45b2b0896667352..0000000000000000000000000000000000000000
--- a/FitConnect/FunctionalBaseClass.cs
+++ /dev/null
@@ -1,89 +0,0 @@
-using System.Net.Http.Headers;
-using System.Net.Http.Json;
-using System.Text;
-using FitConnect.Models;
-using Microsoft.Extensions.Logging;
-
-namespace FitConnect;
-
-public class FunctionalBaseClass : EncryptionBaseClass {
-    protected readonly ILogger? Logger;
-    public FitConnectEndpoints Endpoints { get; }
-
-    /// <summary>
-    /// Constructor for the FunctionalBaseClass
-    /// </summary>
-    /// <param name="logger">ILogger implementation</param>
-    /// <param name="endpoints">FitConnect endpoints</param>
-    protected FunctionalBaseClass(ILogger? logger, FitConnectEndpoints? endpoints) : base(logger) {
-        Endpoints = endpoints ??
-                    FitConnectEndpoints.Create(FitConnectEndpoints.EndpointType.Development);
-
-        Logger = logger;
-    }
-
-
-    /// <summary>
-    /// Requesting an OAuth token from the FitConnect API.
-    /// 
-    /// You can get the Client ID and Client Secret from the FitConnect Self Service portal
-    /// under https://portal.auth-testing.fit-connect.fitko.dev
-    /// </summary>
-    /// <param name="clientId">Your client Id</param>
-    /// <param name="clientSecret">Your client Secret</param>
-    /// <param name="scope">Scope if needed</param>
-    /// <returns></returns>
-    public async Task<OAuthAccessToken?> GetTokenAsync(string clientId, string clientSecret,
-        string? scope = null) {
-        var client = new HttpClient();
-        client.DefaultRequestHeaders.Accept.Add(
-            MediaTypeWithQualityHeaderValue.Parse("application/json"));
-
-        var requestContent = new Dictionary<string, string> {
-            { "grant_type", "client_credentials" },
-            { "client_id", clientId },
-            { "client_secret", clientSecret }
-        };
-
-        if (scope != null)
-            requestContent["scope"] = scope;
-
-        var content = new FormUrlEncodedContent(requestContent);
-
-        var request = new HttpRequestMessage(HttpMethod.Post, Endpoints.TokenUrl) {
-            Content = content,
-            Method = HttpMethod.Post
-        };
-
-        var response = await client.SendAsync(request);
-
-        return await response.Content.ReadFromJsonAsync<OAuthAccessToken>();
-    }
-
-    /// <summary>
-    /// Receive the SET data
-    /// </summary>
-    /// <returns></returns>
-    public Task<SecurityEventToken> GetSetDataAsync() {
-        throw new NotImplementedException();
-    }
-
-
-    private async Task<T?> RestCall<T>(Uri uri, HttpMethod method, string body) {
-        var client = new HttpClient();
-        client.DefaultRequestHeaders.Add("Accept", "application/json");
-        client.DefaultRequestHeaders.Add("Content-Type", "application/json");
-
-        var request = new HttpRequestMessage();
-        request.Method = method;
-        request.Content = new StringContent(body, Encoding.UTF8, "application/json");
-        request.RequestUri = uri;
-
-        var response = await client.SendAsync(request);
-
-        if (response.IsSuccessStatusCode)
-            return (await response.Content.ReadFromJsonAsync<T>());
-
-        throw new HttpRequestException("Error calling FitConnect API");
-    }
-}
diff --git a/FitConnect/HttpCalls/RoutingApi.http b/FitConnect/HttpCalls/RoutingApi.http
new file mode 100644
index 0000000000000000000000000000000000000000..b3cd06e1080086ca3cb22ba98b0a71d043f9bad5
--- /dev/null
+++ b/FitConnect/HttpCalls/RoutingApi.http
@@ -0,0 +1,9 @@
+### Get areas
+GET {{routing_api_url}}/v1/areas?areaSearchexpression=93437
+Accept: application/json
+
+### Get areas
+GET {{routing_api_url}}/v1/routes?leikaKey=99012070006000
+Accept: application/json
+
+
diff --git a/FitConnect/HttpCalls/http-client.env.json b/FitConnect/HttpCalls/http-client.env.json
new file mode 100644
index 0000000000000000000000000000000000000000..c4605fc77dc203f3dd2f89fcdd13111abca531c5
--- /dev/null
+++ b/FitConnect/HttpCalls/http-client.env.json
@@ -0,0 +1,5 @@
+{
+  "dev": {
+    "routing_api_url": "https://routing-api-testing.fit-connect.fitko.dev"
+  }
+}
\ No newline at end of file
diff --git a/FitConnect/Models/Area.cs b/FitConnect/Models/Area.cs
new file mode 100644
index 0000000000000000000000000000000000000000..739981a83da91efcd0429b419770553eeba78829
--- /dev/null
+++ b/FitConnect/Models/Area.cs
@@ -0,0 +1,5 @@
+using System.Text.Json.Serialization;
+
+namespace FitConnect.Models;
+
+public record Area(string Id, string Name, string Type);
\ No newline at end of file
diff --git a/FitConnect/Models/Attachment.cs b/FitConnect/Models/Attachment.cs
new file mode 100644
index 0000000000000000000000000000000000000000..d432c10594ec0b1d0494defa118bbf19064d4d16
--- /dev/null
+++ b/FitConnect/Models/Attachment.cs
@@ -0,0 +1,3 @@
+namespace FitConnect.Models;
+
+public record Attachment(string Id, byte[] Content, string Hash);
diff --git a/FitConnect/Models/Callback.cs b/FitConnect/Models/Callback.cs
index bcf95a72803962d11e1e16c8014b65025e279974..23eaf2c1f13bebcbff6d367fd45b88b395990f10 100644
--- a/FitConnect/Models/Callback.cs
+++ b/FitConnect/Models/Callback.cs
@@ -1,11 +1,10 @@
 using System.Text.Json.Serialization;
+using FitConnect.Services.Models;
 
 namespace FitConnect.Models;
 
-public class Callback {
-    [JsonPropertyName("url")]
-    public string? Url { get; set; }
+public record Callback(string? Url, string? Secret) {
+    public static explicit operator Callback(CallbackDto dto) => new(dto.Url, null);
 
-    [JsonPropertyName("secret")]
-    public string? Secret { get; set; }
+    public static explicit operator CallbackDto(Callback model) => new() { Url = model.Url };
 }
diff --git a/FitConnect/Models/Route.cs b/FitConnect/Models/Route.cs
new file mode 100644
index 0000000000000000000000000000000000000000..982d1a84388493a86165742c1127cacdab8e38e7
--- /dev/null
+++ b/FitConnect/Models/Route.cs
@@ -0,0 +1,3 @@
+namespace FitConnect.Models;
+
+public record Route();
diff --git a/FitConnect/Models/SecurityEventToken.cs b/FitConnect/Models/SecurityEventToken.cs
index 3ba016f8bcb1f585a562d2942da54048e165b213..33b2bd5e898c7b418f3480845a97f577172397b9 100644
--- a/FitConnect/Models/SecurityEventToken.cs
+++ b/FitConnect/Models/SecurityEventToken.cs
@@ -1,5 +1,3 @@
 namespace FitConnect.Models;
 
-public class SecurityEventToken {
-}
-
+public record SecurityEventToken();
diff --git a/FitConnect/Models/ServiceType.cs b/FitConnect/Models/ServiceType.cs
index 72d2ab5baf5568612500b4397c7b7b4111510c2b..2891064d091dab3785354e259100dd361d6bd438 100644
--- a/FitConnect/Models/ServiceType.cs
+++ b/FitConnect/Models/ServiceType.cs
@@ -1,11 +1,22 @@
 using System.Text.Json.Serialization;
+using FitConnect.Services.Models;
 
 namespace FitConnect.Models;
 
-public class ServiceType {
-    [JsonPropertyName("name")]
+public record ServiceType {
     public string? Name { get; set; }
 
-    [JsonPropertyName("identifier")]
+    public string? Description { get; set; }
     public string? Identifier { get; set; }
+
+    public static explicit operator ServiceType(ServiceTypeDto dto) => new() {
+        Description = dto.Description,
+        Identifier = dto.Identifier,
+        Name = dto.Name
+    };
+    public static explicit operator ServiceTypeDto(ServiceType model) => new() {
+        Description = model.Description,
+        Identifier = model.Identifier,
+        Name = model.Name
+    };
 }
diff --git a/FitConnect/Models/Submission.cs b/FitConnect/Models/Submission.cs
index 11db33fd8ca805919c484539a67a59254640fbfe..9a8f31d174459092ccb49c7d23674f6f7f6a0e96 100644
--- a/FitConnect/Models/Submission.cs
+++ b/FitConnect/Models/Submission.cs
@@ -1,17 +1,44 @@
 using System.Text.Json.Serialization;
+using System.Xml;
+using FitConnect.Services.Models;
 
 namespace FitConnect.Models;
 
-public class Submission {
-    [JsonPropertyName("destinationId")]
-    public string? DestinationId { get; set; }
+public record Submission {
+    public string? Id { get; set; }
+    public string DestinationId { get; init; }
+    public string? CaseId { get; set; }
 
-    [JsonPropertyName("announcedAttachments")]
-    public List<string>? AnnouncedAttachments { get; set; }
+    public List<Attachment> Attachments { get; set; } = new();
 
-    [JsonPropertyName("serviceType")]
-    public ServiceType? ServiceType { get; set; }
+    public ServiceType ServiceType { get; init; }
 
-    [JsonPropertyName("callback")]
     public Callback? Callback { get; set; }
+
+
+    /// <summary>
+    /// Fachdaten
+    /// </summary>
+    public string? Data { get; set; }
+
+    public static explicit operator Submission(SubmissionForPickupDto dto) => new() {
+        Id = dto.SubmissionId,
+        Callback = null,
+        DestinationId = dto.DestinationId,
+        ServiceType = null,
+    };
+
+    public static explicit operator Submission(SubmissionDto dto) => new() {
+        Id = dto.SubmissionId,
+        Callback = (Callback)dto.Callback,
+        DestinationId = dto.DestinationId,
+        ServiceType = (ServiceType)dto.ServiceType,
+    };
+
+    public static explicit operator CreateSubmissionDto(Submission sub) => new() {
+        AnnouncedAttachments = sub.Attachments.Select(a => a.Id).ToList(),
+        DestinationId = sub.DestinationId,
+        ServiceType = (ServiceTypeDto)sub.ServiceType,
+        Callback = (CallbackDto)sub.Callback,
+    };
 }
diff --git a/FitConnect/Routing.cs b/FitConnect/Routing.cs
new file mode 100644
index 0000000000000000000000000000000000000000..63720a3af7129271799bb5653e41d828036f42b2
--- /dev/null
+++ b/FitConnect/Routing.cs
@@ -0,0 +1,73 @@
+using System.Security.Cryptography.X509Certificates;
+using FitConnect.Models;
+using Microsoft.Extensions.Logging;
+
+namespace FitConnect;
+
+/// <summary>
+///     Client to the FitConnect Routing Api
+/// </summary>
+public class Routing {
+    private readonly X509Certificate2? _certificate;
+    private readonly FitConnectEndpoints _endpoints;
+    private readonly ILogger? _logger;
+
+    public Routing(ILogger? logger, FitConnectEndpoints endpoints,
+        X509Certificate2? certificate = null) {
+        _logger = logger;
+        _endpoints = endpoints;
+        _certificate = certificate;
+    }
+
+
+    /// <summary>
+    /// </summary>
+    /// <param name="filter"></param>
+    /// <param name="offset"></param>
+    /// <param name="limit"></param>
+    /// <returns></returns>
+    public List<Area> GetAreas(string filter, int offset = 0, int limit = 100) {
+        return GetAreasAsync(filter, offset, limit).Result;
+    }
+
+
+    /// <summary>
+    /// </summary>
+    /// <param name="filter"></param>
+    /// <param name="offset"></param>
+    /// <param name="limit"></param>
+    /// <returns></returns>
+    public async Task<List<Area>> GetAreasAsync(string filter, int offset = 0, int limit = 100) {
+        return new List<Area>();
+    }
+
+
+    /// <summary>
+    /// </summary>
+    /// <param name="leikaKey"></param>
+    /// <param name="ags"></param>
+    /// <param name="ars"></param>
+    /// <param name="areaId"></param>
+    /// <param name="offset"></param>
+    /// <param name="limit"></param>
+    /// <returns></returns>
+    public async Task<List<Route>> GetRoutesAsync(string leikaKey, string ags, string ars,
+        string areaId, int offset = 0, int limit = 100) {
+        return new List<Route>();
+    }
+
+
+    /// <summary>
+    /// </summary>
+    /// <param name="leikaKey"></param>
+    /// <param name="ags"></param>
+    /// <param name="ars"></param>
+    /// <param name="areaId"></param>
+    /// <param name="offset"></param>
+    /// <param name="limit"></param>
+    /// <returns></returns>
+    public List<Route> GetRoutes(string leikaKey, string ags, string ars,
+        string areaId, int offset = 0, int limit = 100) {
+        return GetRoutesAsync(leikaKey, ags, ars, areaId, offset, limit).Result;
+    }
+}
diff --git a/FitConnect/Security/IEncryption.cs b/FitConnect/Security/IEncryption.cs
new file mode 100644
index 0000000000000000000000000000000000000000..048d612c5b138da9a79fc263a714422b3b3f9cd7
--- /dev/null
+++ b/FitConnect/Security/IEncryption.cs
@@ -0,0 +1,28 @@
+using System.Security.Cryptography.X509Certificates;
+
+namespace FitConnect.Security;
+
+public interface IEncryption {
+    /// <summary>
+    ///     Just for Proof of Concept
+    /// </summary>
+    /// <returns></returns>
+    string GetTestToken();
+
+    void ImportCertificate(X509Certificate2 cert);
+
+    /// <summary>
+    ///     Import a public key from a PEM file
+    /// </summary>
+    /// <param name="certificatePath"></param>
+    /// <param name="password">Password for the certificate</param>
+    /// <exception cref="ArgumentException"></exception>
+    /// <exception cref="Exception"></exception>
+    void ImportCertificate(string certificatePath, string password);
+
+    byte[] DecryptDataAsync(byte[] data);
+    byte[] ExportPublicKey();
+    byte[] ExportPrivateKey();
+    byte[] EncryptData(byte[] data);
+    byte[] EncryptData(byte[] data, byte[] publicKey);
+}
diff --git a/FitConnect/Security/RsaEncryption.cs b/FitConnect/Security/RsaEncryption.cs
new file mode 100644
index 0000000000000000000000000000000000000000..860adf39c2040fce9b97241203312b7b6e671e8e
--- /dev/null
+++ b/FitConnect/Security/RsaEncryption.cs
@@ -0,0 +1,160 @@
+using System.IdentityModel.Tokens.Jwt;
+using System.Security.Claims;
+using System.Security.Cryptography;
+using System.Security.Cryptography.X509Certificates;
+using Microsoft.Extensions.Logging;
+using Microsoft.IdentityModel.Tokens;
+
+namespace FitConnect.Security;
+
+public class RsaEncryption : IEncryption {
+    private readonly X509Certificate2? _certificate;
+    private readonly ILogger? _logger;
+    private readonly RSA _rsa;
+    private RSA? _privateKey;
+    private RSA? _publicKey;
+
+
+    internal RsaEncryption(ILogger? logger, X509Certificate2? certificate) {
+        _logger = logger;
+        _rsa = RSA.Create(4096);
+
+        if (certificate != null) {
+            _certificate = certificate;
+            ImportCertificate(certificate);
+        }
+    }
+
+
+    /// <summary>
+    ///     Just for Proof of Concept
+    /// </summary>
+    /// <returns></returns>
+    public string GetTestToken() {
+        var handler = new JwtSecurityTokenHandler();
+        var token = new SecurityTokenDescriptor {
+            Issuer = "FitConnect",
+            Audience = "FitConnect",
+            EncryptingCredentials =
+                new X509EncryptingCredentials(_certificate ??
+                                              new X509Certificate2(CreateSelfSignedCertificate())),
+            Subject = new ClaimsIdentity(new Claim[] {
+                new("Content", "Unencrypted content")
+            })
+        };
+        return handler.CreateEncodedJwt(token);
+    }
+
+
+    public void ImportCertificate(X509Certificate2 cert) {
+        if (!CheckCertificate(cert)) throw new Exception("Invalid certificate");
+
+        _publicKey = cert.GetRSAPublicKey();
+
+        if ((_publicKey?.KeySize ?? 0) == 0)
+            throw new Exception("Invalid certificate, no public key");
+
+        if (cert.HasPrivateKey) _privateKey = cert.GetRSAPrivateKey();
+
+        if (_privateKey != null)
+            _logger?.LogInformation("Certificate with private key imported");
+        else
+            _logger?.LogInformation("Certificate has no private key");
+    }
+
+    /// <summary>
+    ///     Import a public key from a PEM file
+    /// </summary>
+    /// <param name="certificatePath"></param>
+    /// <param name="password">Password for the certificate</param>
+    /// <exception cref="ArgumentException"></exception>
+    /// <exception cref="Exception"></exception>
+    public void ImportCertificate(string certificatePath, string password) {
+        _logger?.LogInformation("Importing certificate {CertPath}", certificatePath);
+        var cert =
+            new X509Certificate2(certificatePath, password, X509KeyStorageFlags.MachineKeySet);
+
+        if (!CheckCertificate(cert)) throw new ArgumentException("Certificate is not valid");
+
+        var parameters = cert.PublicKey.GetRSAPublicKey()?.ExportParameters(true);
+        if (parameters == null) throw new Exception("Could not get public key from certificate");
+
+        _rsa.ImportParameters(parameters.Value);
+    }
+
+    public byte[] DecryptDataAsync(byte[] data) {
+        return (_privateKey ?? _rsa).Decrypt(data, RSAEncryptionPadding.OaepSHA256);
+    }
+
+    public byte[] ExportPublicKey() {
+        return _rsa.ExportRSAPublicKey();
+    }
+
+    public byte[] ExportPrivateKey() {
+        return _rsa.ExportRSAPrivateKey();
+    }
+
+    public byte[] EncryptData(byte[] data) {
+        return (_publicKey ?? _rsa).Encrypt(data, RSAEncryptionPadding.OaepSHA256);
+    }
+
+    public byte[] EncryptData(byte[] data, byte[] publicKey) {
+        _logger?.LogInformation(
+            "Encrypting data with public key: {}",
+            Convert.ToBase64String(_rsa.ExportRSAPublicKey()));
+
+        _rsa.ImportRSAPublicKey(publicKey, out var read);
+        return _rsa.Encrypt(data, RSAEncryptionPadding.OaepSHA256);
+    }
+
+    /// <summary>
+    ///     Creating a self signed certificate
+    /// </summary>
+    /// <param name="exportPath">Location for storing the certificate files</param>
+    /// <returns></returns>
+    /// <exception cref="Exception"></exception>
+    public static X509Certificate2 CreateSelfSignedCertificate(string? exportPath = null) {
+        var rsa = RSA.Create(4096);
+
+        var req = new CertificateRequest("c=DE, cn=fitconnect.de",
+            rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
+
+        var cert = req.CreateSelfSigned(DateTimeOffset.Now.AddSeconds(-5),
+            DateTimeOffset.Now.AddYears(5));
+
+        if (cert.GetRSAPublicKey() == null)
+            throw new Exception("Certificate does not contain a public key");
+
+        if (cert.GetRSAPrivateKey() == null)
+            throw new Exception("Certificate does not contain a private key");
+
+        // Export the certificate to a PEM file, just for
+        // additional extern testing
+        if (exportPath != null) ExportCertificateToFile(exportPath, cert);
+
+        return cert;
+    }
+
+    private static void ExportCertificateToFile(string exportPath, X509Certificate cert) {
+        // Create PFX (PKCS #12) with private key
+        File.WriteAllBytes($"{exportPath}/certificate.pfx",
+            cert.Export(X509ContentType.Pfx, ""));
+
+        // Create Base 64 encoded CER (public key only)
+        File.WriteAllText($"{exportPath}/certificate.cer",
+            "-----BEGIN CERTIFICATE-----\r\n"
+            + Convert.ToBase64String(cert.Export(X509ContentType.Cert, ""),
+                Base64FormattingOptions.InsertLineBreaks)
+            + "\r\n-----END CERTIFICATE-----");
+    }
+
+
+    /// <summary>
+    ///     Checking the certificate for validity
+    /// </summary>
+    /// <param name="cert">Certificate to check</param>
+    /// <returns>true for a fully approved certificate</returns>
+    private bool CheckCertificate(X509Certificate2 cert) {
+        return true;
+    }
+}
diff --git a/FitConnect/Sender.cs b/FitConnect/Sender.cs
index b988be52ef466d29170aebb26ca4a8c9ab5505ca..3b75e37b54739a36cde1cba5cf12c2ab94112fc1 100644
--- a/FitConnect/Sender.cs
+++ b/FitConnect/Sender.cs
@@ -1,23 +1,19 @@
-using System.Buffers.Text;
-using System.ComponentModel;
-using System.Security.Cryptography;
-using System.Text;
+using System.Security.Cryptography.X509Certificates;
+using FitConnect.BaseClasses;
+using FitConnect.Models;
+using FitConnect.Services.Models;
 using Microsoft.Extensions.Logging;
 
 namespace FitConnect;
 
 public class Sender : FunctionalBaseClass {
-    
-    /// <summary>
-    /// Constructor for the Sender class.
-    /// </summary>
-    /// <param name="logger">ILogger implementation</param>
-    /// <param name="endpoints">FitConnect endpoints</param>
-    public Sender(ILogger? logger, FitConnectEndpoints endpoints) : base(logger, endpoints) {
+    public Sender(ILogger? logger, FitConnectEndpoints endpoints,
+        X509Certificate2? certificate = null) : base(logger, endpoints, certificate) {
     }
 
+
     /// <summary>
-    /// Check public keys
+    ///     Check public keys
     /// </summary>
     /// <returns></returns>
     public async Task<bool> CheckPublicKeyAsync(string publicKey) {
@@ -25,16 +21,16 @@ public class Sender : FunctionalBaseClass {
     }
 
     /// <summary>
-    /// Encrypt attachments (Anhänge)
+    ///     Encrypt attachments (Anhänge)
     /// </summary>
     /// <param name="attachment"></param>
     /// <returns></returns>
-    public async Task<string> EncryptAttachmentAsync(string attachment, string publicKey) {
+    public async Task<string> EncryptAttachment(string attachment, string publicKey) {
         throw new NotImplementedException();
     }
 
     /// <summary>
-    /// Create Metadata incl. Hash
+    ///     Create Metadata incl. Hash
     /// </summary>
     /// <param name="data"></param>
     /// <param name="attachment"></param>
@@ -45,7 +41,7 @@ public class Sender : FunctionalBaseClass {
     }
 
     /// <summary>
-    /// Check public keys
+    ///     Check public keys
     /// </summary>
     /// <returns></returns>
     public async Task<bool> CheckPublicKeyAsync() {
@@ -53,25 +49,26 @@ public class Sender : FunctionalBaseClass {
     }
 
     /// <summary>
-    /// Encrypt Data (Fachdaten)
+    ///     Encrypt Data (Fachdaten)
     /// </summary>
     /// <param name="data"></param>
     /// <returns></returns>
-    public byte[] EncryptDataAsync(string data) {
+    public byte[] EncryptDataAsync(string? data) {
+        if (data == null) return new byte[] { };
         throw new NotImplementedException();
     }
 
     /// <summary>
-    /// Encrypt attachments (Anhänge)
+    ///     Encrypt attachments (Anhänge)
     /// </summary>
     /// <param name="attachment"></param>
     /// <returns></returns>
-    public async Task<byte[]> EncryptAttachmentAsync(byte[] attachment) {
+    public KeyValuePair<string, byte[]> EncryptAttachment(Attachment attachment) {
         throw new NotImplementedException();
     }
 
     /// <summary>
-    /// Create Metadata incl. Hash
+    ///     Create Metadata incl. Hash
     /// </summary>
     /// <param name="data"></param>
     /// <param name="attachment"></param>
@@ -79,4 +76,22 @@ public class Sender : FunctionalBaseClass {
     public async Task<string> CreateMetadataAsync(string data, byte[] attachment) {
         throw new NotImplementedException();
     }
+
+    public CreateSubmissionDto CreateSubmissionDto(Submission submission) => new() {
+        DestinationId = submission.DestinationId,
+        ServiceType = (ServiceTypeDto)submission.ServiceType,
+        AnnouncedAttachments = submission.Attachments.Select(a => a.Id).ToList()
+    };
+
+    public async Task UploadAttachmentsAsync(
+        List<KeyValuePair<string, byte[]>> encryptedAttachments) {
+        throw new NotImplementedException();
+    }
+
+    public async Task SubmitSubmissionAsync(Submission submission) {
+        throw new NotImplementedException();
+    }
+
+    public Task<string> GetDestinationIdAsync(string leiaKey, string? ags, string? ars,
+        string? areaId) => ApiService.RouteService.GetDestinationIdAsync(leiaKey, ags, ars, areaId);
 }
diff --git a/FitConnect/Subscriber.cs b/FitConnect/Subscriber.cs
index 88aad24aabe46ff64ebfcb61055c72cd299e0677..42b37f8b157f912ad15f99c0e4c84a6eeb18ca88 100644
--- a/FitConnect/Subscriber.cs
+++ b/FitConnect/Subscriber.cs
@@ -1,4 +1,6 @@
 using System.Reflection;
+using System.Security.Cryptography.X509Certificates;
+using FitConnect.BaseClasses;
 using FitConnect.Models;
 using Microsoft.Extensions.Logging;
 using Newtonsoft.Json.Linq;
@@ -7,31 +9,23 @@ using Newtonsoft.Json.Schema;
 namespace FitConnect;
 
 public class Subscriber : FunctionalBaseClass {
-    /// <summary>
-    /// Constructor for the Subscriber class.
-    /// </summary>
-    /// <param name="logger">ILogger implementation</param>
-    /// <param name="endpoints">FitConnect endpoints</param>
-    public Subscriber(ILogger logger, FitConnectEndpoints endpoints) : base(logger, endpoints) {
+    public Subscriber(ILogger? logger, FitConnectEndpoints endpoints,
+        X509Certificate2? certificate = null) : base(logger, endpoints, certificate) {
     }
 
 
     private async Task<string> GetContentFromEmbeddedResource(string filename) {
         var assembly = typeof(Subscriber).GetTypeInfo().Assembly;
         var resourceName = $"{assembly.GetName().Name}.{filename}";
-        using (var stream = assembly.GetManifestResourceStream(resourceName)) {
-            if (stream == null) {
-                throw new Exception($"Could not find embedded resource {resourceName}");
-            }
+        await using var stream = assembly.GetManifestResourceStream(resourceName);
+        if (stream == null) throw new Exception($"Could not find embedded resource {resourceName}");
 
-            using (var reader = new StreamReader(stream)) {
-                return await reader.ReadToEndAsync();
-            }
-        }
+        using var reader = new StreamReader(stream);
+        return await reader.ReadToEndAsync();
     }
 
     /// <summary>
-    /// Decrypt Data (Fachdaten)
+    ///     Decrypt Data (Fachdaten)
     /// </summary>
     /// <param name="data">(Fachdaten)</param>
     /// <returns></returns>
@@ -40,7 +34,7 @@ public class Subscriber : FunctionalBaseClass {
     }
 
     /// <summary>
-    /// Decrypt attachments (Anhänge)
+    ///     Decrypt attachments (Anhänge)
     /// </summary>
     /// <param name="attachment">Encrypted attachments</param>
     /// <returns></returns>
@@ -49,7 +43,7 @@ public class Subscriber : FunctionalBaseClass {
     }
 
     /// <summary>
-    /// Checks the validity of the given metadata against the schema.
+    ///     Checks the validity of the given metadata against the schema.
     /// </summary>
     /// <param name="jsonMetaData">JSON meta data</param>
     /// <returns></returns>
@@ -63,7 +57,7 @@ public class Subscriber : FunctionalBaseClass {
 
 
     /// <summary>
-    /// Check Hash from Metadata
+    ///     Check Hash from Metadata
     /// </summary>
     /// <param name="jsonMetaData">Metadata in JSON Format</param>
     /// <returns></returns>
@@ -73,7 +67,7 @@ public class Subscriber : FunctionalBaseClass {
 
 
     /// <summary>
-    /// Create SecurityEventToken and signature
+    ///     Create SecurityEventToken and signature
     /// </summary>
     /// <param name="data"></param>
     /// <param name="attachment"></param>
diff --git a/InitializationTests/BaseClassConstructorTests.cs b/InitializationTests/BaseClassConstructorTests.cs
index 0c8379673e7a10913e7ac97e9fe3867410c0928a..e0c7cc7e9cbd73b1dbd451aa57f7e9575aaf4a6e 100644
--- a/InitializationTests/BaseClassConstructorTests.cs
+++ b/InitializationTests/BaseClassConstructorTests.cs
@@ -16,30 +16,30 @@ public class BaseClassConstructorTests {
     }
 
     [Test]
-    public void CreateCustomEndpoints() {
+    public void Sender_CreateCustomEndpoints() {
         var dut = new Sender(_logger, new FitConnectEndpoints(
             "http://localhost:5050/token",
             "http://localhost:5050/submission",
             "http://localhost:5050/routing"));
 
-        dut.Endpoints.RoutingApi.Should().Be("http://localhost:5050/routing");
-        dut.Endpoints.SubmissionApi.Should().Be("http://localhost:5050/submission");
+        dut.Endpoints.RoutingUrl.Should().Be("http://localhost:5050/routing");
+        dut.Endpoints.SubmissionUrl.Should().Be("http://localhost:5050/submission");
         dut.Endpoints.TokenUrl.Should().Be("http://localhost:5050/token");
     }
 
     [Test]
-    public void CreateDevEndpoints() {
+    public void Sender_CreateDevEndpoints() {
         var dut = new Sender(_logger,
             FitConnectEndpoints.Create(FitConnectEndpoints.EndpointType.Development));
 
         dut.Endpoints.TokenUrl.Should().Be("https://auth-testing.fit-connect.fitko.dev/token");
-        dut.Endpoints.SubmissionApi.Should()
+        dut.Endpoints.SubmissionUrl.Should()
             .Be("https://submission-api-testing.fit-connect.fitko.dev");
-        dut.Endpoints.RoutingApi.Should().Be("https://routing-api-testing.fit-connect.fitko.dev");
+        dut.Endpoints.RoutingUrl.Should().Be("https://routing-api-testing.fit-connect.fitko.dev");
     }
 
     [Test]
-    public void CreateTestingEndpoints() {
+    public void Sender_CreateTestingEndpoints_ShouldThrowArgumentException() {
         Assert.Throws<ArgumentException>(() => {
             var sender = new Subscriber(_logger,
                 FitConnectEndpoints.Create(FitConnectEndpoints.EndpointType.Testing));
@@ -47,7 +47,7 @@ public class BaseClassConstructorTests {
     }
 
     [Test]
-    public void CreateProductionEndpoints() {
+    public void Sender_CreateProductionEndpoints_ShouldThrowArgumentException() {
         Assert.Throws<ArgumentException>(() => {
             var sender = new Sender(_logger,
                 FitConnectEndpoints.Create(FitConnectEndpoints.EndpointType.Production));
diff --git a/InitializationTests/InitializationTests.csproj b/InitializationTests/InitializationTests.csproj
index 43b1dc07278ee1dd87ce10971772ba841c4ece36..ce48ba3cc6016e040d512812c74b541d24e45901 100644
--- a/InitializationTests/InitializationTests.csproj
+++ b/InitializationTests/InitializationTests.csproj
@@ -8,16 +8,16 @@
     </PropertyGroup>
 
     <ItemGroup>
-        <PackageReference Include="FluentAssertions" Version="6.7.0" />
-        <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
-        <PackageReference Include="Moq" Version="4.18.1" />
-        <PackageReference Include="NUnit" Version="3.13.2" />
-        <PackageReference Include="NUnit3TestAdapter" Version="4.0.0" />
-        <PackageReference Include="coverlet.collector" Version="3.1.0" />
+        <PackageReference Include="FluentAssertions" Version="6.7.0"/>
+        <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0"/>
+        <PackageReference Include="Moq" Version="4.18.1"/>
+        <PackageReference Include="NUnit" Version="3.13.2"/>
+        <PackageReference Include="NUnit3TestAdapter" Version="4.0.0"/>
+        <PackageReference Include="coverlet.collector" Version="3.1.0"/>
     </ItemGroup>
 
     <ItemGroup>
-      <ProjectReference Include="..\FitConnect\FitConnect.csproj" />
+        <ProjectReference Include="..\FitConnect\FitConnect.csproj"/>
     </ItemGroup>
 
 </Project>
diff --git a/FitConnect/FitConnectEndpoints.cs b/Models/FitConnectEndpoints.cs
similarity index 79%
rename from FitConnect/FitConnectEndpoints.cs
rename to Models/FitConnectEndpoints.cs
index 57277b6d9aec6eb9314eb6af770f061b69133986..f044d8e51f43f290156e759a5e42caa40e1aa129 100644
--- a/FitConnect/FitConnectEndpoints.cs
+++ b/Models/FitConnectEndpoints.cs
@@ -1,42 +1,59 @@
 namespace FitConnect;
 
 public class FitConnectEndpoints {
+    public enum EndpointType {
+        Development,
+        Testing,
+        Production
+    }
+
+    private static readonly FitConnectEndpoints DevEndpoints = new(
+        "https://auth-testing.fit-connect.fitko.dev/token",
+        "https://submission-api-testing.fit-connect.fitko.dev",
+        "https://routing-api-testing.fit-connect.fitko.dev"
+    );
+
+    private static readonly FitConnectEndpoints TestEndpoints = new(
+        "https://auth-testing.fit-connect.fitko.dev/token",
+        "https://submission-api-testing.fit-connect.fitko.dev",
+        "https://routing-api-testing.fit-connect.fitko.dev"
+    );
+
+    private static readonly FitConnectEndpoints ProductionEndpoints = new(
+        "https://auth-testing.fit-connect.fitko.dev/token",
+        "https://submission-api-testing.fit-connect.fitko.dev",
+        "https://routing-api-testing.fit-connect.fitko.dev"
+    );
+
     /// <summary>
-    /// Default constructor.
+    ///     Default constructor.
     /// </summary>
     /// <param name="tokenUrl">URL for receiving the OAuth token</param>
-    /// <param name="submissionApi">URL for the submission API</param>
-    /// <param name="routingApi">URL for the routing API</param>
-    public FitConnectEndpoints(string tokenUrl, string submissionApi, string routingApi) {
+    /// <param name="submissionUrl">URL for the submission API</param>
+    /// <param name="routingUrl">URL for the routing API</param>
+    public FitConnectEndpoints(string tokenUrl, string submissionUrl, string routingUrl) {
         TokenUrl = tokenUrl;
-        SubmissionApi = submissionApi;
-        RoutingApi = routingApi;
+        SubmissionUrl = submissionUrl;
+        RoutingUrl = routingUrl;
     }
 
     /// <summary>
-    /// URL for receiving the OAuth token.
+    ///     URL for receiving the OAuth token.
     /// </summary>
     public string TokenUrl { get; }
 
     /// <summary>
-    /// URL for the submission API.
+    ///     URL for the submission API.
     /// </summary>
-    public string SubmissionApi { get; }
+    public string SubmissionUrl { get; }
 
     /// <summary>
-    /// URL for the routing API.
+    ///     URL for the routing API.
     /// </summary>
-    public string RoutingApi { get; }
-
-
-    public enum EndpointType {
-        Development,
-        Testing,
-        Production
-    }
+    public string RoutingUrl { get; }
 
     /// <summary>
-    /// Creates the endpoints for the given environment.
+    ///     Creates the endpoints for the given environment.
     /// </summary>
     /// <param name="endpointType">Environment to get endpoints for</param>
     /// <returns></returns>
@@ -49,22 +66,4 @@ public class FitConnectEndpoints {
             _ => throw new ArgumentOutOfRangeException(nameof(endpointType), endpointType, null)
         };
     }
-
-    private static readonly FitConnectEndpoints DevEndpoints = new(
-        "https://auth-testing.fit-connect.fitko.dev/token",
-        "https://submission-api-testing.fit-connect.fitko.dev",
-        "https://routing-api-testing.fit-connect.fitko.dev"
-    );
-
-    private static readonly FitConnectEndpoints TestEndpoints = new(
-        "https://auth-testing.fit-connect.fitko.dev/token",
-        "https://submission-api-testing.fit-connect.fitko.dev",
-        "https://routing-api-testing.fit-connect.fitko.dev"
-    );
-
-    private static readonly FitConnectEndpoints ProductionEndpoints = new(
-        "https://auth-testing.fit-connect.fitko.dev/token",
-        "https://submission-api-testing.fit-connect.fitko.dev",
-        "https://routing-api-testing.fit-connect.fitko.dev"
-    );
 }
diff --git a/Models/Models.csproj b/Models/Models.csproj
new file mode 100644
index 0000000000000000000000000000000000000000..42326e5c3ec81e82a29317e741d328d2d68ef0b9
--- /dev/null
+++ b/Models/Models.csproj
@@ -0,0 +1,10 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+    <PropertyGroup>
+        <TargetFramework>net6.0</TargetFramework>
+        <ImplicitUsings>enable</ImplicitUsings>
+        <Nullable>enable</Nullable>
+        <RootNamespace>FitConnect.Models</RootNamespace>
+    </PropertyGroup>
+
+</Project>
diff --git a/RestService/RestCallService.cs b/RestService/RestCallService.cs
new file mode 100644
index 0000000000000000000000000000000000000000..685b80177755ba01e29491440650f38efb18ad11
--- /dev/null
+++ b/RestService/RestCallService.cs
@@ -0,0 +1,30 @@
+using System.Net.Http.Json;
+using System.Text;
+
+namespace FitConnect.RestService;
+
+public abstract class RestCallService {
+    private readonly string _baseUrl;
+
+    protected RestCallService(string baseUrl) {
+        _baseUrl = baseUrl;
+    }
+
+    internal async Task<T?> RestCall<T>(Uri uri, HttpMethod method, string body) {
+        var client = new HttpClient();
+        client.DefaultRequestHeaders.Add("Accept", "application/json");
+        client.DefaultRequestHeaders.Add("Content-Type", "application/json");
+
+        var request = new HttpRequestMessage();
+        request.Method = method;
+        request.Content = new StringContent(body, Encoding.UTF8, "application/json");
+        request.RequestUri = uri;
+
+        var response = await client.SendAsync(request);
+
+        if (response.IsSuccessStatusCode)
+            return await response.Content.ReadFromJsonAsync<T>();
+
+        throw new HttpRequestException("Error calling FitConnect API");
+    }
+}
diff --git a/RestService/RestService.csproj b/RestService/RestService.csproj
new file mode 100644
index 0000000000000000000000000000000000000000..b7d19297180b37a203c1072123f0f3035906fafb
--- /dev/null
+++ b/RestService/RestService.csproj
@@ -0,0 +1,10 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+    <PropertyGroup>
+        <TargetFramework>net6.0</TargetFramework>
+        <ImplicitUsings>enable</ImplicitUsings>
+        <Nullable>enable</Nullable>
+        <RootNamespace>FitConnect.RestService</RootNamespace>
+    </PropertyGroup>
+
+</Project>
diff --git a/SenderTest/SenderEncryptionWithCertificateTest.cs b/SenderTest/SenderEncryptionWithCertificateTest.cs
deleted file mode 100644
index 9e079737c1dde27b5b9a4560955c0b6ef7436481..0000000000000000000000000000000000000000
--- a/SenderTest/SenderEncryptionWithCertificateTest.cs
+++ /dev/null
@@ -1,96 +0,0 @@
-using System;
-using System.IO;
-using System.Security.Cryptography;
-using System.Security.Cryptography.X509Certificates;
-using System.Text;
-using FitConnect;
-using Microsoft.Extensions.Logging;
-using NUnit.Framework;
-
-namespace SenderTest;
-
-public class SenderEncryptionWithCertificateTest {
-    private Sender _sender = null!;
-    private ILogger<SenderEncryptionWithCertificateTest> _logger = null!;
-
-    /*
-     * Encryption test must be changed for production to only allow extern signed certificates
-     * and forbid self-signed certificates.
-     */
-
-    [SetUp]
-    public void Setup() {
-        _logger = LoggerFactory.Create(cfg => cfg.AddConsole())
-            .CreateLogger<SenderEncryptionWithCertificateTest>();
-        _sender = new Sender(_logger,
-            FitConnectEndpoints.Create(FitConnectEndpoints.EndpointType.Development));
-        var certificate = CreateSelfSignedCertificate(null);
-        _sender.ImportCertificate(certificate);
-    }
-
-
-    [Test]
-    public void CryptWithOutPublicKeyImport() {
-        var cypher = _sender.EncryptData(Encoding.UTF8.GetBytes("test"));
-
-        _logger.LogInformation("Cypher: {}", Convert.ToBase64String(cypher));
-    }
-
-
-    [Test]
-    [Ignore("Not applicable for production")]
-    public void CryptWithPublicKeyImport() {
-        var publicKey = Convert.FromBase64String(
-            "MIIBCgKCAQEAzu/ek6A5AMuROs+12pncbYNteGkd6ReU28ZY5gCM4hNFI0h1E+0+OST+Yxw7zhvbFhZbYdVt8LmzonMAtENituLxzZj7MsWom/ZzxTdp4Cx5zlx8x6Qx/ZPoSS2T2Sf0ttymaMc6ZadpWsDhg/Mnf6beF1W/QoGH/bHBa8U4rhkUa+OKf3wyo08km8oyUJaj6kkB0VdhRp5rSyvXJtUMZ5A0LcYFygnkHTSQlQhdrAK+6nTo//mfNfPtqta2wBb9ONpVwN0V7I5PSdH2WxZMZsYFicLOGbNeF08gibmL+7TeBTssYtrNVM88cG0v+aWeBun0WVrpCntDIA9HIujWowIDAQAB");
-
-        var cypher = _sender.EncryptData(Encoding.UTF8.GetBytes("test"), publicKey);
-
-        _logger.LogInformation("Cypher: {}", Convert.ToBase64String(cypher));
-    }
-
-    [Test]
-    public void ExportPrivateKey() {
-        var privateKey = _sender.ExportPrivateKey();
-        _logger.LogInformation("Private key: {}", Convert.ToBase64String(privateKey));
-    }
-
-
-    #region Static helpers
-
-    private X509Certificate2 CreateSelfSignedCertificate(string? exportPath = "../../../") {
-        var req = new CertificateRequest("cn=foobar", ECDsa.Create(), HashAlgorithmName.SHA256);
-        var cert = req.CreateSelfSigned(DateTimeOffset.Now, DateTimeOffset.Now.AddYears(5));
-
-        if (cert.GetRSAPublicKey() == null)
-            throw new Exception("Certificate does not contain a public key");
-
-        if (cert.GetRSAPrivateKey() == null)
-            throw new Exception("Certificate does not contain a private key");
-
-        // Export the certificate to a PEM file, just for
-        // additional extern testing
-        if (exportPath != null) {
-            ExportCertificateToFile(exportPath, cert);
-        }
-
-        return cert;
-    }
-
-    private void ExportCertificateToFile(string exportPath, X509Certificate cert) {
-        // Create PFX (PKCS #12) with private key
-        File.WriteAllBytes($"{exportPath}/certificate.pfx",
-            cert.Export(X509ContentType.Pfx, ""));
-
-        // Create Base 64 encoded CER (public key only)
-        File.WriteAllText($"{exportPath}/certificate.cer",
-            "-----BEGIN CERTIFICATE-----\r\n"
-            + Convert.ToBase64String(cert.Export(X509ContentType.Cert, ""),
-                Base64FormattingOptions.InsertLineBreaks)
-            + "\r\n-----END CERTIFICATE-----");
-
-        _logger?.LogInformation("Exporting {}",
-            Convert.ToBase64String(cert.Export(X509ContentType.Cert, "")));
-    }
-}
-
-#endregion
diff --git a/SenderTest/SenderEncryptionWithImportedCertificateTest.cs b/SenderTest/SenderEncryptionWithImportedCertificateTest.cs
deleted file mode 100644
index 772bcfde18b62e23b2591303d38c739db24c393b..0000000000000000000000000000000000000000
--- a/SenderTest/SenderEncryptionWithImportedCertificateTest.cs
+++ /dev/null
@@ -1,4 +0,0 @@
-namespace SenderTest;
-
-public class SenderEncryptionWithImportedCertificateTest {
-}
diff --git a/SenderTest/SenderEncryptionWithoutCertificateTest.cs b/SenderTest/SenderEncryptionWithoutCertificateTest.cs
deleted file mode 100644
index 06bd1d0659f76941caf720b58a463408d85c19d5..0000000000000000000000000000000000000000
--- a/SenderTest/SenderEncryptionWithoutCertificateTest.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-using System;
-using System.Text;
-using FitConnect;
-using Microsoft.Extensions.Logging;
-using NUnit.Framework;
-
-namespace SenderTest;
-
-
-public class SenderEncryptionWithoutCertificateTest {
-    private Sender _sender = null!;
-    private ILogger<SenderEncryptionWithoutCertificateTest> _logger = null!;
-
-    /*
-     * Encryption test must be changed for production to only allow extern signed certificates
-     * and forbid self-signed certificates.
-     */
-
-    [SetUp]
-    public void Setup() {
-        _logger = LoggerFactory.Create(cfg => cfg.AddConsole())
-            .CreateLogger<SenderEncryptionWithoutCertificateTest>();
-        _sender = new Sender(_logger,
-            FitConnectEndpoints.Create(FitConnectEndpoints.EndpointType.Development));
-    }
-
-
-    [Test]
-    public void CryptWithOutPublicKeyImport() {
-        var cypher = _sender.EncryptData(Encoding.UTF8.GetBytes("test"));
-
-        _logger.LogInformation("Cypher: {}", Convert.ToBase64String(cypher));
-    }
-
-
-    [Test]
-    [Ignore("Not applicable for production")]
-    public void CryptWithPublicKeyImport() {
-        var publicKey = Convert.FromBase64String(
-            "MIIBCgKCAQEAzu/ek6A5AMuROs+12pncbYNteGkd6ReU28ZY5gCM4hNFI0h1E+0+OST+Yxw7zhvbFhZbYdVt8LmzonMAtENituLxzZj7MsWom/ZzxTdp4Cx5zlx8x6Qx/ZPoSS2T2Sf0ttymaMc6ZadpWsDhg/Mnf6beF1W/QoGH/bHBa8U4rhkUa+OKf3wyo08km8oyUJaj6kkB0VdhRp5rSyvXJtUMZ5A0LcYFygnkHTSQlQhdrAK+6nTo//mfNfPtqta2wBb9ONpVwN0V7I5PSdH2WxZMZsYFicLOGbNeF08gibmL+7TeBTssYtrNVM88cG0v+aWeBun0WVrpCntDIA9HIujWowIDAQAB");
-
-        var cypher = _sender.EncryptData(Encoding.UTF8.GetBytes("test"), publicKey);
-
-        _logger.LogInformation("Cypher: {}", Convert.ToBase64String(cypher));
-    }
-
-    [Test]
-    public void ExportPrivateKey() {
-        var privateKey = _sender.ExportPrivateKey();
-        _logger.LogInformation("Private key: {}", Convert.ToBase64String(privateKey));
-    }
-
-}
diff --git a/Services/CasesService.cs b/Services/CasesService.cs
new file mode 100644
index 0000000000000000000000000000000000000000..2f679e7685f58b03ea97cdf4572e3fa03039096d
--- /dev/null
+++ b/Services/CasesService.cs
@@ -0,0 +1,37 @@
+using FitConnect.RestService;
+using FitConnect.Services.Models;
+
+namespace FitConnect.Services;
+
+
+public class CasesService : RestCallService {
+    public CasesService(string baseUrl) : base(baseUrl) {
+    }
+
+
+    /// <summary>
+    ///     <para>
+    ///         @GetMapping("/cases/{caseId}/events")
+    ///     </para>
+    /// </summary>
+    /// <param name="caseId">PathVariable</param>
+    /// <param name="offset">RequestParam</param>
+    /// <param name="limit">RequestParam</param>
+    /// <returns></returns>
+    /// <exception cref="NotImplementedException"></exception>
+    public EventLogDto GetEventLog(string caseId, int offset, int limit) {
+        throw new NotImplementedException();
+    }
+
+    // 
+    /// <summary>
+    ///     <para>@PostMapping(value = "/cases/{caseId}/events", consumes = "application/jose")</para>
+    /// </summary>
+    /// <param name="caseId">PathVariable</param>
+    /// <param name="eventToken">RequestBody</param>
+    /// <returns></returns>
+    /// <exception cref="NotImplementedException"></exception>
+    public bool ProcessCaseEvent(string caseId, string eventToken) {
+        throw new NotImplementedException();
+    }
+}
\ No newline at end of file
diff --git a/Services/DestinationService.cs b/Services/DestinationService.cs
new file mode 100644
index 0000000000000000000000000000000000000000..af415b5299e3f453f23a30d188f5971fbf185b51
--- /dev/null
+++ b/Services/DestinationService.cs
@@ -0,0 +1,78 @@
+using FitConnect.RestService;
+using FitConnect.Services.Models;
+
+namespace FitConnect.Services;
+
+public class DestinationService : RestCallService {
+    public DestinationService(string baseUrl) : base(baseUrl) {
+    }
+
+    /// <summary>
+    ///     <para>@PostMapping("/destinations")</para>
+    /// </summary>
+    /// <param name="createDestination">RequestBody</param>
+    /// <returns></returns>
+    /// <exception cref="NotImplementedException"></exception>
+    public PrivateDestinationDto CreateDestination(CreateDestinationDto createDestination) {
+        throw new NotImplementedException();
+    }
+
+
+    /// <summary>
+    ///     <para>@GetMapping("/destinations/{destinationId}")</para>
+    /// </summary>
+    /// <param name="destinationId">PathVariable</param>
+    /// <exception cref="NotImplementedException"></exception>
+    public void GetDestination(string destinationId) {
+        throw new NotImplementedException();
+    }
+
+
+    /// <summary>
+    ///     <para>@DeleteMapping("/destinations/{destinationId}")</para>
+    /// </summary>
+    /// <param name="destinationId">PathVariable</param>
+    /// <returns></returns>
+    /// <exception cref="NotImplementedException"></exception>
+    public bool DeleteDestination(string destinationId) {
+        throw new NotImplementedException();
+    }
+
+
+    /// <summary>
+    ///     <para>@PatchMapping("/destinations/{destinationId}")</para>
+    /// </summary>
+    /// <param name="destinationId">PathVariable</param>
+    /// <param name="patchDestination">RequestBody</param>
+    /// <returns></returns>
+    /// <exception cref="NotImplementedException"></exception>
+    public PrivateDestinationDto PatchDestination(string destinationId,
+        PatchDestinationDto patchDestination) {
+        throw new NotImplementedException();
+    }
+
+
+    /// <summary>
+    ///     <para>@GetMapping("/destinations")</para>
+    /// </summary>
+    /// <param name="offset">RequestParam</param>
+    /// <param name="limit">RequestParam</param>
+    /// <returns></returns>
+    /// <exception cref="NotImplementedException"></exception>
+    public DestinationListDto ListDestinations(int offset, int limit) {
+        throw new NotImplementedException();
+    }
+
+
+    /// <summary>
+    ///     <para>@PutMapping("/destinations/{destinationId}")</para>
+    /// </summary>
+    /// <param name="destinationId">PathVariable</param>
+    /// <param name="updateDestination">RequestBody</param>
+    /// <returns></returns>
+    /// <exception cref="NotImplementedException"></exception>
+    public PrivateDestinationDto UpdateDestination(string destinationId,
+        UpdateDestinationDto updateDestination) {
+        throw new NotImplementedException();
+    }
+}
diff --git a/Services/FitConnectApiService.cs b/Services/FitConnectApiService.cs
new file mode 100644
index 0000000000000000000000000000000000000000..1b97070eb488f2a0d96421e90948e88fe61c6c56
--- /dev/null
+++ b/Services/FitConnectApiService.cs
@@ -0,0 +1,19 @@
+using Microsoft.Extensions.Logging;
+
+namespace FitConnect.Services;
+
+public class FitConnectApiService {
+    protected readonly CasesService CasesService;
+    protected readonly DestinationService DestinationService;
+    protected readonly OAuthService OAuthService;
+    protected readonly SubmissionService SubmissionService;
+    public readonly RouteService RouteService;
+
+    public FitConnectApiService(FitConnectEndpoints endpoints, ILogger? logger = null) {
+        CasesService = new CasesService(endpoints.SubmissionUrl);
+        DestinationService = new DestinationService(endpoints.SubmissionUrl);
+        SubmissionService = new SubmissionService(endpoints.SubmissionUrl);
+        OAuthService = new OAuthService(endpoints.TokenUrl);
+        RouteService = new RouteService(endpoints.RoutingUrl);
+    }
+}
diff --git a/Services/InfoService.cs b/Services/InfoService.cs
new file mode 100644
index 0000000000000000000000000000000000000000..fd3d9ae5c747bca0e0778410a3d56a883bea718d
--- /dev/null
+++ b/Services/InfoService.cs
@@ -0,0 +1,17 @@
+using FitConnect.RestService;
+
+namespace FitConnect.Services;
+
+public class InfoService : RestCallService {
+    public InfoService(string baseUrl) : base(baseUrl) {
+    }
+
+    /// <summary>
+    ///     @GetMapping("/info")
+    /// </summary>
+    /// <returns></returns>
+    /// <exception cref="NotImplementedException"></exception>
+    public string GetInfo() {
+        throw new NotImplementedException();
+    }
+}
diff --git a/Services/Models/ApiInfoDto.cs b/Services/Models/ApiInfoDto.cs
new file mode 100644
index 0000000000000000000000000000000000000000..5cc8756064c2fa0b71a55d252659ace554ac430e
--- /dev/null
+++ b/Services/Models/ApiInfoDto.cs
@@ -0,0 +1,4 @@
+namespace FitConnect.Services.Models;
+
+public class ApiInfoDto {
+}
diff --git a/Services/Models/CallbackDto.cs b/Services/Models/CallbackDto.cs
new file mode 100644
index 0000000000000000000000000000000000000000..2a2e45adfbdf83955c5c784b972d4786f80783c3
--- /dev/null
+++ b/Services/Models/CallbackDto.cs
@@ -0,0 +1,11 @@
+using System.Text.Json.Serialization;
+
+namespace FitConnect.Services.Models;
+
+public class CallbackDto {
+    [JsonPropertyName("url")]
+    public string Url { get; set; }
+
+    [JsonPropertyName("secret")]
+    public string? Secret { get; set; }
+}
diff --git a/Services/Models/Case/EventLogDto.cs b/Services/Models/Case/EventLogDto.cs
new file mode 100644
index 0000000000000000000000000000000000000000..02e6e888af58fd89d1c294bd9a5e0b9fef3b535f
--- /dev/null
+++ b/Services/Models/Case/EventLogDto.cs
@@ -0,0 +1,17 @@
+using System.Text.Json.Serialization;
+
+namespace FitConnect.Services.Models;
+
+public class EventLogDto {
+    [JsonPropertyName("count")]
+    public int Count;
+
+    [JsonPropertyName("eventLog")]
+    public List<string> EventLog;
+
+    [JsonPropertyName("offset")]
+    public int Offset;
+
+    [JsonPropertyName("totalCount")]
+    public long TotalCount;
+}
diff --git a/Services/Models/Destination/ContactInformationDto.cs b/Services/Models/Destination/ContactInformationDto.cs
new file mode 100644
index 0000000000000000000000000000000000000000..00b02222857b47e0d1e6cbd083f0cf03b7bd7ba6
--- /dev/null
+++ b/Services/Models/Destination/ContactInformationDto.cs
@@ -0,0 +1,20 @@
+using System.Text.Json.Serialization;
+
+namespace FitConnect.Services.Models;
+
+public class ContactInformationDto {
+    [JsonPropertyName("address")]
+    public string Address;
+
+    [JsonPropertyName("email")]
+    public string Email;
+
+    [JsonPropertyName("legalName")]
+    public string LegalName;
+
+    [JsonPropertyName("phone")]
+    public string Phone;
+
+    [JsonPropertyName("unit")]
+    public string Unit;
+}
diff --git a/Services/Models/Destination/CreateDestinationDto.cs b/Services/Models/Destination/CreateDestinationDto.cs
new file mode 100644
index 0000000000000000000000000000000000000000..92767ff8542bc0f5c11cfa00e999a849ccfd6cea
--- /dev/null
+++ b/Services/Models/Destination/CreateDestinationDto.cs
@@ -0,0 +1,35 @@
+using System.Text.Json.Serialization;
+
+namespace FitConnect.Services.Models;
+
+public class CreateDestinationDto {
+    [JsonPropertyName("callback")]
+    public CallbackDto Callback;
+
+    [JsonPropertyName("contactInformation")]
+    public ContactInformationDto ContactInformation;
+
+
+    [JsonPropertyName("encryptionKid")]
+    public string EncryptionKid;
+
+
+    [JsonPropertyName("encryptionPublicKey")]
+    public string EncryptionPublicKey;
+
+
+    [JsonPropertyName("metadataVersions")]
+    public List<string> metadataVersions;
+
+
+    [JsonPropertyName("replyChannels")]
+    public DestinationReplyChannelsDto ReplyChannels;
+
+
+    [JsonPropertyName("services")]
+    public List<DestinationServiceDto> Services;
+
+
+    [JsonPropertyName("signingPublicKey")]
+    public string SigningPublicKey;
+}
diff --git a/Services/Models/Destination/DeMailDto.cs b/Services/Models/Destination/DeMailDto.cs
new file mode 100644
index 0000000000000000000000000000000000000000..34c7cab917aad09d716cb4aeadc8d261708b046e
--- /dev/null
+++ b/Services/Models/Destination/DeMailDto.cs
@@ -0,0 +1,4 @@
+namespace FitConnect.Services.Models;
+
+public class DeMailDto {
+}
diff --git a/Services/Models/Destination/DestinationListDto.cs b/Services/Models/Destination/DestinationListDto.cs
new file mode 100644
index 0000000000000000000000000000000000000000..55aa52c4af09b259d42384c6d34f5d5bf82e4d9e
--- /dev/null
+++ b/Services/Models/Destination/DestinationListDto.cs
@@ -0,0 +1,20 @@
+using System.Text.Json.Serialization;
+
+namespace FitConnect.Services.Models;
+
+public class DestinationListDto {
+    [JsonPropertyName("count")]
+    public int Count;
+
+
+    [JsonPropertyName("destinations")]
+    public List<PrivateDestinationDto> Destinations;
+
+
+    [JsonPropertyName("offset")]
+    public int Offset;
+
+
+    [JsonPropertyName("totalCount")]
+    public long TotalCount;
+}
diff --git a/Services/Models/Destination/DestinationReplyChannelsDto.cs b/Services/Models/Destination/DestinationReplyChannelsDto.cs
new file mode 100644
index 0000000000000000000000000000000000000000..95435299ccabf50a5e3cecc7c0133e080eb3eca4
--- /dev/null
+++ b/Services/Models/Destination/DestinationReplyChannelsDto.cs
@@ -0,0 +1,29 @@
+namespace FitConnect.Services.Models;
+
+public class DestinationReplyChannelsDto {
+    public DeMailDto? DeMail;
+
+
+    public ElsterDto? Elster;
+    public EmailDto? EMail;
+
+
+    public FinkDto? Fink;
+
+
+    public DestinationReplyChannelsDto(
+        EmailDto eMail,
+        DeMailDto deMail,
+        FinkDto fink,
+        ElsterDto elster) {
+        EMail = EMail;
+        DeMail = DeMail;
+        Fink = Fink;
+        Elster = Elster;
+    }
+
+
+    public bool IsEmpty() {
+        return EMail == null && DeMail == null && Fink == null && Elster == null;
+    }
+}
diff --git a/Services/Models/Destination/DestinationServiceDto.cs b/Services/Models/Destination/DestinationServiceDto.cs
new file mode 100644
index 0000000000000000000000000000000000000000..a3f72f3a9b7c593f7b1f72d46b0888bb66755bad
--- /dev/null
+++ b/Services/Models/Destination/DestinationServiceDto.cs
@@ -0,0 +1,15 @@
+using System.Text.Json.Serialization;
+
+namespace FitConnect.Services.Models;
+
+public class DestinationServiceDto {
+    [JsonPropertyName("identifier")]
+    public string Identifier;
+
+
+    [JsonPropertyName("regions")]
+    public List<string> Regions;
+
+    [JsonPropertyName("submissionSchemas")]
+    public List<SubmissionSchemaDto> SubmissionSchemas;
+}
diff --git a/Services/Models/Destination/ElsterDto.cs b/Services/Models/Destination/ElsterDto.cs
new file mode 100644
index 0000000000000000000000000000000000000000..05f7cc5f8d5cfaa22e5a6850296c12eb70edc716
--- /dev/null
+++ b/Services/Models/Destination/ElsterDto.cs
@@ -0,0 +1,4 @@
+namespace FitConnect.Services.Models;
+
+public class ElsterDto {
+}
diff --git a/Services/Models/Destination/EmailDto.cs b/Services/Models/Destination/EmailDto.cs
new file mode 100644
index 0000000000000000000000000000000000000000..ffaf5ccabc0edd79b1f3dc5183c7daf20a0283e5
--- /dev/null
+++ b/Services/Models/Destination/EmailDto.cs
@@ -0,0 +1,4 @@
+namespace FitConnect.Services.Models;
+
+public class EmailDto {
+}
diff --git a/Services/Models/Destination/FinkDto.cs b/Services/Models/Destination/FinkDto.cs
new file mode 100644
index 0000000000000000000000000000000000000000..862620319fa862da5c46b75add2d4bf9dd9d04e6
--- /dev/null
+++ b/Services/Models/Destination/FinkDto.cs
@@ -0,0 +1,4 @@
+namespace FitConnect.Services.Models;
+
+public class FinkDto {
+}
diff --git a/Services/Models/Destination/PatchDestinationDto.cs b/Services/Models/Destination/PatchDestinationDto.cs
new file mode 100644
index 0000000000000000000000000000000000000000..f557d726c29f64bb27a8970021ecb7c2901df99b
--- /dev/null
+++ b/Services/Models/Destination/PatchDestinationDto.cs
@@ -0,0 +1,31 @@
+using System.Text.Json.Serialization;
+
+namespace FitConnect.Services.Models;
+
+public class PatchDestinationDto {
+    [JsonPropertyName("callback")]
+    public CallbackDto Callback;
+
+
+    [JsonPropertyName("contactInformation")]
+    public ContactInformationDto ContactInformation;
+
+
+    [JsonPropertyName("encryptionKid")]
+    public string EncryptionKid;
+
+
+    [JsonPropertyName("metadataVersions")]
+    public List<string> metadataVersions;
+
+
+    [JsonPropertyName("replyChannels")]
+    public DestinationReplyChannelsDto ReplyChannels;
+
+
+    [JsonPropertyName("services")]
+    public List<DestinationServiceDto> Services;
+
+    [JsonPropertyName("status")]
+    public string Status;
+}
diff --git a/Services/Models/Destination/PrivateDestinationDto.cs b/Services/Models/Destination/PrivateDestinationDto.cs
new file mode 100644
index 0000000000000000000000000000000000000000..3db3fa3b67c63aea48b57e0bb3910cc4c801d1a2
--- /dev/null
+++ b/Services/Models/Destination/PrivateDestinationDto.cs
@@ -0,0 +1,35 @@
+using System.Text.Json.Serialization;
+
+namespace FitConnect.Services.Models;
+
+public class PrivateDestinationDto {
+    [JsonPropertyName("callback")]
+    public CallbackDto Callback;
+
+
+    [JsonPropertyName("contactInformation")]
+    public ContactInformationDto ContactInformation;
+
+    [JsonPropertyName("destinationId")]
+    public string DestinationId;
+
+
+    [JsonPropertyName("encryptionKid")]
+    public string EncryptionKid;
+
+
+    [JsonPropertyName("metadataVersions")]
+    public List<string> MetadataVersions;
+
+
+    [JsonPropertyName("replyChannels")]
+    public DestinationReplyChannelsDto ReplyChannels;
+
+
+    [JsonPropertyName("services")]
+    public List<DestinationServiceDto> Services;
+
+
+    [JsonPropertyName("status")]
+    public string Status;
+}
diff --git a/Services/Models/Destination/PublicDestinationDto.cs b/Services/Models/Destination/PublicDestinationDto.cs
new file mode 100644
index 0000000000000000000000000000000000000000..4bf90d449e4f99d15a6a358f4f82e0d52770d06c
--- /dev/null
+++ b/Services/Models/Destination/PublicDestinationDto.cs
@@ -0,0 +1,28 @@
+using System.Text.Json.Serialization;
+
+namespace FitConnect.Services.Models;
+
+public class PublicDestinationDto {
+    [JsonPropertyName("destinationId")]
+    public string DestinationId;
+
+
+    [JsonPropertyName("encryptionKid")]
+    public string EncryptionKid;
+
+
+    [JsonPropertyName("metadataVersions")]
+    public List<string> MetadataVersions;
+
+
+    [JsonPropertyName("replyChannels")]
+    public DestinationReplyChannelsDto ReplyChannels;
+
+
+    [JsonPropertyName("services")]
+    public List<DestinationServiceDto> Services;
+
+
+    [JsonPropertyName("status")]
+    public string Status;
+}
diff --git a/Services/Models/Destination/SubmissionSchemaDto.cs b/Services/Models/Destination/SubmissionSchemaDto.cs
new file mode 100644
index 0000000000000000000000000000000000000000..6bb3cc3b7584814403cd96d027eac47bbe2a1dcf
--- /dev/null
+++ b/Services/Models/Destination/SubmissionSchemaDto.cs
@@ -0,0 +1,12 @@
+using System.Text.Json.Serialization;
+
+namespace FitConnect.Services.Models;
+
+public class SubmissionSchemaDto {
+    [JsonPropertyName("mimeType")]
+    //private SubmissionSchemaMimeTypeDto mimeType;
+    public int mimeType;
+
+    [JsonPropertyName("schemaUri")]
+    public string schemaUri;
+}
diff --git a/Services/Models/Destination/UpdateDestinationDto.cs b/Services/Models/Destination/UpdateDestinationDto.cs
new file mode 100644
index 0000000000000000000000000000000000000000..92f0aa48091bb79130a3da96ba5593cd4b17a85f
--- /dev/null
+++ b/Services/Models/Destination/UpdateDestinationDto.cs
@@ -0,0 +1,31 @@
+using System.Text.Json.Serialization;
+
+namespace FitConnect.Services.Models;
+
+public class UpdateDestinationDto {
+    [JsonPropertyName("callback")]
+    public CallbackDto Callback;
+
+
+    [JsonPropertyName("contactInformation")]
+    public ContactInformationDto ContactInformation;
+
+
+    [JsonPropertyName("encryptionKid")]
+    public string EncryptionKid;
+
+
+    [JsonPropertyName("metadataVersions")]
+    public List<string> metadataVersions;
+
+
+    [JsonPropertyName("replyChannels")]
+    public DestinationReplyChannelsDto ReplyChannels;
+
+
+    [JsonPropertyName("services")]
+    public List<DestinationServiceDto> Services;
+
+    [JsonPropertyName("status")]
+    public string Status;
+}
diff --git a/FitConnect/Models/OAuthAccessToken.cs b/Services/Models/OAuthAccessToken.cs
similarity index 91%
rename from FitConnect/Models/OAuthAccessToken.cs
rename to Services/Models/OAuthAccessToken.cs
index 87ac3872e52a9a9e88e1df33eace09bb8fbd3ed1..3fc70d9b9c1063c2df508e3accbd4756e85939e4 100644
--- a/FitConnect/Models/OAuthAccessToken.cs
+++ b/Services/Models/OAuthAccessToken.cs
@@ -1,6 +1,6 @@
 using System.Text.Json.Serialization;
 
-namespace FitConnect.Models;
+namespace FitConnect.Services.Models;
 
 public class OAuthAccessToken {
     [JsonPropertyName("access_token")]
diff --git a/Services/Models/ServiceTypeDto.cs b/Services/Models/ServiceTypeDto.cs
new file mode 100644
index 0000000000000000000000000000000000000000..97b5a604fec11305eb21684cc6675b828f121ddb
--- /dev/null
+++ b/Services/Models/ServiceTypeDto.cs
@@ -0,0 +1,14 @@
+using System.Text.Json.Serialization;
+
+namespace FitConnect.Services.Models;
+
+public class ServiceTypeDto {
+    [JsonPropertyName("name")]
+    public string? Name { get; set; }
+
+    [JsonPropertyName("description")]
+    public string? Description { get; set; }
+
+    [JsonPropertyName("identifier")]
+    public string? Identifier { get; set; }
+}
diff --git a/Services/Models/Submission/CreateSubmissionDto.cs b/Services/Models/Submission/CreateSubmissionDto.cs
new file mode 100644
index 0000000000000000000000000000000000000000..c19cad9e5adb2bd8b9ad1c3051f6555dd79fb97b
--- /dev/null
+++ b/Services/Models/Submission/CreateSubmissionDto.cs
@@ -0,0 +1,22 @@
+using System.Text.Json.Serialization;
+
+namespace FitConnect.Services.Models;
+
+public class CreateSubmissionDto {
+    [JsonPropertyName("callback")]
+    public CallbackDto Callback { get; set; }
+
+
+    [JsonPropertyName("serviceType")]
+    public ServiceTypeDto ServiceType { get; set; }
+
+
+    [JsonPropertyName("announcedAttachments")]
+    public List<string> AnnouncedAttachments { get; set; }
+
+    [JsonPropertyName("caseId")]
+    public string CaseId { get; set; }
+
+    [JsonPropertyName("destinationId")]
+    public string DestinationId { get; set; }
+}
diff --git a/Services/Models/Submission/SubmissionCreatedDto.cs b/Services/Models/Submission/SubmissionCreatedDto.cs
new file mode 100644
index 0000000000000000000000000000000000000000..950d4096b31f14b86a4274af66bb5fd9c2b44bc4
--- /dev/null
+++ b/Services/Models/Submission/SubmissionCreatedDto.cs
@@ -0,0 +1,14 @@
+using System.Text.Json.Serialization;
+
+namespace FitConnect.Services.Models;
+
+public class SubmissionCreatedDto {
+    [JsonPropertyName("destinationId")]
+    public string DestinationId { get; set; }
+
+    [JsonPropertyName("submissionId")]
+    public string SubmissionId { get; set; }
+
+    [JsonPropertyName("caseId")]
+    public string CaseId { get; set; }
+}
diff --git a/Services/Models/Submission/SubmissionDto.cs b/Services/Models/Submission/SubmissionDto.cs
new file mode 100644
index 0000000000000000000000000000000000000000..d5816c52f505d35d8f575bba9bd150c8db0add1c
--- /dev/null
+++ b/Services/Models/Submission/SubmissionDto.cs
@@ -0,0 +1,35 @@
+using System.Text.Json.Serialization;
+
+namespace FitConnect.Services.Models;
+
+public class SubmissionDto {
+    [JsonPropertyName("attachments")]
+    public List<string> Attachments;
+
+
+    [JsonPropertyName("callback")]
+    public CallbackDto Callback;
+
+
+    [JsonPropertyName("caseId")]
+    public string CaseId;
+
+    [JsonPropertyName("destinationId")]
+    public string DestinationId;
+
+
+    [JsonPropertyName("encryptedData")]
+    public string EncryptedData;
+
+
+    [JsonPropertyName("encryptedMetadata")]
+    public string EncryptedMetadata;
+
+
+    [JsonPropertyName("serviceType")]
+    public ServiceTypeDto ServiceType;
+
+
+    [JsonPropertyName("submissionId")]
+    public string SubmissionId;
+}
diff --git a/Services/Models/Submission/SubmissionForPickupDto.cs b/Services/Models/Submission/SubmissionForPickupDto.cs
new file mode 100644
index 0000000000000000000000000000000000000000..eab6ce3327722cd6a842d2d946ae12c5aaf80b70
--- /dev/null
+++ b/Services/Models/Submission/SubmissionForPickupDto.cs
@@ -0,0 +1,14 @@
+using System.Text.Json.Serialization;
+
+namespace FitConnect.Services.Models;
+
+public class SubmissionForPickupDto {
+    [JsonPropertyName("caseId")]
+    public string CaseId;
+
+    [JsonPropertyName("destinationId")]
+    public string DestinationId;
+
+    [JsonPropertyName("submissionId")]
+    public string SubmissionId;
+}
diff --git a/Services/Models/Submission/SubmissionReducedDto.cs b/Services/Models/Submission/SubmissionReducedDto.cs
new file mode 100644
index 0000000000000000000000000000000000000000..2d83e86a8accbd84468f71eaf0ab2c27ac43bfa0
--- /dev/null
+++ b/Services/Models/Submission/SubmissionReducedDto.cs
@@ -0,0 +1,27 @@
+using System.Text.Json.Serialization;
+
+namespace FitConnect.Services.Models;
+
+public class SubmissionReducedDto {
+    [JsonPropertyName("serviceType")]
+    private ServiceTypeDto _serviceTypeDto;
+
+
+    [JsonPropertyName("attachments")]
+    private List<string> Attachments;
+
+
+    [JsonPropertyName("callback")]
+    private CallbackDto Callback;
+
+
+    [JsonPropertyName("caseId")]
+    private string CaseId;
+
+    [JsonPropertyName("destinationId")]
+    private string DestinationId;
+
+
+    [JsonPropertyName("submissionId")]
+    private string SubmissionId;
+}
diff --git a/Services/Models/Submission/SubmissionsForPickupDto.cs b/Services/Models/Submission/SubmissionsForPickupDto.cs
new file mode 100644
index 0000000000000000000000000000000000000000..e17182b6737733683b49d6477a3097b23ca24f35
--- /dev/null
+++ b/Services/Models/Submission/SubmissionsForPickupDto.cs
@@ -0,0 +1,17 @@
+using System.Text.Json.Serialization;
+
+namespace FitConnect.Services.Models;
+
+public class SubmissionsForPickupDto {
+    [JsonPropertyName("count")]
+    public int Count;
+
+    [JsonPropertyName("offset")]
+    public int Offset;
+
+    [JsonPropertyName("submissions")]
+    public List<SubmissionForPickupDto> Submissions;
+
+    [JsonPropertyName("totalCount")]
+    public long TotalCount;
+}
diff --git a/Services/Models/Submission/SubmitSubmissionDto.cs b/Services/Models/Submission/SubmitSubmissionDto.cs
new file mode 100644
index 0000000000000000000000000000000000000000..ec47ff8a5fe4adc0f8c9e46ffc8fc5728d407c65
--- /dev/null
+++ b/Services/Models/Submission/SubmitSubmissionDto.cs
@@ -0,0 +1,11 @@
+using System.Text.Json.Serialization;
+
+namespace FitConnect.Services.Models;
+
+public class SubmitSubmissionDto {
+    [JsonPropertyName("encryptedData")]
+    public string EncryptedData;
+
+    [JsonPropertyName("encryptedMetadata")]
+    public string EncryptedMetadata;
+}
diff --git a/Services/OAuthService.cs b/Services/OAuthService.cs
new file mode 100644
index 0000000000000000000000000000000000000000..bc1d939fe0dd0f45825866950cb405cdb374675f
--- /dev/null
+++ b/Services/OAuthService.cs
@@ -0,0 +1,52 @@
+using System.Net.Http.Headers;
+using System.Net.Http.Json;
+using FitConnect.Services.Models;
+
+namespace FitConnect.Services;
+
+public class OAuthService {
+    private readonly string _tokenUrl;
+
+    public OAuthService(string tokenUrl) {
+        _tokenUrl = tokenUrl;
+    }
+
+    /// <summary>
+    ///     Requesting an OAuth token from the FitConnect API.
+    ///     <para>
+    ///         You can get the Client ID and Client Secret from the FitConnect Self Service portal
+    ///         under <br />
+    ///         https://portal.auth-testing.fit-connect.fitko.dev
+    ///     </para>
+    /// </summary>
+    /// <param name="clientId">Your client Id</param>
+    /// <param name="clientSecret">Your client Secret</param>
+    /// <param name="scope">Scope if needed</param>
+    /// <returns>The received token or null</returns>
+    public async Task<OAuthAccessToken?> GetTokenAsync(string clientId, string clientSecret,
+        string? scope = null) {
+        var client = new HttpClient();
+        client.DefaultRequestHeaders.Accept.Add(
+            MediaTypeWithQualityHeaderValue.Parse("application/json"));
+
+        var requestContent = new Dictionary<string, string> {
+            { "grant_type", "client_credentials" },
+            { "client_id", clientId },
+            { "client_secret", clientSecret }
+        };
+
+        if (scope != null)
+            requestContent["scope"] = scope;
+
+        var content = new FormUrlEncodedContent(requestContent);
+
+        var request = new HttpRequestMessage(HttpMethod.Post, _tokenUrl) {
+            Content = content,
+            Method = HttpMethod.Post
+        };
+
+        var response = await client.SendAsync(request);
+
+        return await response.Content.ReadFromJsonAsync<OAuthAccessToken>();
+    }
+}
diff --git a/Services/RouteService.cs b/Services/RouteService.cs
new file mode 100644
index 0000000000000000000000000000000000000000..0f11935e238721be49d09b03a7dff869f481e030
--- /dev/null
+++ b/Services/RouteService.cs
@@ -0,0 +1,22 @@
+using FitConnect.RestService;
+
+namespace FitConnect.Services;
+
+public class RouteService : RestCallService {
+    public RouteService(string baseUrl) : base(baseUrl) {
+    }
+
+    /// <summary>
+    /// Returns the destination id for the given intent.
+    /// </summary>
+    /// <param name="leiaKey"></param>
+    /// <param name="ags"></param>
+    /// <param name="ars"></param>
+    /// <param name="areaId"></param>
+    /// <returns></returns>
+    /// <exception cref="NotImplementedException"></exception>
+    public Task<string> GetDestinationIdAsync(string leiaKey, string? ags, string? ars,
+        string? areaId) {
+        throw new NotImplementedException();
+    }
+}
diff --git a/Services/Services.csproj b/Services/Services.csproj
new file mode 100644
index 0000000000000000000000000000000000000000..4f40401bc9d2194670a8eff2890155ffff494112
--- /dev/null
+++ b/Services/Services.csproj
@@ -0,0 +1,19 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+    <PropertyGroup>
+        <TargetFramework>net6.0</TargetFramework>
+        <ImplicitUsings>enable</ImplicitUsings>
+        <Nullable>enable</Nullable>
+        <RootNamespace>FitConnect.Services</RootNamespace>
+    </PropertyGroup>
+
+    <ItemGroup>
+        <ProjectReference Include="..\Models\Models.csproj" />
+        <ProjectReference Include="..\RestService\RestService.csproj" />
+    </ItemGroup>
+
+    <ItemGroup>
+      <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.1" />
+    </ItemGroup>
+
+</Project>
diff --git a/Services/Services.csproj.DotSettings b/Services/Services.csproj.DotSettings
new file mode 100644
index 0000000000000000000000000000000000000000..813beff19dbf997729c10d1fb5277c01d04646ca
--- /dev/null
+++ b/Services/Services.csproj.DotSettings
@@ -0,0 +1,5 @@
+<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
+	<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Ccase/@EntryIndexedValue">True</s:Boolean>
+	<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cdestination/@EntryIndexedValue">True</s:Boolean>
+	<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cdestinations/@EntryIndexedValue">True</s:Boolean>
+	<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Csubmission/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
\ No newline at end of file
diff --git a/Services/SubmissionService.cs b/Services/SubmissionService.cs
new file mode 100644
index 0000000000000000000000000000000000000000..4c37e10da8a62449545b76ee8869fccb0fe0c94c
--- /dev/null
+++ b/Services/SubmissionService.cs
@@ -0,0 +1,86 @@
+using FitConnect.RestService;
+using FitConnect.Services.Models;
+
+namespace FitConnect.Services;
+
+public class SubmissionService : RestCallService {
+    public SubmissionService(string baseUrl) : base(baseUrl) {
+    }
+
+    /// <summary>
+    ///     <para>@PostMapping("/submissions")</para>
+    /// </summary>
+    /// <param name="submissionDto">RequestBody</param>
+    /// <returns></returns>
+    /// <exception cref="NotImplementedException"></exception>
+    public SubmissionCreatedDto CreateSubmission(CreateSubmissionDto submissionDto) {
+        throw new NotImplementedException();
+    }
+
+
+    /// <summary>
+    ///     <para>
+    ///         @PutMapping(value = "/submissions/{submissionId}/attachments/{attachmentId}", consumes =
+    ///         "application/jose")
+    ///     </para>
+    /// </summary>
+    /// <param name="submissionId">PathVariable</param>
+    /// <param name="attachmentId">PathVariable</param>
+    /// <param name="encryptedAttachmentContent">RequestBody</param>
+    /// <returns></returns>
+    /// <exception cref="NotImplementedException"></exception>
+    public bool AddSubmissionAttachment(string submissionId, string attachmentId,
+        string encryptedAttachmentContent) {
+        throw new NotImplementedException();
+    }
+
+    /// <summary>
+    ///     <para>@PutMapping(value = "/submissions/{submissionId}", consumes = "application/json") </para>
+    /// </summary>
+    /// <param name="submissionId">PathVariable</param>
+    /// <param name="submitSubmission">RequestBody</param>
+    /// <returns></returns>
+    /// <exception cref="NotImplementedException"></exception>
+    public SubmissionReducedDto SubmitSubmission(string submissionId,
+        SubmitSubmissionDto submitSubmission) {
+        throw new NotImplementedException();
+    }
+
+
+    /// <summary>
+    ///     <para>@GetMapping("/submissions")</para>
+    /// </summary>
+    /// <param name="destinationId">RequestParam</param>
+    /// <param name="offset">RequestParam</param>
+    /// <param name="limit">RequestParam</param>
+    /// <returns></returns>
+    /// <exception cref="NotImplementedException"></exception>
+    public async Task<SubmissionsForPickupDto> ListSubmissions(string destinationId, int offset, int limit) {
+        throw new NotImplementedException();
+    }
+
+    /// <summary>
+    ///     <para>@GetMapping("/submissions/{submissionId}")</para>
+    /// </summary>
+    /// <param name="submissionId">PathVariable</param>
+    /// <returns></returns>
+    /// <exception cref="NotImplementedException"></exception>
+    public SubmissionDto GetSubmission(string submissionId) {
+        throw new NotImplementedException();
+    }
+
+
+    /// <summary>
+    ///     <para>
+    ///         @GetMapping(value = "/submissions/{submissionId}/attachments/{attachmentId}", produces =
+    ///         "application/jose")
+    ///     </para>
+    /// </summary>
+    /// <param name="submissionId">PathVariable</param>
+    /// <param name="attachmentId">PathVariable</param>
+    /// <returns></returns>
+    /// <exception cref="NotImplementedException"></exception>
+    public string GetAttachment(string submissionId, string attachmentId) {
+        throw new NotImplementedException();
+    }
+}
diff --git a/readme.md b/readme.md
index bf546573d17a2fd6f4b40cddaafd25229568d4ff..3dfd9971dd5bd1c8742d13e25621e1801a76d1a8 100644
--- a/readme.md
+++ b/readme.md
@@ -2,10 +2,90 @@
 
 **Fit-Connect .NET SDK** is a .NET library for the Fit-Connect API.
 
-**IN DEVELOPMENT NOT FOR PRODUCTION USE**
+## **!! IN DEVELOPMENT NOT FOR PRODUCTION USE !!**
+
+## Structure
+
+```mermaid
+ classDiagram
+  class FitConnectSDK{
+   FitConnectApiService
+  }
+  
+  class FitConnectApiService{
+    CasesService
+    DestinationService
+    InfoService
+    OAuthService  
+    RouteService  
+  }
+  
+  FitConnectSDK ..> Sender : public
+  FitConnectSDK ..> Subscriber : public
+  Sender --|> FunctionalBaseClass
+  Subscriber --|> FunctionalBaseClass
+  FunctionalBaseClass ..> FitConnectApiService : protected
+
+  FitConnectApiService ..> RouteService : public
+  FitConnectApiService ..> CasesService : public
+  FitConnectApiService ..> DestinationService : public
+  FitConnectApiService ..> InfoService : public
+  FitConnectApiService ..> OAuthService : public
+  
+  RouteService --|> RestCallService : Inheritance
+  CasesService --|> RestCallService : Inheritance
+  DestinationService --|> RestCallService : Inheritance
+  InfoService --|> RestCallService : Inheritance
+  OAuthService --|> RestCallService : Inheritance
+  
+```
+
+With that structure the user of the SDK is intended to see the following:
+
+```mermaid
+  classDiagram
+  
+    class FitConnectSDK {
+        +SendSumission
+        +GetSubmissions
+    }
+    
+    class Sender {
+    << Draft >>
+        + Einreichung anlegen und ankündigen
+        + Anlagen verschlüsseln
+        + Anlagen hochladen
+        + Metadaten befüllen und verschlüsseln
+        + Fachdaten verschlüsseln
+        + Fachdaten & Metadaten hochladen und Einreichung absenden
+    }
+    
+    class Subscriber { 
+    << Draft >>
+     < TO BE DEFINED >
+    }
+    
+      FitConnectSDK --> Sender
+      FitConnectSDK --> Subscriber
+```
+
+### Annotation
+
+The structure ensures a abstraction of the API calls for the user and a 'simple' way to change the
+API calls if a new version of the API is released. Currently the API call is not versioned and hard
+coded.
+
+#### Abstractions for API calls
+
+- The use of a dependency injection can be added to
+  inject the API calls into the SDK. But is not yet implemented.
+- Another approach would be using a generic class for the API calls.
 
 ## Ignored Files
 
+The files listed below are ignored and necessary just for development. In production the information
+is provided by the user of the SDK.
+
 You need a secret file for e2e test like:
 
 ```json
diff --git a/working_notes.md b/working_notes.md
index 517d433b53dbfa873b286a70452895f17e60a3eb..91b76b4a0db6dd3058c0fe7392d4bf4edd2a3c84 100644
--- a/working_notes.md
+++ b/working_notes.md
@@ -18,6 +18,11 @@
 |     X     |             |        | Sender, Subscriber | Unterstüzung / Abstraktion der API-Nutzung (`fitconnect.sendSubmission(metadata, destinationID, ...)` o.ä.) für die oben genannten Use-Cases  |
 |     X     |             |        | Sender, Subscriber | Logging (Logging-Modul muss von außen kommen)                                                                                                 |
 
+# Routing API
+
+- [Description](https://docs.fitko.de/fit-connect/docs/responsibilities/get-destination)
+- [Swagger](https://docs.fitko.de/fit-connect/docs/apis/routing-api#get-/routes)
+
 ## Links
 
 - [SDK-Konzept im Wiki](https://wiki.fit-connect.fitko.dev/de/Konzeption/Konzeption_SDK)
@@ -29,3 +34,4 @@
 - [Documentation](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/)
+