diff --git a/api/src/main/java/de/fitko/fitconnect/api/domain/model/destination/Destination.java b/api/src/main/java/de/fitko/fitconnect/api/domain/model/destination/Destination.java
new file mode 100644
index 0000000000000000000000000000000000000000..21f58696efd1b89283e25d232d8136374df4cb8e
--- /dev/null
+++ b/api/src/main/java/de/fitko/fitconnect/api/domain/model/destination/Destination.java
@@ -0,0 +1,11 @@
+package de.fitko.fitconnect.api.domain.model.destination;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.util.UUID;
+
+public class Destination {
+
+    @JsonProperty("encryptionKid")
+    UUID encryptionKid;
+}
diff --git a/api/src/main/java/de/fitko/fitconnect/api/domain/model/metadata/ContentStructure.java b/api/src/main/java/de/fitko/fitconnect/api/domain/model/metadata/ContentStructure.java
index 8e06ae6c6d144d63ab4ab5cebe4bc1179cfc5019..1fbebed0cd06063788cd3eb553ccbc4d6854e17d 100644
--- a/api/src/main/java/de/fitko/fitconnect/api/domain/model/metadata/ContentStructure.java
+++ b/api/src/main/java/de/fitko/fitconnect/api/domain/model/metadata/ContentStructure.java
@@ -6,6 +6,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonPropertyOrder;
 import de.fitko.fitconnect.api.domain.model.metadata.attachment.Attachment;
 import de.fitko.fitconnect.api.domain.model.metadata.data.Data;
+import lombok.Builder;
 import lombok.Getter;
 import lombok.Setter;
 
@@ -19,6 +20,7 @@ import java.util.Map;
 })
 @Getter
 @Setter
+@Builder
 public class ContentStructure {
 
     @JsonProperty("data")
diff --git a/api/src/main/java/de/fitko/fitconnect/api/domain/model/metadata/attachment/Attachment.java b/api/src/main/java/de/fitko/fitconnect/api/domain/model/metadata/attachment/Attachment.java
index 8147f76647a4629f9dfc44787fcdf26e4e774f33..c88f7b1ac64774e86aaedee57f2767889b0b3abb 100644
--- a/api/src/main/java/de/fitko/fitconnect/api/domain/model/metadata/attachment/Attachment.java
+++ b/api/src/main/java/de/fitko/fitconnect/api/domain/model/metadata/attachment/Attachment.java
@@ -6,8 +6,10 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonPropertyOrder;
 import de.fitko.fitconnect.api.domain.model.metadata.attachment.signature.Hash__1;
 import de.fitko.fitconnect.api.domain.model.metadata.attachment.signature.Signature__1;
+import lombok.Builder;
 import lombok.Getter;
 import lombok.Setter;
+import lombok.Value;
 
 import java.util.Map;
 import java.util.UUID;
@@ -24,6 +26,7 @@ import java.util.UUID;
 })
 @Getter
 @Setter
+@Builder
 public class Attachment {
 
     @JsonProperty("hash")
diff --git a/api/src/main/java/de/fitko/fitconnect/api/domain/model/submission/Submission.java b/api/src/main/java/de/fitko/fitconnect/api/domain/model/submission/SubmissionRequest.java
similarity index 95%
rename from api/src/main/java/de/fitko/fitconnect/api/domain/model/submission/Submission.java
rename to api/src/main/java/de/fitko/fitconnect/api/domain/model/submission/SubmissionRequest.java
index c2c8da391c7c1e80d66ac4b8449d80b9da70d77f..0b691c7ba65675947f2b5548ed4df7dcfbba27ec 100644
--- a/api/src/main/java/de/fitko/fitconnect/api/domain/model/submission/Submission.java
+++ b/api/src/main/java/de/fitko/fitconnect/api/domain/model/submission/SubmissionRequest.java
@@ -14,7 +14,7 @@ import java.util.UUID;
 @Setter
 @Value
 @Builder
-public class Submission {
+public class SubmissionRequest {
 
     @JsonProperty("destinationId")
     UUID destinationId;
diff --git a/api/src/main/java/de/fitko/fitconnect/api/domain/model/submission/SubmissionResponse.java b/api/src/main/java/de/fitko/fitconnect/api/domain/model/submission/SubmissionResponse.java
new file mode 100644
index 0000000000000000000000000000000000000000..d15106e5304873e1a0847526b87727de6ee7cf2e
--- /dev/null
+++ b/api/src/main/java/de/fitko/fitconnect/api/domain/model/submission/SubmissionResponse.java
@@ -0,0 +1,19 @@
+package de.fitko.fitconnect.api.domain.model.submission;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Value;
+
+import java.util.UUID;
+
+@Value
+public class SubmissionResponse {
+
+    @JsonProperty("destinationId")
+    private final UUID destinationId;
+
+    @JsonProperty("submissionId")
+    private final UUID submissionId;
+
+    @JsonProperty("caseId")
+    private final UUID caseId;
+}
diff --git a/api/src/main/java/de/fitko/fitconnect/api/domain/validation/ValidationResult.java b/api/src/main/java/de/fitko/fitconnect/api/domain/validation/ValidationResult.java
index d1f8f89b2314d5bfa220f1857a82afef550524ab..0293bfbeddd683860d1d44d37dd93b1b2d93d04e 100644
--- a/api/src/main/java/de/fitko/fitconnect/api/domain/validation/ValidationResult.java
+++ b/api/src/main/java/de/fitko/fitconnect/api/domain/validation/ValidationResult.java
@@ -34,6 +34,10 @@ public class ValidationResult {
         return this.isValid;
     }
 
+    public boolean hasErrors() {
+        return !isValid || !errors.isEmpty();
+    }
+
     public List<Exception> getErrors() {
         return this.errors;
     }
diff --git a/api/src/main/java/de/fitko/fitconnect/api/exceptions/client/AttachmentUploadError.java b/api/src/main/java/de/fitko/fitconnect/api/exceptions/client/AttachmentUploadError.java
index 3843c9eb0cec27fd49c61d0a53980e4c5a33f9de..819a018fb5752f750856e102e13cad22197905eb 100644
--- a/api/src/main/java/de/fitko/fitconnect/api/exceptions/client/AttachmentUploadError.java
+++ b/api/src/main/java/de/fitko/fitconnect/api/exceptions/client/AttachmentUploadError.java
@@ -1,10 +1,10 @@
 package de.fitko.fitconnect.api.exceptions.client;
 
 import de.fitko.fitconnect.api.domain.model.metadata.attachment.Attachment;
-import de.fitko.fitconnect.api.domain.model.submission.Submission;
+import de.fitko.fitconnect.api.domain.model.submission.SubmissionRequest;
 
 /**
- * Error during upload of the {@link Submission}s {@link Attachment}s
+ * Error during upload of the {@link SubmissionRequest}s {@link Attachment}s
  */
 public class AttachmentUploadError extends RuntimeException {
 
diff --git a/api/src/main/java/de/fitko/fitconnect/api/exceptions/client/SubmissionCreationError.java b/api/src/main/java/de/fitko/fitconnect/api/exceptions/client/SubmissionCreationError.java
index 2074888d42301c0b2f58726d5bd30bb1573bc154..c83e00b78d666f7ae6ce318be3720c5f46d14a08 100644
--- a/api/src/main/java/de/fitko/fitconnect/api/exceptions/client/SubmissionCreationError.java
+++ b/api/src/main/java/de/fitko/fitconnect/api/exceptions/client/SubmissionCreationError.java
@@ -1,9 +1,9 @@
 package de.fitko.fitconnect.api.exceptions.client;
 
-import de.fitko.fitconnect.api.domain.model.submission.Submission;
+import de.fitko.fitconnect.api.domain.model.submission.SubmissionRequest;
 
 /**
- * Error during the creation process of a {@link Submission}
+ * Error during the creation process of a {@link SubmissionRequest}
  */
 public class SubmissionCreationError extends RuntimeException {
 
diff --git a/api/src/main/java/de/fitko/fitconnect/api/exceptions/client/SubmissionSendError.java b/api/src/main/java/de/fitko/fitconnect/api/exceptions/client/SubmissionSendError.java
index 6d0ea812cc00fd1f2186e7cc5e1bc69eecd36f17..028ce74bd2dd36b1f11dc07d85b90fec5f955363 100644
--- a/api/src/main/java/de/fitko/fitconnect/api/exceptions/client/SubmissionSendError.java
+++ b/api/src/main/java/de/fitko/fitconnect/api/exceptions/client/SubmissionSendError.java
@@ -1,9 +1,9 @@
 package de.fitko.fitconnect.api.exceptions.client;
 
-import de.fitko.fitconnect.api.domain.model.submission.Submission;
+import de.fitko.fitconnect.api.domain.model.submission.SubmissionRequest;
 
 /**
- * Error during the creation process of a {@link Submission}
+ * Error during the creation process of a {@link SubmissionRequest}
  */
 public class SubmissionSendError extends RuntimeException {
 
diff --git a/api/src/main/java/de/fitko/fitconnect/api/services/Sender.java b/api/src/main/java/de/fitko/fitconnect/api/services/Sender.java
index d9ba7a1e37a16144da449811bfff787674df1110..f6db1e33166b7da719e48806474c45cd0ee687dc 100644
--- a/api/src/main/java/de/fitko/fitconnect/api/services/Sender.java
+++ b/api/src/main/java/de/fitko/fitconnect/api/services/Sender.java
@@ -5,17 +5,20 @@ import de.fitko.fitconnect.api.domain.auth.OAuthToken;
 import de.fitko.fitconnect.api.domain.model.metadata.Metadata;
 import de.fitko.fitconnect.api.domain.model.metadata.attachment.Attachment;
 import de.fitko.fitconnect.api.domain.model.metadata.data.Data;
-import de.fitko.fitconnect.api.domain.model.submission.Submission;
+import de.fitko.fitconnect.api.domain.model.submission.SubmissionRequest;
+import de.fitko.fitconnect.api.domain.model.submission.SubmissionResponse;
 import de.fitko.fitconnect.api.domain.validation.ValidationResult;
 
+import java.io.File;
 import java.util.List;
 import java.util.Optional;
+import java.util.UUID;
 
 /**
  * A technical system that creates a submission via the FIT-Connect Submission API.
  * <p>
  * The Sender acts as a common interface wrapping all client functionality to authenticate <p>
- * and create a valid {@link Submission} including encrypted {@link Data} and {@link Attachment}s
+ * and create a valid {@link SubmissionRequest} including encrypted {@link Data} and {@link Attachment}s
  *
  * @see <a href="https://docs.fitko.de/fit-connect/docs/sending/overview">Sending Submissions</a>
  */
@@ -68,19 +71,37 @@ public interface Sender {
     Optional<Metadata> createMetadata(final Data data, final List<Attachment> attachments);
 
     /**
-     * Creates and announces a new {@link Submission}
+     * Creates and uploads a {@link Metadata} object that contains {@link Data}, {@link Attachment} and their hashes so a subscriber
+     * can verify the integrity.
+     *
+     * @param attachments a list of binary {@link Attachment}s
+     * @return a valid {@link Metadata} object with hashed {@link Data} and {@link Attachment}s, is empty if an error occurred
+     */
+    Optional<Metadata> createMetadata(final List<Attachment> attachments);
+
+    /**
+     * Creates and announces a new {@link SubmissionRequest}
      *
      * @param submission with a destinationId, a list of attachmentIds and a serviceType
      * @return the created submission
      */
-    Optional<Submission> createSubmission(Submission submission);
+    Optional<SubmissionResponse> createSubmission(SubmissionRequest submission);
+
 
     /**
-     * Posts the announced {@link Submission}
+     * Posts the announced {@link SubmissionRequest}
+     *
      * @param submissionId identifier of the announced submission
-     * @param metadata the encrypted metadata
+     * @param encryptedMetadata the encrypted metadata
      *
      * @return the submission
      */
-    Optional<Submission> sendSubmission(String submissionId, Metadata metadata);
+    Optional<SubmissionResponse> sendSubmission(UUID submissionId, Metadata encryptedMetadata);
+
+
+    void uploadAttachments(UUID submissionId, List<Attachment> encryptedAttachments);
+
+    Optional<Attachment> createAttachment(File file);
+
+    RSAKey getEncryptionKeyForDestination(UUID destinationId);
 }
diff --git a/api/src/main/java/de/fitko/fitconnect/api/services/Subscriber.java b/api/src/main/java/de/fitko/fitconnect/api/services/Subscriber.java
index 9dd45d25a7e554832cab27e7fa54de51f6e4984a..d2d175dc40e3cb7859893380f75d0504ca1c7517 100644
--- a/api/src/main/java/de/fitko/fitconnect/api/services/Subscriber.java
+++ b/api/src/main/java/de/fitko/fitconnect/api/services/Subscriber.java
@@ -6,7 +6,7 @@ import de.fitko.fitconnect.api.domain.model.metadata.Metadata;
 import de.fitko.fitconnect.api.domain.model.metadata.attachment.Attachment;
 import de.fitko.fitconnect.api.domain.model.metadata.data.Data;
 import de.fitko.fitconnect.api.domain.model.event.SecurityEventToken;
-import de.fitko.fitconnect.api.domain.model.submission.Submission;
+import de.fitko.fitconnect.api.domain.model.submission.SubmissionRequest;
 import de.fitko.fitconnect.api.domain.validation.ValidationResult;
 
 import java.util.List;
@@ -66,7 +66,7 @@ public interface Subscriber {
     ValidationResult validateMetadataHashValues(final Metadata metadata);
 
     /**
-     * Polls for available {@link Submission}s on the given destinationId
+     * Polls for available {@link SubmissionRequest}s on the given destinationId
      *
      * @param destinationId restricts the query to a specific destination
      * @param limit number of submissions in result (max. is 500)
@@ -74,17 +74,17 @@ public interface Subscriber {
      *
      * @return list of found submissions
      */
-    List<Submission> pollAvailableSubmissions(String destinationId, int limit, int offset);
+    List<SubmissionRequest> pollAvailableSubmissions(String destinationId, int limit, int offset);
 
     /**
-     * Gets a specific {@link Submission}.
+     * Gets a specific {@link SubmissionRequest}.
      *
-     * @param submissionId the unique identifier of a {@link Submission}
+     * @param submissionId the unique identifier of a {@link SubmissionRequest}
      *
      * @return the optional submission, is empty if none was found
      *
      */
-    Optional<Submission> getSubmission(String submissionId);
+    Optional<SubmissionRequest> getSubmission(String submissionId);
 
 
     Optional<SecurityEventToken> createSecurityEventToken(Data data, Attachment attachment, RSAKey privateKey);
diff --git a/api/src/main/java/de/fitko/fitconnect/api/services/auth/OAuthService.java b/api/src/main/java/de/fitko/fitconnect/api/services/auth/OAuthService.java
index fba2424f370a0a4d58f2bcf415e1cf79f489239b..c6683988ee5d7b2d25b6784ee2d03954d597dc99 100644
--- a/api/src/main/java/de/fitko/fitconnect/api/services/auth/OAuthService.java
+++ b/api/src/main/java/de/fitko/fitconnect/api/services/auth/OAuthService.java
@@ -1,12 +1,12 @@
 package de.fitko.fitconnect.api.services.auth;
 
 import de.fitko.fitconnect.api.domain.auth.OAuthToken;
-import de.fitko.fitconnect.api.domain.model.submission.Submission;
+import de.fitko.fitconnect.api.domain.model.submission.SubmissionRequest;
 import de.fitko.fitconnect.api.exceptions.internal.AuthenticationException;
 
 /**
  * A Service that provides an interface to authenticate against the Fit-Connect API in order
- * to send a {@link Submission}.
+ * to send a {@link SubmissionRequest}.
  *
  * @see <a href="https://docs.fitko.de/fit-connect/docs/getting-started/authentication">Fit-Connect documentation on authentication</a>
  *
diff --git a/api/src/main/java/de/fitko/fitconnect/api/services/crypto/CryptoService.java b/api/src/main/java/de/fitko/fitconnect/api/services/crypto/CryptoService.java
index 465fdbb77da11d7655bcf679883954895549a23f..9a493990b7b217585cc667136a1ddfed1dbc5927 100644
--- a/api/src/main/java/de/fitko/fitconnect/api/services/crypto/CryptoService.java
+++ b/api/src/main/java/de/fitko/fitconnect/api/services/crypto/CryptoService.java
@@ -3,12 +3,12 @@ package de.fitko.fitconnect.api.services.crypto;
 import com.nimbusds.jose.jwk.RSAKey;
 import de.fitko.fitconnect.api.domain.model.metadata.data.Data;
 import de.fitko.fitconnect.api.domain.model.metadata.attachment.Attachment;
-import de.fitko.fitconnect.api.domain.model.submission.Submission;
+import de.fitko.fitconnect.api.domain.model.submission.SubmissionRequest;
 import de.fitko.fitconnect.api.exceptions.internal.DecryptionException;
 import de.fitko.fitconnect.api.exceptions.internal.EncryptionException;
 
 /**
- * A service that allows to encrypt and decrypt {@link Data} and {@link Attachment}s of a {@link Submission} via JWE.
+ * A service that allows to encrypt and decrypt {@link Data} and {@link Attachment}s of a {@link SubmissionRequest} via JWE.
  *
  * @see <a href="https://datatracker.ietf.org/doc/html/rfc7516">JSON-Web-Encryption</a>
  */
diff --git a/api/src/main/java/de/fitko/fitconnect/api/services/metadata/MetadataService.java b/api/src/main/java/de/fitko/fitconnect/api/services/metadata/MetadataService.java
index e43dbca1bfbd34dd141530762f272ffa5ccd9771..2071fdcf411078b524314742b431824ca5f4ac64 100644
--- a/api/src/main/java/de/fitko/fitconnect/api/services/metadata/MetadataService.java
+++ b/api/src/main/java/de/fitko/fitconnect/api/services/metadata/MetadataService.java
@@ -3,12 +3,12 @@ package de.fitko.fitconnect.api.services.metadata;
 import de.fitko.fitconnect.api.domain.model.metadata.Metadata;
 import de.fitko.fitconnect.api.domain.model.metadata.attachment.Attachment;
 import de.fitko.fitconnect.api.domain.model.metadata.data.Data;
-import de.fitko.fitconnect.api.domain.model.submission.Submission;
+import de.fitko.fitconnect.api.domain.model.submission.SubmissionRequest;
 
 import java.util.List;
 
 /**
- * Provides the generation of correct and valid {@link Metadata} for a {@link Submission}
+ * Provides the generation of correct and valid {@link Metadata} for a {@link SubmissionRequest}
  *
  * @see
  * <a href="https://docs.fitko.de/fit-connect/docs/metadataoverview">Metadata</a> and
diff --git a/api/src/main/java/de/fitko/fitconnect/api/services/validation/MetadataValidator.java b/api/src/main/java/de/fitko/fitconnect/api/services/validation/MetadataValidator.java
index 22ecc04545091b81c649f8987e3c62474832b377..e788b315320a8fb9a32279131061e18f9f12459b 100644
--- a/api/src/main/java/de/fitko/fitconnect/api/services/validation/MetadataValidator.java
+++ b/api/src/main/java/de/fitko/fitconnect/api/services/validation/MetadataValidator.java
@@ -3,11 +3,11 @@ package de.fitko.fitconnect.api.services.validation;
 import de.fitko.fitconnect.api.domain.model.metadata.Metadata;
 import de.fitko.fitconnect.api.domain.model.metadata.attachment.Attachment;
 import de.fitko.fitconnect.api.domain.model.metadata.data.Data;
-import de.fitko.fitconnect.api.domain.model.submission.Submission;
+import de.fitko.fitconnect.api.domain.model.submission.SubmissionRequest;
 import de.fitko.fitconnect.api.domain.validation.ValidationResult;
 
 /**
- * A validator that ensure the integrity of the transferred {@link Metadata} of a {@link Submission}.
+ * A validator that ensure the integrity of the transferred {@link Metadata} of a {@link SubmissionRequest}.
  * Both schema-validation and hash value validation is provided.
  *
  * @see <a href="https://docs.fitko.de/fit-connect/docs/sending/metadata#integrity">Metadata Integrity</a>
diff --git a/client/src/main/java/de/fitko/fitconnect/TestRunner.java b/client/src/main/java/de/fitko/fitconnect/TestRunner.java
index ec74ce06dc6354afdc10b453de99ad756f42e410..d2f148e550148a0d25e3545e30bda020d57ec77f 100644
--- a/client/src/main/java/de/fitko/fitconnect/TestRunner.java
+++ b/client/src/main/java/de/fitko/fitconnect/TestRunner.java
@@ -1,44 +1,50 @@
 package de.fitko.fitconnect;
 
-import de.fitko.fitconnect.api.domain.model.metadata.Metadata;
-import de.fitko.fitconnect.api.domain.model.metadata.data.Data;
-import de.fitko.fitconnect.api.domain.model.submission.Submission;
+import de.fitko.fitconnect.api.domain.model.submission.SubmissionRequest;
 import de.fitko.fitconnect.client.SenderClient;
 import de.fitko.fitconnect.client.SubscriberClient;
 
 import java.util.Collections;
 import java.util.List;
-import java.util.Optional;
+import java.util.UUID;
 
 public class TestRunner {
 
     public static void main(String[] args) {
+        senderSample();
+    }
 
-        var clientId = "781f6213-0f0f-4a79-9372-e7187ffda98b";
-        var secret = "PnzR8Vbmhpv_VwTkT34wponqXWK8WBm-LADlryYdV4o";
+    private static void senderSample() {
 
-        senderSample(clientId, secret);
-        subscriberSample(clientId, secret);
-    }
+        // Without data
+        SenderClient.build()
+                .withDestination(UUID.randomUUID())
+                .withAttachments(Collections.emptyList())
+                .submit();
 
-    private static void senderSample(String clientId, String secret) {
-        final Optional<Submission> sentSubmission =  SenderClient.builder()
-                .authenticate(clientId, secret)
-                .createSubmission(Submission.builder().build())
-                .uploadAttachments(Collections.emptyList())
-                .sendSubmission(Metadata.builder().build(), Data.builder().build());
+        // With data
+        SenderClient.build()
+                .withDestination(UUID.randomUUID())
+                .withAttachments(Collections.emptyList())
+                .withData("some json or xml")
+                .submit();
     }
 
-    private static void subscriberSample(String clientId, String secret) {
+    private static void subscriberSample() {
+
+        var clientId = "781f6213-0f0f-4a79-9372-e7187ffda98b";
+        var secret = "PnzR8Vbmhpv_VwTkT34wponqXWK8WBm-LADlryYdV4o";
+
+
         // #1 authenticate
         var authenticatedClient = SubscriberClient.builder().authenticate(clientId, secret);
 
         // #2 poll for available submissions
-        List<Submission> availableSubmissions = authenticatedClient.getAvailableSubmissions("someDestinationId");
+        List<SubmissionRequest> availableSubmissions = authenticatedClient.getAvailableSubmissions("someDestinationId");
 
         // #3 get a submission and its data
         var confirmedSubmission = authenticatedClient
-                .requestSubmission(Submission.builder().build())
+                .requestSubmission(SubmissionRequest.builder().build())
                 .requestMetadata()
                 .requestAttachments()
                 .confirmSubmission();
diff --git a/client/src/main/java/de/fitko/fitconnect/client/Client.java b/client/src/main/java/de/fitko/fitconnect/client/Client.java
index d066e86376e1ccb03eac4231233755d8bb6a37a7..dca737f162b6db2ba57056def4f6752af7001c49 100644
--- a/client/src/main/java/de/fitko/fitconnect/client/Client.java
+++ b/client/src/main/java/de/fitko/fitconnect/client/Client.java
@@ -2,6 +2,8 @@ package de.fitko.fitconnect.client;
 
 import com.google.inject.Guice;
 import com.google.inject.Injector;
+import com.google.inject.Key;
+import com.google.inject.name.Names;
 import de.fitko.fitconnect.dependency.SdkModule;
 
 public abstract class Client {
@@ -11,4 +13,8 @@ public abstract class Client {
     static <T> T getService(Class<T> clazz){
         return injector.getInstance(clazz);
     }
+
+    static String getProperty(String propertyName){
+        return injector.getInstance(Key.get(String.class, Names.named(propertyName)));
+    }
 }
diff --git a/client/src/main/java/de/fitko/fitconnect/client/SenderClient.java b/client/src/main/java/de/fitko/fitconnect/client/SenderClient.java
index ebadcbcf3f0e622a402e8efe4eab4ce389ad2e4c..d76d5608139d65c42aceb3c364dea17f674b03b3 100644
--- a/client/src/main/java/de/fitko/fitconnect/client/SenderClient.java
+++ b/client/src/main/java/de/fitko/fitconnect/client/SenderClient.java
@@ -1,113 +1,190 @@
 package de.fitko.fitconnect.client;
 
+import com.nimbusds.jose.jwk.RSAKey;
 import de.fitko.fitconnect.api.domain.auth.OAuthToken;
 import de.fitko.fitconnect.api.domain.model.metadata.Metadata;
 import de.fitko.fitconnect.api.domain.model.metadata.attachment.Attachment;
 import de.fitko.fitconnect.api.domain.model.metadata.data.Data;
-import de.fitko.fitconnect.api.domain.model.submission.Submission;
-import de.fitko.fitconnect.api.exceptions.client.AttachmentUploadError;
+import de.fitko.fitconnect.api.domain.model.submission.SubmissionRequest;
+import de.fitko.fitconnect.api.domain.model.submission.SubmissionResponse;
+import de.fitko.fitconnect.api.domain.validation.ValidationResult;
 import de.fitko.fitconnect.api.exceptions.client.ClientNotAuthenticated;
 import de.fitko.fitconnect.api.services.Sender;
 
+import java.io.File;
+import java.nio.charset.StandardCharsets;
 import java.util.List;
 import java.util.Optional;
+import java.util.UUID;
+import java.util.stream.Collectors;
 
 /**
- * A fluent client for announcing and handing in a {@link Submission}
+ * A fluent client for announcing and handing in a {@link SubmissionRequest}
  */
 public class SenderClient extends Client {
 
-    private SenderClient() {}
+    private SenderClient() {
+    }
 
-     public static Authenticate builder() {
-         return new ClientBuilder(getService(Sender.class));
+    public static WithDestination build() {
+        final Sender sender = getService(Sender.class);
+        final String clientId = getProperty("clientId");
+        final String secret = getProperty("clientSecret");
+        return new ClientBuilder(sender, clientId, secret);
     }
 
-    public interface Authenticate {
+    public interface WithDestination {
+
         /**
-         * Authenticates the client against the FitConnect-Auth-API and retrieves an {@link OAuthToken}.
-         *
-         * @param clientId a unique client identifier
-         * @param secret the applications secret key
-         * @param scope 1 or more client scopes that determine if a submission is accepted by the client
-         * @return the step for creating a new submission if the authentication was successful
+         * Configures the client for the given destination and load the public key
          *
-         * @throws ClientNotAuthenticated if the OAuth token could not be retrieved
+         * @param destinationId the clients destination
+         * @return the upload step for attachments
          */
-        CreateSubmission authenticate(String clientId, String secret, String... scope) throws ClientNotAuthenticated;
+        WithAttachments withDestination(UUID destinationId);
     }
 
-    public interface AttachmentUpload {
+    public interface WithAttachments {
+
         /**
-         * Encrypts and Uploads all {@link Attachment}s to the FitConnect-API
-         *
-         * @param attachments a list of attachments that are uploaded
-         * @return the step for sending the submission if the creating step was successful
+         * Sends the submission with a list of attachments
          *
-         * @throws ClientNotAuthenticated if the client is not authenticated
-         * @throws AttachmentUploadError if the upload failed
+         * @param attachments that are sent with the submission
+         * @return the step where additional data can be added to the submission
          */
-        SendSubmission uploadAttachments(List<Attachment> attachments);
+        WithData withAttachments(List<File> attachments);
     }
 
-    public interface CreateSubmission {
-        /**
-         * Creates and announces a new {@link Submission}
-         *
-         * @param submission the new {@link Submission} that should be created on server-side
-         * @return the step for upload the attachments if the creation was successful
-         */
-        AttachmentUpload createSubmission(Submission submission);
+    public interface WithData {
+
+        Submit withData(String data);
+
+        Submit withData(byte[] data);
+
+        SubmissionResponse submit();
     }
 
-    public interface SendSubmission {
-        /**
-         * Encrypts and uploads  the {@link Metadata} and {@link Data} and hands in the {@link Submission} at
-         * the defined destination-id.
-         *
-         * @param metaData the submissions {@link Metadata}
-         * @param data the submissions {@link Data}
-         *
-         * @return the finally uploaded and sent submission, empty if an error occurred
-         */
-        Optional<Submission> sendSubmission(Metadata metaData, Data data);
+    public interface Submit {
+        SubmissionResponse submit();
     }
 
-    public static class ClientBuilder implements Authenticate, AttachmentUpload, CreateSubmission, SendSubmission {
+    public static class ClientBuilder implements WithDestination, WithAttachments, WithData, Submit {
 
         private Sender sender;
-        private Optional<OAuthToken> token;
+        private final String clientId;
+        private final String secret;
 
-        private ClientBuilder(Sender sender) {
+        private UUID destinationId;
+        private Data data;
+        private List<Attachment> attachments;
+        private RSAKey encryptionKey;
+        private UUID submissionId;
+
+        public ClientBuilder(Sender sender, String clientId, String secret) {
             this.sender = sender;
+            this.clientId = clientId;
+            this.secret = secret;
+            authenticate();
         }
 
         @Override
-        public CreateSubmission authenticate(String clientId, String secret, String... scope) {
-            this.token = sender.retrieveOAuthToken(clientId, secret, scope);
-            checkIfAuthenticated();
+        public WithAttachments withDestination(UUID destinationId) {
+            final RSAKey encryptionKey = sender.getEncryptionKeyForDestination(destinationId);
+            final ValidationResult validationResult = sender.validatePublicKey(encryptionKey);
+            if(validationResult.hasErrors()){
+                throw new RuntimeException("Public encryption key is not valid");
+            }
+            this.encryptionKey = encryptionKey;
             return this;
         }
 
         @Override
-        public SendSubmission uploadAttachments(List<Attachment> attachments) {
+        public Submit withData(String data) {
+            return withData(data.getBytes(StandardCharsets.UTF_8));
+        }
+
+        @Override
+        public Submit withData(byte[] data) {
+            var unencryptedData = Data.builder().build();
+            final Optional<Data> encryptedData = sender.encryptSubmissionData(encryptionKey, unencryptedData);
+            if(encryptedData.isEmpty()){
+                throw new RuntimeException("Data could not be encrypted");
+            }
+            this.data = encryptedData.get();
             return this;
         }
 
         @Override
-        public AttachmentUpload createSubmission(Submission submission) {
+        public WithData withAttachments(List<File> attachmentFiles) {
+            final List<Attachment> attachments = readFilesToAttachments(attachmentFiles);
+            final SubmissionResponse createdSubmission = createSubmission(destinationId, attachments);
+            this.submissionId = createdSubmission.getSubmissionId();
+            final List<Attachment> encryptedAttachments = encryptAttachments(encryptionKey, attachments);
+            sender.uploadAttachments(submissionId, encryptedAttachments);
             return this;
         }
 
         @Override
-        public Optional<Submission> sendSubmission(Metadata metaData, Data data) {
-            throw new UnsupportedOperationException("not yet implemented");
+        public SubmissionResponse submit() {
+            final Optional<Metadata> metadata = getMetadata();
+            if(metadata.isEmpty()){
+                throw new RuntimeException("Metadata could not be created");
+            }
+            return sender.sendSubmission(submissionId, metadata.get()).orElseThrow();
+        }
+
+        private Optional<Metadata> getMetadata() {
+            return this.data == null ? sender.createMetadata(attachments) : sender.createMetadata(data, attachments);
+        }
+
+        private List<Attachment> encryptAttachments(RSAKey encryptionKey, List<Attachment> attachments) {
+            return attachments.stream().map(attachment -> encryptAttachment(encryptionKey, attachment)).collect(Collectors.toList());
+        }
+
+        private Attachment encryptAttachment(RSAKey encryptionKey, Attachment attachment) {
+            final Optional<Attachment> encryptedAttachment = sender.encryptAttachment(encryptionKey, attachment);
+            if (encryptedAttachment.isEmpty()) {
+                throw new RuntimeException("Attachment could not be encrypted");
+            }
+            return encryptedAttachment.get();
+        }
+
+        private SubmissionResponse createSubmission(UUID destinationId, List<Attachment> attachments) {
+            final SubmissionRequest request = SubmissionRequest.builder()
+                    .destinationId(destinationId)
+                    .announcedAttachments(asListOfAttachmentsIds(attachments))
+                    .build();
+
+            final Optional<SubmissionResponse> response = sender.createSubmission(request);
+            if (response.isEmpty()) {
+                throw new RuntimeException("Could not create submission");
+            }
+            return response.get();
+        }
+
+        private List<UUID> asListOfAttachmentsIds(List<Attachment> attachments) {
+            return attachments.stream().map(attachment -> attachment.getAttachmentId()).collect(Collectors.toList());
+        }
+
+        private void authenticate() {
+            final Optional<OAuthToken> oAuthToken = sender.retrieveOAuthToken(clientId, secret);
+            if (oAuthToken.isEmpty()) {
+                throw new ClientNotAuthenticated("Client is not authenticated, please authenticate first");
+            }
+        }
+
+        private List<Attachment> readFilesToAttachments(List<File> attachmentFiles) {
+            return attachmentFiles.stream()
+                    .map(this::readFileToAttachment)
+                    .collect(Collectors.toList());
         }
 
-        private void checkIfAuthenticated(){
-            if(this.token == null || this.token.isEmpty()){
-                throw new ClientNotAuthenticated("Not authenticated, please authenticate first");
+        private Attachment readFileToAttachment(File file) {
+            final Optional<Attachment> attachment = sender.createAttachment(file);
+            if(attachment.isEmpty()){
+                throw new RuntimeException("Attachment could not be created");
             }
+            return attachment.get();
         }
     }
 }
\ No newline at end of file
diff --git a/client/src/main/java/de/fitko/fitconnect/client/SubscriberClient.java b/client/src/main/java/de/fitko/fitconnect/client/SubscriberClient.java
index 7faaa4d010aa7250d6b113378d11ee3f13fc8d5f..62e74c2a9f91e10b162e2717a3f92837c357eeec 100644
--- a/client/src/main/java/de/fitko/fitconnect/client/SubscriberClient.java
+++ b/client/src/main/java/de/fitko/fitconnect/client/SubscriberClient.java
@@ -3,7 +3,7 @@ package de.fitko.fitconnect.client;
 import de.fitko.fitconnect.api.domain.auth.OAuthToken;
 import de.fitko.fitconnect.api.domain.model.metadata.Metadata;
 import de.fitko.fitconnect.api.domain.model.metadata.attachment.Attachment;
-import de.fitko.fitconnect.api.domain.model.submission.Submission;
+import de.fitko.fitconnect.api.domain.model.submission.SubmissionRequest;
 import de.fitko.fitconnect.api.services.Subscriber;
 
 import java.util.Collections;
@@ -28,8 +28,8 @@ public class SubscriberClient extends Client {
 
     public interface PollSubmissions {
 
-        List<Submission> getAvailableSubmissions(String destinationId);
-        RequestMetadata requestSubmission(Submission submission);
+        List<SubmissionRequest> getAvailableSubmissions(String destinationId);
+        RequestMetadata requestSubmission(SubmissionRequest submission);
     }
 
     public interface RequestMetadata {
@@ -45,7 +45,7 @@ public class SubscriberClient extends Client {
     }
 
     public interface AccessData {
-        Submission getSubmission();
+        SubmissionRequest getSubmission();
         List<Attachment> getAttachments();
         Metadata getMetadata();
     }
@@ -55,7 +55,7 @@ public class SubscriberClient extends Client {
 
         private final Subscriber subscriber;
 
-        private Optional<Submission> submission = Optional.empty();
+        private Optional<SubmissionRequest> submission = Optional.empty();
         private Optional<Metadata> metadata = Optional.empty();
         private List<Attachment> attachments = Collections.emptyList();
         private Optional<OAuthToken> token;
@@ -71,12 +71,12 @@ public class SubscriberClient extends Client {
         }
 
         @Override
-        public List<Submission> getAvailableSubmissions(String destinationId) {
+        public List<SubmissionRequest> getAvailableSubmissions(String destinationId) {
             throw new UnsupportedOperationException("not yet implemented");
         }
 
         @Override
-        public RequestMetadata requestSubmission(Submission submission) {
+        public RequestMetadata requestSubmission(SubmissionRequest submission) {
             throw new UnsupportedOperationException("not yet implemented");
         }
 
@@ -97,7 +97,7 @@ public class SubscriberClient extends Client {
         }
 
         @Override
-        public Submission getSubmission() {
+        public SubmissionRequest getSubmission() {
             return this.submission.orElseThrow();
         }
 
diff --git a/client/src/main/java/de/fitko/fitconnect/cmd/CommandLineRunner.java b/client/src/main/java/de/fitko/fitconnect/cmd/CommandLineRunner.java
index fae9f0351ea151ab3edd74dbfa3c2cbefe3e1d9d..b95103262b9428d273362e11826d23b86e8cdecb 100644
--- a/client/src/main/java/de/fitko/fitconnect/cmd/CommandLineRunner.java
+++ b/client/src/main/java/de/fitko/fitconnect/cmd/CommandLineRunner.java
@@ -1,9 +1,6 @@
 package de.fitko.fitconnect.cmd;
 
 import com.beust.jcommander.JCommander;
-import de.fitko.fitconnect.client.SenderClient;
-
-import java.util.Optional;
 
 public class CommandLineRunner {
 
@@ -20,8 +17,7 @@ public class CommandLineRunner {
         var secret = cmdArgs.secret;
 
         // sample high -level- api calls to send a submission
-        SenderClient.builder()
-                .authenticate(clientId, secret);
+        //SenderClient.builder().authenticate(clientId, secret);
 
     }
 }
diff --git a/impl/src/main/java/de/fitko/fitconnect/impl/SubmissionSender.java b/impl/src/main/java/de/fitko/fitconnect/impl/SubmissionSender.java
index ed9e91748a69de8353db33ee764382b345557cf8..13ca5ab2493852ca9606c72aa5dcf8a1a685ad9a 100644
--- a/impl/src/main/java/de/fitko/fitconnect/impl/SubmissionSender.java
+++ b/impl/src/main/java/de/fitko/fitconnect/impl/SubmissionSender.java
@@ -5,8 +5,11 @@ import com.nimbusds.jose.jwk.RSAKey;
 import de.fitko.fitconnect.api.domain.auth.OAuthToken;
 import de.fitko.fitconnect.api.domain.model.metadata.Metadata;
 import de.fitko.fitconnect.api.domain.model.metadata.attachment.Attachment;
+import de.fitko.fitconnect.api.domain.model.metadata.attachment.signature.Hash__1;
+import de.fitko.fitconnect.api.domain.model.metadata.attachment.signature.Type;
 import de.fitko.fitconnect.api.domain.model.metadata.data.Data;
-import de.fitko.fitconnect.api.domain.model.submission.Submission;
+import de.fitko.fitconnect.api.domain.model.submission.SubmissionRequest;
+import de.fitko.fitconnect.api.domain.model.submission.SubmissionResponse;
 import de.fitko.fitconnect.api.domain.validation.ValidationResult;
 import de.fitko.fitconnect.api.exceptions.internal.AuthenticationException;
 import de.fitko.fitconnect.api.services.Sender;
@@ -14,11 +17,15 @@ import de.fitko.fitconnect.api.services.auth.OAuthService;
 import de.fitko.fitconnect.api.services.crypto.CryptoService;
 import de.fitko.fitconnect.api.services.metadata.MetadataService;
 import de.fitko.fitconnect.api.services.validation.CertificateValidator;
+import de.fitko.fitconnect.impl.crypto.HashUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.io.File;
+import java.io.IOException;
 import java.util.List;
 import java.util.Optional;
+import java.util.UUID;
 
 public class SubmissionSender implements Sender {
 
@@ -29,6 +36,8 @@ public class SubmissionSender implements Sender {
     private final CryptoService cryptoService;
     private final MetadataService metadataService;
 
+    private HashUtil hashUtil = new HashUtil();
+
     @Inject
     public SubmissionSender(final OAuthService authService,
                             final CryptoService encryptionService,
@@ -74,12 +83,46 @@ public class SubmissionSender implements Sender {
     }
 
     @Override
-    public Optional<Submission> createSubmission(Submission submission) {
+    public Optional<Metadata> createMetadata(List<Attachment> attachments) {
+        throw new UnsupportedOperationException("not yet implemented");
+    }
+
+    @Override
+    public Optional<SubmissionResponse> createSubmission(SubmissionRequest submission) {
+        throw new UnsupportedOperationException("not yet implemented");
+    }
+
+    @Override
+    public Optional<SubmissionResponse> sendSubmission(UUID submissionId, Metadata encryptedMetadata) {
+        throw new UnsupportedOperationException("not yet implemented");
+    }
+
+    @Override
+    public void uploadAttachments(UUID submissionId, List<Attachment> encryptedAttachments) {
         throw new UnsupportedOperationException("not yet implemented");
     }
 
     @Override
-    public Optional<Submission> sendSubmission(String submissionId, Metadata metadata) {
+    public Optional<Attachment> createAttachment(File file) {
+        try {
+            String hashedFileContent = hashUtil.createHashFromFile(file);
+            Hash__1 hash = new Hash__1();
+            hash.setType(Type.SHA_512);
+            hash.setContent(hashedFileContent);
+            return Optional.ofNullable(Attachment.builder()
+                    .attachmentId(UUID.randomUUID())
+                    .filename(file.getName())
+                    .hash(hash)
+                    .build());
+        } catch (IOException e) {
+            logger.error("Attachment could not be read", e);
+            return Optional.empty();
+        }
+    }
+
+    @Override
+    public RSAKey getEncryptionKeyForDestination(UUID destinationId) {
         throw new UnsupportedOperationException("not yet implemented");
     }
+
 }
diff --git a/impl/src/main/java/de/fitko/fitconnect/impl/SubmissionSubscriber.java b/impl/src/main/java/de/fitko/fitconnect/impl/SubmissionSubscriber.java
index 2faf8217edef9151072004dc7e32ac0f744d5733..0a672df5a04b4f7123312aae6aea005bc0fadcad 100644
--- a/impl/src/main/java/de/fitko/fitconnect/impl/SubmissionSubscriber.java
+++ b/impl/src/main/java/de/fitko/fitconnect/impl/SubmissionSubscriber.java
@@ -7,7 +7,7 @@ import de.fitko.fitconnect.api.domain.model.metadata.Metadata;
 import de.fitko.fitconnect.api.domain.model.metadata.attachment.Attachment;
 import de.fitko.fitconnect.api.domain.model.metadata.data.Data;
 import de.fitko.fitconnect.api.domain.model.event.SecurityEventToken;
-import de.fitko.fitconnect.api.domain.model.submission.Submission;
+import de.fitko.fitconnect.api.domain.model.submission.SubmissionRequest;
 import de.fitko.fitconnect.api.domain.validation.ValidationResult;
 import de.fitko.fitconnect.api.exceptions.internal.AuthenticationException;
 import de.fitko.fitconnect.api.services.Subscriber;
@@ -69,12 +69,12 @@ public class SubmissionSubscriber implements Subscriber {
     }
 
     @Override
-    public List<Submission> pollAvailableSubmissions(String destinationId, int limit, int offset) {
+    public List<SubmissionRequest> pollAvailableSubmissions(String destinationId, int limit, int offset) {
         throw new UnsupportedOperationException("not yet implemented");
     }
 
     @Override
-    public Optional<Submission> getSubmission(String submissionId) {
+    public Optional<SubmissionRequest> getSubmission(String submissionId) {
         throw new UnsupportedOperationException("not yet implemented");
     }
 
diff --git a/impl/src/main/java/de/fitko/fitconnect/impl/auth/DefaultOAuthService.java b/impl/src/main/java/de/fitko/fitconnect/impl/auth/DefaultOAuthService.java
index 754a71de438f944d4b29ef7d739e044c26ee8b12..b73ac916d8d03779410e728407ebc5550eda78c5 100644
--- a/impl/src/main/java/de/fitko/fitconnect/impl/auth/DefaultOAuthService.java
+++ b/impl/src/main/java/de/fitko/fitconnect/impl/auth/DefaultOAuthService.java
@@ -1,5 +1,7 @@
 package de.fitko.fitconnect.impl.auth;
 
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
 import de.fitko.fitconnect.api.domain.auth.OAuthToken;
 import de.fitko.fitconnect.api.exceptions.internal.AuthenticationException;
 import de.fitko.fitconnect.api.services.auth.OAuthService;
@@ -11,7 +13,6 @@ import org.springframework.web.client.RestClientException;
 import org.springframework.web.client.RestTemplate;
 
 import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
@@ -23,7 +24,8 @@ public class DefaultOAuthService implements OAuthService {
     private final RestTemplate restTemplate;
     private final String tokenUrl;
 
-    public DefaultOAuthService(final RestTemplate restTemplate, final String tokenUrl) {
+    @Inject
+    public DefaultOAuthService(final RestTemplate restTemplate, @Named("authTokenUrl") String tokenUrl) {
         this.restTemplate = restTemplate;
         this.tokenUrl = tokenUrl;
     }
diff --git a/impl/src/main/java/de/fitko/fitconnect/impl/validation/MetadataSubmissionValidator.java b/impl/src/main/java/de/fitko/fitconnect/impl/validation/MetadataSubmissionValidator.java
index f4bfcaa5b4b481fcaa459acf016da478da0efc70..c07dd4697b3065cfe38ebf0245ab331739273c7f 100644
--- a/impl/src/main/java/de/fitko/fitconnect/impl/validation/MetadataSubmissionValidator.java
+++ b/impl/src/main/java/de/fitko/fitconnect/impl/validation/MetadataSubmissionValidator.java
@@ -5,7 +5,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 import de.fitko.fitconnect.api.domain.model.metadata.Metadata;
 import de.fitko.fitconnect.api.services.validation.MetadataValidator;
 import de.fitko.fitconnect.api.domain.validation.ValidationResult;
-import de.fitko.fitconnect.impl.crypto.MetadataVerifier;
+import de.fitko.fitconnect.impl.crypto.HashUtil;
 import org.everit.json.schema.Schema;
 import org.everit.json.schema.ValidationException;
 import org.everit.json.schema.loader.SchemaLoader;
@@ -15,7 +15,7 @@ import org.json.JSONTokener;
 public class MetadataSubmissionValidator implements MetadataValidator {
 
     public static final String DEFAULT_SCHEMA_PATH = "schemas/metadata.schema.json";
-    private static final MetadataVerifier verifier = new MetadataVerifier();
+    private static final HashUtil verifier = new HashUtil();
     private final ObjectMapper mapper = new ObjectMapper();
 
     @Override