diff --git a/api/src/main/java/dev/fitko/fitconnect/api/config/SchemaConfig.java b/api/src/main/java/dev/fitko/fitconnect/api/config/SchemaConfig.java
index eeffbfb7dce1506b1c6af3e8229df2183f644955..e5dd7541f2a8787a098e40222765c5fe48d8c62b 100644
--- a/api/src/main/java/dev/fitko/fitconnect/api/config/SchemaConfig.java
+++ b/api/src/main/java/dev/fitko/fitconnect/api/config/SchemaConfig.java
@@ -15,7 +15,6 @@ public enum SchemaConfig {
     SET_V_1_0_1(SCHEMA_BASE_URL.schemaUri.resolve("set-payload/1.0.1/set-payload.schema.json"), "set_schema_1.0.1.json"),
     SET_V_1_0_0(SCHEMA_BASE_URL.schemaUri.resolve("set-payload/1.0.0/set-payload.schema.json"), "set_schema_1.0.0.json"),
     METADATA_V_1_0_0(SCHEMA_BASE_URL.schemaUri.resolve("metadata/1.0.0/metadata.schema.json"), "metadata_schema_1.0.0.json"),
-
     XZUFI_DESTINATION_SCHEMA(SCHEMA_BASE_URL.schemaUri.resolve("xzufi/destination.schema.json"), "destination_schema.json");
 
     private final URI schemaUri;
@@ -50,6 +49,12 @@ public enum SchemaConfig {
                 .collect(Collectors.toList());
     }
 
+    public static List<String> getSubmissionDataSchemaPaths(final String submissionDataSchemaBaseDir) {
+        return Stream.empty()
+                .map(fileName -> submissionDataSchemaBaseDir + "/" + fileName)
+                .collect(Collectors.toList());
+    }
+
     @Override
     public String toString() {
         return schemaUri.toString();
diff --git a/api/src/main/java/dev/fitko/fitconnect/api/domain/schema/SchemaResources.java b/api/src/main/java/dev/fitko/fitconnect/api/domain/schema/SchemaResources.java
index 022b164a45561ce5305734532cc14a518787625f..f64692e175cced47719ca2fca139d4bd8edbc106 100644
--- a/api/src/main/java/dev/fitko/fitconnect/api/domain/schema/SchemaResources.java
+++ b/api/src/main/java/dev/fitko/fitconnect/api/domain/schema/SchemaResources.java
@@ -10,4 +10,5 @@ public class SchemaResources {
     List<String> setSchemaPaths;
     List<String> metadataSchemaPaths;
     List<String> destinationSchemaPaths;
+    List<String> submissionDataSchemaPaths;
 }
diff --git a/api/src/main/java/dev/fitko/fitconnect/api/services/Sender.java b/api/src/main/java/dev/fitko/fitconnect/api/services/Sender.java
index ecee117fa17047f292f00b3e1fb7920b3eda226d..a0201739d0aea68d919757e293beec7f13a9725c 100644
--- a/api/src/main/java/dev/fitko/fitconnect/api/services/Sender.java
+++ b/api/src/main/java/dev/fitko/fitconnect/api/services/Sender.java
@@ -12,6 +12,7 @@ import dev.fitko.fitconnect.api.domain.model.submission.*;
 import dev.fitko.fitconnect.api.domain.validation.ValidationResult;
 import dev.fitko.fitconnect.api.exceptions.*;
 
+import java.net.URI;
 import java.util.List;
 import java.util.UUID;
 
@@ -140,10 +141,11 @@ public interface Sender {
      * Tests if a given string is well-formed JSON syntax.
      *
      * @param json json string that is tested
+     * @param schemaUri URI of schema to validate against
      *
      * @return a {@link ValidationResult} with an optional error
      */
-    ValidationResult validateJsonFormat(SubmissionPayload json);
+    ValidationResult validateJsonFormat(String json, URI schemaUri);
 
     /**
      * Tests if a given string is well-formed XML syntax.
diff --git a/api/src/main/java/dev/fitko/fitconnect/api/services/validation/ValidationService.java b/api/src/main/java/dev/fitko/fitconnect/api/services/validation/ValidationService.java
index c5d747b3f9e54e225c6f9ef0d55aad86628c4f4d..99057bf38655458ec9ec8d8206ed768545854f38 100644
--- a/api/src/main/java/dev/fitko/fitconnect/api/services/validation/ValidationService.java
+++ b/api/src/main/java/dev/fitko/fitconnect/api/services/validation/ValidationService.java
@@ -4,6 +4,7 @@ import com.nimbusds.jose.jwk.RSAKey;
 import dev.fitko.fitconnect.api.domain.model.metadata.Metadata;
 import dev.fitko.fitconnect.api.domain.validation.ValidationResult;
 
+import java.net.URI;
 import java.util.Map;
 
 /**
@@ -77,10 +78,11 @@ public interface ValidationService {
      * Tests if a given string is well-formed JSON syntax.
      *
      * @param json json string that is tested
+     * @param schemaUri URI of schema to validate against
      *
      * @return a {@link ValidationResult} with an optional error
      */
-    ValidationResult validateJsonFormat(String json);
+    ValidationResult validateJsonFormat(String json, URI schemaUri);
 
     /**
      * Tests if a given string is well-formed XML syntax.
diff --git a/client/src/main/java/dev/fitko/fitconnect/client/SenderClient.java b/client/src/main/java/dev/fitko/fitconnect/client/SenderClient.java
index 4970c09efeaadfca5460fc50842b53ec26feed76..523193e4379bd075df2c4a7e5dd5a517df80fe79 100644
--- a/client/src/main/java/dev/fitko/fitconnect/client/SenderClient.java
+++ b/client/src/main/java/dev/fitko/fitconnect/client/SenderClient.java
@@ -11,7 +11,7 @@ import dev.fitko.fitconnect.api.domain.model.submission.SubmitSubmission;
 import dev.fitko.fitconnect.api.domain.validation.ValidationResult;
 import dev.fitko.fitconnect.api.services.Sender;
 import dev.fitko.fitconnect.client.sender.model.EncryptedSubmissionPayload;
-import dev.fitko.fitconnect.api.domain.model.submission.SubmissionPayload;
+import dev.fitko.fitconnect.client.sender.model.SubmissionPayload;
 import dev.fitko.fitconnect.client.sender.strategies.SendEncryptedSubmissionStrategy;
 import dev.fitko.fitconnect.client.sender.strategies.SendNewSubmissionStrategy;
 import dev.fitko.fitconnect.client.util.ValidDataGuard;
diff --git a/client/src/main/java/dev/fitko/fitconnect/client/cli/CommandExecutor.java b/client/src/main/java/dev/fitko/fitconnect/client/cli/CommandExecutor.java
index c3f6b15ce439c9f7ef7960bc035cb002be5f8ca7..7410ce89e10fa6bf8d10e83ffdd5bf56e590eea4 100644
--- a/client/src/main/java/dev/fitko/fitconnect/client/cli/CommandExecutor.java
+++ b/client/src/main/java/dev/fitko/fitconnect/client/cli/CommandExecutor.java
@@ -10,7 +10,7 @@ import dev.fitko.fitconnect.client.cli.batch.ImportRecord;
 import dev.fitko.fitconnect.client.cli.commands.*;
 import dev.fitko.fitconnect.client.cli.util.AttachmentDataType;
 import dev.fitko.fitconnect.client.sender.SubmissionBuilder;
-import dev.fitko.fitconnect.api.domain.model.submission.SubmissionPayload;
+import dev.fitko.fitconnect.client.sender.model.SubmissionPayload;
 import dev.fitko.fitconnect.client.subscriber.ReceivedSubmission;
 import dev.fitko.fitconnect.client.subscriber.model.ReceivedAttachment;
 import dev.fitko.fitconnect.core.util.StopWatch;
diff --git a/client/src/main/java/dev/fitko/fitconnect/client/factory/ClientFactory.java b/client/src/main/java/dev/fitko/fitconnect/client/factory/ClientFactory.java
index cfdd4ee6d739976c8ef678ef0ca8c09470575669..24eff7a4a2621a0b10291a9b9793c445cbf52a34 100644
--- a/client/src/main/java/dev/fitko/fitconnect/client/factory/ClientFactory.java
+++ b/client/src/main/java/dev/fitko/fitconnect/client/factory/ClientFactory.java
@@ -59,9 +59,9 @@ public final class ClientFactory {
 
     private static final String CONFIG_ENV_KEY_NAME = "FIT_CONNECT_CONFIG";
     private static final String SET_SCHEMA_DIR = "/set-schema";
-
     private static final String DESTINATION_SCHEMA_DIR = "/destination-schema";
     private static final String METADATA_SCHEMA_DIR = "/metadata-schema";
+    private static final String SUBMISSION_DATA_SCHEMA_DIR = "/submission-data-schema";
 
     private ClientFactory() {
     }
@@ -129,7 +129,7 @@ public final class ClientFactory {
     public static RoutingClient routingClient(final ApplicationConfig config) {
         LOGGER.info("Initializing routing client ...");
         final RestTemplate restTemplate = getRestTemplate(config, ApplicationConfigLoader.loadBuildInfo());
-        final SchemaProvider schemaProvider = getSchemaProvider();
+        final SchemaProvider schemaProvider = getSchemaProvider(restTemplate);
         final OAuthService authService = getSenderConfiguredAuthService(config, restTemplate);
 
         final MessageDigestService messageDigestService = getMessageDigestService();
@@ -145,7 +145,7 @@ public final class ClientFactory {
 
     private static Sender getSender(final ApplicationConfig config, final BuildInfo buildInfo) {
         final RestTemplate restTemplate = getRestTemplate(config, buildInfo);
-        final SchemaProvider schemaProvider = getSchemaProvider();
+        final SchemaProvider schemaProvider = getSchemaProvider(restTemplate);
         final MessageDigestService messageDigestService = getMessageDigestService();
 
         final CryptoService cryptoService = getCryptoService(messageDigestService);
@@ -162,7 +162,7 @@ public final class ClientFactory {
 
     private static Subscriber getSubscriber(final ApplicationConfig config, final BuildInfo buildInfo) {
         final RestTemplate restTemplate = getRestTemplate(config, buildInfo);
-        final SchemaProvider schemaProvider = getSchemaProvider();
+        final SchemaProvider schemaProvider = getSchemaProvider(restTemplate);
         final MessageDigestService messageDigestService = getMessageDigestService();
 
         final CryptoService cryptoService = getCryptoService(messageDigestService);
@@ -231,12 +231,13 @@ public final class ClientFactory {
         return new EventLogVerifier(keyService, validationService);
     }
 
-    private static SchemaProvider getSchemaProvider() {
+    private static SchemaProvider getSchemaProvider(RestTemplate restTemplate) {
         final List<String> setSchemaFiles = SchemaConfig.getSetSchemaFilePaths(SET_SCHEMA_DIR);
         final List<String> metadataSchemaFiles = SchemaConfig.getMetadataSchemaFileNames(METADATA_SCHEMA_DIR);
         final List<String> destinationSchemaFiles = SchemaConfig.getDestinationSchemaPaths(DESTINATION_SCHEMA_DIR);
-        final SchemaResources schemaResources = new SchemaResources(setSchemaFiles, metadataSchemaFiles, destinationSchemaFiles);
-        return new SchemaResourceProvider(schemaResources);
+        final List<String> submissionDataSchemaFiles = SchemaConfig.getSubmissionDataSchemaPaths(SUBMISSION_DATA_SCHEMA_DIR);
+        final SchemaResources schemaResources = new SchemaResources(setSchemaFiles, metadataSchemaFiles, destinationSchemaFiles, submissionDataSchemaFiles);
+        return new SchemaResourceProvider(restTemplate, schemaResources);
     }
 
     private static RoutingService getRoutingService(final ApplicationConfig config, final RestTemplate restTemplate) {
diff --git a/client/src/main/java/dev/fitko/fitconnect/client/sender/SubmissionBuilder.java b/client/src/main/java/dev/fitko/fitconnect/client/sender/SubmissionBuilder.java
index 4298f643133ce5c5c7be0c50fa2c432e4b2710e3..89a55fd239a0adeacc5dfba66fa45a9ee5b4fa20 100644
--- a/client/src/main/java/dev/fitko/fitconnect/client/sender/SubmissionBuilder.java
+++ b/client/src/main/java/dev/fitko/fitconnect/client/sender/SubmissionBuilder.java
@@ -2,7 +2,7 @@ package dev.fitko.fitconnect.client.sender;
 
 import dev.fitko.fitconnect.api.domain.model.metadata.data.MimeType;
 import dev.fitko.fitconnect.api.domain.model.submission.ServiceType;
-import dev.fitko.fitconnect.api.domain.model.submission.SubmissionPayload;
+import dev.fitko.fitconnect.client.sender.model.SubmissionPayload;
 import dev.fitko.fitconnect.client.sender.steps.*;
 import lombok.Getter;
 import org.slf4j.Logger;
diff --git a/api/src/main/java/dev/fitko/fitconnect/api/domain/model/submission/SubmissionPayload.java b/client/src/main/java/dev/fitko/fitconnect/client/sender/model/SubmissionPayload.java
similarity index 94%
rename from api/src/main/java/dev/fitko/fitconnect/api/domain/model/submission/SubmissionPayload.java
rename to client/src/main/java/dev/fitko/fitconnect/client/sender/model/SubmissionPayload.java
index f276501e0bf62ef7701597c29323d932915f53da..fc7956049bd99f805db90ea84834cf161cf16337 100644
--- a/api/src/main/java/dev/fitko/fitconnect/api/domain/model/submission/SubmissionPayload.java
+++ b/client/src/main/java/dev/fitko/fitconnect/client/sender/model/SubmissionPayload.java
@@ -1,4 +1,4 @@
-package dev.fitko.fitconnect.api.domain.model.submission;
+package dev.fitko.fitconnect.client.sender.model;
 
 import dev.fitko.fitconnect.api.domain.model.metadata.data.MimeType;
 import dev.fitko.fitconnect.api.domain.model.submission.ServiceType;
diff --git a/client/src/main/java/dev/fitko/fitconnect/client/sender/steps/BuildStep.java b/client/src/main/java/dev/fitko/fitconnect/client/sender/steps/BuildStep.java
index a5e1defc933ba7038bdb38f17c4b84c094ce9d7d..2ecd116d6e5616c808a692fbddb98fd894ea178b 100644
--- a/client/src/main/java/dev/fitko/fitconnect/client/sender/steps/BuildStep.java
+++ b/client/src/main/java/dev/fitko/fitconnect/client/sender/steps/BuildStep.java
@@ -1,6 +1,6 @@
 package dev.fitko.fitconnect.client.sender.steps;
 
-import dev.fitko.fitconnect.api.domain.model.submission.SubmissionPayload;
+import dev.fitko.fitconnect.client.sender.model.SubmissionPayload;
 
 public interface BuildStep {
 
diff --git a/client/src/main/java/dev/fitko/fitconnect/client/sender/strategies/SendNewSubmissionStrategy.java b/client/src/main/java/dev/fitko/fitconnect/client/sender/strategies/SendNewSubmissionStrategy.java
index fbe3e33e1628ff8d888c0da90a72749e3f0bcc6f..664109153eb409b19e28c53657b6bb46f6cad3e0 100644
--- a/client/src/main/java/dev/fitko/fitconnect/client/sender/strategies/SendNewSubmissionStrategy.java
+++ b/client/src/main/java/dev/fitko/fitconnect/client/sender/strategies/SendNewSubmissionStrategy.java
@@ -2,6 +2,7 @@ package dev.fitko.fitconnect.client.sender.strategies;
 
 import com.nimbusds.jose.jwk.RSAKey;
 import dev.fitko.fitconnect.api.domain.model.destination.Destination;
+import dev.fitko.fitconnect.api.domain.model.destination.DestinationService;
 import dev.fitko.fitconnect.api.domain.model.metadata.ContentStructure;
 import dev.fitko.fitconnect.api.domain.model.metadata.Hash;
 import dev.fitko.fitconnect.api.domain.model.metadata.Metadata;
@@ -27,7 +28,7 @@ import dev.fitko.fitconnect.api.exceptions.SchemaNotFoundException;
 import dev.fitko.fitconnect.api.exceptions.SubmissionNotCreatedException;
 import dev.fitko.fitconnect.api.services.Sender;
 import dev.fitko.fitconnect.client.sender.model.AttachmentPayload;
-import dev.fitko.fitconnect.api.domain.model.submission.SubmissionPayload;
+import dev.fitko.fitconnect.client.sender.model.SubmissionPayload;
 import dev.fitko.fitconnect.core.util.StopWatch;
 import org.apache.tika.Tika;
 import org.slf4j.Logger;
@@ -40,6 +41,7 @@ import java.net.URLConnection;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Paths;
+import java.util.Collection;
 import java.util.List;
 import java.util.Objects;
 import java.util.UUID;
diff --git a/client/src/main/java/dev/fitko/fitconnect/client/util/ValidDataGuard.java b/client/src/main/java/dev/fitko/fitconnect/client/util/ValidDataGuard.java
index 0e15340daa25242c9d25b35e215f21aa0f8a2d79..12491f857bbff1a0fb2b8da53145f57925d44cc1 100644
--- a/client/src/main/java/dev/fitko/fitconnect/client/util/ValidDataGuard.java
+++ b/client/src/main/java/dev/fitko/fitconnect/client/util/ValidDataGuard.java
@@ -7,7 +7,7 @@ import dev.fitko.fitconnect.api.domain.model.submission.ServiceType;
 import dev.fitko.fitconnect.api.domain.validation.ValidationResult;
 import dev.fitko.fitconnect.api.services.Sender;
 import dev.fitko.fitconnect.client.sender.model.EncryptedSubmissionPayload;
-import dev.fitko.fitconnect.api.domain.model.submission.SubmissionPayload;
+import dev.fitko.fitconnect.client.sender.model.SubmissionPayload;
 
 import java.net.URI;
 import java.util.Objects;
@@ -136,7 +136,7 @@ public class ValidDataGuard {
     }
 
     private void checkJsonFormat(final SubmissionPayload submissionPayload) {
-        final ValidationResult validationResult = sender.validateJsonFormat(submissionPayload.getData());
+        final ValidationResult validationResult = sender.validateJsonFormat(submissionPayload.getData(), submissionPayload.getSchemaUri());
         if (validationResult.hasError()) {
             throw new IllegalArgumentException("Data is not in expected json format, please provide valid json: " + validationResult.getError().getMessage());
         }
diff --git a/client/src/test/java/dev/fitko/fitconnect/client/SenderClientTest.java b/client/src/test/java/dev/fitko/fitconnect/client/SenderClientTest.java
index 3ae0ca490f445fb370a766d18700b1be36be78e6..a7ef9d0a2ec8cc3b58bf5b5fd5cf81f62ceb9a52 100644
--- a/client/src/test/java/dev/fitko/fitconnect/client/SenderClientTest.java
+++ b/client/src/test/java/dev/fitko/fitconnect/client/SenderClientTest.java
@@ -23,7 +23,7 @@ import dev.fitko.fitconnect.api.services.Sender;
 import dev.fitko.fitconnect.client.sender.EncryptedSubmissionBuilder;
 import dev.fitko.fitconnect.client.sender.SubmissionBuilder;
 import dev.fitko.fitconnect.client.sender.model.EncryptedSubmissionPayload;
-import dev.fitko.fitconnect.api.domain.model.submission.SubmissionPayload;
+import dev.fitko.fitconnect.client.sender.model.SubmissionPayload;
 import dev.fitko.fitconnect.client.testutil.LogCaptor;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
@@ -77,7 +77,7 @@ public class SenderClientTest {
         when(senderMock.sendSubmission(any())).thenReturn(expectedSubmission);
         when(senderMock.validatePublicKey(any())).thenReturn(ValidationResult.ok());
         when(senderMock.getEncryptionKeyForDestination(any())).thenReturn(publicKey);
-        when(senderMock.validateJsonFormat(any())).thenReturn(ValidationResult.ok());
+        when(senderMock.validateJsonFormat(any(), URI.create("urn:something"))).thenReturn(ValidationResult.ok());
         when(senderMock.validateMetadata(any())).thenReturn(ValidationResult.ok());
 
 
@@ -182,7 +182,7 @@ public class SenderClientTest {
         when(senderMock.getDestination(any())).thenReturn(destination);
         when(senderMock.createSubmission(any())).thenReturn(announcedSubmission);
         when(senderMock.validatePublicKey(any())).thenReturn(ValidationResult.ok());
-        when(senderMock.validateJsonFormat(any())).thenReturn(ValidationResult.ok());
+        when(senderMock.validateJsonFormat(any(), URI.create("urn:something"))).thenReturn(ValidationResult.ok());
         when(senderMock.getEncryptionKeyForDestination(any())).thenReturn(publicKey);
 
         // When
@@ -513,7 +513,7 @@ public class SenderClientTest {
         when(senderMock.getEncryptionKeyForDestination(any())).thenReturn(publicKey);
         when(senderMock.validateMetadata(any())).thenReturn(ValidationResult.ok());
         when(senderMock.validateXmlFormat(any())).thenReturn(ValidationResult.ok());
-        when(senderMock.validateJsonFormat(any())).thenReturn(ValidationResult.ok());
+        when(senderMock.validateJsonFormat(any(), URI.create("urn:something"))).thenReturn(ValidationResult.ok());
         when(senderMock.sendSubmission(any())).thenReturn(new Submission());
 
         return destinationId;
diff --git a/client/src/test/java/dev/fitko/fitconnect/client/cli/CommandLineClientTest.java b/client/src/test/java/dev/fitko/fitconnect/client/cli/CommandLineClientTest.java
index ae4a9f465b0ad7f942f6b3bb2d7f825ae00456f1..61e54c21aca6754a05348568d776afe5dc1b1802 100644
--- a/client/src/test/java/dev/fitko/fitconnect/client/cli/CommandLineClientTest.java
+++ b/client/src/test/java/dev/fitko/fitconnect/client/cli/CommandLineClientTest.java
@@ -11,7 +11,7 @@ import dev.fitko.fitconnect.client.SubscriberClient;
 import dev.fitko.fitconnect.client.cli.batch.CsvImporter;
 import dev.fitko.fitconnect.client.cli.batch.ImportRecord;
 import dev.fitko.fitconnect.client.sender.model.EncryptedSubmissionPayload;
-import dev.fitko.fitconnect.api.domain.model.submission.SubmissionPayload;
+import dev.fitko.fitconnect.client.sender.model.SubmissionPayload;
 import dev.fitko.fitconnect.client.subscriber.ReceivedSubmission;
 import dev.fitko.fitconnect.client.subscriber.model.ReceivedAttachment;
 import dev.fitko.fitconnect.client.subscriber.model.ReceivedData;
diff --git a/client/src/test/java/dev/fitko/fitconnect/client/util/ValidDataGuardTest.java b/client/src/test/java/dev/fitko/fitconnect/client/util/ValidDataGuardTest.java
index a3e1453fe975257bd64cef25767de302dc07f170..ef356cb038f5576a41b9be92f44563ac84abf238 100644
--- a/client/src/test/java/dev/fitko/fitconnect/client/util/ValidDataGuardTest.java
+++ b/client/src/test/java/dev/fitko/fitconnect/client/util/ValidDataGuardTest.java
@@ -9,7 +9,7 @@ import dev.fitko.fitconnect.api.services.Sender;
 import dev.fitko.fitconnect.client.sender.EncryptedSubmissionBuilder;
 import dev.fitko.fitconnect.client.sender.SubmissionBuilder;
 import dev.fitko.fitconnect.client.sender.model.EncryptedSubmissionPayload;
-import dev.fitko.fitconnect.api.domain.model.submission.SubmissionPayload;
+import dev.fitko.fitconnect.client.sender.model.SubmissionPayload;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
@@ -56,7 +56,7 @@ class ValidDataGuardTest {
             destination.setServices(Set.of(service));
 
             when(senderMock.getDestination(any())).thenReturn(destination);
-            when(senderMock.validateJsonFormat(any())).thenReturn(ValidationResult.ok());
+            when(senderMock.validateJsonFormat(any(), URI.create("urn:something"))).thenReturn(ValidationResult.ok());
 
             final SubmissionPayload submissionPayload = SubmissionBuilder.Builder()
                     .withJsonData("\"test\": \"json\"",
@@ -107,7 +107,7 @@ class ValidDataGuardTest {
         void testMissingDestinationId() {
 
             // Given
-            when(senderMock.validateJsonFormat(any())).thenReturn(ValidationResult.ok());
+            when(senderMock.validateJsonFormat(any(), URI.create("urn:something"))).thenReturn(ValidationResult.ok());
 
             final SubmissionPayload submissionPayload = SubmissionBuilder.Builder()
                     .withJsonData("{}", URI.create("https://schema.fitko.de/fim/s00000000009_1.0.0.schema.json"))
@@ -126,7 +126,7 @@ class ValidDataGuardTest {
         void testInvalidServiceIdentifier() {
 
             // Given
-            when(senderMock.validateJsonFormat(any())).thenReturn(ValidationResult.ok());
+            when(senderMock.validateJsonFormat(any(), URI.create("urn:something"))).thenReturn(ValidationResult.ok());
 
             final SubmissionPayload submissionPayload = SubmissionBuilder.Builder()
                     .withJsonData("{\"test\" . \"data\"}",
@@ -145,7 +145,7 @@ class ValidDataGuardTest {
         void testMissingServiceIdentifier() {
 
             // Given
-            when(senderMock.validateJsonFormat(any())).thenReturn(ValidationResult.ok());
+            when(senderMock.validateJsonFormat(any(), URI.create("urn:something"))).thenReturn(ValidationResult.ok());
 
             final SubmissionPayload submissionPayload = SubmissionBuilder.Builder()
                     .withJsonData("{\"test\" . \"data\"}",
@@ -171,7 +171,7 @@ class ValidDataGuardTest {
             destination.setServices(Set.of(service));
 
             when(senderMock.getDestination(any())).thenReturn(destination);
-            when(senderMock.validateJsonFormat(any())).thenReturn(ValidationResult.ok());
+            when(senderMock.validateJsonFormat(any(), URI.create("urn:something"))).thenReturn(ValidationResult.ok());
 
             final SubmissionPayload submissionPayload = SubmissionBuilder.Builder()
                     .withJsonData("\"test\": \"json\"",
@@ -202,7 +202,7 @@ class ValidDataGuardTest {
             destination.setServices(Set.of(service));
 
             when(senderMock.getDestination(any())).thenReturn(destination);
-            when(senderMock.validateJsonFormat(any())).thenReturn(ValidationResult.ok());
+            when(senderMock.validateJsonFormat(any(), URI.create("urn:something"))).thenReturn(ValidationResult.ok());
 
             final SubmissionPayload submissionPayload = SubmissionBuilder.Builder()
                     .withJsonData("\"test\": \"json\"",
@@ -234,7 +234,7 @@ class ValidDataGuardTest {
             destination.setServices(Set.of(service));
 
             when(senderMock.getDestination(any())).thenReturn(destination);
-            when(senderMock.validateJsonFormat(any())).thenReturn(ValidationResult.ok());
+            when(senderMock.validateJsonFormat(any(), URI.create("urn:something"))).thenReturn(ValidationResult.ok());
 
             final SubmissionPayload submissionPayload = SubmissionBuilder.Builder()
                     .withJsonData("\"test\": \"json\"",
@@ -268,7 +268,7 @@ class ValidDataGuardTest {
             destination.setServices(Set.of(service));
 
             when(senderMock.getDestination(any())).thenReturn(destination);
-            when(senderMock.validateJsonFormat(any())).thenReturn(ValidationResult.ok());
+            when(senderMock.validateJsonFormat(any(), URI.create("urn:something"))).thenReturn(ValidationResult.ok());
 
             final EncryptedSubmissionPayload encryptedSubmissionPayload = EncryptedSubmissionBuilder.Builder()
                     .withEncryptedData("4Y0sJhadfrQnNZXeS7Pqh73FvtF")
@@ -321,7 +321,7 @@ class ValidDataGuardTest {
         void testMissingDestinationId() {
 
             // Given
-            when(senderMock.validateJsonFormat(any())).thenReturn(ValidationResult.ok());
+            when(senderMock.validateJsonFormat(any(), URI.create("urn:something"))).thenReturn(ValidationResult.ok());
 
             final EncryptedSubmissionPayload encryptedSubmissionPayload = EncryptedSubmissionBuilder.Builder()
                     .withEncryptedData("4Y0sJhadfrQnNZXeS7Pqh73FvtF")
@@ -341,7 +341,7 @@ class ValidDataGuardTest {
         void testInvalidServiceIdentifier() {
 
             // Given
-            when(senderMock.validateJsonFormat(any())).thenReturn(ValidationResult.ok());
+            when(senderMock.validateJsonFormat(any(), URI.create("urn:something"))).thenReturn(ValidationResult.ok());
 
             final EncryptedSubmissionPayload encryptedSubmissionPayload = EncryptedSubmissionBuilder.Builder()
                     .withEncryptedData("4Y0sJhadfrQnNZXeS7Pqh73FvtF")
@@ -361,7 +361,7 @@ class ValidDataGuardTest {
         void testMissingServiceIdentifier() {
 
             // Given
-            when(senderMock.validateJsonFormat(any())).thenReturn(ValidationResult.ok());
+            when(senderMock.validateJsonFormat(any(), URI.create("urn:something"))).thenReturn(ValidationResult.ok());
 
             final EncryptedSubmissionPayload encryptedSubmissionPayload = EncryptedSubmissionBuilder.Builder()
                     .withEncryptedData("4Y0sJhadfrQnNZXeS7Pqh73FvtF")
@@ -387,7 +387,7 @@ class ValidDataGuardTest {
             destination.setServices(Set.of(service));
 
             when(senderMock.getDestination(any())).thenReturn(destination);
-            when(senderMock.validateJsonFormat(any())).thenReturn(ValidationResult.ok());
+            when(senderMock.validateJsonFormat(any(), URI.create("urn:something"))).thenReturn(ValidationResult.ok());
 
             final EncryptedSubmissionPayload encryptedSubmissionPayload = EncryptedSubmissionBuilder.Builder()
                     .withEncryptedData("4Y0sJhadfrQnNZXeS7Pqh73FvtF")
diff --git a/core/src/main/java/dev/fitko/fitconnect/core/SubmissionSender.java b/core/src/main/java/dev/fitko/fitconnect/core/SubmissionSender.java
index eb5cc289f429871403de518cefccfca60b5cd1b2..d58b74baf4733d024a5014b348d05cb44351b7a8 100644
--- a/core/src/main/java/dev/fitko/fitconnect/core/SubmissionSender.java
+++ b/core/src/main/java/dev/fitko/fitconnect/core/SubmissionSender.java
@@ -6,7 +6,10 @@ import dev.fitko.fitconnect.api.domain.model.event.EventLogEntry;
 import dev.fitko.fitconnect.api.domain.model.event.EventStatus;
 import dev.fitko.fitconnect.api.domain.model.event.authtags.AuthenticationTags;
 import dev.fitko.fitconnect.api.domain.model.metadata.Metadata;
-import dev.fitko.fitconnect.api.domain.model.submission.*;
+import dev.fitko.fitconnect.api.domain.model.submission.CreateSubmission;
+import dev.fitko.fitconnect.api.domain.model.submission.Submission;
+import dev.fitko.fitconnect.api.domain.model.submission.SubmissionForPickup;
+import dev.fitko.fitconnect.api.domain.model.submission.SubmitSubmission;
 import dev.fitko.fitconnect.api.domain.validation.ValidationResult;
 import dev.fitko.fitconnect.api.services.Sender;
 import dev.fitko.fitconnect.api.services.crypto.CryptoService;
@@ -17,6 +20,7 @@ import dev.fitko.fitconnect.api.services.validation.ValidationService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.net.URI;
 import java.util.List;
 import java.util.UUID;
 
@@ -112,9 +116,9 @@ public class SubmissionSender implements Sender {
     }
 
     @Override
-    public ValidationResult validateJsonFormat(final SubmissionPayload json) {
+    public ValidationResult validateJsonFormat(final String json, final URI schemaUri) {
         LOGGER.info("Validating data json format");
-        return validationService.validateJsonFormat(json);
+        return validationService.validateJsonFormat(json, schemaUri);
     }
 
     @Override
diff --git a/core/src/main/java/dev/fitko/fitconnect/core/schema/SchemaResourceProvider.java b/core/src/main/java/dev/fitko/fitconnect/core/schema/SchemaResourceProvider.java
index cb5cfef450e902b2db6af39322660c5d56e21acd..cb81e6849f036aaf147d460cac118a155c35b394 100644
--- a/core/src/main/java/dev/fitko/fitconnect/core/schema/SchemaResourceProvider.java
+++ b/core/src/main/java/dev/fitko/fitconnect/core/schema/SchemaResourceProvider.java
@@ -9,6 +9,7 @@ import dev.fitko.fitconnect.api.exceptions.SchemaNotFoundException;
 import dev.fitko.fitconnect.api.services.schema.SchemaProvider;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.web.client.RestTemplate;
 
 import java.io.BufferedReader;
 import java.io.InputStream;
@@ -32,15 +33,22 @@ public class SchemaResourceProvider implements SchemaProvider {
 
     private final Map<URI, String> destinationSchemas;
 
+    private final Map<URI, String> submissionDataSchemas;
+
+    private final RestTemplate restTemplate;
+
     private static final ObjectMapper MAPPER = new ObjectMapper();
 
-    public SchemaResourceProvider(final SchemaResources schemaResources) {
+    public SchemaResourceProvider(final RestTemplate restTemplate, final SchemaResources schemaResources) {
         setSchemas = new HashMap<>();
         metadataSchemas = new HashMap<>();
         destinationSchemas = new HashMap<>();
+        submissionDataSchemas = new HashMap<>();
+        this.restTemplate = restTemplate;
         populateSetSchemas(schemaResources.getSetSchemaPaths());
         populateMetadataSchemas(schemaResources.getMetadataSchemaPaths());
         populateDestinationSchemas(schemaResources.getDestinationSchemaPaths());
+        populateSubmissionDataSchemas(schemaResources.getSubmissionDataSchemaPaths());
     }
 
     private void populateMetadataSchemas(final List<String> metadataSchemaPaths) {
@@ -58,6 +66,11 @@ public class SchemaResourceProvider implements SchemaProvider {
         getResourceFiles(destinationSchemaPaths).forEach(this::addDestinationSchema);
     }
 
+    private void populateSubmissionDataSchemas(final List<String> submissionDataSchemaPaths) {
+        LOGGER.info("Initializing submission data schemas");
+        getResourceFiles(submissionDataSchemaPaths).forEach(this::addSubmissionDataSchema);
+    }
+
     @Override
     public boolean isAllowedSetSchema(final URI schemaUri) {
         return schemaVersionMatchesPattern(schemaUri, ALLOWED_SCHEMA_PATTERN);
@@ -99,14 +112,19 @@ public class SchemaResourceProvider implements SchemaProvider {
     @Override
     public String loadSubmissionDataSchema(final URI schemaUri) throws SchemaNotFoundException {
 
-        String schema;
-        if(schemaUri.toString().matches("http.+")) {
-            schema = "load schema from remote";
+        if (schemaUri.toString().matches("http.+")) {
+            try {
+                return restTemplate.getForEntity(schemaUri, String.class).getBody();
+            } catch (Exception exception) {
+                throw new SchemaNotFoundException("Submission data schema " + schemaUri + " is not available.", exception);
+            }
         }
-        schema = destinationSchemas.get(schemaUri);
+
+        final String schema = submissionDataSchemas.get(schemaUri);
         if (schema == null) {
-            throw new SchemaNotFoundException("Destination schema " + schemaUri.toString() + " is not available.");
+            throw new SchemaNotFoundException("Submission data schema " + schemaUri + " is not available.");
         }
+
         return schema;
     }
 
@@ -122,6 +140,10 @@ public class SchemaResourceProvider implements SchemaProvider {
         destinationSchemas.put(readIdFromSchema(schema), schema);
     }
 
+    private void addSubmissionDataSchema(final String schema) {
+        submissionDataSchemas.put(readIdFromSchema(schema), schema);
+    }
+
     private URI readIdFromSchema(final String schema) {
         try {
             return URI.create(MAPPER.readTree(schema).get("$id").asText());
diff --git a/core/src/main/java/dev/fitko/fitconnect/core/validation/DefaultValidationService.java b/core/src/main/java/dev/fitko/fitconnect/core/validation/DefaultValidationService.java
index 37455f13cf52a0e8c6b8e053712ae8ce11da4454..31a70c2137720dce5bcd40a1875ecd2005e7ced7 100644
--- a/core/src/main/java/dev/fitko/fitconnect/core/validation/DefaultValidationService.java
+++ b/core/src/main/java/dev/fitko/fitconnect/core/validation/DefaultValidationService.java
@@ -33,7 +33,6 @@ import org.xml.sax.XMLReader;
 
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.parsers.SAXParserFactory;
-
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.net.InetSocketAddress;
@@ -152,9 +151,11 @@ public class DefaultValidationService implements ValidationService {
     }
 
     @Override
-    public ValidationResult validateJsonFormat(final String json) {
+    public ValidationResult validateJsonFormat(final String json, final URI schemaUri) {
+
+        String schema = schemaProvider.loadSubmissionDataSchema(schemaUri);
         try {
-            MAPPER.readTree(json);
+            returnValidationResult(SCHEMA_FACTORY_DRAFT_2007.getSchema(schema).validate(MAPPER.readTree(json)));
         } catch (final JacksonException e) {
             return ValidationResult.error(e);
         }
diff --git a/core/src/test/java/dev/fitko/fitconnect/core/SubmissionSenderTest.java b/core/src/test/java/dev/fitko/fitconnect/core/SubmissionSenderTest.java
index 46a8f81341450573d2aa69c7c65c0ec54c063f20..7887831208484aa9945cb6b79e7f8e1d19e1028c 100644
--- a/core/src/test/java/dev/fitko/fitconnect/core/SubmissionSenderTest.java
+++ b/core/src/test/java/dev/fitko/fitconnect/core/SubmissionSenderTest.java
@@ -37,6 +37,7 @@ import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
 import java.io.IOException;
+import java.net.URI;
 import java.text.ParseException;
 import java.util.Collections;
 import java.util.Date;
@@ -54,6 +55,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
@@ -331,10 +333,10 @@ public class SubmissionSenderTest {
     void testValidJsonFormatValidation() {
 
         // Given
-        when(validationServiceMock.validateJsonFormat(any())).thenReturn(ValidationResult.ok());
+        when(validationServiceMock.validateJsonFormat(any(), eq(URI.create("urn:something")))).thenReturn(ValidationResult.ok());
 
         // When
-        final ValidationResult validationResult = underTest.validateJsonFormat("{}");
+        final ValidationResult validationResult = underTest.validateJsonFormat("{}", URI.create("urn:something"));
 
         //Then
         assertTrue(validationResult.isValid());
@@ -344,10 +346,10 @@ public class SubmissionSenderTest {
     void testInvalidJsonFormatValidation() {
 
         // Given
-        when(validationServiceMock.validateJsonFormat(any())).thenReturn(ValidationResult.error(new ValidationException("Invalid json")));
+        when(validationServiceMock.validateJsonFormat(any(), eq(URI.create("urn:something")))).thenReturn(ValidationResult.error(new ValidationException("Invalid json")));
 
         // When
-        final ValidationResult validationResult = underTest.validateJsonFormat("$%&/()");
+        final ValidationResult validationResult = underTest.validateJsonFormat("$%&/()", URI.create("urn:something"));
 
         //Then
         assertTrue(validationResult.hasError());
diff --git a/core/src/test/java/dev/fitko/fitconnect/core/events/SecurityEventTokenServiceTest.java b/core/src/test/java/dev/fitko/fitconnect/core/events/SecurityEventTokenServiceTest.java
index a790df4634bbef654f6e6d7eefda5a7661df9da7..c894ac53ad9d76576289815db42492223f081f7b 100644
--- a/core/src/test/java/dev/fitko/fitconnect/core/events/SecurityEventTokenServiceTest.java
+++ b/core/src/test/java/dev/fitko/fitconnect/core/events/SecurityEventTokenServiceTest.java
@@ -27,6 +27,7 @@ import dev.fitko.fitconnect.core.schema.SchemaResourceProvider;
 import dev.fitko.fitconnect.core.validation.DefaultValidationService;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
+import org.springframework.web.client.RestTemplate;
 
 import java.io.File;
 import java.io.IOException;
@@ -41,6 +42,7 @@ import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.containsString;
 import static org.hamcrest.Matchers.is;
 import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.mock;
 
 class SecurityEventTokenServiceTest {
 
@@ -61,8 +63,9 @@ class SecurityEventTokenServiceTest {
         final List<String> setSchemas = SchemaConfig.getSetSchemaFilePaths("/set-schema");
         final List<String> metadataSchemas = SchemaConfig.getMetadataSchemaFileNames("/metadata-schema");
         final List<String> destinationSchemas = SchemaConfig.getDestinationSchemaPaths("/destination-schema");
-        final SchemaResources schemaResources = new SchemaResources(setSchemas, metadataSchemas, destinationSchemas);
-        final SchemaProvider schemaProvider = new SchemaResourceProvider(schemaResources);
+        final List<String> submissionDataSchemas = SchemaConfig.getSubmissionDataSchemaPaths("/submission-data-schema");
+        final SchemaResources schemaResources = new SchemaResources(setSchemas, metadataSchemas, destinationSchemas, submissionDataSchemas);
+        final SchemaProvider schemaProvider = new SchemaResourceProvider(mock(RestTemplate.class), schemaResources);
 
         validationService = new DefaultValidationService(config, new HashService(), schemaProvider);
         underTest = new SecurityEventTokenService(config, validationService, signingKey);
diff --git a/core/src/test/java/dev/fitko/fitconnect/core/schema/SchemaResourceProviderTest.java b/core/src/test/java/dev/fitko/fitconnect/core/schema/SchemaResourceProviderTest.java
index 0b1899e945d8a6eda17770d21ff9a9ba381ae8e5..764644acc6ba655c6a259d84647a9eab21e1411a 100644
--- a/core/src/test/java/dev/fitko/fitconnect/core/schema/SchemaResourceProviderTest.java
+++ b/core/src/test/java/dev/fitko/fitconnect/core/schema/SchemaResourceProviderTest.java
@@ -8,6 +8,7 @@ import dev.fitko.fitconnect.api.exceptions.SchemaNotFoundException;
 import dev.fitko.fitconnect.api.services.schema.SchemaProvider;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
+import org.springframework.web.client.RestTemplate;
 
 import java.net.URI;
 import java.util.List;
@@ -15,6 +16,7 @@ import java.util.List;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.equalTo;
 import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.mock;
 
 class SchemaResourceProviderTest {
 
@@ -25,8 +27,9 @@ class SchemaResourceProviderTest {
         final List<String> setSchemas = SchemaConfig.getSetSchemaFilePaths("/set-schema");
         final List<String> metadataSchemas = SchemaConfig.getMetadataSchemaFileNames("/metadata-schema");
         final List<String> destinationSchemas = SchemaConfig.getDestinationSchemaPaths("/destination-schema");
-        final SchemaResources schemaResources = new SchemaResources(setSchemas, metadataSchemas, destinationSchemas);
-        underTest = new SchemaResourceProvider(schemaResources);
+        final List<String> submissionDataSchemas = SchemaConfig.getSubmissionDataSchemaPaths("/submission-data-schema");
+        final SchemaResources schemaResources = new SchemaResources(setSchemas, metadataSchemas, destinationSchemas, submissionDataSchemas);
+        underTest = new SchemaResourceProvider(mock(RestTemplate.class), schemaResources);
     }
 
     @Test
diff --git a/core/src/test/java/dev/fitko/fitconnect/core/validation/DefaultValidationServiceTest.java b/core/src/test/java/dev/fitko/fitconnect/core/validation/DefaultValidationServiceTest.java
index ba7f6ec3e1f553294408cf421a9218f2ad9f2462..ede11c83a93f887693e1075dba52b62c03f1737a 100644
--- a/core/src/test/java/dev/fitko/fitconnect/core/validation/DefaultValidationServiceTest.java
+++ b/core/src/test/java/dev/fitko/fitconnect/core/validation/DefaultValidationServiceTest.java
@@ -32,6 +32,7 @@ import dev.fitko.fitconnect.jwkvalidator.exceptions.JWKValidationException;
 import org.hamcrest.CoreMatchers;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
+import org.springframework.web.client.RestTemplate;
 
 import java.io.IOException;
 import java.net.URI;
@@ -59,8 +60,9 @@ class DefaultValidationServiceTest {
         final List<String> setSchemas = SchemaConfig.getSetSchemaFilePaths("/set-schema");
         final List<String> metadataSchemas = SchemaConfig.getMetadataSchemaFileNames("/metadata-schema");
         final List<String> destinationSchemas = SchemaConfig.getDestinationSchemaPaths("/destination-schema");
-        final SchemaResources schemaResources = new SchemaResources(setSchemas, metadataSchemas, destinationSchemas);
-        schemaProvider = new SchemaResourceProvider(schemaResources);
+        final List<String> submissionDataSchemas = SchemaConfig.getSubmissionDataSchemaPaths("/submission-data-schema");
+        final SchemaResources schemaResources = new SchemaResources(setSchemas, metadataSchemas, destinationSchemas, submissionDataSchemas);
+        schemaProvider = new SchemaResourceProvider(mock(RestTemplate.class), schemaResources);
         underTest = new DefaultValidationService(config, hashService, schemaProvider);
     }
 
@@ -412,7 +414,7 @@ class DefaultValidationServiceTest {
         final var validJson = getResource("/valid_json_data.json");
 
         // When
-        final ValidationResult validationResult = underTest.validateJsonFormat(validJson);
+        final ValidationResult validationResult = underTest.validateJsonFormat(validJson, URI.create("urn:something"));
 
         // Then
         assertTrue(validationResult.isValid());
@@ -425,7 +427,7 @@ class DefaultValidationServiceTest {
         final var invalidJson = getResource("/invalid_json_data.json");
 
         // When
-        final ValidationResult validationResult = underTest.validateJsonFormat(invalidJson);
+        final ValidationResult validationResult = underTest.validateJsonFormat(invalidJson, URI.create("urn:something"));
 
         // Then
         assertFalse(validationResult.isValid());